From 75d03970b78538346308c612ca6be15559e15b5b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 May 2009 16:38:45 +0200 Subject: s3:smbd: move more session specific globals to struct smbd_server_connection metze --- source3/smbd/password.c | 191 ++++++++++++++++++++++++++++-------------------- 1 file changed, 112 insertions(+), 79 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 460cba35a0..abe348e02b 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -25,7 +25,9 @@ enum server_allocated_state { SERVER_ALLOCATED_REQUIRED_YES, SERVER_ALLOCATED_REQUIRED_NO, SERVER_ALLOCATED_REQUIRED_ANY}; -static user_struct *get_valid_user_struct_internal(uint16 vuid, +static user_struct *get_valid_user_struct_internal( + struct smbd_server_connection *sconn, + uint16 vuid, enum server_allocated_state server_allocated) { user_struct *usp; @@ -34,7 +36,8 @@ static user_struct *get_valid_user_struct_internal(uint16 vuid, if (vuid == UID_FIELD_INVALID) return NULL; - for (usp=validated_users;usp;usp=usp->next,count++) { + usp=sconn->smb1.sessions.validated_users; + for (;usp;usp=usp->next,count++) { if (vuid == usp->vuid) { switch (server_allocated) { case SERVER_ALLOCATED_REQUIRED_YES: @@ -50,7 +53,8 @@ static user_struct *get_valid_user_struct_internal(uint16 vuid, break; } if (count > 10) { - DLIST_PROMOTE(validated_users, usp); + DLIST_PROMOTE(sconn->smb1.sessions.validated_users, + usp); } return usp; } @@ -65,24 +69,26 @@ static user_struct *get_valid_user_struct_internal(uint16 vuid, tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ -user_struct *get_valid_user_struct(uint16 vuid) +user_struct *get_valid_user_struct(struct smbd_server_connection *sconn, + uint16 vuid) { - return get_valid_user_struct_internal(vuid, + return get_valid_user_struct_internal(sconn, vuid, SERVER_ALLOCATED_REQUIRED_YES); } -bool is_partial_auth_vuid(uint16 vuid) +bool is_partial_auth_vuid(struct smbd_server_connection *sconn, uint16 vuid) { - return (get_partial_auth_user_struct(vuid) != NULL); + return (get_partial_auth_user_struct(sconn, vuid) != NULL); } /**************************************************************************** Get the user struct of a partial NTLMSSP login ****************************************************************************/ -user_struct *get_partial_auth_user_struct(uint16 vuid) +user_struct *get_partial_auth_user_struct(struct smbd_server_connection *sconn, + uint16 vuid) { - return get_valid_user_struct_internal(vuid, + return get_valid_user_struct_internal(sconn, vuid, SERVER_ALLOCATED_REQUIRED_NO); } @@ -90,11 +96,11 @@ user_struct *get_partial_auth_user_struct(uint16 vuid) Invalidate a uid. ****************************************************************************/ -void invalidate_vuid(uint16 vuid) +void invalidate_vuid(struct smbd_server_connection *sconn, uint16 vuid) { user_struct *vuser = NULL; - vuser = get_valid_user_struct_internal(vuid, + vuser = get_valid_user_struct_internal(sconn, vuid, SERVER_ALLOCATED_REQUIRED_ANY); if (vuser == NULL) { return; @@ -106,24 +112,25 @@ void invalidate_vuid(uint16 vuid) auth_ntlmssp_end(&vuser->auth_ntlmssp_state); } - DLIST_REMOVE(validated_users, vuser); + DLIST_REMOVE(sconn->smb1.sessions.validated_users, vuser); /* clear the vuid from the 'cache' on each connection, and from the vuid 'owner' of connections */ conn_clear_vuid_caches(vuid); TALLOC_FREE(vuser); - num_validated_vuids--; + sconn->smb1.sessions.num_validated_vuids--; } /**************************************************************************** Invalidate all vuid entries for this process. ****************************************************************************/ -void invalidate_all_vuids(void) +void invalidate_all_vuids(struct smbd_server_connection *sconn) { - while (validated_users != NULL) { - invalidate_vuid(validated_users->vuid); + while (sconn->smb1.sessions.validated_users != NULL) { + invalidate_vuid(sconn, + sconn->smb1.sessions.validated_users->vuid); } } @@ -141,7 +148,7 @@ static void increment_next_vuid(uint16_t *vuid) Create a new partial auth user struct. *****************************************************/ -int register_initial_vuid(void) +int register_initial_vuid(struct smbd_server_connection *sconn) { user_struct *vuser; @@ -152,7 +159,7 @@ int register_initial_vuid(void) } /* Limit allowed vuids to 16bits - VUID_OFFSET. */ - if (num_validated_vuids >= 0xFFFF-VUID_OFFSET) { + if (sconn->smb1.sessions.num_validated_vuids >= 0xFFFF-VUID_OFFSET) { return UID_FIELD_INVALID; } @@ -163,25 +170,26 @@ int register_initial_vuid(void) } /* Allocate a free vuid. Yes this is a linear search... */ - while( get_valid_user_struct_internal(next_vuid, + while( get_valid_user_struct_internal(sconn, + sconn->smb1.sessions.next_vuid, SERVER_ALLOCATED_REQUIRED_ANY) != NULL ) { - increment_next_vuid(&next_vuid); + increment_next_vuid(&sconn->smb1.sessions.next_vuid); } DEBUG(10,("register_initial_vuid: allocated vuid = %u\n", - (unsigned int)next_vuid )); + (unsigned int)sconn->smb1.sessions.next_vuid )); - vuser->vuid = next_vuid; + vuser->vuid = sconn->smb1.sessions.next_vuid; /* * This happens in an unfinished NTLMSSP session setup. We * need to allocate a vuid between the first and second calls * to NTLMSSP. */ - increment_next_vuid(&next_vuid); - num_validated_vuids++; + increment_next_vuid(&sconn->smb1.sessions.next_vuid); + sconn->smb1.sessions.num_validated_vuids++; - DLIST_ADD(validated_users, vuser); + DLIST_ADD(sconn->smb1.sessions.validated_users, vuser); return vuser->vuid; } @@ -234,7 +242,8 @@ static int register_homes_share(const char *username) * */ -int register_existing_vuid(uint16 vuid, +int register_existing_vuid(struct smbd_server_connection *sconn, + uint16 vuid, auth_serversupplied_info *server_info, DATA_BLOB response_blob, const char *smb_name) @@ -242,7 +251,7 @@ int register_existing_vuid(uint16 vuid, fstring tmp; user_struct *vuser; - vuser = get_partial_auth_user_struct(vuid); + vuser = get_partial_auth_user_struct(sconn, vuid); if (!vuser) { goto fail; } @@ -318,7 +327,7 @@ int register_existing_vuid(uint16 vuid, fail: if (vuser) { - invalidate_vuid(vuid); + invalidate_vuid(sconn, vuid); } return UID_FIELD_INVALID; } @@ -327,7 +336,8 @@ int register_existing_vuid(uint16 vuid, Add a name to the session users list. ****************************************************************************/ -void add_session_user(const char *user) +void add_session_user(struct smbd_server_connection *sconn, + const char *user) { struct passwd *pw; char *tmp; @@ -338,28 +348,29 @@ void add_session_user(const char *user) return; } - if (session_userlist == NULL) { - session_userlist = SMB_STRDUP(pw->pw_name); + if (sconn->smb1.sessions.session_userlist == NULL) { + sconn->smb1.sessions.session_userlist = SMB_STRDUP(pw->pw_name); goto done; } - if (in_list(pw->pw_name,session_userlist,False) ) { + if (in_list(pw->pw_name,sconn->smb1.sessions.session_userlist,false)) { goto done; } - if (strlen(session_userlist) > 128 * 1024) { + if (strlen(sconn->smb1.sessions.session_userlist) > 128 * 1024) { DEBUG(3,("add_session_user: session userlist already " "too large.\n")); goto done; } - if (asprintf(&tmp, "%s %s", session_userlist, pw->pw_name) == -1) { + if (asprintf(&tmp, "%s %s", + sconn->smb1.sessions.session_userlist, pw->pw_name) == -1) { DEBUG(3, ("asprintf failed\n")); goto done; } - SAFE_FREE(session_userlist); - session_userlist = tmp; + SAFE_FREE(sconn->smb1.sessions.session_userlist); + sconn->smb1.sessions.session_userlist = tmp; done: TALLOC_FREE(pw); } @@ -369,12 +380,13 @@ void add_session_user(const char *user) what Vista uses for the NTLMv2 calculation. ****************************************************************************/ -void add_session_workgroup(const char *workgroup) +void add_session_workgroup(struct smbd_server_connection *sconn, + const char *workgroup) { - if (session_workgroup) { - SAFE_FREE(session_workgroup); + if (sconn->smb1.sessions.session_workgroup) { + SAFE_FREE(sconn->smb1.sessions.session_workgroup); } - session_workgroup = smb_xstrdup(workgroup); + sconn->smb1.sessions.session_workgroup = smb_xstrdup(workgroup); } /**************************************************************************** @@ -382,9 +394,9 @@ void add_session_workgroup(const char *workgroup) what Vista uses for the NTLMv2 calculation. ****************************************************************************/ -const char *get_session_workgroup(void) +const char *get_session_workgroup(struct smbd_server_connection *sconn) { - return session_workgroup; + return sconn->smb1.sessions.session_workgroup; } /**************************************************************************** @@ -392,25 +404,30 @@ const char *get_session_workgroup(void) try lower case. ****************************************************************************/ -bool user_in_netgroup(const char *user, const char *ngname) +bool user_in_netgroup(struct smbd_server_connection *sconn, + const char *user, const char *ngname) { #ifdef HAVE_NETGROUP fstring lowercase_user; - if (my_yp_domain == NULL) - yp_get_default_domain(&my_yp_domain); + if (sconn->smb1.sessions.my_yp_domain == NULL) { + yp_get_default_domain(&sconn->smb1.sessions.my_yp_domain); + } - if(my_yp_domain == NULL) { + if (sconn->smb1.sessions.my_yp_domain == NULL) { DEBUG(5,("Unable to get default yp domain, " "let's try without specifying it\n")); } DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", - user, my_yp_domain?my_yp_domain:"(ANY)", ngname)); + user, + sconn->smb1.sessions.my_yp_domain? + sconn->smb1.sessions.my_yp_domain:"(ANY)", + ngname)); - if (innetgr(ngname, NULL, user, my_yp_domain)) { + if (innetgr(ngname, NULL, user, sconn->smb1.sessions.my_yp_domain)) { DEBUG(5,("user_in_netgroup: Found\n")); - return (True); + return true; } else { /* @@ -422,15 +439,19 @@ bool user_in_netgroup(const char *user, const char *ngname) strlower_m(lowercase_user); DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", - lowercase_user, my_yp_domain?my_yp_domain:"(ANY)", ngname)); + lowercase_user, + sconn->smb1.sessions.my_yp_domain? + sconn->smb1.sessions.my_yp_domain:"(ANY)", + ngname)); - if (innetgr(ngname, NULL, lowercase_user, my_yp_domain)) { + if (innetgr(ngname, NULL, lowercase_user, + sconn->smb1.sessions.my_yp_domain)) { DEBUG(5,("user_in_netgroup: Found\n")); - return (True); + return true; } } #endif /* HAVE_NETGROUP */ - return False; + return false; } /**************************************************************************** @@ -438,7 +459,8 @@ bool user_in_netgroup(const char *user, const char *ngname) and netgroup lists. ****************************************************************************/ -bool user_in_list(const char *user,const char **list) +bool user_in_list(struct smbd_server_connection *sconn, + const char *user,const char **list) { if (!list || !*list) return False; @@ -466,7 +488,7 @@ bool user_in_list(const char *user,const char **list) * Old behaviour. Check netgroup list * followed by UNIX list. */ - if(user_in_netgroup(user, *list +1)) + if(user_in_netgroup(sconn, user, *list +1)) return True; if(user_in_group(user, *list +1)) return True; @@ -478,7 +500,7 @@ bool user_in_list(const char *user,const char **list) */ if(user_in_group(user, *list +2)) return True; - if(user_in_netgroup(user, *list +2)) + if(user_in_netgroup(sconn, user, *list +2)) return True; } else { @@ -497,7 +519,7 @@ bool user_in_list(const char *user,const char **list) /* * Search netgroup list followed by UNIX list. */ - if(user_in_netgroup(user, *list +2)) + if(user_in_netgroup(sconn, user, *list +2)) return True; if(user_in_group(user, *list +2)) return True; @@ -505,7 +527,7 @@ bool user_in_list(const char *user,const char **list) /* * Just search netgroup list. */ - if(user_in_netgroup(user, *list +1)) + if(user_in_netgroup(sconn, user, *list +1)) return True; } } @@ -519,7 +541,8 @@ bool user_in_list(const char *user,const char **list) Check if a username is valid. ****************************************************************************/ -static bool user_ok(const char *user, int snum) +static bool user_ok(struct smbd_server_connection *sconn, + const char *user, int snum) { char **valid, **invalid; bool ret; @@ -536,7 +559,7 @@ static bool user_ok(const char *user, int snum) * around to pass to str_list_sub_basic() */ if ( invalid && str_list_sub_basic(invalid, "", "") ) { - ret = !user_in_list(user, + ret = !user_in_list(sconn, user, (const char **)invalid); } } @@ -552,7 +575,8 @@ static bool user_ok(const char *user, int snum) * around to pass to str_list_sub_basic() */ if ( valid && str_list_sub_basic(valid, "", "") ) { - ret = user_in_list(user, (const char **)valid); + ret = user_in_list(sconn, user, + (const char **)valid); } } } @@ -564,7 +588,8 @@ static bool user_ok(const char *user, int snum) if (user_list && str_list_substitute(user_list, "%S", lp_servicename(snum))) { - ret = user_in_list(user, (const char **)user_list); + ret = user_in_list(sconn, user, + (const char **)user_list); } TALLOC_FREE(user_list); } @@ -576,19 +601,21 @@ static bool user_ok(const char *user, int snum) Validate a group username entry. Return the username or NULL. ****************************************************************************/ -static char *validate_group(char *group, DATA_BLOB password,int snum) +static char *validate_group(struct smbd_server_connection *sconn, + char *group, DATA_BLOB password,int snum) { #ifdef HAVE_NETGROUP { char *host, *user, *domain; - struct smbd_server_connection *sconn = smbd_server_conn; struct auth_context *actx = sconn->smb1.negprot.auth_context; bool enc = sconn->smb1.negprot.encrypted_passwords; setnetgrent(group); while (getnetgrent(&host, &user, &domain)) { if (user) { - if (user_ok(user, snum) && - password_ok(actx, enc, user,password)) { + if (user_ok(sconn, user, snum) && + password_ok(actx, enc, + get_session_workgroup(sconn), + user,password)) { endnetgrent(); return(user); } @@ -601,7 +628,6 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) #ifdef HAVE_GETGRENT { struct group *gptr; - struct smbd_server_connection *sconn = smbd_server_conn; struct auth_context *actx = sconn->smb1.negprot.auth_context; bool enc = sconn->smb1.negprot.encrypted_passwords; @@ -652,8 +678,10 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) member = member_list; while (*member) { - if (user_ok(member,snum) && - password_ok(actx, enc, member,password)) { + if (user_ok(sconn, member,snum) && + password_ok(actx, enc, + get_session_workgroup(sconn), + member,password)) { char *name = talloc_strdup(talloc_tos(), member); SAFE_FREE(member_list); @@ -681,11 +709,11 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) Note this is *NOT* used when logging on using sessionsetup_and_X. ****************************************************************************/ -bool authorise_login(int snum, fstring user, DATA_BLOB password, +bool authorise_login(struct smbd_server_connection *sconn, + int snum, fstring user, DATA_BLOB password, bool *guest) { bool ok = False; - struct smbd_server_connection *sconn = smbd_server_conn; struct auth_context *actx = sconn->smb1.negprot.auth_context; bool enc = sconn->smb1.negprot.encrypted_passwords; @@ -716,8 +744,8 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password, char *user_list = NULL; char *saveptr; - if ( session_userlist ) - user_list = SMB_STRDUP(session_userlist); + if (sconn->smb1.sessions.session_userlist) + user_list = SMB_STRDUP(sconn->smb1.sessions.session_userlist); else user_list = SMB_STRDUP(""); @@ -729,10 +757,12 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password, auser = strtok_r(NULL, LIST_SEP, &saveptr)) { fstring user2; fstrcpy(user2,auser); - if (!user_ok(user2,snum)) + if (!user_ok(sconn,user2,snum)) continue; - if (password_ok(actx, enc, user2,password)) { + if (password_ok(actx, enc, + get_session_workgroup(sconn), + user2,password)) { ok = True; fstrcpy(user,user2); DEBUG(3,("authorise_login: ACCEPTED: session " @@ -768,7 +798,8 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password, auser && !ok; auser = strtok_r(NULL, LIST_SEP, &saveptr)) { if (*auser == '@') { - auser = validate_group(auser+1,password,snum); + auser = validate_group(sconn,auser+1, + password,snum); if (auser) { ok = True; fstrcpy(user,auser); @@ -779,8 +810,10 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password, } else { fstring user2; fstrcpy(user2,auser); - if (user_ok(user2,snum) && - password_ok(actx, enc, user2,password)) { + if (user_ok(sconn,user2,snum) && + password_ok(actx, enc, + get_session_workgroup(sconn), + user2,password)) { ok = True; fstrcpy(user,user2); DEBUG(3,("authorise_login: ACCEPTED: " @@ -813,7 +846,7 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password, *guest = True; } - if (ok && !user_ok(user, snum)) { + if (ok && !user_ok(sconn, user, snum)) { DEBUG(0,("authorise_login: rejected invalid user %s\n",user)); ok = False; } -- cgit