1da6c28aaSamw /* 2da6c28aaSamw * CDDL HEADER START 3da6c28aaSamw * 4da6c28aaSamw * The contents of this file are subject to the terms of the 5da6c28aaSamw * Common Development and Distribution License (the "License"). 6da6c28aaSamw * You may not use this file except in compliance with the License. 7da6c28aaSamw * 8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10da6c28aaSamw * See the License for the specific language governing permissions 11da6c28aaSamw * and limitations under the License. 12da6c28aaSamw * 13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18da6c28aaSamw * 19da6c28aaSamw * CDDL HEADER END 20da6c28aaSamw */ 21da6c28aaSamw /* 22c5866007SKeyur Desai * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23*12b65585SGordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved. 24da6c28aaSamw */ 25da6c28aaSamw 26da6c28aaSamw /* 27da6c28aaSamw * General Structures Layout 28da6c28aaSamw * ------------------------- 29da6c28aaSamw * 30da6c28aaSamw * This is a simplified diagram showing the relationship between most of the 31da6c28aaSamw * main structures. 32da6c28aaSamw * 33da6c28aaSamw * +-------------------+ 34da6c28aaSamw * | SMB_INFO | 35da6c28aaSamw * +-------------------+ 36da6c28aaSamw * | 37da6c28aaSamw * | 38da6c28aaSamw * v 39da6c28aaSamw * +-------------------+ +-------------------+ +-------------------+ 40da6c28aaSamw * | SESSION |<----->| SESSION |......| SESSION | 41da6c28aaSamw * +-------------------+ +-------------------+ +-------------------+ 423b13a1efSThomas Keiser * | | 433b13a1efSThomas Keiser * | | 443b13a1efSThomas Keiser * | v 453b13a1efSThomas Keiser * | +-------------------+ +-------------------+ +-------------------+ 463b13a1efSThomas Keiser * | | USER |<--->| USER |...| USER | 473b13a1efSThomas Keiser * | +-------------------+ +-------------------+ +-------------------+ 48da6c28aaSamw * | 49da6c28aaSamw * | 50da6c28aaSamw * v 51da6c28aaSamw * +-------------------+ +-------------------+ +-------------------+ 52da6c28aaSamw * | TREE |<----->| TREE |......| TREE | 53da6c28aaSamw * +-------------------+ +-------------------+ +-------------------+ 54da6c28aaSamw * | | 55da6c28aaSamw * | | 56da6c28aaSamw * | v 57da6c28aaSamw * | +-------+ +-------+ +-------+ 58da6c28aaSamw * | | OFILE |<----->| OFILE |......| OFILE | 59da6c28aaSamw * | +-------+ +-------+ +-------+ 60da6c28aaSamw * | 61da6c28aaSamw * | 62da6c28aaSamw * v 63da6c28aaSamw * +-------+ +------+ +------+ 64da6c28aaSamw * | ODIR |<----->| ODIR |......| ODIR | 65da6c28aaSamw * +-------+ +------+ +------+ 66da6c28aaSamw * 67da6c28aaSamw * 68da6c28aaSamw * User State Machine 69da6c28aaSamw * ------------------ 70da6c28aaSamw * 71*12b65585SGordon Ross * 72*12b65585SGordon Ross * | T0: Creation/Allocation 73*12b65585SGordon Ross * | (1st session setup) 74*12b65585SGordon Ross * v 75*12b65585SGordon Ross * +-----------------------------+ 76*12b65585SGordon Ross * | SMB_USER_STATE_LOGGING_ON |<----------+ 77*12b65585SGordon Ross * +-----------------------------+ addl. session setup 78*12b65585SGordon Ross * | | (more proc. required) 79*12b65585SGordon Ross * | T2 | ^ 80*12b65585SGordon Ross * | | | T1: (cont.) 81*12b65585SGordon Ross * | +------->-------? 82*12b65585SGordon Ross * v | T3: (fail) 83*12b65585SGordon Ross * +-----------------------------+ v 84*12b65585SGordon Ross * | SMB_USER_STATE_LOGGED_ON | (logged off) 85da6c28aaSamw * +-----------------------------+ 86da6c28aaSamw * | 87*12b65585SGordon Ross * | T4 88da6c28aaSamw * | 89da6c28aaSamw * v 90da6c28aaSamw * +-----------------------------+ 91da6c28aaSamw * | SMB_USER_STATE_LOGGING_OFF | 92da6c28aaSamw * +-----------------------------+ 93da6c28aaSamw * | 94*12b65585SGordon Ross * | T5 95da6c28aaSamw * | 96da6c28aaSamw * v 97*12b65585SGordon Ross * +-----------------------------+ T6 98da6c28aaSamw * | SMB_USER_STATE_LOGGED_OFF |----------> Deletion/Free 99da6c28aaSamw * +-----------------------------+ 100da6c28aaSamw * 101*12b65585SGordon Ross * SMB_USER_STATE_LOGGING_ON 102da6c28aaSamw * 103da6c28aaSamw * While in this state: 104*12b65585SGordon Ross * - The user is in the list of users for his session. 105*12b65585SGordon Ross * - References will be given out ONLY for session setup. 106*12b65585SGordon Ross * - This user can not access anything yet. 107*12b65585SGordon Ross * 108*12b65585SGordon Ross * SMB_USER_STATE_LOGGED_ON 109*12b65585SGordon Ross * 110*12b65585SGordon Ross * While in this state: 111*12b65585SGordon Ross * - The user is in the list of users for his session. 112da6c28aaSamw * - References will be given out if the user is looked up. 113da6c28aaSamw * - The user can access files and pipes. 114da6c28aaSamw * 115da6c28aaSamw * SMB_USER_STATE_LOGGING_OFF 116da6c28aaSamw * 117da6c28aaSamw * While in this state: 118*12b65585SGordon Ross * - The user is in the list of users for his session. 119da6c28aaSamw * - References will not be given out if the user is looked up. 120da6c28aaSamw * - The trees the user connected are being disconnected. 121da6c28aaSamw * - The resources associated with the user remain. 122da6c28aaSamw * 123*12b65585SGordon Ross * SMB_USER_STATE_LOGGED_OFF 124da6c28aaSamw * 125da6c28aaSamw * While in this state: 126da6c28aaSamw * - The user is queued in the list of users of his session. 127da6c28aaSamw * - References will not be given out if the user is looked up. 128da6c28aaSamw * - The user has no more trees connected. 129da6c28aaSamw * - The resources associated with the user remain. 130da6c28aaSamw * 131da6c28aaSamw * Transition T0 132da6c28aaSamw * 133*12b65585SGordon Ross * First request in an SMB Session Setup sequence creates a 134*12b65585SGordon Ross * new user object and adds it to the list of users for 135*12b65585SGordon Ross * this session. User UID is assigned and returned. 136da6c28aaSamw * 137da6c28aaSamw * Transition T1 138da6c28aaSamw * 139*12b65585SGordon Ross * Subsequent SMB Session Setup requests (on the same UID 140*12b65585SGordon Ross * assigned in T0) update the state of this user object, 141*12b65585SGordon Ross * communicating with smbd for the crypto work. 142da6c28aaSamw * 143da6c28aaSamw * Transition T2 144da6c28aaSamw * 145*12b65585SGordon Ross * If the SMB Session Setup sequence is successful, T2 146*12b65585SGordon Ross * makes the new user object available for requests. 147*12b65585SGordon Ross * 148*12b65585SGordon Ross * Transition T3 149*12b65585SGordon Ross * 150*12b65585SGordon Ross * If an Session Setup request gets an error other than 151*12b65585SGordon Ross * the expected "more processing required", then T3 152*12b65585SGordon Ross * leads to state "LOGGED_OFF" and then tear-down of the 153*12b65585SGordon Ross * partially constructed user. 154*12b65585SGordon Ross * 155*12b65585SGordon Ross * Transition T4 156*12b65585SGordon Ross * 157*12b65585SGordon Ross * Normal SMB User Logoff request, or session tear-down. 158*12b65585SGordon Ross * 159*12b65585SGordon Ross * Transition T5 160*12b65585SGordon Ross * 161da6c28aaSamw * This transition occurs in smb_user_release(). The resources associated 162da6c28aaSamw * with the user are deleted as well as the user. For the transition to 163da6c28aaSamw * occur, the user must be in the SMB_USER_STATE_LOGGED_OFF state and the 164da6c28aaSamw * reference count be zero. 165da6c28aaSamw * 166da6c28aaSamw * Comments 167da6c28aaSamw * -------- 168da6c28aaSamw * 169da6c28aaSamw * The state machine of the user structures is controlled by 3 elements: 170da6c28aaSamw * - The list of users of the session he belongs to. 171da6c28aaSamw * - The mutex embedded in the structure itself. 172da6c28aaSamw * - The reference count. 173da6c28aaSamw * 174da6c28aaSamw * There's a mutex embedded in the user structure used to protect its fields 175da6c28aaSamw * and there's a lock embedded in the list of users of a session. To 176da6c28aaSamw * increment or to decrement the reference count the mutex must be entered. 177da6c28aaSamw * To insert the user into the list of users of the session and to remove 178da6c28aaSamw * the user from it, the lock must be entered in RW_WRITER mode. 179da6c28aaSamw * 180da6c28aaSamw * Rules of access to a user structure: 181da6c28aaSamw * 182da6c28aaSamw * 1) In order to avoid deadlocks, when both (mutex and lock of the session 183da6c28aaSamw * list) have to be entered, the lock must be entered first. 184da6c28aaSamw * 185da6c28aaSamw * 2) All actions applied to a user require a reference count. 186da6c28aaSamw * 187da6c28aaSamw * 3) There are 2 ways of getting a reference count. One is when the user 1889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * logs in. The other when the user is looked up. 189da6c28aaSamw * 190da6c28aaSamw * It should be noted that the reference count of a user registers the 191da6c28aaSamw * number of references to the user in other structures (such as an smb 192da6c28aaSamw * request). The reference count is not incremented in these 2 instances: 193da6c28aaSamw * 194da6c28aaSamw * 1) The user is logged in. An user is anchored by his state. If there's 195da6c28aaSamw * no activity involving a user currently logged in, the reference 196da6c28aaSamw * count of that user is zero. 197da6c28aaSamw * 198da6c28aaSamw * 2) The user is queued in the list of users of the session. The fact of 199da6c28aaSamw * being queued in that list is NOT registered by incrementing the 200da6c28aaSamw * reference count. 201da6c28aaSamw */ 202148c5f43SAlan Wright #include <sys/types.h> 203148c5f43SAlan Wright #include <sys/sid.h> 204148c5f43SAlan Wright #include <sys/priv_names.h> 205bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h> 2069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_door.h> 207da6c28aaSamw 208c8ec8eeaSjose borrego #define ADMINISTRATORS_SID "S-1-5-32-544" 209c8ec8eeaSjose borrego 2101fcced4cSJordan Brown static int smb_user_enum_private(smb_user_t *, smb_svcenum_t *); 2118622ec45SGordon Ross static void smb_user_auth_logoff(smb_user_t *); 212c8ec8eeaSjose borrego 213b819cea2SGordon Ross 214da6c28aaSamw /* 215148c5f43SAlan Wright * Create a new user. 216da6c28aaSamw */ 217da6c28aaSamw smb_user_t * 218*12b65585SGordon Ross smb_user_new(smb_session_t *session) 219*12b65585SGordon Ross { 220*12b65585SGordon Ross smb_user_t *user; 221*12b65585SGordon Ross 222*12b65585SGordon Ross ASSERT(session); 223*12b65585SGordon Ross ASSERT(session->s_magic == SMB_SESSION_MAGIC); 224*12b65585SGordon Ross 225*12b65585SGordon Ross user = kmem_cache_alloc(smb_cache_user, KM_SLEEP); 226*12b65585SGordon Ross bzero(user, sizeof (smb_user_t)); 227*12b65585SGordon Ross 228*12b65585SGordon Ross user->u_refcnt = 1; 229*12b65585SGordon Ross user->u_session = session; 230*12b65585SGordon Ross user->u_server = session->s_server; 231*12b65585SGordon Ross user->u_logon_time = gethrestime_sec(); 232*12b65585SGordon Ross 233*12b65585SGordon Ross if (smb_idpool_alloc(&session->s_uid_pool, &user->u_uid)) 234*12b65585SGordon Ross goto errout; 235*12b65585SGordon Ross 236*12b65585SGordon Ross mutex_init(&user->u_mutex, NULL, MUTEX_DEFAULT, NULL); 237*12b65585SGordon Ross user->u_state = SMB_USER_STATE_LOGGING_ON; 238*12b65585SGordon Ross user->u_magic = SMB_USER_MAGIC; 239*12b65585SGordon Ross 240*12b65585SGordon Ross smb_llist_enter(&session->s_user_list, RW_WRITER); 241*12b65585SGordon Ross smb_llist_insert_tail(&session->s_user_list, user); 242*12b65585SGordon Ross smb_llist_exit(&session->s_user_list); 243*12b65585SGordon Ross smb_server_inc_users(session->s_server); 244*12b65585SGordon Ross 245*12b65585SGordon Ross return (user); 246*12b65585SGordon Ross 247*12b65585SGordon Ross errout: 248*12b65585SGordon Ross if (user->u_uid != 0) 249*12b65585SGordon Ross smb_idpool_free(&session->s_uid_pool, user->u_uid); 250*12b65585SGordon Ross kmem_cache_free(smb_cache_user, user); 251*12b65585SGordon Ross return (NULL); 252*12b65585SGordon Ross } 253*12b65585SGordon Ross 254*12b65585SGordon Ross /* 255*12b65585SGordon Ross * Fill in the details of a user, meaning a transition 256*12b65585SGordon Ross * from state LOGGING_ON to state LOGGED_ON. 257*12b65585SGordon Ross */ 258*12b65585SGordon Ross int 259*12b65585SGordon Ross smb_user_logon( 260*12b65585SGordon Ross smb_user_t *user, 261da6c28aaSamw cred_t *cr, 262da6c28aaSamw char *domain_name, 263da6c28aaSamw char *account_name, 264da6c28aaSamw uint32_t flags, 265da6c28aaSamw uint32_t privileges, 266da6c28aaSamw uint32_t audit_sid) 267da6c28aaSamw { 268da6c28aaSamw 269*12b65585SGordon Ross ASSERT(user->u_magic == SMB_USER_MAGIC); 270da6c28aaSamw ASSERT(cr); 271da6c28aaSamw ASSERT(account_name); 272da6c28aaSamw ASSERT(domain_name); 273da6c28aaSamw 274*12b65585SGordon Ross mutex_enter(&user->u_mutex); 275*12b65585SGordon Ross 276*12b65585SGordon Ross if (user->u_state != SMB_USER_STATE_LOGGING_ON) { 277*12b65585SGordon Ross mutex_exit(&user->u_mutex); 278*12b65585SGordon Ross return (-1); 279*12b65585SGordon Ross } 280*12b65585SGordon Ross 281*12b65585SGordon Ross smb_authsock_close(user); 282*12b65585SGordon Ross 283*12b65585SGordon Ross user->u_state = SMB_USER_STATE_LOGGED_ON; 284da6c28aaSamw user->u_flags = flags; 285da6c28aaSamw user->u_name_len = strlen(account_name) + 1; 286da6c28aaSamw user->u_domain_len = strlen(domain_name) + 1; 2879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States user->u_name = smb_mem_strdup(account_name); 2889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States user->u_domain = smb_mem_strdup(domain_name); 289da6c28aaSamw user->u_audit_sid = audit_sid; 290da6c28aaSamw 291148c5f43SAlan Wright smb_user_setcred(user, cr, privileges); 292da6c28aaSamw 293*12b65585SGordon Ross mutex_exit(&user->u_mutex); 294da6c28aaSamw 295*12b65585SGordon Ross return (0); 296da6c28aaSamw } 297da6c28aaSamw 298da6c28aaSamw /* 299da6c28aaSamw * smb_user_logoff 300da6c28aaSamw * 3011fcced4cSJordan Brown * Change the user state and disconnect trees. 3021fcced4cSJordan Brown * The user list must not be entered or modified here. 303da6c28aaSamw */ 304da6c28aaSamw void 305da6c28aaSamw smb_user_logoff( 306da6c28aaSamw smb_user_t *user) 307da6c28aaSamw { 308da6c28aaSamw ASSERT(user->u_magic == SMB_USER_MAGIC); 309da6c28aaSamw 310da6c28aaSamw mutex_enter(&user->u_mutex); 311da6c28aaSamw ASSERT(user->u_refcnt); 312da6c28aaSamw switch (user->u_state) { 313*12b65585SGordon Ross case SMB_USER_STATE_LOGGING_ON: { 314*12b65585SGordon Ross smb_authsock_close(user); 315*12b65585SGordon Ross user->u_state = SMB_USER_STATE_LOGGED_OFF; 316*12b65585SGordon Ross smb_server_dec_users(user->u_server); 317*12b65585SGordon Ross break; 318*12b65585SGordon Ross } 319*12b65585SGordon Ross 320*12b65585SGordon Ross case SMB_USER_STATE_LOGGED_ON: { 321da6c28aaSamw /* 322da6c28aaSamw * The user is moved into a state indicating that the log off 323da6c28aaSamw * process has started. 324da6c28aaSamw */ 325da6c28aaSamw user->u_state = SMB_USER_STATE_LOGGING_OFF; 326da6c28aaSamw mutex_exit(&user->u_mutex); 3273b13a1efSThomas Keiser smb_session_disconnect_owned_trees(user->u_session, user); 3288622ec45SGordon Ross smb_user_auth_logoff(user); 329da6c28aaSamw mutex_enter(&user->u_mutex); 330da6c28aaSamw user->u_state = SMB_USER_STATE_LOGGED_OFF; 331148c5f43SAlan Wright smb_server_dec_users(user->u_server); 332da6c28aaSamw break; 333da6c28aaSamw } 334da6c28aaSamw case SMB_USER_STATE_LOGGED_OFF: 335da6c28aaSamw case SMB_USER_STATE_LOGGING_OFF: 336da6c28aaSamw break; 337da6c28aaSamw 338da6c28aaSamw default: 339da6c28aaSamw ASSERT(0); 340da6c28aaSamw break; 341da6c28aaSamw } 342da6c28aaSamw mutex_exit(&user->u_mutex); 343da6c28aaSamw } 344da6c28aaSamw 345da6c28aaSamw /* 3463b13a1efSThomas Keiser * Take a reference on a user. Do not return a reference unless the user is in 3473b13a1efSThomas Keiser * the logged-in state. 3481fcced4cSJordan Brown */ 3491fcced4cSJordan Brown boolean_t 3501fcced4cSJordan Brown smb_user_hold(smb_user_t *user) 3511fcced4cSJordan Brown { 3523b13a1efSThomas Keiser SMB_USER_VALID(user); 3531fcced4cSJordan Brown 3541fcced4cSJordan Brown mutex_enter(&user->u_mutex); 3551fcced4cSJordan Brown 356*12b65585SGordon Ross if (user->u_state == SMB_USER_STATE_LOGGED_ON) { 3571fcced4cSJordan Brown user->u_refcnt++; 3581fcced4cSJordan Brown mutex_exit(&user->u_mutex); 3591fcced4cSJordan Brown return (B_TRUE); 3601fcced4cSJordan Brown } 3611fcced4cSJordan Brown 3621fcced4cSJordan Brown mutex_exit(&user->u_mutex); 3631fcced4cSJordan Brown return (B_FALSE); 3641fcced4cSJordan Brown } 3651fcced4cSJordan Brown 3661fcced4cSJordan Brown /* 3673b13a1efSThomas Keiser * Unconditionally take a reference on a user. 3683b13a1efSThomas Keiser */ 3693b13a1efSThomas Keiser void 3703b13a1efSThomas Keiser smb_user_hold_internal(smb_user_t *user) 3713b13a1efSThomas Keiser { 3723b13a1efSThomas Keiser SMB_USER_VALID(user); 3733b13a1efSThomas Keiser 3743b13a1efSThomas Keiser mutex_enter(&user->u_mutex); 3753b13a1efSThomas Keiser user->u_refcnt++; 3763b13a1efSThomas Keiser mutex_exit(&user->u_mutex); 3773b13a1efSThomas Keiser } 3783b13a1efSThomas Keiser 3793b13a1efSThomas Keiser /* 3809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Release a reference on a user. If the reference count falls to 3819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * zero and the user has logged off, post the object for deletion. 3829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Object deletion is deferred to avoid modifying a list while an 3839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * iteration may be in progress. 384da6c28aaSamw */ 385da6c28aaSamw void 386da6c28aaSamw smb_user_release( 387da6c28aaSamw smb_user_t *user) 388da6c28aaSamw { 389da6c28aaSamw ASSERT(user->u_magic == SMB_USER_MAGIC); 390da6c28aaSamw 391da6c28aaSamw mutex_enter(&user->u_mutex); 392da6c28aaSamw ASSERT(user->u_refcnt); 393da6c28aaSamw user->u_refcnt--; 394c5866007SKeyur Desai 395da6c28aaSamw switch (user->u_state) { 396da6c28aaSamw case SMB_USER_STATE_LOGGED_OFF: 3979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (user->u_refcnt == 0) 3989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_session_post_user(user->u_session, user); 399da6c28aaSamw break; 400da6c28aaSamw 401*12b65585SGordon Ross case SMB_USER_STATE_LOGGING_ON: 402*12b65585SGordon Ross case SMB_USER_STATE_LOGGED_ON: 403da6c28aaSamw case SMB_USER_STATE_LOGGING_OFF: 404da6c28aaSamw break; 405da6c28aaSamw 406da6c28aaSamw default: 407da6c28aaSamw ASSERT(0); 408da6c28aaSamw break; 409da6c28aaSamw } 410da6c28aaSamw mutex_exit(&user->u_mutex); 411da6c28aaSamw } 412da6c28aaSamw 4131fcced4cSJordan Brown /* 414c8ec8eeaSjose borrego * Determine whether or not the user is an administrator. 415c8ec8eeaSjose borrego * Members of the administrators group have administrative rights. 416c8ec8eeaSjose borrego */ 417c8ec8eeaSjose borrego boolean_t 418148c5f43SAlan Wright smb_user_is_admin(smb_user_t *user) 419c8ec8eeaSjose borrego { 420b819cea2SGordon Ross #ifdef _KERNEL 421148c5f43SAlan Wright char sidstr[SMB_SID_STRSZ]; 422148c5f43SAlan Wright ksidlist_t *ksidlist; 423148c5f43SAlan Wright ksid_t ksid1; 424148c5f43SAlan Wright ksid_t *ksid2; 425148c5f43SAlan Wright int i; 426b819cea2SGordon Ross #endif /* _KERNEL */ 427b819cea2SGordon Ross boolean_t rc = B_FALSE; 428c8ec8eeaSjose borrego 429c8ec8eeaSjose borrego ASSERT(user); 430148c5f43SAlan Wright ASSERT(user->u_cred); 431c8ec8eeaSjose borrego 432148c5f43SAlan Wright if (SMB_USER_IS_ADMIN(user)) 433c8ec8eeaSjose borrego return (B_TRUE); 434c8ec8eeaSjose borrego 435b819cea2SGordon Ross #ifdef _KERNEL 436148c5f43SAlan Wright bzero(&ksid1, sizeof (ksid_t)); 437148c5f43SAlan Wright (void) strlcpy(sidstr, ADMINISTRATORS_SID, SMB_SID_STRSZ); 438148c5f43SAlan Wright ASSERT(smb_sid_splitstr(sidstr, &ksid1.ks_rid) == 0); 439148c5f43SAlan Wright ksid1.ks_domain = ksid_lookupdomain(sidstr); 440148c5f43SAlan Wright 441148c5f43SAlan Wright ksidlist = crgetsidlist(user->u_cred); 442148c5f43SAlan Wright ASSERT(ksidlist); 443148c5f43SAlan Wright ASSERT(ksid1.ks_domain); 444148c5f43SAlan Wright ASSERT(ksid1.ks_domain->kd_name); 445148c5f43SAlan Wright 446148c5f43SAlan Wright i = 0; 447148c5f43SAlan Wright ksid2 = crgetsid(user->u_cred, KSID_USER); 448148c5f43SAlan Wright do { 449148c5f43SAlan Wright ASSERT(ksid2->ks_domain); 450148c5f43SAlan Wright ASSERT(ksid2->ks_domain->kd_name); 451148c5f43SAlan Wright 452148c5f43SAlan Wright if (strcmp(ksid1.ks_domain->kd_name, 453148c5f43SAlan Wright ksid2->ks_domain->kd_name) == 0 && 454148c5f43SAlan Wright ksid1.ks_rid == ksid2->ks_rid) { 455148c5f43SAlan Wright user->u_flags |= SMB_USER_FLAG_ADMIN; 456148c5f43SAlan Wright rc = B_TRUE; 457148c5f43SAlan Wright break; 458148c5f43SAlan Wright } 459148c5f43SAlan Wright 460148c5f43SAlan Wright ksid2 = &ksidlist->ksl_sids[i]; 461148c5f43SAlan Wright } while (i++ < ksidlist->ksl_nsid); 462148c5f43SAlan Wright 463148c5f43SAlan Wright ksid_rele(&ksid1); 464b819cea2SGordon Ross #endif /* _KERNEL */ 465148c5f43SAlan Wright return (rc); 466c8ec8eeaSjose borrego } 467c8ec8eeaSjose borrego 4681fcced4cSJordan Brown /* 4691fcced4cSJordan Brown * This function should be called with a hold on the user. 4701fcced4cSJordan Brown */ 4711fcced4cSJordan Brown boolean_t 4721fcced4cSJordan Brown smb_user_namecmp(smb_user_t *user, const char *name) 4731fcced4cSJordan Brown { 4741fcced4cSJordan Brown char *fq_name; 4751fcced4cSJordan Brown boolean_t match; 4761fcced4cSJordan Brown 477bbf6f00cSJordan Brown if (smb_strcasecmp(name, user->u_name, 0) == 0) 4781fcced4cSJordan Brown return (B_TRUE); 4791fcced4cSJordan Brown 4801fcced4cSJordan Brown fq_name = kmem_alloc(MAXNAMELEN, KM_SLEEP); 4811fcced4cSJordan Brown 4821fcced4cSJordan Brown (void) snprintf(fq_name, MAXNAMELEN, "%s\\%s", 4831fcced4cSJordan Brown user->u_domain, user->u_name); 4841fcced4cSJordan Brown 485bbf6f00cSJordan Brown match = (smb_strcasecmp(name, fq_name, 0) == 0); 4861fcced4cSJordan Brown if (!match) { 4871fcced4cSJordan Brown (void) snprintf(fq_name, MAXNAMELEN, "%s@%s", 4881fcced4cSJordan Brown user->u_name, user->u_domain); 4891fcced4cSJordan Brown 490bbf6f00cSJordan Brown match = (smb_strcasecmp(name, fq_name, 0) == 0); 4911fcced4cSJordan Brown } 4921fcced4cSJordan Brown 4931fcced4cSJordan Brown kmem_free(fq_name, MAXNAMELEN); 4941fcced4cSJordan Brown return (match); 4951fcced4cSJordan Brown } 4961fcced4cSJordan Brown 4971fcced4cSJordan Brown /* 4981fcced4cSJordan Brown * If the enumeration request is for user data, handle the request 4991fcced4cSJordan Brown * here. Otherwise, pass it on to the trees. 5001fcced4cSJordan Brown * 5011fcced4cSJordan Brown * This function should be called with a hold on the user. 5021fcced4cSJordan Brown */ 5031fcced4cSJordan Brown int 5041fcced4cSJordan Brown smb_user_enum(smb_user_t *user, smb_svcenum_t *svcenum) 5051fcced4cSJordan Brown { 5063b13a1efSThomas Keiser int rc = 0; 5071fcced4cSJordan Brown 5081fcced4cSJordan Brown ASSERT(user); 5091fcced4cSJordan Brown ASSERT(user->u_magic == SMB_USER_MAGIC); 5101fcced4cSJordan Brown 5111fcced4cSJordan Brown if (svcenum->se_type == SMB_SVCENUM_TYPE_USER) 5121fcced4cSJordan Brown return (smb_user_enum_private(user, svcenum)); 5131fcced4cSJordan Brown 5141fcced4cSJordan Brown return (rc); 5151fcced4cSJordan Brown } 5161fcced4cSJordan Brown 517da6c28aaSamw /* *************************** Static Functions ***************************** */ 518da6c28aaSamw 519da6c28aaSamw /* 5209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Delete a user. The tree list should be empty. 5219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 5229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Remove the user from the session's user list before freeing resources 5239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * associated with the user. 524da6c28aaSamw */ 5259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void 5269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_user_delete(void *arg) 527da6c28aaSamw { 528da6c28aaSamw smb_session_t *session; 5299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_user_t *user = (smb_user_t *)arg; 530da6c28aaSamw 5319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_USER_VALID(user); 532da6c28aaSamw ASSERT(user->u_refcnt == 0); 533da6c28aaSamw ASSERT(user->u_state == SMB_USER_STATE_LOGGED_OFF); 534*12b65585SGordon Ross ASSERT(user->u_authsock == NULL); 535da6c28aaSamw 536da6c28aaSamw session = user->u_session; 537da6c28aaSamw smb_llist_enter(&session->s_user_list, RW_WRITER); 538da6c28aaSamw smb_llist_remove(&session->s_user_list, user); 5399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idpool_free(&session->s_uid_pool, user->u_uid); 540da6c28aaSamw smb_llist_exit(&session->s_user_list); 541da6c28aaSamw 5429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&user->u_mutex); 5439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&user->u_mutex); 5449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 545da6c28aaSamw user->u_magic = (uint32_t)~SMB_USER_MAGIC; 546da6c28aaSamw mutex_destroy(&user->u_mutex); 547148c5f43SAlan Wright if (user->u_cred) 548da6c28aaSamw crfree(user->u_cred); 549b89a8333Snatalie li - Sun Microsystems - Irvine United States if (user->u_privcred) 550b89a8333Snatalie li - Sun Microsystems - Irvine United States crfree(user->u_privcred); 5519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_mem_free(user->u_name); 5529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_mem_free(user->u_domain); 5538622ec45SGordon Ross kmem_cache_free(smb_cache_user, user); 554da6c28aaSamw } 555c8ec8eeaSjose borrego 556b89a8333Snatalie li - Sun Microsystems - Irvine United States cred_t * 557b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_user_getcred(smb_user_t *user) 558b89a8333Snatalie li - Sun Microsystems - Irvine United States { 559b89a8333Snatalie li - Sun Microsystems - Irvine United States return (user->u_cred); 560b89a8333Snatalie li - Sun Microsystems - Irvine United States } 561b89a8333Snatalie li - Sun Microsystems - Irvine United States 562b89a8333Snatalie li - Sun Microsystems - Irvine United States cred_t * 563b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_user_getprivcred(smb_user_t *user) 564b89a8333Snatalie li - Sun Microsystems - Irvine United States { 565b89a8333Snatalie li - Sun Microsystems - Irvine United States return ((user->u_privcred)? user->u_privcred : user->u_cred); 566b89a8333Snatalie li - Sun Microsystems - Irvine United States } 5671fcced4cSJordan Brown 568b819cea2SGordon Ross #ifdef _KERNEL 5691fcced4cSJordan Brown /* 570148c5f43SAlan Wright * Assign the user cred and privileges. 571148c5f43SAlan Wright * 572148c5f43SAlan Wright * If the user has backup and/or restore privleges, dup the cred 573148c5f43SAlan Wright * and add those privileges to this new privileged cred. 574148c5f43SAlan Wright */ 575b819cea2SGordon Ross void 576148c5f43SAlan Wright smb_user_setcred(smb_user_t *user, cred_t *cr, uint32_t privileges) 577148c5f43SAlan Wright { 578148c5f43SAlan Wright cred_t *privcred = NULL; 579148c5f43SAlan Wright 580148c5f43SAlan Wright ASSERT(cr); 581148c5f43SAlan Wright crhold(cr); 582148c5f43SAlan Wright 583148c5f43SAlan Wright if (privileges & (SMB_USER_PRIV_BACKUP | SMB_USER_PRIV_RESTORE)) 584148c5f43SAlan Wright privcred = crdup(cr); 585148c5f43SAlan Wright 586148c5f43SAlan Wright if (privcred != NULL) { 587148c5f43SAlan Wright if (privileges & SMB_USER_PRIV_BACKUP) { 588148c5f43SAlan Wright (void) crsetpriv(privcred, PRIV_FILE_DAC_READ, 589148c5f43SAlan Wright PRIV_FILE_DAC_SEARCH, PRIV_SYS_MOUNT, NULL); 590148c5f43SAlan Wright } 591148c5f43SAlan Wright 592148c5f43SAlan Wright if (privileges & SMB_USER_PRIV_RESTORE) { 593148c5f43SAlan Wright (void) crsetpriv(privcred, PRIV_FILE_DAC_WRITE, 594148c5f43SAlan Wright PRIV_FILE_CHOWN, PRIV_FILE_CHOWN_SELF, 595148c5f43SAlan Wright PRIV_FILE_DAC_SEARCH, PRIV_FILE_LINK_ANY, 596148c5f43SAlan Wright PRIV_FILE_OWNER, PRIV_FILE_SETID, 597148c5f43SAlan Wright PRIV_SYS_LINKDIR, PRIV_SYS_MOUNT, NULL); 598148c5f43SAlan Wright } 599148c5f43SAlan Wright } 600148c5f43SAlan Wright 601148c5f43SAlan Wright user->u_cred = cr; 602148c5f43SAlan Wright user->u_privcred = privcred; 603148c5f43SAlan Wright user->u_privileges = privileges; 604148c5f43SAlan Wright } 605b819cea2SGordon Ross #endif /* _KERNEL */ 606148c5f43SAlan Wright 607148c5f43SAlan Wright /* 6081fcced4cSJordan Brown * Private function to support smb_user_enum. 6091fcced4cSJordan Brown */ 6101fcced4cSJordan Brown static int 6111fcced4cSJordan Brown smb_user_enum_private(smb_user_t *user, smb_svcenum_t *svcenum) 6121fcced4cSJordan Brown { 6131fcced4cSJordan Brown uint8_t *pb; 6141fcced4cSJordan Brown uint_t nbytes; 6151fcced4cSJordan Brown int rc; 6161fcced4cSJordan Brown 6171fcced4cSJordan Brown if (svcenum->se_nskip > 0) { 6181fcced4cSJordan Brown svcenum->se_nskip--; 6191fcced4cSJordan Brown return (0); 6201fcced4cSJordan Brown } 6211fcced4cSJordan Brown 6221fcced4cSJordan Brown if (svcenum->se_nitems >= svcenum->se_nlimit) { 6231fcced4cSJordan Brown svcenum->se_nitems = svcenum->se_nlimit; 6241fcced4cSJordan Brown return (0); 6251fcced4cSJordan Brown } 6261fcced4cSJordan Brown 6271fcced4cSJordan Brown pb = &svcenum->se_buf[svcenum->se_bused]; 6281fcced4cSJordan Brown rc = smb_user_netinfo_encode(user, pb, svcenum->se_bavail, &nbytes); 6291fcced4cSJordan Brown if (rc == 0) { 6301fcced4cSJordan Brown svcenum->se_bavail -= nbytes; 6311fcced4cSJordan Brown svcenum->se_bused += nbytes; 6321fcced4cSJordan Brown svcenum->se_nitems++; 6331fcced4cSJordan Brown } 6341fcced4cSJordan Brown 6351fcced4cSJordan Brown return (rc); 6361fcced4cSJordan Brown } 6371fcced4cSJordan Brown 6381fcced4cSJordan Brown /* 6391fcced4cSJordan Brown * Encode the NetInfo for a user into a buffer. NetInfo contains 6401fcced4cSJordan Brown * information that is often needed in user space to support RPC 6411fcced4cSJordan Brown * requests. 6421fcced4cSJordan Brown */ 6431fcced4cSJordan Brown int 6441fcced4cSJordan Brown smb_user_netinfo_encode(smb_user_t *user, uint8_t *buf, size_t buflen, 6451fcced4cSJordan Brown uint32_t *nbytes) 6461fcced4cSJordan Brown { 6471fcced4cSJordan Brown smb_netuserinfo_t info; 6481fcced4cSJordan Brown int rc; 6491fcced4cSJordan Brown 6501fcced4cSJordan Brown smb_user_netinfo_init(user, &info); 6511fcced4cSJordan Brown rc = smb_netuserinfo_encode(&info, buf, buflen, nbytes); 6521fcced4cSJordan Brown smb_user_netinfo_fini(&info); 6531fcced4cSJordan Brown 6541fcced4cSJordan Brown return (rc); 6551fcced4cSJordan Brown } 6561fcced4cSJordan Brown 6571fcced4cSJordan Brown void 6581fcced4cSJordan Brown smb_user_netinfo_init(smb_user_t *user, smb_netuserinfo_t *info) 6591fcced4cSJordan Brown { 6601fcced4cSJordan Brown smb_session_t *session; 6611fcced4cSJordan Brown char *buf; 6621fcced4cSJordan Brown 6631fcced4cSJordan Brown ASSERT(user); 6641fcced4cSJordan Brown ASSERT(user->u_domain); 6651fcced4cSJordan Brown ASSERT(user->u_name); 6661fcced4cSJordan Brown 6671fcced4cSJordan Brown session = user->u_session; 6681fcced4cSJordan Brown ASSERT(session); 6691fcced4cSJordan Brown ASSERT(session->workstation); 6701fcced4cSJordan Brown 6711fcced4cSJordan Brown info->ui_session_id = session->s_kid; 6721fcced4cSJordan Brown info->ui_native_os = session->native_os; 6731fcced4cSJordan Brown info->ui_ipaddr = session->ipaddr; 6741fcced4cSJordan Brown info->ui_numopens = session->s_file_cnt; 675c5866007SKeyur Desai info->ui_smb_uid = user->u_uid; 6761fcced4cSJordan Brown info->ui_logon_time = user->u_logon_time; 6771fcced4cSJordan Brown info->ui_flags = user->u_flags; 678c5866007SKeyur Desai info->ui_posix_uid = crgetuid(user->u_cred); 6791fcced4cSJordan Brown 6801fcced4cSJordan Brown info->ui_domain_len = user->u_domain_len; 6819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States info->ui_domain = smb_mem_strdup(user->u_domain); 6821fcced4cSJordan Brown 6831fcced4cSJordan Brown info->ui_account_len = user->u_name_len; 6849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States info->ui_account = smb_mem_strdup(user->u_name); 6851fcced4cSJordan Brown 6861fcced4cSJordan Brown buf = kmem_alloc(MAXNAMELEN, KM_SLEEP); 6871fcced4cSJordan Brown smb_session_getclient(session, buf, MAXNAMELEN); 6881fcced4cSJordan Brown info->ui_workstation_len = strlen(buf) + 1; 6899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States info->ui_workstation = smb_mem_strdup(buf); 6901fcced4cSJordan Brown kmem_free(buf, MAXNAMELEN); 6911fcced4cSJordan Brown } 6921fcced4cSJordan Brown 6931fcced4cSJordan Brown void 6941fcced4cSJordan Brown smb_user_netinfo_fini(smb_netuserinfo_t *info) 6951fcced4cSJordan Brown { 6961fcced4cSJordan Brown if (info == NULL) 6971fcced4cSJordan Brown return; 6981fcced4cSJordan Brown 6991fcced4cSJordan Brown if (info->ui_domain) 7009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_mem_free(info->ui_domain); 7011fcced4cSJordan Brown if (info->ui_account) 7029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_mem_free(info->ui_account); 7031fcced4cSJordan Brown if (info->ui_workstation) 7049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_mem_free(info->ui_workstation); 7051fcced4cSJordan Brown 7061fcced4cSJordan Brown bzero(info, sizeof (smb_netuserinfo_t)); 7071fcced4cSJordan Brown } 7089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void 7108622ec45SGordon Ross smb_user_auth_logoff(smb_user_t *user) 7119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 7128622ec45SGordon Ross uint32_t audit_sid = user->u_audit_sid; 7138622ec45SGordon Ross 7148622ec45SGordon Ross (void) smb_kdoor_upcall(user->u_server, SMB_DR_USER_AUTH_LOGOFF, 7159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &audit_sid, xdr_uint32_t, NULL, NULL); 7169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 717