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