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 2018 Nexenta Systems, 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 <smbsrv/smb_kproto.h> 209 #include <smbsrv/smb_door.h> 210 211 #define ADMINISTRATORS_SID "S-1-5-32-544" 212 213 /* Don't leak object addresses */ 214 #define SMB_USER_SSNID(u) \ 215 ((uintptr_t)&smb_cache_user ^ (uintptr_t)(u)) 216 217 static void smb_user_delete(void *); 218 static int smb_user_enum_private(smb_user_t *, smb_svcenum_t *); 219 static void smb_user_auth_logoff(smb_user_t *); 220 static void smb_user_logoff_tq(void *); 221 222 /* 223 * Create a new user. 224 * 225 * For SMB2 and later, session IDs (u_ssnid) need to be unique among all 226 * current and "recent" sessions. The session ID is derived from the 227 * address of the smb_user object (obscured by XOR with a constant). 228 * This adds a 3-bit generation number in the low bits, incremented 229 * when we allocate an smb_user_t from its kmem cache, so it can't 230 * be confused with a (recent) previous incarnation of this object. 231 */ 232 smb_user_t * 233 smb_user_new(smb_session_t *session) 234 { 235 smb_user_t *user; 236 uint_t gen; // generation (low 3 bits of ssnid) 237 238 ASSERT(session); 239 ASSERT(session->s_magic == SMB_SESSION_MAGIC); 240 241 user = kmem_cache_alloc(smb_cache_user, KM_SLEEP); 242 gen = (user->u_ssnid + 1) & 7; 243 bzero(user, sizeof (smb_user_t)); 244 245 user->u_refcnt = 1; 246 user->u_session = session; 247 user->u_server = session->s_server; 248 user->u_logon_time = gethrestime_sec(); 249 250 if (smb_idpool_alloc(&session->s_uid_pool, &user->u_uid)) 251 goto errout; 252 user->u_ssnid = SMB_USER_SSNID(user) + gen; 253 254 mutex_init(&user->u_mutex, NULL, MUTEX_DEFAULT, NULL); 255 user->u_state = SMB_USER_STATE_LOGGING_ON; 256 user->u_magic = SMB_USER_MAGIC; 257 258 smb_llist_enter(&session->s_user_list, RW_WRITER); 259 smb_llist_insert_tail(&session->s_user_list, user); 260 smb_llist_exit(&session->s_user_list); 261 smb_server_inc_users(session->s_server); 262 263 return (user); 264 265 errout: 266 if (user->u_uid != 0) 267 smb_idpool_free(&session->s_uid_pool, user->u_uid); 268 kmem_cache_free(smb_cache_user, user); 269 return (NULL); 270 } 271 272 /* 273 * Fill in the details of a user, meaning a transition 274 * from state LOGGING_ON to state LOGGED_ON. 275 */ 276 int 277 smb_user_logon( 278 smb_user_t *user, 279 cred_t *cr, 280 char *domain_name, 281 char *account_name, 282 uint32_t flags, 283 uint32_t privileges, 284 uint32_t audit_sid) 285 { 286 ksocket_t authsock = NULL; 287 timeout_id_t tmo = NULL; 288 289 ASSERT(user->u_magic == SMB_USER_MAGIC); 290 ASSERT(cr); 291 ASSERT(account_name); 292 ASSERT(domain_name); 293 294 mutex_enter(&user->u_mutex); 295 296 if (user->u_state != SMB_USER_STATE_LOGGING_ON) { 297 mutex_exit(&user->u_mutex); 298 return (-1); 299 } 300 301 /* 302 * In the transition from LOGGING_ON to LOGGED_ON, 303 * we always have an auth. socket to close. 304 */ 305 authsock = user->u_authsock; 306 ASSERT(authsock != NULL); 307 user->u_authsock = NULL; 308 tmo = user->u_auth_tmo; 309 user->u_auth_tmo = NULL; 310 311 user->u_state = SMB_USER_STATE_LOGGED_ON; 312 user->u_flags = flags; 313 user->u_name_len = strlen(account_name) + 1; 314 user->u_domain_len = strlen(domain_name) + 1; 315 user->u_name = smb_mem_strdup(account_name); 316 user->u_domain = smb_mem_strdup(domain_name); 317 user->u_audit_sid = audit_sid; 318 319 smb_user_setcred(user, cr, privileges); 320 321 mutex_exit(&user->u_mutex); 322 323 /* Timeout callback takes u_mutex. See untimeout(9f) */ 324 if (tmo != NULL) 325 (void) untimeout(tmo); 326 327 /* This close can block, so not under the mutex. */ 328 smb_authsock_close(user, authsock); 329 330 return (0); 331 } 332 333 /* 334 * smb_user_logoff 335 * 336 * Change the user state to "logging off" and disconnect trees. 337 * The user list must not be entered or modified here. 338 * 339 * We remain in state "logging off" until the last ref. is gone, 340 * then smb_user_release takes us to state "logged off". 341 */ 342 void 343 smb_user_logoff( 344 smb_user_t *user) 345 { 346 ksocket_t authsock = NULL; 347 timeout_id_t tmo = NULL; 348 349 ASSERT(user->u_magic == SMB_USER_MAGIC); 350 351 mutex_enter(&user->u_mutex); 352 ASSERT(user->u_refcnt); 353 switch (user->u_state) { 354 case SMB_USER_STATE_LOGGING_ON: 355 authsock = user->u_authsock; 356 user->u_authsock = NULL; 357 tmo = user->u_auth_tmo; 358 user->u_auth_tmo = NULL; 359 user->u_state = SMB_USER_STATE_LOGGING_OFF; 360 mutex_exit(&user->u_mutex); 361 362 /* Timeout callback takes u_mutex. See untimeout(9f) */ 363 if (tmo != NULL) 364 (void) untimeout(tmo); 365 /* This close can block, so not under the mutex. */ 366 if (authsock != NULL) 367 smb_authsock_close(user, authsock); 368 break; 369 370 case SMB_USER_STATE_LOGGED_ON: 371 /* 372 * The user is moved into a state indicating that the log off 373 * process has started. 374 */ 375 user->u_state = SMB_USER_STATE_LOGGING_OFF; 376 mutex_exit(&user->u_mutex); 377 smb_session_disconnect_owned_trees(user->u_session, user); 378 smb_user_auth_logoff(user); 379 break; 380 381 case SMB_USER_STATE_LOGGED_OFF: 382 case SMB_USER_STATE_LOGGING_OFF: 383 mutex_exit(&user->u_mutex); 384 break; 385 386 default: 387 ASSERT(0); 388 mutex_exit(&user->u_mutex); 389 break; 390 } 391 } 392 393 /* 394 * Take a reference on a user. Do not return a reference unless the user is in 395 * the logged-in state. 396 */ 397 boolean_t 398 smb_user_hold(smb_user_t *user) 399 { 400 SMB_USER_VALID(user); 401 402 mutex_enter(&user->u_mutex); 403 404 if (user->u_state == SMB_USER_STATE_LOGGED_ON) { 405 user->u_refcnt++; 406 mutex_exit(&user->u_mutex); 407 return (B_TRUE); 408 } 409 410 mutex_exit(&user->u_mutex); 411 return (B_FALSE); 412 } 413 414 /* 415 * Unconditionally take a reference on a user. 416 */ 417 void 418 smb_user_hold_internal(smb_user_t *user) 419 { 420 SMB_USER_VALID(user); 421 422 mutex_enter(&user->u_mutex); 423 user->u_refcnt++; 424 mutex_exit(&user->u_mutex); 425 } 426 427 /* 428 * Release a reference on a user. If the reference count falls to 429 * zero and the user has logged off, post the object for deletion. 430 * Object deletion is deferred to avoid modifying a list while an 431 * iteration may be in progress. 432 */ 433 void 434 smb_user_release( 435 smb_user_t *user) 436 { 437 smb_session_t *ssn = user->u_session; 438 439 SMB_USER_VALID(user); 440 441 /* flush the tree list delete queue */ 442 smb_llist_flush(&ssn->s_tree_list); 443 444 mutex_enter(&user->u_mutex); 445 ASSERT(user->u_refcnt); 446 user->u_refcnt--; 447 448 switch (user->u_state) { 449 case SMB_USER_STATE_LOGGING_OFF: 450 if (user->u_refcnt == 0) { 451 smb_session_t *ssn = user->u_session; 452 user->u_state = SMB_USER_STATE_LOGGED_OFF; 453 smb_llist_post(&ssn->s_user_list, user, 454 smb_user_delete); 455 } 456 break; 457 458 case SMB_USER_STATE_LOGGING_ON: 459 case SMB_USER_STATE_LOGGED_ON: 460 break; 461 462 case SMB_USER_STATE_LOGGED_OFF: 463 default: 464 ASSERT(0); 465 break; 466 } 467 mutex_exit(&user->u_mutex); 468 } 469 470 /* 471 * Timeout handler for user logons that stay too long in 472 * state SMB_USER_STATE_LOGGING_ON. This is setup by a 473 * timeout call in smb_authsock_open, and called in a 474 * callout thread, so schedule a taskq job to do the 475 * real work of logging off this user. 476 */ 477 void 478 smb_user_auth_tmo(void *arg) 479 { 480 smb_user_t *user = arg; 481 smb_request_t *sr; 482 483 SMB_USER_VALID(user); 484 485 /* 486 * If we can't allocate a request, it means the 487 * session is being torn down, so nothing to do. 488 */ 489 sr = smb_request_alloc(user->u_session, 0); 490 if (sr == NULL) 491 return; 492 493 /* 494 * Check user state, and take a hold if it's 495 * still logging on. If not, we're done. 496 */ 497 mutex_enter(&user->u_mutex); 498 if (user->u_state != SMB_USER_STATE_LOGGING_ON) { 499 mutex_exit(&user->u_mutex); 500 smb_request_free(sr); 501 return; 502 } 503 /* smb_user_hold_internal */ 504 user->u_refcnt++; 505 mutex_exit(&user->u_mutex); 506 507 /* 508 * The user hold is given to the SR, and released in 509 * smb_user_logoff_tq / smb_request_free 510 */ 511 sr->uid_user = user; 512 sr->user_cr = user->u_cred; 513 sr->sr_state = SMB_REQ_STATE_SUBMITTED; 514 515 (void) taskq_dispatch( 516 user->u_server->sv_worker_pool, 517 smb_user_logoff_tq, sr, TQ_SLEEP); 518 } 519 520 /* 521 * Helper for smb_user_auth_tmo() 522 */ 523 static void 524 smb_user_logoff_tq(void *arg) 525 { 526 smb_request_t *sr = arg; 527 528 SMB_REQ_VALID(sr); 529 530 mutex_enter(&sr->sr_mutex); 531 sr->sr_worker = curthread; 532 sr->sr_state = SMB_REQ_STATE_ACTIVE; 533 mutex_exit(&sr->sr_mutex); 534 535 smb_user_logoff(sr->uid_user); 536 537 sr->sr_state = SMB_REQ_STATE_COMPLETED; 538 smb_request_free(sr); 539 } 540 541 /* 542 * Determine whether or not the user is an administrator. 543 * Members of the administrators group have administrative rights. 544 */ 545 boolean_t 546 smb_user_is_admin(smb_user_t *user) 547 { 548 #ifdef _KERNEL 549 char sidstr[SMB_SID_STRSZ]; 550 ksidlist_t *ksidlist; 551 ksid_t ksid1; 552 ksid_t *ksid2; 553 int i; 554 #endif /* _KERNEL */ 555 boolean_t rc = B_FALSE; 556 557 ASSERT(user); 558 ASSERT(user->u_cred); 559 560 if (SMB_USER_IS_ADMIN(user)) 561 return (B_TRUE); 562 563 #ifdef _KERNEL 564 bzero(&ksid1, sizeof (ksid_t)); 565 (void) strlcpy(sidstr, ADMINISTRATORS_SID, SMB_SID_STRSZ); 566 ASSERT(smb_sid_splitstr(sidstr, &ksid1.ks_rid) == 0); 567 ksid1.ks_domain = ksid_lookupdomain(sidstr); 568 569 ksidlist = crgetsidlist(user->u_cred); 570 ASSERT(ksidlist); 571 ASSERT(ksid1.ks_domain); 572 ASSERT(ksid1.ks_domain->kd_name); 573 574 i = 0; 575 ksid2 = crgetsid(user->u_cred, KSID_USER); 576 do { 577 ASSERT(ksid2->ks_domain); 578 ASSERT(ksid2->ks_domain->kd_name); 579 580 if (strcmp(ksid1.ks_domain->kd_name, 581 ksid2->ks_domain->kd_name) == 0 && 582 ksid1.ks_rid == ksid2->ks_rid) { 583 user->u_flags |= SMB_USER_FLAG_ADMIN; 584 rc = B_TRUE; 585 break; 586 } 587 588 ksid2 = &ksidlist->ksl_sids[i]; 589 } while (i++ < ksidlist->ksl_nsid); 590 591 ksid_rele(&ksid1); 592 #endif /* _KERNEL */ 593 return (rc); 594 } 595 596 /* 597 * This function should be called with a hold on the user. 598 */ 599 boolean_t 600 smb_user_namecmp(smb_user_t *user, const char *name) 601 { 602 char *fq_name; 603 boolean_t match; 604 605 if (smb_strcasecmp(name, user->u_name, 0) == 0) 606 return (B_TRUE); 607 608 fq_name = kmem_alloc(MAXNAMELEN, KM_SLEEP); 609 610 (void) snprintf(fq_name, MAXNAMELEN, "%s\\%s", 611 user->u_domain, user->u_name); 612 613 match = (smb_strcasecmp(name, fq_name, 0) == 0); 614 if (!match) { 615 (void) snprintf(fq_name, MAXNAMELEN, "%s@%s", 616 user->u_name, user->u_domain); 617 618 match = (smb_strcasecmp(name, fq_name, 0) == 0); 619 } 620 621 kmem_free(fq_name, MAXNAMELEN); 622 return (match); 623 } 624 625 /* 626 * If the enumeration request is for user data, handle the request 627 * here. Otherwise, pass it on to the trees. 628 * 629 * This function should be called with a hold on the user. 630 */ 631 int 632 smb_user_enum(smb_user_t *user, smb_svcenum_t *svcenum) 633 { 634 int rc = 0; 635 636 ASSERT(user); 637 ASSERT(user->u_magic == SMB_USER_MAGIC); 638 639 if (svcenum->se_type == SMB_SVCENUM_TYPE_USER) 640 return (smb_user_enum_private(user, svcenum)); 641 642 return (rc); 643 } 644 645 /* *************************** Static Functions ***************************** */ 646 647 /* 648 * Delete a user. The tree list should be empty. 649 * 650 * Remove the user from the session's user list before freeing resources 651 * associated with the user. 652 */ 653 static void 654 smb_user_delete(void *arg) 655 { 656 smb_session_t *session; 657 smb_user_t *user = (smb_user_t *)arg; 658 uint32_t ucount; 659 660 SMB_USER_VALID(user); 661 ASSERT(user->u_refcnt == 0); 662 ASSERT(user->u_state == SMB_USER_STATE_LOGGED_OFF); 663 ASSERT(user->u_authsock == NULL); 664 ASSERT(user->u_auth_tmo == NULL); 665 666 session = user->u_session; 667 668 smb_server_dec_users(session->s_server); 669 smb_llist_enter(&session->s_user_list, RW_WRITER); 670 smb_llist_remove(&session->s_user_list, user); 671 smb_idpool_free(&session->s_uid_pool, user->u_uid); 672 ucount = smb_llist_get_count(&session->s_user_list); 673 smb_llist_exit(&session->s_user_list); 674 675 if (ucount == 0) { 676 smb_rwx_rwenter(&session->s_lock, RW_WRITER); 677 session->s_state = SMB_SESSION_STATE_SHUTDOWN; 678 smb_rwx_cvbcast(&session->s_lock); 679 smb_rwx_rwexit(&session->s_lock); 680 } 681 682 /* 683 * This user is no longer on s_user_list, however... 684 * 685 * This is called via smb_llist_post, which means it may run 686 * BEFORE smb_user_release drops u_mutex (if another thread 687 * flushes the delete queue before we do). Synchronize. 688 */ 689 mutex_enter(&user->u_mutex); 690 mutex_exit(&user->u_mutex); 691 692 user->u_magic = (uint32_t)~SMB_USER_MAGIC; 693 mutex_destroy(&user->u_mutex); 694 if (user->u_cred) 695 crfree(user->u_cred); 696 if (user->u_privcred) 697 crfree(user->u_privcred); 698 smb_mem_free(user->u_name); 699 smb_mem_free(user->u_domain); 700 kmem_cache_free(smb_cache_user, user); 701 } 702 703 cred_t * 704 smb_user_getcred(smb_user_t *user) 705 { 706 return (user->u_cred); 707 } 708 709 cred_t * 710 smb_user_getprivcred(smb_user_t *user) 711 { 712 return ((user->u_privcred)? user->u_privcred : user->u_cred); 713 } 714 715 #ifdef _KERNEL 716 /* 717 * Assign the user cred and privileges. 718 * 719 * If the user has backup and/or restore privleges, dup the cred 720 * and add those privileges to this new privileged cred. 721 */ 722 void 723 smb_user_setcred(smb_user_t *user, cred_t *cr, uint32_t privileges) 724 { 725 cred_t *privcred = NULL; 726 727 ASSERT(cr); 728 crhold(cr); 729 730 if (privileges & (SMB_USER_PRIV_BACKUP | SMB_USER_PRIV_RESTORE)) 731 privcred = crdup(cr); 732 733 if (privcred != NULL) { 734 if (privileges & SMB_USER_PRIV_BACKUP) { 735 (void) crsetpriv(privcred, PRIV_FILE_DAC_READ, 736 PRIV_FILE_DAC_SEARCH, PRIV_SYS_MOUNT, NULL); 737 } 738 739 if (privileges & SMB_USER_PRIV_RESTORE) { 740 (void) crsetpriv(privcred, PRIV_FILE_DAC_WRITE, 741 PRIV_FILE_CHOWN, PRIV_FILE_CHOWN_SELF, 742 PRIV_FILE_DAC_SEARCH, PRIV_FILE_LINK_ANY, 743 PRIV_FILE_OWNER, PRIV_FILE_SETID, 744 PRIV_SYS_LINKDIR, PRIV_SYS_MOUNT, NULL); 745 } 746 } 747 748 user->u_cred = cr; 749 user->u_privcred = privcred; 750 user->u_privileges = privileges; 751 } 752 #endif /* _KERNEL */ 753 754 /* 755 * Private function to support smb_user_enum. 756 */ 757 static int 758 smb_user_enum_private(smb_user_t *user, smb_svcenum_t *svcenum) 759 { 760 uint8_t *pb; 761 uint_t nbytes; 762 int rc; 763 764 if (svcenum->se_nskip > 0) { 765 svcenum->se_nskip--; 766 return (0); 767 } 768 769 if (svcenum->se_nitems >= svcenum->se_nlimit) { 770 svcenum->se_nitems = svcenum->se_nlimit; 771 return (0); 772 } 773 774 pb = &svcenum->se_buf[svcenum->se_bused]; 775 rc = smb_user_netinfo_encode(user, pb, svcenum->se_bavail, &nbytes); 776 if (rc == 0) { 777 svcenum->se_bavail -= nbytes; 778 svcenum->se_bused += nbytes; 779 svcenum->se_nitems++; 780 } 781 782 return (rc); 783 } 784 785 /* 786 * Encode the NetInfo for a user into a buffer. NetInfo contains 787 * information that is often needed in user space to support RPC 788 * requests. 789 */ 790 int 791 smb_user_netinfo_encode(smb_user_t *user, uint8_t *buf, size_t buflen, 792 uint32_t *nbytes) 793 { 794 smb_netuserinfo_t info; 795 int rc; 796 797 smb_user_netinfo_init(user, &info); 798 rc = smb_netuserinfo_encode(&info, buf, buflen, nbytes); 799 smb_user_netinfo_fini(&info); 800 801 return (rc); 802 } 803 804 void 805 smb_user_netinfo_init(smb_user_t *user, smb_netuserinfo_t *info) 806 { 807 smb_session_t *session; 808 char *buf; 809 810 ASSERT(user); 811 ASSERT(user->u_domain); 812 ASSERT(user->u_name); 813 814 session = user->u_session; 815 ASSERT(session); 816 ASSERT(session->workstation); 817 818 info->ui_session_id = session->s_kid; 819 info->ui_native_os = session->native_os; 820 info->ui_ipaddr = session->ipaddr; 821 info->ui_numopens = session->s_file_cnt; 822 info->ui_logon_time = user->u_logon_time; 823 info->ui_flags = user->u_flags; 824 info->ui_posix_uid = crgetuid(user->u_cred); 825 826 info->ui_domain_len = user->u_domain_len; 827 info->ui_domain = smb_mem_strdup(user->u_domain); 828 829 info->ui_account_len = user->u_name_len; 830 info->ui_account = smb_mem_strdup(user->u_name); 831 832 buf = kmem_alloc(MAXNAMELEN, KM_SLEEP); 833 smb_session_getclient(session, buf, MAXNAMELEN); 834 info->ui_workstation_len = strlen(buf) + 1; 835 info->ui_workstation = smb_mem_strdup(buf); 836 kmem_free(buf, MAXNAMELEN); 837 } 838 839 void 840 smb_user_netinfo_fini(smb_netuserinfo_t *info) 841 { 842 if (info == NULL) 843 return; 844 845 if (info->ui_domain) 846 smb_mem_free(info->ui_domain); 847 if (info->ui_account) 848 smb_mem_free(info->ui_account); 849 if (info->ui_workstation) 850 smb_mem_free(info->ui_workstation); 851 852 bzero(info, sizeof (smb_netuserinfo_t)); 853 } 854 855 /* 856 * Tell smbd this user is going away so it can clean up their 857 * audit session, autohome dir, etc. 858 * 859 * Note that when we're shutting down, smbd will already have set 860 * smbd.s_shutting_down and therefore will ignore door calls. 861 * Skip this during shutdown to reduce upcall noise. 862 */ 863 static void 864 smb_user_auth_logoff(smb_user_t *user) 865 { 866 smb_server_t *sv = user->u_server; 867 uint32_t audit_sid; 868 869 if (sv->sv_state != SMB_SERVER_STATE_RUNNING) 870 return; 871 872 audit_sid = user->u_audit_sid; 873 (void) smb_kdoor_upcall(sv, SMB_DR_USER_AUTH_LOGOFF, 874 &audit_sid, xdr_uint32_t, NULL, NULL); 875 } 876 877 boolean_t 878 smb_is_same_user(cred_t *cr1, cred_t *cr2) 879 { 880 ksid_t *ks1 = crgetsid(cr1, KSID_USER); 881 ksid_t *ks2 = crgetsid(cr2, KSID_USER); 882 883 return (ks1->ks_rid == ks2->ks_rid && 884 strcmp(ks1->ks_domain->kd_name, ks2->ks_domain->kd_name) == 0); 885 } 886