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 (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2019 Nexenta by DDN, Inc. All rights reserved. 24 * Copyright (c) 2016 by Delphix. All rights reserved. 25 */ 26 27 /* 28 * General Structures Layout 29 * ------------------------- 30 * 31 * This is a simplified diagram showing the relationship between most of the 32 * main structures. 33 * 34 * +-------------------+ 35 * | SMB_INFO | 36 * +-------------------+ 37 * | 38 * | 39 * v 40 * +-------------------+ +-------------------+ +-------------------+ 41 * | SESSION |<----->| SESSION |......| SESSION | 42 * +-------------------+ +-------------------+ +-------------------+ 43 * | | 44 * | | 45 * | v 46 * | +-------------------+ +-------------------+ +-------------------+ 47 * | | USER |<--->| USER |...| USER | 48 * | +-------------------+ +-------------------+ +-------------------+ 49 * | 50 * | 51 * v 52 * +-------------------+ +-------------------+ +-------------------+ 53 * | TREE |<----->| TREE |......| TREE | 54 * +-------------------+ +-------------------+ +-------------------+ 55 * | | 56 * | | 57 * | v 58 * | +-------+ +-------+ +-------+ 59 * | | OFILE |<----->| OFILE |......| OFILE | 60 * | +-------+ +-------+ +-------+ 61 * | 62 * | 63 * v 64 * +-------+ +------+ +------+ 65 * | ODIR |<----->| ODIR |......| ODIR | 66 * +-------+ +------+ +------+ 67 * 68 * 69 * User State Machine 70 * ------------------ 71 * 72 * 73 * | T0: Creation/Allocation 74 * | (1st session setup) 75 * v 76 * +-----------------------------+ 77 * | SMB_USER_STATE_LOGGING_ON |<----------+ 78 * +-----------------------------+ addl. session setup 79 * | | (more proc. required) 80 * | T2 | ^ 81 * | | | T1: (cont.) 82 * | +------->-------? 83 * v | T3: (fail) 84 * +-----------------------------+ v 85 * | SMB_USER_STATE_LOGGED_ON | (logged off) 86 * +-----------------------------+ 87 * | 88 * | T4 89 * | 90 * v 91 * +-----------------------------+ 92 * | SMB_USER_STATE_LOGGING_OFF | 93 * +-----------------------------+ 94 * | 95 * | T5 96 * | 97 * v 98 * +-----------------------------+ T6 99 * | SMB_USER_STATE_LOGGED_OFF |----------> Deletion/Free 100 * +-----------------------------+ 101 * 102 * SMB_USER_STATE_LOGGING_ON 103 * 104 * While in this state: 105 * - The user is in the list of users for their session. 106 * - References will be given out ONLY for session setup. 107 * - This user can not access anything yet. 108 * 109 * SMB_USER_STATE_LOGGED_ON 110 * 111 * While in this state: 112 * - The user is in the list of users for their session. 113 * - References will be given out if the user is looked up. 114 * - The user can access files and pipes. 115 * 116 * SMB_USER_STATE_LOGGING_OFF 117 * 118 * While in this state: 119 * - The user is in the list of users for their session. 120 * - References will not be given out if the user is looked up. 121 * - The trees the user connected are being disconnected. 122 * - The resources associated with the user remain. 123 * 124 * SMB_USER_STATE_LOGGED_OFF 125 * 126 * While in this state: 127 * - The user is queued in the list of users of their session. 128 * - References will not be given out if the user is looked up. 129 * - The user has no more trees connected. 130 * - The resources associated with the user remain. 131 * 132 * Transition T0 133 * 134 * First request in an SMB Session Setup sequence creates a 135 * new user object and adds it to the list of users for 136 * this session. User UID is assigned and returned. 137 * 138 * Transition T1 139 * 140 * Subsequent SMB Session Setup requests (on the same UID 141 * assigned in T0) update the state of this user object, 142 * communicating with smbd for the crypto work. 143 * 144 * Transition T2 145 * 146 * If the SMB Session Setup sequence is successful, T2 147 * makes the new user object available for requests. 148 * 149 * Transition T3 150 * 151 * If an Session Setup request gets an error other than 152 * the expected "more processing required", then T3 153 * leads to state "LOGGED_OFF" and then tear-down of the 154 * partially constructed user. 155 * 156 * Transition T4 157 * 158 * Normal SMB User Logoff request, or session tear-down. 159 * 160 * Transition T5 161 * 162 * This transition occurs in smb_user_release(). The resources associated 163 * with the user are deleted as well as the user. For the transition to 164 * occur, the user must be in the SMB_USER_STATE_LOGGED_OFF state and the 165 * reference count be zero. 166 * 167 * Comments 168 * -------- 169 * 170 * The state machine of the user structures is controlled by 3 elements: 171 * - The list of users of the session they belong to. 172 * - The mutex embedded in the structure itself. 173 * - The reference count. 174 * 175 * There's a mutex embedded in the user structure used to protect its fields 176 * and there's a lock embedded in the list of users of a session. To 177 * increment or to decrement the reference count the mutex must be entered. 178 * To insert the user into the list of users of the session and to remove 179 * the user from it, the lock must be entered in RW_WRITER mode. 180 * 181 * Rules of access to a user structure: 182 * 183 * 1) In order to avoid deadlocks, when both (mutex and lock of the session 184 * list) have to be entered, the lock must be entered first. Additionally, 185 * one may NOT flush the deleteq of either the tree list or the ofile list 186 * while the user mutex is held. 187 * 188 * 2) All actions applied to a user require a reference count. 189 * 190 * 3) There are 2 ways of getting a reference count. One is when the user 191 * logs in. The other when the user is looked up. 192 * 193 * It should be noted that the reference count of a user registers the 194 * number of references to the user in other structures (such as an smb 195 * request). The reference count is not incremented in these 2 instances: 196 * 197 * 1) The user is logged in. An user is anchored by their state. If there's 198 * no activity involving a user currently logged in, the reference 199 * count of that user is zero. 200 * 201 * 2) The user is queued in the list of users of the session. The fact of 202 * being queued in that list is NOT registered by incrementing the 203 * reference count. 204 */ 205 #include <sys/types.h> 206 #include <sys/sid.h> 207 #include <sys/priv_names.h> 208 #include <sys/priv.h> 209 #include <sys/policy.h> 210 #include <smbsrv/smb_kproto.h> 211 #include <smbsrv/smb_door.h> 212 213 #define ADMINISTRATORS_SID "S-1-5-32-544" 214 215 /* Don't leak object addresses */ 216 #define SMB_USER_SSNID(u) \ 217 ((uintptr_t)&smb_cache_user ^ (uintptr_t)(u)) 218 219 static void smb_user_delete(void *); 220 static int smb_user_enum_private(smb_user_t *, smb_svcenum_t *); 221 static void smb_user_auth_logoff(smb_user_t *); 222 static void smb_user_logoff_tq(void *); 223 224 /* 225 * Create a new user. 226 * 227 * For SMB2 and later, session IDs (u_ssnid) need to be unique among all 228 * current and "recent" sessions. The session ID is derived from the 229 * address of the smb_user object (obscured by XOR with a constant). 230 * This adds a 3-bit generation number in the low bits, incremented 231 * when we allocate an smb_user_t from its kmem cache, so it can't 232 * be confused with a (recent) previous incarnation of this object. 233 */ 234 smb_user_t * 235 smb_user_new(smb_session_t *session) 236 { 237 smb_user_t *user; 238 uint_t gen; // generation (low 3 bits of ssnid) 239 uint32_t ucount; 240 241 ASSERT(session); 242 ASSERT(session->s_magic == SMB_SESSION_MAGIC); 243 244 user = kmem_cache_alloc(smb_cache_user, KM_SLEEP); 245 gen = (user->u_ssnid + 1) & 7; 246 bzero(user, sizeof (smb_user_t)); 247 248 user->u_refcnt = 1; 249 user->u_session = session; 250 user->u_server = session->s_server; 251 user->u_logon_time = gethrestime_sec(); 252 253 if (smb_idpool_alloc(&session->s_uid_pool, &user->u_uid)) 254 goto errout; 255 user->u_ssnid = SMB_USER_SSNID(user) + gen; 256 257 mutex_init(&user->u_mutex, NULL, MUTEX_DEFAULT, NULL); 258 user->u_state = SMB_USER_STATE_LOGGING_ON; 259 user->u_magic = SMB_USER_MAGIC; 260 261 smb_llist_enter(&session->s_user_list, RW_WRITER); 262 ucount = smb_llist_get_count(&session->s_user_list); 263 smb_llist_insert_tail(&session->s_user_list, user); 264 smb_llist_exit(&session->s_user_list); 265 smb_server_inc_users(session->s_server); 266 267 /* 268 * If we added the first user to the session, cancel the 269 * timeout that was started in smb_session_receiver(). 270 */ 271 if (ucount == 0) { 272 timeout_id_t tmo = NULL; 273 274 smb_rwx_rwenter(&session->s_lock, RW_WRITER); 275 tmo = session->s_auth_tmo; 276 session->s_auth_tmo = NULL; 277 smb_rwx_rwexit(&session->s_lock); 278 279 if (tmo != NULL) 280 (void) untimeout(tmo); 281 } 282 283 return (user); 284 285 errout: 286 if (user->u_uid != 0) 287 smb_idpool_free(&session->s_uid_pool, user->u_uid); 288 kmem_cache_free(smb_cache_user, user); 289 return (NULL); 290 } 291 292 /* 293 * Fill in the details of a user, meaning a transition 294 * from state LOGGING_ON to state LOGGED_ON. 295 */ 296 int 297 smb_user_logon( 298 smb_user_t *user, 299 cred_t *cr, 300 char *domain_name, 301 char *account_name, 302 uint32_t flags, 303 uint32_t privileges, 304 uint32_t audit_sid) 305 { 306 ksocket_t authsock = NULL; 307 timeout_id_t tmo = NULL; 308 309 ASSERT(user->u_magic == SMB_USER_MAGIC); 310 ASSERT(cr); 311 ASSERT(account_name); 312 ASSERT(domain_name); 313 314 mutex_enter(&user->u_mutex); 315 316 if (user->u_state != SMB_USER_STATE_LOGGING_ON) { 317 mutex_exit(&user->u_mutex); 318 return (-1); 319 } 320 321 /* 322 * In the transition from LOGGING_ON to LOGGED_ON, 323 * we always have an auth. socket to close. 324 */ 325 authsock = user->u_authsock; 326 user->u_authsock = NULL; 327 tmo = user->u_auth_tmo; 328 user->u_auth_tmo = NULL; 329 330 user->u_state = SMB_USER_STATE_LOGGED_ON; 331 user->u_flags = flags; 332 user->u_name_len = strlen(account_name) + 1; 333 user->u_domain_len = strlen(domain_name) + 1; 334 user->u_name = smb_mem_strdup(account_name); 335 user->u_domain = smb_mem_strdup(domain_name); 336 user->u_audit_sid = audit_sid; 337 338 smb_user_setcred(user, cr, privileges); 339 340 mutex_exit(&user->u_mutex); 341 342 /* Timeout callback takes u_mutex. See untimeout(9f) */ 343 if (tmo != NULL) 344 (void) untimeout(tmo); 345 346 /* This close can block, so not under the mutex. */ 347 if (authsock != NULL) 348 smb_authsock_close(user, authsock); 349 350 return (0); 351 } 352 353 /* 354 * smb_user_logoff 355 * 356 * Change the user state to "logging off" and disconnect trees. 357 * The user list must not be entered or modified here. 358 * 359 * We remain in state "logging off" until the last ref. is gone, 360 * then smb_user_release takes us to state "logged off". 361 */ 362 void 363 smb_user_logoff( 364 smb_user_t *user) 365 { 366 ksocket_t authsock = NULL; 367 timeout_id_t tmo = NULL; 368 369 ASSERT(user->u_magic == SMB_USER_MAGIC); 370 371 mutex_enter(&user->u_mutex); 372 ASSERT(user->u_refcnt); 373 switch (user->u_state) { 374 case SMB_USER_STATE_LOGGING_ON: 375 authsock = user->u_authsock; 376 user->u_authsock = NULL; 377 tmo = user->u_auth_tmo; 378 user->u_auth_tmo = NULL; 379 user->u_state = SMB_USER_STATE_LOGGING_OFF; 380 mutex_exit(&user->u_mutex); 381 382 /* Timeout callback takes u_mutex. See untimeout(9f) */ 383 if (tmo != NULL) 384 (void) untimeout(tmo); 385 /* This close can block, so not under the mutex. */ 386 if (authsock != NULL) 387 smb_authsock_close(user, authsock); 388 break; 389 390 case SMB_USER_STATE_LOGGED_ON: 391 /* 392 * The user is moved into a state indicating that the log off 393 * process has started. 394 */ 395 user->u_state = SMB_USER_STATE_LOGGING_OFF; 396 mutex_exit(&user->u_mutex); 397 smb_session_disconnect_owned_trees(user->u_session, user); 398 smb_user_auth_logoff(user); 399 break; 400 401 case SMB_USER_STATE_LOGGED_OFF: 402 case SMB_USER_STATE_LOGGING_OFF: 403 mutex_exit(&user->u_mutex); 404 break; 405 406 default: 407 ASSERT(0); 408 mutex_exit(&user->u_mutex); 409 break; 410 } 411 } 412 413 /* 414 * Take a reference on a user. Do not return a reference unless the user is in 415 * the logged-in state. 416 */ 417 boolean_t 418 smb_user_hold(smb_user_t *user) 419 { 420 SMB_USER_VALID(user); 421 422 mutex_enter(&user->u_mutex); 423 424 if (user->u_state == SMB_USER_STATE_LOGGED_ON) { 425 user->u_refcnt++; 426 mutex_exit(&user->u_mutex); 427 return (B_TRUE); 428 } 429 430 mutex_exit(&user->u_mutex); 431 return (B_FALSE); 432 } 433 434 /* 435 * Unconditionally take a reference on a user. 436 */ 437 void 438 smb_user_hold_internal(smb_user_t *user) 439 { 440 SMB_USER_VALID(user); 441 442 mutex_enter(&user->u_mutex); 443 user->u_refcnt++; 444 mutex_exit(&user->u_mutex); 445 } 446 447 /* 448 * Release a reference on a user. If the reference count falls to 449 * zero and the user has logged off, post the object for deletion. 450 * Object deletion is deferred to avoid modifying a list while an 451 * iteration may be in progress. 452 */ 453 void 454 smb_user_release( 455 smb_user_t *user) 456 { 457 smb_session_t *ssn = user->u_session; 458 459 SMB_USER_VALID(user); 460 461 /* flush the tree list delete queue */ 462 smb_llist_flush(&ssn->s_tree_list); 463 464 mutex_enter(&user->u_mutex); 465 ASSERT(user->u_refcnt); 466 user->u_refcnt--; 467 468 switch (user->u_state) { 469 case SMB_USER_STATE_LOGGING_OFF: 470 if (user->u_refcnt == 0) { 471 smb_session_t *ssn = user->u_session; 472 user->u_state = SMB_USER_STATE_LOGGED_OFF; 473 smb_llist_post(&ssn->s_user_list, user, 474 smb_user_delete); 475 } 476 break; 477 478 case SMB_USER_STATE_LOGGING_ON: 479 case SMB_USER_STATE_LOGGED_ON: 480 break; 481 482 case SMB_USER_STATE_LOGGED_OFF: 483 default: 484 ASSERT(0); 485 break; 486 } 487 mutex_exit(&user->u_mutex); 488 } 489 490 /* 491 * Timeout handler for user logons that stay too long in 492 * state SMB_USER_STATE_LOGGING_ON. This is setup by a 493 * timeout call in smb_authsock_open, and called in a 494 * callout thread, so schedule a taskq job to do the 495 * real work of logging off this user. 496 */ 497 void 498 smb_user_auth_tmo(void *arg) 499 { 500 smb_user_t *user = arg; 501 smb_request_t *sr; 502 taskqid_t tqid; 503 504 SMB_USER_VALID(user); 505 506 /* 507 * If we can't allocate a request, it means the 508 * session is being torn down, so nothing to do. 509 */ 510 sr = smb_request_alloc(user->u_session, 0); 511 if (sr == NULL) 512 return; 513 514 /* 515 * Check user state, and take a hold if it's 516 * still logging on. If not, we're done. 517 */ 518 mutex_enter(&user->u_mutex); 519 if (user->u_state != SMB_USER_STATE_LOGGING_ON) { 520 mutex_exit(&user->u_mutex); 521 smb_request_free(sr); 522 return; 523 } 524 /* smb_user_hold_internal */ 525 user->u_refcnt++; 526 mutex_exit(&user->u_mutex); 527 528 /* 529 * The user hold is given to the SR, and released in 530 * smb_user_logoff_tq / smb_request_free 531 */ 532 sr->uid_user = user; 533 sr->user_cr = user->u_cred; 534 sr->sr_state = SMB_REQ_STATE_SUBMITTED; 535 tqid = taskq_dispatch( 536 user->u_server->sv_worker_pool, 537 smb_user_logoff_tq, sr, TQ_SLEEP); 538 VERIFY(tqid != TASKQID_INVALID); 539 } 540 541 /* 542 * Helper for smb_user_auth_tmo() 543 */ 544 static void 545 smb_user_logoff_tq(void *arg) 546 { 547 smb_request_t *sr = arg; 548 549 SMB_REQ_VALID(sr); 550 551 mutex_enter(&sr->sr_mutex); 552 sr->sr_worker = curthread; 553 sr->sr_state = SMB_REQ_STATE_ACTIVE; 554 mutex_exit(&sr->sr_mutex); 555 556 smb_user_logoff(sr->uid_user); 557 558 sr->sr_state = SMB_REQ_STATE_COMPLETED; 559 smb_request_free(sr); 560 } 561 562 /* 563 * Determine whether or not the user is an administrator. 564 * Members of the administrators group have administrative rights. 565 */ 566 boolean_t 567 smb_user_is_admin(smb_user_t *user) 568 { 569 #ifdef _KERNEL 570 char sidstr[SMB_SID_STRSZ]; 571 ksidlist_t *ksidlist; 572 ksid_t ksid1; 573 ksid_t *ksid2; 574 int i; 575 #endif /* _KERNEL */ 576 boolean_t rc = B_FALSE; 577 578 ASSERT(user); 579 ASSERT(user->u_cred); 580 581 if (SMB_USER_IS_ADMIN(user)) 582 return (B_TRUE); 583 584 #ifdef _KERNEL 585 bzero(&ksid1, sizeof (ksid_t)); 586 (void) strlcpy(sidstr, ADMINISTRATORS_SID, SMB_SID_STRSZ); 587 ASSERT(smb_sid_splitstr(sidstr, &ksid1.ks_rid) == 0); 588 ksid1.ks_domain = ksid_lookupdomain(sidstr); 589 590 ksidlist = crgetsidlist(user->u_cred); 591 ASSERT(ksidlist); 592 ASSERT(ksid1.ks_domain); 593 ASSERT(ksid1.ks_domain->kd_name); 594 595 i = 0; 596 ksid2 = crgetsid(user->u_cred, KSID_USER); 597 do { 598 ASSERT(ksid2->ks_domain); 599 ASSERT(ksid2->ks_domain->kd_name); 600 601 if (strcmp(ksid1.ks_domain->kd_name, 602 ksid2->ks_domain->kd_name) == 0 && 603 ksid1.ks_rid == ksid2->ks_rid) { 604 user->u_flags |= SMB_USER_FLAG_ADMIN; 605 rc = B_TRUE; 606 break; 607 } 608 609 ksid2 = &ksidlist->ksl_sids[i]; 610 } while (i++ < ksidlist->ksl_nsid); 611 612 ksid_rele(&ksid1); 613 #endif /* _KERNEL */ 614 return (rc); 615 } 616 617 /* 618 * This function should be called with a hold on the user. 619 */ 620 boolean_t 621 smb_user_namecmp(smb_user_t *user, const char *name) 622 { 623 char *fq_name; 624 boolean_t match; 625 626 if (smb_strcasecmp(name, user->u_name, 0) == 0) 627 return (B_TRUE); 628 629 fq_name = kmem_alloc(MAXNAMELEN, KM_SLEEP); 630 631 (void) snprintf(fq_name, MAXNAMELEN, "%s\\%s", 632 user->u_domain, user->u_name); 633 634 match = (smb_strcasecmp(name, fq_name, 0) == 0); 635 if (!match) { 636 (void) snprintf(fq_name, MAXNAMELEN, "%s@%s", 637 user->u_name, user->u_domain); 638 639 match = (smb_strcasecmp(name, fq_name, 0) == 0); 640 } 641 642 kmem_free(fq_name, MAXNAMELEN); 643 return (match); 644 } 645 646 /* 647 * If the enumeration request is for user data, handle the request 648 * here. Otherwise, pass it on to the trees. 649 * 650 * This function should be called with a hold on the user. 651 */ 652 int 653 smb_user_enum(smb_user_t *user, smb_svcenum_t *svcenum) 654 { 655 int rc = 0; 656 657 ASSERT(user); 658 ASSERT(user->u_magic == SMB_USER_MAGIC); 659 660 if (svcenum->se_type == SMB_SVCENUM_TYPE_USER) 661 return (smb_user_enum_private(user, svcenum)); 662 663 return (rc); 664 } 665 666 /* 667 * Count references by trees this user owns, 668 * and allow waiting for them to go away. 669 */ 670 void 671 smb_user_inc_trees(smb_user_t *user) 672 { 673 mutex_enter(&user->u_mutex); 674 user->u_owned_tree_cnt++; 675 mutex_exit(&user->u_mutex); 676 } 677 678 void 679 smb_user_dec_trees(smb_user_t *user) 680 { 681 mutex_enter(&user->u_mutex); 682 user->u_owned_tree_cnt--; 683 if (user->u_owned_tree_cnt == 0) 684 cv_broadcast(&user->u_owned_tree_cv); 685 mutex_exit(&user->u_mutex); 686 } 687 688 int smb_user_wait_tree_tmo = 30; 689 690 /* 691 * Wait (up to 30 sec.) for trees to go away. 692 * Should happen in less than a second. 693 */ 694 void 695 smb_user_wait_trees(smb_user_t *user) 696 { 697 clock_t time; 698 699 time = SEC_TO_TICK(smb_user_wait_tree_tmo) + ddi_get_lbolt(); 700 mutex_enter(&user->u_mutex); 701 while (user->u_owned_tree_cnt != 0) { 702 if (cv_timedwait(&user->u_owned_tree_cv, 703 &user->u_mutex, time) < 0) 704 break; 705 } 706 mutex_exit(&user->u_mutex); 707 #ifdef DEBUG 708 if (user->u_owned_tree_cnt != 0) { 709 cmn_err(CE_NOTE, "smb_user_wait_trees failed"); 710 debug_enter("smb_user_wait_trees debug"); 711 } 712 #endif 713 } 714 715 /* *************************** Static Functions ***************************** */ 716 717 /* 718 * Delete a user. The tree list should be empty. 719 * 720 * Remove the user from the session's user list before freeing resources 721 * associated with the user. 722 */ 723 static void 724 smb_user_delete(void *arg) 725 { 726 smb_session_t *session; 727 smb_user_t *user = (smb_user_t *)arg; 728 uint32_t ucount; 729 730 SMB_USER_VALID(user); 731 ASSERT(user->u_refcnt == 0); 732 ASSERT(user->u_state == SMB_USER_STATE_LOGGED_OFF); 733 ASSERT(user->u_authsock == NULL); 734 ASSERT(user->u_auth_tmo == NULL); 735 736 session = user->u_session; 737 738 smb_server_dec_users(session->s_server); 739 smb_llist_enter(&session->s_user_list, RW_WRITER); 740 smb_llist_remove(&session->s_user_list, user); 741 smb_idpool_free(&session->s_uid_pool, user->u_uid); 742 ucount = smb_llist_get_count(&session->s_user_list); 743 smb_llist_exit(&session->s_user_list); 744 745 /* 746 * When the last smb_user_t object goes away, schedule a timeout 747 * after which we'll terminate this session if the client hasn't 748 * authenticated another smb_user_t on this session by then. 749 */ 750 if (ucount == 0) { 751 smb_rwx_rwenter(&session->s_lock, RW_WRITER); 752 if (session->s_state == SMB_SESSION_STATE_NEGOTIATED && 753 session->s_auth_tmo == NULL) { 754 session->s_auth_tmo = 755 timeout((tmo_func_t)smb_session_disconnect, 756 session, SEC_TO_TICK(smb_session_auth_tmo)); 757 } 758 smb_rwx_cvbcast(&session->s_lock); 759 smb_rwx_rwexit(&session->s_lock); 760 } 761 762 /* 763 * This user is no longer on s_user_list, however... 764 * 765 * This is called via smb_llist_post, which means it may run 766 * BEFORE smb_user_release drops u_mutex (if another thread 767 * flushes the delete queue before we do). Synchronize. 768 */ 769 mutex_enter(&user->u_mutex); 770 mutex_exit(&user->u_mutex); 771 772 user->u_magic = (uint32_t)~SMB_USER_MAGIC; 773 mutex_destroy(&user->u_mutex); 774 if (user->u_cred) 775 crfree(user->u_cred); 776 if (user->u_privcred) 777 crfree(user->u_privcred); 778 smb_mem_free(user->u_name); 779 smb_mem_free(user->u_domain); 780 kmem_cache_free(smb_cache_user, user); 781 } 782 783 cred_t * 784 smb_user_getcred(smb_user_t *user) 785 { 786 return (user->u_cred); 787 } 788 789 cred_t * 790 smb_user_getprivcred(smb_user_t *user) 791 { 792 return ((user->u_privcred)? user->u_privcred : user->u_cred); 793 } 794 795 #ifdef _KERNEL 796 /* 797 * Assign the user cred and privileges. 798 * 799 * If the user has backup and/or restore privleges, dup the cred 800 * and add those privileges to this new privileged cred. 801 */ 802 void 803 smb_user_setcred(smb_user_t *user, cred_t *cr, uint32_t privileges) 804 { 805 cred_t *privcred = NULL; 806 807 ASSERT(cr); 808 crhold(cr); 809 810 /* 811 * See smb.4 bypass_traverse_checking 812 * 813 * For historical reasons, the Windows privilege is named 814 * SeChangeNotifyPrivilege, though the description is 815 * "Bypass traverse checking". 816 */ 817 if ((privileges & SMB_USER_PRIV_CHANGE_NOTIFY) != 0) { 818 (void) crsetpriv(cr, PRIV_FILE_DAC_SEARCH, NULL); 819 } 820 821 /* 822 * Window's "take ownership privilege" is similar to our 823 * PRIV_FILE_CHOWN privilege. It's normally given to members of the 824 * "Administrators" group, which normally includes the the local 825 * Administrator (like root) and when joined to a domain, 826 * "Domain Admins". 827 */ 828 if ((privileges & SMB_USER_PRIV_TAKE_OWNERSHIP) != 0) { 829 (void) crsetpriv(cr, 830 PRIV_FILE_CHOWN, 831 PRIV_FILE_CHOWN_SELF, 832 NULL); 833 } 834 835 /* 836 * Bypass ACL for READ accesses. 837 */ 838 if ((privileges & SMB_USER_PRIV_READ_FILE) != 0) { 839 (void) crsetpriv(cr, PRIV_FILE_DAC_READ, NULL); 840 } 841 842 /* 843 * Bypass ACL for WRITE accesses. 844 * Include FILE_OWNER, as it covers WRITE_ACL and DELETE. 845 */ 846 if ((privileges & SMB_USER_PRIV_WRITE_FILE) != 0) { 847 (void) crsetpriv(cr, 848 PRIV_FILE_DAC_WRITE, 849 PRIV_FILE_OWNER, 850 NULL); 851 } 852 853 /* 854 * These privileges are used only when a file is opened with 855 * 'backup intent'. These allow users to bypass certain access 856 * controls. Administrators typically have these privileges, 857 * and they are used during recursive take-ownership operations. 858 * Some commonly used tools use 'backup intent' to administrate 859 * files that do not grant explicit permissions to Administrators. 860 */ 861 if (privileges & (SMB_USER_PRIV_BACKUP | SMB_USER_PRIV_RESTORE)) 862 privcred = crdup(cr); 863 864 if (privcred != NULL) { 865 if (privileges & SMB_USER_PRIV_BACKUP) { 866 (void) crsetpriv(privcred, PRIV_FILE_DAC_READ, 867 PRIV_FILE_DAC_SEARCH, PRIV_SYS_MOUNT, NULL); 868 } 869 870 if (privileges & SMB_USER_PRIV_RESTORE) { 871 (void) crsetpriv(privcred, PRIV_FILE_DAC_WRITE, 872 PRIV_FILE_CHOWN, PRIV_FILE_CHOWN_SELF, 873 PRIV_FILE_DAC_SEARCH, PRIV_FILE_LINK_ANY, 874 PRIV_FILE_OWNER, PRIV_FILE_SETID, 875 PRIV_SYS_LINKDIR, PRIV_SYS_MOUNT, NULL); 876 } 877 } 878 879 user->u_cred = cr; 880 user->u_privcred = privcred; 881 user->u_privileges = privileges; 882 } 883 #endif /* _KERNEL */ 884 885 /* 886 * Determines whether a user can be granted ACCESS_SYSTEM_SECURITY 887 */ 888 boolean_t 889 smb_user_has_security_priv(smb_user_t *user, cred_t *cr) 890 { 891 /* Need SeSecurityPrivilege to get/set SACL */ 892 if ((user->u_privileges & SMB_USER_PRIV_SECURITY) != 0) 893 return (B_TRUE); 894 895 #ifdef _KERNEL 896 /* 897 * ACCESS_SYSTEM_SECURITY is also granted if the file is opened with 898 * BACKUP/RESTORE intent by a user with BACKUP/RESTORE privilege, 899 * which means we'll be using u_privcred. 900 * 901 * We translate BACKUP as DAC_READ and RESTORE as DAC_WRITE, 902 * to account for our various SMB_USER_* privileges. 903 */ 904 if (PRIV_POLICY_ONLY(cr, 905 priv_getbyname(PRIV_FILE_DAC_READ, 0), B_FALSE) || 906 PRIV_POLICY_ONLY(cr, 907 priv_getbyname(PRIV_FILE_DAC_WRITE, 0), B_FALSE)) 908 return (B_TRUE); 909 #else 910 /* 911 * No "real" privileges in fksmbsrv, so use the SMB privs instead. 912 */ 913 if ((user->u_privileges & 914 (SMB_USER_PRIV_BACKUP | 915 SMB_USER_PRIV_RESTORE | 916 SMB_USER_PRIV_READ_FILE | 917 SMB_USER_PRIV_WRITE_FILE)) != 0) 918 return (B_TRUE); 919 #endif 920 921 return (B_FALSE); 922 } 923 924 /* 925 * Private function to support smb_user_enum. 926 */ 927 static int 928 smb_user_enum_private(smb_user_t *user, smb_svcenum_t *svcenum) 929 { 930 uint8_t *pb; 931 uint_t nbytes; 932 int rc; 933 934 if (svcenum->se_nskip > 0) { 935 svcenum->se_nskip--; 936 return (0); 937 } 938 939 if (svcenum->se_nitems >= svcenum->se_nlimit) { 940 svcenum->se_nitems = svcenum->se_nlimit; 941 return (0); 942 } 943 944 pb = &svcenum->se_buf[svcenum->se_bused]; 945 rc = smb_user_netinfo_encode(user, pb, svcenum->se_bavail, &nbytes); 946 if (rc == 0) { 947 svcenum->se_bavail -= nbytes; 948 svcenum->se_bused += nbytes; 949 svcenum->se_nitems++; 950 } 951 952 return (rc); 953 } 954 955 /* 956 * Encode the NetInfo for a user into a buffer. NetInfo contains 957 * information that is often needed in user space to support RPC 958 * requests. 959 */ 960 int 961 smb_user_netinfo_encode(smb_user_t *user, uint8_t *buf, size_t buflen, 962 uint32_t *nbytes) 963 { 964 smb_netuserinfo_t info; 965 int rc; 966 967 smb_user_netinfo_init(user, &info); 968 rc = smb_netuserinfo_encode(&info, buf, buflen, nbytes); 969 smb_user_netinfo_fini(&info); 970 971 return (rc); 972 } 973 974 void 975 smb_user_netinfo_init(smb_user_t *user, smb_netuserinfo_t *info) 976 { 977 smb_session_t *session; 978 char *buf; 979 980 ASSERT(user); 981 ASSERT(user->u_domain); 982 ASSERT(user->u_name); 983 984 session = user->u_session; 985 ASSERT(session); 986 ASSERT(session->workstation); 987 988 info->ui_session_id = session->s_kid; 989 info->ui_native_os = session->native_os; 990 info->ui_ipaddr = session->ipaddr; 991 info->ui_numopens = session->s_file_cnt; 992 info->ui_logon_time = user->u_logon_time; 993 info->ui_flags = user->u_flags; 994 info->ui_posix_uid = crgetuid(user->u_cred); 995 996 info->ui_domain_len = user->u_domain_len; 997 info->ui_domain = smb_mem_strdup(user->u_domain); 998 999 info->ui_account_len = user->u_name_len; 1000 info->ui_account = smb_mem_strdup(user->u_name); 1001 1002 buf = kmem_alloc(MAXNAMELEN, KM_SLEEP); 1003 smb_session_getclient(session, buf, MAXNAMELEN); 1004 info->ui_workstation_len = strlen(buf) + 1; 1005 info->ui_workstation = smb_mem_strdup(buf); 1006 kmem_free(buf, MAXNAMELEN); 1007 } 1008 1009 void 1010 smb_user_netinfo_fini(smb_netuserinfo_t *info) 1011 { 1012 if (info == NULL) 1013 return; 1014 1015 if (info->ui_domain) 1016 smb_mem_free(info->ui_domain); 1017 if (info->ui_account) 1018 smb_mem_free(info->ui_account); 1019 if (info->ui_workstation) 1020 smb_mem_free(info->ui_workstation); 1021 1022 bzero(info, sizeof (smb_netuserinfo_t)); 1023 } 1024 1025 /* 1026 * Tell smbd this user is going away so it can clean up their 1027 * audit session, autohome dir, etc. 1028 * 1029 * Note that when we're shutting down, smbd will already have set 1030 * smbd.s_shutting_down and therefore will ignore door calls. 1031 * Skip this during shutdown to reduce upcall noise. 1032 */ 1033 static void 1034 smb_user_auth_logoff(smb_user_t *user) 1035 { 1036 smb_server_t *sv = user->u_server; 1037 uint32_t audit_sid; 1038 1039 if (sv->sv_state != SMB_SERVER_STATE_RUNNING) 1040 return; 1041 1042 audit_sid = user->u_audit_sid; 1043 (void) smb_kdoor_upcall(sv, SMB_DR_USER_AUTH_LOGOFF, 1044 &audit_sid, xdr_uint32_t, NULL, NULL); 1045 } 1046 1047 boolean_t 1048 smb_is_same_user(cred_t *cr1, cred_t *cr2) 1049 { 1050 ksid_t *ks1 = crgetsid(cr1, KSID_USER); 1051 ksid_t *ks2 = crgetsid(cr2, KSID_USER); 1052 1053 if (ks1 == NULL || ks2 == NULL) { 1054 return (B_FALSE); 1055 } 1056 return (ks1->ks_rid == ks2->ks_rid && 1057 strcmp(ks1->ks_domain->kd_name, ks2->ks_domain->kd_name) == 0); 1058 } 1059