1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Security database interface. 28 */ 29 #include <unistd.h> 30 #include <strings.h> 31 #include <pwd.h> 32 #include <grp.h> 33 #include <time.h> 34 #include <syslog.h> 35 #include <assert.h> 36 37 #include <smbsrv/libsmb.h> 38 #include <smbsrv/libmlsvc.h> 39 40 #include <smbsrv/smbinfo.h> 41 #include <smbsrv/smb_token.h> 42 #include <lsalib.h> 43 44 extern uint32_t netlogon_logon(netr_client_t *clnt, smb_userinfo_t *uinfo); 45 static uint32_t smb_logon_domain(netr_client_t *clnt, smb_userinfo_t *uinfo); 46 static uint32_t smb_logon_local(netr_client_t *clnt, smb_userinfo_t *uinfo); 47 static uint32_t smb_logon_none(netr_client_t *clnt, smb_userinfo_t *uinfo); 48 49 static uint32_t smb_setup_luinfo(smb_userinfo_t *, netr_client_t *, uid_t); 50 51 static int smb_token_is_member(smb_token_t *token, smb_sid_t *sid); 52 static int smb_token_is_valid(smb_token_t *token); 53 static smb_win_grps_t *smb_token_create_wingrps(smb_userinfo_t *user_info); 54 55 static smb_posix_grps_t *smb_token_create_pxgrps(uid_t uid); 56 57 /* Consolidation private function from Network Repository */ 58 extern int _getgroupsbymember(const char *, gid_t[], int, int); 59 60 static idmap_stat 61 smb_token_idmap(smb_token_t *token, smb_idmap_batch_t *sib) 62 { 63 idmap_stat stat; 64 smb_idmap_t *sim; 65 smb_id_t *id; 66 int i; 67 68 if (!token || !sib) 69 return (IDMAP_ERR_ARG); 70 71 sim = sib->sib_maps; 72 73 if (token->tkn_flags & SMB_ATF_ANON) { 74 token->tkn_user->i_id = UID_NOBODY; 75 token->tkn_owner->i_id = UID_NOBODY; 76 } else { 77 /* User SID */ 78 id = token->tkn_user; 79 sim->sim_id = &id->i_id; 80 stat = smb_idmap_batch_getid(sib->sib_idmaph, sim++, 81 id->i_sidattr.sid, SMB_IDMAP_USER); 82 83 if (stat != IDMAP_SUCCESS) 84 return (stat); 85 86 /* Owner SID */ 87 id = token->tkn_owner; 88 sim->sim_id = &id->i_id; 89 stat = smb_idmap_batch_getid(sib->sib_idmaph, sim++, 90 id->i_sidattr.sid, SMB_IDMAP_USER); 91 92 if (stat != IDMAP_SUCCESS) 93 return (stat); 94 } 95 96 /* Primary Group SID */ 97 id = token->tkn_primary_grp; 98 sim->sim_id = &id->i_id; 99 stat = smb_idmap_batch_getid(sib->sib_idmaph, sim++, 100 id->i_sidattr.sid, SMB_IDMAP_GROUP); 101 102 if (stat != IDMAP_SUCCESS) 103 return (stat); 104 105 /* Other Windows Group SIDs */ 106 for (i = 0; i < token->tkn_win_grps->wg_count; i++, sim++) { 107 id = &token->tkn_win_grps->wg_groups[i]; 108 sim->sim_id = &id->i_id; 109 stat = smb_idmap_batch_getid(sib->sib_idmaph, sim, 110 id->i_sidattr.sid, SMB_IDMAP_GROUP); 111 112 if (stat != IDMAP_SUCCESS) 113 break; 114 } 115 116 return (stat); 117 } 118 119 /* 120 * smb_token_sids2ids 121 * 122 * This will map all the SIDs of the access token to UIDs/GIDs. 123 * 124 * Returns 0 upon success. Otherwise, returns -1. 125 */ 126 static int 127 smb_token_sids2ids(smb_token_t *token) 128 { 129 idmap_stat stat; 130 int nmaps, retries = 0; 131 smb_idmap_batch_t sib; 132 133 /* 134 * Number of idmap lookups: user SID, owner SID, primary group SID, 135 * and all Windows group SIDs 136 */ 137 if (token->tkn_flags & SMB_ATF_ANON) 138 /* 139 * Don't include user and owner SID, they're Anonymous 140 */ 141 nmaps = 1; 142 else 143 nmaps = 3; 144 145 nmaps += token->tkn_win_grps->wg_count; 146 147 do { 148 stat = smb_idmap_batch_create(&sib, nmaps, SMB_IDMAP_SID2ID); 149 if (stat != IDMAP_SUCCESS) 150 return (-1); 151 152 stat = smb_token_idmap(token, &sib); 153 if (stat != IDMAP_SUCCESS) { 154 smb_idmap_batch_destroy(&sib); 155 return (-1); 156 } 157 158 stat = smb_idmap_batch_getmappings(&sib); 159 smb_idmap_batch_destroy(&sib); 160 if (stat == IDMAP_ERR_RPC_HANDLE) 161 if (smb_idmap_restart() < 0) 162 break; 163 } while (stat == IDMAP_ERR_RPC_HANDLE && retries++ < 3); 164 165 return (stat == IDMAP_SUCCESS ? 0 : -1); 166 } 167 168 /* 169 * smb_token_create_pxgrps 170 * 171 * Setup the POSIX group membership of the access token if the given UID is 172 * a POSIX UID (non-ephemeral). Both the user's primary group and 173 * supplementary groups will be added to the POSIX group array of the access 174 * token. 175 */ 176 static smb_posix_grps_t * 177 smb_token_create_pxgrps(uid_t uid) 178 { 179 struct passwd *pwd; 180 smb_posix_grps_t *pgrps; 181 int ngroups_max, num; 182 gid_t *gids; 183 184 if ((ngroups_max = sysconf(_SC_NGROUPS_MAX)) < 0) { 185 syslog(LOG_ERR, "smb_logon: failed to get _SC_NGROUPS_MAX"); 186 return (NULL); 187 } 188 189 pwd = getpwuid(uid); 190 if (pwd == NULL) { 191 pgrps = malloc(sizeof (smb_posix_grps_t)); 192 if (pgrps == NULL) 193 return (NULL); 194 195 pgrps->pg_ngrps = 0; 196 return (pgrps); 197 } 198 199 if (pwd->pw_name == NULL) { 200 pgrps = malloc(sizeof (smb_posix_grps_t)); 201 if (pgrps == NULL) 202 return (NULL); 203 204 pgrps->pg_ngrps = 1; 205 pgrps->pg_grps[0] = pwd->pw_gid; 206 return (pgrps); 207 } 208 209 gids = (gid_t *)malloc(ngroups_max * sizeof (gid_t)); 210 if (gids == NULL) { 211 return (NULL); 212 } 213 bzero(gids, ngroups_max * sizeof (gid_t)); 214 215 gids[0] = pwd->pw_gid; 216 217 /* 218 * Setup the groups starting at index 1 (the last arg) 219 * of gids array. 220 */ 221 num = _getgroupsbymember(pwd->pw_name, gids, ngroups_max, 1); 222 223 if (num == -1) { 224 syslog(LOG_ERR, "smb_logon: unable " 225 "to get user's supplementary groups"); 226 num = 1; 227 } 228 229 pgrps = (smb_posix_grps_t *)malloc(SMB_POSIX_GRPS_SIZE(num)); 230 if (pgrps) { 231 pgrps->pg_ngrps = num; 232 bcopy(gids, pgrps->pg_grps, num * sizeof (gid_t)); 233 } 234 235 free(gids); 236 return (pgrps); 237 } 238 239 /* 240 * smb_token_destroy 241 * 242 * Release all of the memory associated with a token structure. Ensure 243 * that the token has been unlinked before calling. 244 */ 245 void 246 smb_token_destroy(smb_token_t *token) 247 { 248 smb_win_grps_t *groups; 249 int i; 250 251 if (token == NULL) 252 return; 253 254 if (token->tkn_user) { 255 free(token->tkn_user->i_sidattr.sid); 256 free(token->tkn_user); 257 } 258 259 if (token->tkn_owner) { 260 free(token->tkn_owner->i_sidattr.sid); 261 free(token->tkn_owner); 262 } 263 264 if (token->tkn_primary_grp) { 265 free(token->tkn_primary_grp->i_sidattr.sid); 266 free(token->tkn_primary_grp); 267 } 268 269 if ((groups = token->tkn_win_grps) != NULL) { 270 for (i = 0; i < groups->wg_count; ++i) 271 free(groups->wg_groups[i].i_sidattr.sid); 272 free(groups); 273 } 274 275 smb_privset_free(token->tkn_privileges); 276 277 free(token->tkn_posix_grps); 278 free(token->tkn_account_name); 279 free(token->tkn_domain_name); 280 free(token->tkn_session_key); 281 282 free(token); 283 } 284 285 static smb_id_t * 286 smb_token_create_id(smb_sid_t *sid) 287 { 288 smb_id_t *id; 289 290 if ((id = malloc(sizeof (smb_id_t))) == NULL) 291 return (NULL); 292 293 id->i_id = (uid_t)-1; 294 id->i_sidattr.attrs = 7; 295 id->i_sidattr.sid = smb_sid_dup(sid); 296 297 if (id->i_sidattr.sid == NULL) { 298 free(id); 299 id = NULL; 300 } 301 302 return (id); 303 } 304 305 /* 306 * Token owner should be set to local Administrators group 307 * in two cases: 308 * 1. The logged on user is a member of Domain Admins group 309 * 2. he/she is a member of local Administrators group 310 */ 311 static smb_id_t * 312 smb_token_create_owner(smb_userinfo_t *user_info) 313 { 314 #ifdef SMB_SUPPORT_GROUP_OWNER 315 smb_sid_t *owner_sid; 316 smb_wka_t *wka; 317 318 if (user_info->flags & SMB_UINFO_FLAG_ADMIN) { 319 wka = smb_wka_lookup("Administrators"); 320 assert(wka); 321 owner_sid = wka->wka_binsid; 322 } else { 323 owner_sid = user_info->user_sid; 324 } 325 326 return (smb_token_create_id(owner_sid)); 327 #endif 328 return (smb_token_create_id(user_info->user_sid)); 329 } 330 331 static smb_privset_t * 332 smb_token_create_privs(smb_userinfo_t *user_info) 333 { 334 smb_privset_t *privs; 335 smb_giter_t gi; 336 smb_group_t grp; 337 int rc; 338 339 privs = smb_privset_new(); 340 if (privs == NULL) 341 return (NULL); 342 343 if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) { 344 smb_privset_free(privs); 345 return (NULL); 346 } 347 348 while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) { 349 if (smb_lgrp_is_member(&grp, user_info->user_sid)) { 350 smb_privset_merge(privs, grp.sg_privs); 351 } 352 smb_lgrp_free(&grp); 353 } 354 smb_lgrp_iterclose(&gi); 355 356 if (user_info->flags & SMB_UINFO_FLAG_ADMIN) { 357 rc = smb_lgrp_getbyname("Administrators", &grp); 358 if (rc == SMB_LGRP_SUCCESS) { 359 smb_privset_merge(privs, grp.sg_privs); 360 smb_lgrp_free(&grp); 361 } 362 363 /* 364 * This privilege is required to view/edit SACL 365 */ 366 smb_privset_enable(privs, SE_SECURITY_LUID); 367 } 368 369 return (privs); 370 } 371 372 static void 373 smb_token_set_flags(smb_token_t *token, smb_userinfo_t *user_info) 374 { 375 smb_wka_t *wka; 376 377 if (user_info->flags & SMB_UINFO_FLAG_ANON) { 378 token->tkn_flags |= SMB_ATF_ANON; 379 return; 380 } 381 382 if (user_info->rid == DOMAIN_USER_RID_GUEST) { 383 token->tkn_flags |= SMB_ATF_GUEST; 384 return; 385 } 386 387 wka = smb_wka_lookup("Administrators"); 388 if (wka->wka_binsid && smb_token_is_member(token, wka->wka_binsid)) 389 token->tkn_flags |= SMB_ATF_ADMIN; 390 391 wka = smb_wka_lookup("Power Users"); 392 if (wka->wka_binsid && smb_token_is_member(token, wka->wka_binsid)) 393 token->tkn_flags |= SMB_ATF_POWERUSER; 394 395 wka = smb_wka_lookup("Backup Operators"); 396 if (wka->wka_binsid && smb_token_is_member(token, wka->wka_binsid)) 397 token->tkn_flags |= SMB_ATF_BACKUPOP; 398 399 } 400 401 /* 402 * smb_token_create 403 * 404 * Build an access token based on the given user information (user_info). 405 * 406 * If everything is successful, a pointer to an access token is 407 * returned. Otherwise a null pointer is returned. 408 */ 409 static smb_token_t * 410 smb_token_create(smb_userinfo_t *user_info) 411 { 412 smb_token_t *token; 413 414 if (user_info->sid_name_use != SidTypeUser) 415 return (NULL); 416 417 token = (smb_token_t *)malloc(sizeof (smb_token_t)); 418 if (token == NULL) { 419 syslog(LOG_ERR, "smb_token_create: resource shortage"); 420 return (NULL); 421 } 422 bzero(token, sizeof (smb_token_t)); 423 424 /* User */ 425 token->tkn_user = smb_token_create_id(user_info->user_sid); 426 if (token->tkn_user == NULL) { 427 smb_token_destroy(token); 428 return (NULL); 429 } 430 431 /* Owner */ 432 token->tkn_owner = smb_token_create_owner(user_info); 433 if (token->tkn_owner == NULL) { 434 smb_token_destroy(token); 435 return (NULL); 436 } 437 438 /* Primary Group */ 439 token->tkn_primary_grp = smb_token_create_id(user_info->pgrp_sid); 440 if (token->tkn_primary_grp == NULL) { 441 smb_token_destroy(token); 442 return (NULL); 443 } 444 445 /* Privileges */ 446 token->tkn_privileges = smb_token_create_privs(user_info); 447 if (token->tkn_privileges == NULL) { 448 smb_token_destroy(token); 449 return (NULL); 450 } 451 452 /* Windows Groups */ 453 token->tkn_win_grps = smb_token_create_wingrps(user_info); 454 455 smb_token_set_flags(token, user_info); 456 457 /* 458 * IMPORTANT 459 * 460 * This function has to be called after all the SIDs in the 461 * token are setup (i.e. user, owner, primary and supplementary 462 * groups) and before setting up Solaris groups. 463 */ 464 if (smb_token_sids2ids(token) != 0) { 465 syslog(LOG_ERR, "%s\\%s: idmap failed", 466 (user_info->domain_name) ? user_info->domain_name : "", 467 (user_info->name) ? user_info->name : ""); 468 smb_token_destroy(token); 469 return (NULL); 470 } 471 472 /* Solaris Groups */ 473 token->tkn_posix_grps = smb_token_create_pxgrps(token->tkn_user->i_id); 474 475 if (user_info->session_key) { 476 token->tkn_session_key = malloc(sizeof (smb_session_key_t)); 477 if (token->tkn_session_key == NULL) { 478 smb_token_destroy(token); 479 return (NULL); 480 } 481 482 (void) memcpy(token->tkn_session_key, 483 user_info->session_key, sizeof (smb_session_key_t)); 484 } 485 486 token->tkn_account_name = strdup(user_info->name); 487 token->tkn_domain_name = strdup(user_info->domain_name); 488 489 if (!smb_token_is_valid(token)) { 490 smb_token_destroy(token); 491 return (NULL); 492 } 493 494 return (token); 495 } 496 497 /* 498 * smb_token_create_wingrps 499 * 500 * This private function supports smb_token_create() by mapping the group 501 * information in the user_info structure to the form required in an 502 * access token. The main difference is that the user_info contains 503 * RIDs while and access token contains full SIDs. Memory allocated 504 * here will be deallocated as part of smb_token_destroy(). 505 * 506 * If everything is successful, a pointer to a smb_win_grps_t 507 * structure is returned. Otherwise a null pointer is returned. 508 */ 509 static smb_win_grps_t * 510 smb_token_create_wingrps(smb_userinfo_t *user_info) 511 { 512 static char *wk_grps[] = 513 {"Authenticated Users", "NETWORK", "Administrators"}; 514 smb_win_grps_t *tkn_grps; 515 smb_sid_attrs_t *dlg_grps; 516 smb_rid_attrs_t *g_grps; 517 smb_sid_attrs_t *grp; 518 smb_sid_t *builtin_sid; 519 smb_giter_t gi; 520 smb_group_t lgrp; 521 uint32_t n_gg, n_lg, n_dlg, n_wg; 522 uint32_t i, j; 523 int size, count; 524 525 if (user_info == NULL) 526 return (NULL); 527 528 n_gg = user_info->n_groups; /* Global Groups */ 529 n_dlg = user_info->n_other_grps; /* Domain Local Groups */ 530 531 /* Local Groups */ 532 (void) smb_lgrp_numbymember(user_info->user_sid, (int *)&n_lg); 533 534 /* Well known Groups */ 535 if ((user_info->flags & SMB_UINFO_FLAG_ADMIN) == SMB_UINFO_FLAG_DADMIN) 536 /* if user is a domain admin but not a local admin */ 537 n_wg = 3; 538 else if (user_info->flags & SMB_UINFO_FLAG_ANON) 539 n_wg = 0; 540 else 541 n_wg = 2; 542 543 count = n_gg + n_dlg + n_lg + n_wg; 544 size = sizeof (smb_win_grps_t) + (count * sizeof (smb_id_t)); 545 546 if ((tkn_grps = malloc(size)) == NULL) 547 return (NULL); 548 bzero(tkn_grps, size); 549 550 /* Add global groups */ 551 g_grps = user_info->groups; 552 for (i = 0; i < n_gg; i++) { 553 grp = &tkn_grps->wg_groups[i].i_sidattr; 554 grp->sid = smb_sid_splice(user_info->domain_sid, g_grps[i].rid); 555 if (grp->sid == NULL) 556 break; 557 grp->attrs = g_grps[i].attributes; 558 } 559 560 if (n_gg == 0) { 561 /* 562 * if there's no global group should add the 563 * primary group. 564 */ 565 grp = &tkn_grps->wg_groups[i].i_sidattr; 566 grp->sid = smb_sid_dup(user_info->pgrp_sid); 567 if (grp->sid != NULL) { 568 grp->attrs = 0x7; 569 i++; 570 } 571 } 572 573 /* Add domain local groups */ 574 dlg_grps = user_info->other_grps; 575 for (j = 0; j < n_dlg; j++, i++) { 576 grp = &tkn_grps->wg_groups[i].i_sidattr; 577 grp->sid = smb_sid_dup(dlg_grps[j].sid); 578 if (grp->sid == NULL) 579 break; 580 grp->attrs = dlg_grps[j].attrs; 581 } 582 583 /* Add local groups */ 584 if (n_lg && (smb_lgrp_iteropen(&gi) == SMB_LGRP_SUCCESS)) { 585 j = 0; 586 while (smb_lgrp_iterate(&gi, &lgrp) == SMB_LGRP_SUCCESS) { 587 if ((j < n_lg) && 588 smb_lgrp_is_member(&lgrp, user_info->user_sid)) { 589 grp = &tkn_grps->wg_groups[i].i_sidattr; 590 grp->sid = smb_sid_dup(lgrp.sg_id.gs_sid); 591 if (grp->sid == NULL) { 592 smb_lgrp_free(&lgrp); 593 break; 594 } 595 grp->attrs = lgrp.sg_attr; 596 i++; 597 j++; 598 } 599 smb_lgrp_free(&lgrp); 600 } 601 smb_lgrp_iterclose(&gi); 602 } 603 604 /* Add well known groups */ 605 for (j = 0; j < n_wg; j++, i++) { 606 builtin_sid = smb_wka_lookup_name(wk_grps[j], NULL); 607 if (builtin_sid == NULL) 608 break; 609 tkn_grps->wg_groups[i].i_sidattr.sid = builtin_sid; 610 tkn_grps->wg_groups[i].i_sidattr.attrs = 0x7; 611 } 612 613 tkn_grps->wg_count = i; 614 return (tkn_grps); 615 } 616 617 /* 618 * smb_logon 619 * 620 * Performs user authentication and creates a token if the 621 * authentication is successful. 622 * 623 * Returns pointer to the created token. 624 */ 625 smb_token_t * 626 smb_logon(netr_client_t *clnt) 627 { 628 smb_token_t *token = NULL; 629 smb_userinfo_t *uinfo; 630 uint32_t status; 631 632 if ((uinfo = mlsvc_alloc_user_info()) == 0) 633 return (NULL); 634 635 switch (clnt->flags) { 636 case NETR_CFLG_DOMAIN: 637 /* Pass through authentication with DC */ 638 status = smb_logon_domain(clnt, uinfo); 639 break; 640 641 case NETR_CFLG_LOCAL: 642 /* Local authentication */ 643 status = smb_logon_local(clnt, uinfo); 644 break; 645 646 case NETR_CFLG_ANON: 647 /* Anonymous user; no authentication */ 648 status = smb_logon_none(clnt, uinfo); 649 break; 650 651 default: 652 status = NT_STATUS_INVALID_PARAMETER; 653 break; 654 } 655 656 if (status == NT_STATUS_SUCCESS) 657 token = smb_token_create(uinfo); 658 659 mlsvc_free_user_info(uinfo); 660 return (token); 661 } 662 663 /* 664 * smb_logon_domain 665 * 666 * Performs pass through authentication with PDC. 667 */ 668 static uint32_t 669 smb_logon_domain(netr_client_t *clnt, smb_userinfo_t *uinfo) 670 { 671 uint32_t status; 672 673 if ((status = netlogon_logon(clnt, uinfo)) != 0) { 674 if (status == NT_STATUS_CANT_ACCESS_DOMAIN_INFO) { 675 if ((status = netlogon_logon(clnt, uinfo)) != 0) { 676 syslog(LOG_INFO, "SmbLogon[%s\\%s]: %s", 677 clnt->domain, clnt->username, 678 xlate_nt_status(status)); 679 return (status); 680 } 681 } 682 } 683 684 return (status); 685 } 686 687 /* 688 * smb_logon_local 689 * 690 * Check to see if connected user has an entry in the local 691 * smbpasswd database. If it has, tries both LM hash and NT 692 * hash with user's password(s) to authenticate the user. 693 */ 694 static uint32_t 695 smb_logon_local(netr_client_t *clnt, smb_userinfo_t *uinfo) 696 { 697 smb_passwd_t smbpw; 698 boolean_t lm_ok, nt_ok; 699 uint32_t status; 700 701 if (smb_pwd_getpwnam(clnt->username, &smbpw) == NULL) { 702 /* 703 * If user doesn't have entry either in smbpasswd 704 * or passwd it's considered as an invalid user. 705 */ 706 status = NT_STATUS_NO_SUCH_USER; 707 syslog(LOG_NOTICE, "SmbLogon[%s\\%s]: %s", 708 clnt->domain, clnt->username, 709 xlate_nt_status(status)); 710 return (status); 711 } 712 if (smbpw.pw_flags & SMB_PWF_DISABLE) 713 return (NT_STATUS_ACCOUNT_DISABLED); 714 715 nt_ok = lm_ok = B_FALSE; 716 if ((smbpw.pw_flags & SMB_PWF_LM) && 717 (clnt->lm_password.lm_password_len != 0)) { 718 lm_ok = smb_auth_validate_lm( 719 clnt->challenge_key.challenge_key_val, 720 clnt->challenge_key.challenge_key_len, 721 &smbpw, 722 clnt->lm_password.lm_password_val, 723 clnt->lm_password.lm_password_len, 724 clnt->domain, 725 clnt->username); 726 uinfo->session_key = NULL; 727 } 728 729 if (!lm_ok && (clnt->nt_password.nt_password_len != 0)) { 730 if ((uinfo->session_key = 731 malloc(SMBAUTH_SESSION_KEY_SZ)) == NULL) 732 return (NT_STATUS_NO_MEMORY); 733 nt_ok = smb_auth_validate_nt( 734 clnt->challenge_key.challenge_key_val, 735 clnt->challenge_key.challenge_key_len, 736 &smbpw, 737 clnt->nt_password.nt_password_val, 738 clnt->nt_password.nt_password_len, 739 clnt->domain, 740 clnt->username, 741 (uchar_t *)uinfo->session_key); 742 } 743 744 if (!nt_ok && !lm_ok) { 745 status = NT_STATUS_WRONG_PASSWORD; 746 syslog(LOG_NOTICE, "SmbLogon[%s\\%s]: %s", 747 clnt->domain, clnt->username, 748 xlate_nt_status(status)); 749 return (status); 750 } 751 752 status = smb_setup_luinfo(uinfo, clnt, smbpw.pw_uid); 753 return (status); 754 } 755 756 /* 757 * smb_logon_none 758 * 759 * Setup user information for anonymous user. 760 * No authentication is required. 761 */ 762 static uint32_t 763 smb_logon_none(netr_client_t *clnt, smb_userinfo_t *uinfo) 764 { 765 return (smb_setup_luinfo(uinfo, clnt, (uid_t)-1)); 766 } 767 768 /* 769 * smb_setup_luinfo 770 * 771 * Setup local user information based on the client information and 772 * user's record in the local password file. 773 */ 774 static uint32_t 775 smb_setup_luinfo(smb_userinfo_t *lui, netr_client_t *clnt, uid_t uid) 776 { 777 idmap_stat stat; 778 smb_idmap_batch_t sib; 779 smb_idmap_t *umap, *gmap; 780 smb_group_t grp; 781 struct passwd pw; 782 char pwbuf[1024]; 783 char nbname[NETBIOS_NAME_SZ]; 784 785 (void) smb_getnetbiosname(nbname, sizeof (nbname)); 786 lui->sid_name_use = SidTypeUser; 787 lui->domain_sid = smb_sid_dup(nt_domain_local_sid()); 788 lui->name = strdup(clnt->username); 789 lui->domain_name = strdup(nbname); 790 lui->n_groups = 0; 791 lui->groups = NULL; 792 lui->n_other_grps = 0; 793 lui->other_grps = NULL; 794 lui->flags = 0; 795 796 if (lui->name == NULL || lui->domain_name == NULL || 797 lui->domain_sid == NULL) 798 return (NT_STATUS_INVALID_PARAMETER); 799 800 if (clnt->flags & NETR_CFLG_ANON) { 801 lui->user_sid = smb_wka_lookup_name("Anonymous", NULL); 802 lui->pgrp_sid = smb_wka_lookup_name("Anonymous", NULL); 803 lui->flags = SMB_UINFO_FLAG_ANON; 804 805 if (lui->user_sid == NULL || lui->pgrp_sid == NULL) 806 return (NT_STATUS_NO_MEMORY); 807 808 return (NT_STATUS_SUCCESS); 809 } 810 811 if (getpwuid_r(uid, &pw, pwbuf, sizeof (pwbuf)) == NULL) 812 return (NT_STATUS_NO_SUCH_USER); 813 814 /* Get the SID for user's uid & gid */ 815 stat = smb_idmap_batch_create(&sib, 2, SMB_IDMAP_ID2SID); 816 if (stat != IDMAP_SUCCESS) { 817 return (NT_STATUS_INTERNAL_ERROR); 818 } 819 820 umap = &sib.sib_maps[0]; 821 stat = smb_idmap_batch_getsid(sib.sib_idmaph, umap, pw.pw_uid, 822 SMB_IDMAP_USER); 823 824 if (stat != IDMAP_SUCCESS) { 825 smb_idmap_batch_destroy(&sib); 826 return (NT_STATUS_INTERNAL_ERROR); 827 } 828 829 gmap = &sib.sib_maps[1]; 830 stat = smb_idmap_batch_getsid(sib.sib_idmaph, gmap, pw.pw_gid, 831 SMB_IDMAP_GROUP); 832 833 if (stat != IDMAP_SUCCESS) { 834 smb_idmap_batch_destroy(&sib); 835 return (NT_STATUS_INTERNAL_ERROR); 836 } 837 838 stat = smb_idmap_batch_getmappings(&sib); 839 840 if (stat != IDMAP_SUCCESS) { 841 return (NT_STATUS_INTERNAL_ERROR); 842 } 843 844 lui->rid = umap->sim_rid; 845 lui->user_sid = smb_sid_dup(umap->sim_sid); 846 847 lui->primary_group_rid = gmap->sim_rid; 848 lui->pgrp_sid = smb_sid_dup(gmap->sim_sid); 849 850 smb_idmap_batch_destroy(&sib); 851 852 if ((lui->user_sid == NULL) || (lui->pgrp_sid == NULL)) 853 return (NT_STATUS_NO_MEMORY); 854 855 if (smb_lgrp_getbyname("Administrators", &grp) == SMB_LGRP_SUCCESS) { 856 if (smb_lgrp_is_member(&grp, lui->user_sid)) 857 lui->flags = SMB_UINFO_FLAG_LADMIN; 858 smb_lgrp_free(&grp); 859 } 860 861 return (NT_STATUS_SUCCESS); 862 } 863 864 /* 865 * smb_token_is_valid 866 * 867 * check to see if specified fields of the given access 868 * token are valid. 869 * Returns 1 if all of them are valid; otherwise 0. 870 */ 871 static int 872 smb_token_is_valid(smb_token_t *token) 873 { 874 int valid; 875 876 valid = (token->tkn_user != 0) && 877 (token->tkn_user->i_sidattr.sid != 0) && 878 (token->tkn_privileges != 0) && 879 (token->tkn_win_grps != 0) && 880 (token->tkn_owner != 0) && 881 (token->tkn_owner->i_sidattr.sid != 0) && 882 (token->tkn_primary_grp != 0) && 883 (token->tkn_primary_grp->i_sidattr.sid != 0); 884 885 return (valid); 886 } 887 888 /* 889 * smb_token_user_sid 890 * 891 * Return a pointer to the user SID in the specified token. A null 892 * pointer indicates an error. 893 */ 894 static smb_sid_t * 895 smb_token_user_sid(smb_token_t *token) 896 { 897 if (token && token->tkn_user) 898 return ((token)->tkn_user->i_sidattr.sid); 899 900 return (NULL); 901 } 902 903 /* 904 * smb_token_group_sid 905 * 906 * Return a pointer to the group SID as indicated by the iterator. 907 * Setting the iterator to 0 before calling this function will return 908 * the first group, which will always be the primary group. The 909 * iterator will be incremented before returning the SID so that this 910 * function can be used to cycle through the groups. The caller can 911 * adjust the iterator as required between calls to obtain any specific 912 * group. 913 * 914 * On success a pointer to the appropriate group SID will be returned. 915 * Otherwise a null pointer will be returned. 916 */ 917 static smb_sid_t * 918 smb_token_group_sid(smb_token_t *token, int *iterator) 919 { 920 smb_win_grps_t *groups; 921 int index; 922 923 if (token == NULL || iterator == NULL) { 924 return (NULL); 925 } 926 927 if ((groups = token->tkn_win_grps) == NULL) { 928 return (NULL); 929 } 930 931 index = *iterator; 932 933 if (index < 0 || index >= groups->wg_count) { 934 return (NULL); 935 } 936 937 ++(*iterator); 938 return (groups->wg_groups[index].i_sidattr.sid); 939 } 940 941 /* 942 * smb_token_is_member 943 * 944 * This function will determine whether or not the specified SID is a 945 * member of a token. The user SID and all group SIDs are tested. 946 * Returns 1 if the SID is a member of the token. Otherwise returns 0. 947 */ 948 static int 949 smb_token_is_member(smb_token_t *token, smb_sid_t *sid) 950 { 951 smb_sid_t *tsid; 952 int iterator = 0; 953 954 tsid = smb_token_user_sid(token); 955 while (tsid) { 956 if (smb_sid_cmp(tsid, sid)) 957 return (1); 958 959 tsid = smb_token_group_sid(token, &iterator); 960 } 961 962 return (0); 963 } 964 965 /* 966 * smb_token_log 967 * 968 * Diagnostic routine to write the contents of a token to the log. 969 */ 970 void 971 smb_token_log(smb_token_t *token) 972 { 973 smb_win_grps_t *w_grps; 974 smb_posix_grps_t *x_grps; 975 smb_sid_attrs_t *grp; 976 char sidstr[SMB_SID_STRSZ]; 977 int i; 978 979 if (token == NULL) 980 return; 981 982 syslog(LOG_DEBUG, "Token for %s\\%s", 983 (token->tkn_domain_name) ? token->tkn_domain_name : "-NULL-", 984 (token->tkn_account_name) ? token->tkn_account_name : "-NULL-"); 985 986 syslog(LOG_DEBUG, " User->Attr: %d", 987 token->tkn_user->i_sidattr.attrs); 988 smb_sid_tostr((smb_sid_t *)token->tkn_user->i_sidattr.sid, sidstr); 989 syslog(LOG_DEBUG, " User->Sid: %s (id=%u)", 990 sidstr, token->tkn_user->i_id); 991 992 smb_sid_tostr((smb_sid_t *)token->tkn_owner->i_sidattr.sid, sidstr); 993 syslog(LOG_DEBUG, " Ownr->Sid: %s (id=%u)", 994 sidstr, token->tkn_owner->i_id); 995 996 smb_sid_tostr((smb_sid_t *)token->tkn_primary_grp->i_sidattr.sid, 997 sidstr); 998 syslog(LOG_DEBUG, " PGrp->Sid: %s (id=%u)", 999 sidstr, token->tkn_primary_grp->i_id); 1000 1001 w_grps = token->tkn_win_grps; 1002 if (w_grps) { 1003 syslog(LOG_DEBUG, " Windows groups: %d", 1004 w_grps->wg_count); 1005 1006 for (i = 0; i < w_grps->wg_count; ++i) { 1007 grp = &w_grps->wg_groups[i].i_sidattr; 1008 syslog(LOG_DEBUG, 1009 " Grp[%d].Attr:%d", i, grp->attrs); 1010 if (w_grps->wg_groups[i].i_sidattr.sid) { 1011 smb_sid_tostr((smb_sid_t *)grp->sid, sidstr); 1012 syslog(LOG_DEBUG, 1013 " Grp[%d].Sid: %s (id=%u)", i, sidstr, 1014 w_grps->wg_groups[i].i_id); 1015 } 1016 } 1017 } 1018 else 1019 syslog(LOG_DEBUG, " No Windows groups"); 1020 1021 x_grps = token->tkn_posix_grps; 1022 if (x_grps) { 1023 syslog(LOG_DEBUG, " Solaris groups: %d", 1024 x_grps->pg_ngrps); 1025 for (i = 0; i < x_grps->pg_ngrps; i++) 1026 syslog(LOG_DEBUG, " %u", 1027 x_grps->pg_grps[i]); 1028 } 1029 else 1030 syslog(LOG_DEBUG, " No Solaris groups"); 1031 1032 if (token->tkn_privileges) 1033 smb_privset_log(token->tkn_privileges); 1034 else 1035 syslog(LOG_DEBUG, " No privileges"); 1036 } 1037