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; for (i=0;i<conn->vuid_cache.entries && i< VUID_CACHE_SIZE;i++) { if (conn->vuid_cache.array[i].vuid == vuser->vuid) { ent = &conn->vuid_cache.array[i]; conn->read_only = ent->read_only; conn->admin_user = ent->admin_user; return(True); } } if (!user_ok_token(vuser->user.unix_name, vuser->nt_user_token, snum)) return(False); readonly_share = is_share_read_only_for_token(vuser->user.unix_name, vuser->nt_user_token, conn->service); if (!readonly_share && !share_access_check(conn, snum, vuser, FILE_WRITE_DATA)) { /* smb.conf allows r/w, but the security descriptor denies * write. Fall back to looking at readonly. */ readonly_share = True; DEBUG(5,("falling back to read-only access-evaluation due to " "security descriptor\n")); } if (!share_access_check(conn, snum, vuser, readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { return False; } i = conn->vuid_cache.entries % VUID_CACHE_SIZE; if (conn->vuid_cache.entries < VUID_CACHE_SIZE) conn->vuid_cache.entries++; ent = &conn->vuid_cache.array[i]; ent->vuid = vuser->vuid; ent->read_only = readonly_share; ent->admin_user = token_contains_name_in_list( vuser->user.unix_name, NULL, vuser->nt_user_token, lp_admin_users(conn->service)); conn->read_only = ent->read_only; conn->admin_user = ent->admin_user; return(True); }
NTSTATUS check_user_share_access(connection_struct *conn, const struct auth_session_info *session_info, uint32_t *p_share_access, bool *p_readonly_share) { int snum = SNUM(conn); uint32_t share_access = 0; bool readonly_share = false; if (!user_ok_token(session_info->unix_info->unix_name, session_info->info->domain_name, session_info->security_token, snum)) { return NT_STATUS_ACCESS_DENIED; } readonly_share = is_share_read_only_for_token( session_info->unix_info->unix_name, session_info->info->domain_name, session_info->security_token, conn); share_access = create_share_access_mask(snum, readonly_share, session_info->security_token); if ((share_access & (FILE_READ_DATA|FILE_WRITE_DATA)) == 0) { /* No access, read or write. */ DEBUG(0,("user %s connection to %s denied due to share " "security descriptor.\n", session_info->unix_info->unix_name, lp_servicename(talloc_tos(), snum))); return NT_STATUS_ACCESS_DENIED; } if (!readonly_share && !(share_access & FILE_WRITE_DATA)) { /* smb.conf allows r/w, but the security descriptor denies * write. Fall back to looking at readonly. */ readonly_share = True; DEBUG(5,("falling back to read-only access-evaluation due to " "security descriptor\n")); } *p_share_access = share_access; *p_readonly_share = readonly_share; return NT_STATUS_OK; }
static bool check_user_ok(connection_struct *conn, uint16_t vuid, const struct auth_serversupplied_info *session_info, int snum) { bool valid_vuid = (vuid != UID_FIELD_INVALID); unsigned int i; bool readonly_share; bool admin_user; if (valid_vuid) { struct vuid_cache_entry *ent; for (i=0; i<VUID_CACHE_SIZE; i++) { ent = &conn->vuid_cache.array[i]; if (ent->vuid == vuid) { free_conn_session_info_if_unused(conn); conn->session_info = ent->session_info; conn->read_only = ent->read_only; return(True); } } } if (!user_ok_token(session_info->unix_name, session_info->info3->base.domain.string, session_info->security_token, snum)) return(False); readonly_share = is_share_read_only_for_token( session_info->unix_name, session_info->info3->base.domain.string, session_info->security_token, conn); if (!readonly_share && !share_access_check(session_info->security_token, lp_servicename(snum), FILE_WRITE_DATA, NULL)) { /* smb.conf allows r/w, but the security descriptor denies * write. Fall back to looking at readonly. */ readonly_share = True; DEBUG(5,("falling back to read-only access-evaluation due to " "security descriptor\n")); } if (!share_access_check(session_info->security_token, lp_servicename(snum), readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA, NULL)) { return False; } admin_user = token_contains_name_in_list( session_info->unix_name, session_info->info3->base.domain.string, NULL, session_info->security_token, lp_admin_users(snum)); if (valid_vuid) { struct vuid_cache_entry *ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry]; conn->vuid_cache.next_entry = (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE; TALLOC_FREE(ent->session_info); /* * If force_user was set, all session_info's are based on the same * username-based faked one. */ ent->session_info = copy_serverinfo( conn, conn->force_user ? conn->session_info : session_info); if (ent->session_info == NULL) { ent->vuid = UID_FIELD_INVALID; return false; } ent->vuid = vuid; ent->read_only = readonly_share; free_conn_session_info_if_unused(conn); conn->session_info = ent->session_info; } conn->read_only = readonly_share; if (admin_user) { DEBUG(2,("check_user_ok: user %s is an admin user. " "Setting uid as %d\n", conn->session_info->unix_name, sec_initial_uid() )); conn->session_info->utok.uid = sec_initial_uid(); } return(True); }