diff options
-rw-r--r-- | source3/include/smb.h | 2 | ||||
-rw-r--r-- | source3/smbd/conn.c | 1 | ||||
-rw-r--r-- | source3/smbd/service.c | 28 | ||||
-rw-r--r-- | source3/smbd/uid.c | 58 |
4 files changed, 34 insertions, 55 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h index dd8513f704..e1f17a178a 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -527,6 +527,7 @@ typedef struct files_struct { struct vuid_cache_entry { uint16 vuid; + struct auth_serversupplied_info *server_info; bool read_only; bool admin_user; }; @@ -637,7 +638,6 @@ typedef struct connection_struct { /* This groups info is valid for the user that *opened* the connection */ size_t ngroups; gid_t *groups; - NT_USER_TOKEN *nt_user_token; time_t lastused; time_t lastused_count; diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index 3baf0cfaab..ce3512c4ec 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -244,6 +244,7 @@ void conn_clear_vuid_cache(uint16 vuid) if (ent->vuid == vuid) { ent->vuid = UID_FIELD_INVALID; + TALLOC_FREE(ent->server_info); ent->read_only = False; ent->admin_user = False; } diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 267ca3c29f..77ed320e07 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -725,7 +725,6 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, } conn->params->service = snum; - conn->nt_user_token = NULL; status = create_connection_server_info( conn, snum, vuser ? vuser->server_info : NULL, password, @@ -871,32 +870,13 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, { bool can_write = False; - NT_USER_TOKEN *token = conn->nt_user_token ? - conn->nt_user_token : - (vuser ? vuser->server_info->ptok : NULL); - /* - * I don't believe this can happen. But the - * logic above is convoluted enough to confuse - * automated checkers, so be sure. JRA. - */ - - if (token == NULL) { - DEBUG(0,("make_connection: connection to %s " - "denied due to missing " - "NT token.\n", - lp_servicename(snum))); - conn_free(conn); - *pstatus = NT_STATUS_ACCESS_DENIED; - return NULL; - } - - can_write = share_access_check(token, - lp_servicename(snum), - FILE_WRITE_DATA); + can_write = share_access_check(conn->server_info->ptok, + lp_servicename(snum), + FILE_WRITE_DATA); if (!can_write) { - if (!share_access_check(token, + if (!share_access_check(conn->server_info->ptok, lp_servicename(snum), FILE_READ_DATA)) { /* No access, read or write. */ diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 2335bff9fd..8a4a54f867 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -56,6 +56,9 @@ bool change_to_guest(void) /******************************************************************* Check if a username is OK. + + This sets up conn->server_info with a copy related to this vuser that + later code can then mess with. ********************************************************************/ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) @@ -63,11 +66,11 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) unsigned int i; struct vuid_cache_entry *ent = NULL; bool readonly_share; - NT_USER_TOKEN *token; for (i=0; i<VUID_CACHE_SIZE; i++) { ent = &conn->vuid_cache.array[i]; if (ent->vuid == vuser->vuid) { + conn->server_info = ent->server_info; conn->read_only = ent->read_only; conn->admin_user = ent->admin_user; return(True); @@ -83,11 +86,8 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) vuser->server_info->unix_name, vuser->server_info->ptok, SNUM(conn)); - token = conn->nt_user_token ? - conn->nt_user_token : vuser->server_info->ptok; - if (!readonly_share && - !share_access_check(token, lp_servicename(snum), + !share_access_check(vuser->server_info->ptok, lp_servicename(snum), FILE_WRITE_DATA)) { /* smb.conf allows r/w, but the security descriptor denies * write. Fall back to looking at readonly. */ @@ -96,7 +96,7 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) "security descriptor\n")); } - if (!share_access_check(token, lp_servicename(snum), + if (!share_access_check(vuser->server_info->ptok, lp_servicename(snum), readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { return False; @@ -107,6 +107,14 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) conn->vuid_cache.next_entry = (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE; + TALLOC_FREE(ent->server_info); + + ent->server_info = copy_serverinfo(conn, vuser->server_info); + if (ent->server_info == NULL) { + ent->vuid = UID_FIELD_INVALID; + return false; + } + ent->vuid = vuser->vuid; ent->read_only = readonly_share; @@ -116,6 +124,7 @@ static bool check_user_ok(connection_struct *conn, user_struct *vuser,int snum) conn->read_only = ent->read_only; conn->admin_user = ent->admin_user; + conn->server_info = ent->server_info; return(True); } @@ -132,8 +141,6 @@ bool change_to_user(connection_struct *conn, uint16 vuid) gid_t gid; uid_t uid; char group_c; - bool must_free_token = False; - NT_USER_TOKEN *token = NULL; int num_groups = 0; gid_t *group_list = NULL; @@ -173,18 +180,21 @@ bool change_to_user(connection_struct *conn, uint16 vuid) return False; } + /* + * conn->server_info is now correctly set up with a copy we can mess + * with for force_group etc. + */ + if (conn->force_user) /* security = share sets this too */ { uid = conn->uid; gid = conn->gid; group_list = conn->groups; num_groups = conn->ngroups; - token = conn->nt_user_token; } else if (vuser) { uid = conn->admin_user ? 0 : vuser->server_info->uid; - gid = vuser->server_info->gid; - num_groups = vuser->server_info->n_groups; - group_list = vuser->server_info->groups; - token = vuser->server_info->ptok; + gid = conn->server_info->gid; + num_groups = conn->server_info->n_groups; + group_list = conn->server_info->groups; } else { DEBUG(2,("change_to_user: Invalid vuid used %d in accessing " "share %s.\n",vuid, lp_servicename(snum) )); @@ -199,13 +209,6 @@ bool change_to_user(connection_struct *conn, uint16 vuid) if((group_c = *lp_force_group(snum))) { - token = dup_nt_token(talloc_tos(), token); - if (token == NULL) { - DEBUG(0, ("dup_nt_token failed\n")); - return False; - } - must_free_token = True; - if(group_c == '+') { /* @@ -219,13 +222,15 @@ bool change_to_user(connection_struct *conn, uint16 vuid) for (i = 0; i < num_groups; i++) { if (group_list[i] == conn->gid) { gid = conn->gid; - gid_to_sid(&token->user_sids[1], gid); + gid_to_sid(&conn->server_info->ptok + ->user_sids[1], gid); break; } } } else { gid = conn->gid; - gid_to_sid(&token->user_sids[1], gid); + gid_to_sid(&conn->server_info->ptok->user_sids[1], + gid); } } @@ -236,14 +241,7 @@ bool change_to_user(connection_struct *conn, uint16 vuid) current_user.ut.groups = group_list; set_sec_ctx(uid, gid, current_user.ut.ngroups, current_user.ut.groups, - token); - - /* - * Free the new token (as set_sec_ctx copies it). - */ - - if (must_free_token) - TALLOC_FREE(token); + conn->server_info->ptok); current_user.conn = conn; current_user.vuid = vuid; |