bool is_share_read_only_for_token(const char *username, const char *domain, const struct nt_user_token *token, connection_struct *conn) { int snum = SNUM(conn); bool result = conn->read_only; if (lp_readlist(snum) != NULL) { if (token_contains_name_in_list(username, domain, lp_servicename(snum), token, lp_readlist(snum))) { result = True; } } if (lp_writelist(snum) != NULL) { if (token_contains_name_in_list(username, domain, lp_servicename(snum), token, lp_writelist(snum))) { result = False; } } DEBUG(10,("is_share_read_only_for_user: share %s is %s for unix user " "%s\n", lp_servicename(snum), result ? "read-only" : "read-write", username)); return result; }
bool user_ok_token(const char *username, const char *domain, const struct nt_user_token *token, int snum) { if (lp_invalid_users(snum) != NULL) { if (token_contains_name_in_list(username, domain, lp_servicename(snum), token, lp_invalid_users(snum))) { DEBUG(10, ("User %s in 'invalid users'\n", username)); return False; } } if (lp_valid_users(snum) != NULL) { if (!token_contains_name_in_list(username, domain, lp_servicename(snum), token, lp_valid_users(snum))) { DEBUG(10, ("User %s not in 'valid users'\n", username)); return False; } } if (lp_onlyuser(snum)) { const char *list[2]; list[0] = lp_username(snum); list[1] = NULL; if ((list[0] == NULL) || (*list[0] == '\0')) { DEBUG(0, ("'only user = yes' and no 'username ='******'username'\n", username)); return False; } } DEBUG(10, ("user_ok_token: share %s is ok for unix user %s\n", lp_servicename(snum), username)); return True; }
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); }
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); }
static bool check_user_ok(connection_struct *conn, uint64_t vuid, const struct auth_session_info *session_info, int snum) { unsigned int i; bool readonly_share = false; bool admin_user = false; struct vuid_cache_entry *ent = NULL; uint32_t share_access = 0; NTSTATUS status; for (i=0; i<VUID_CACHE_SIZE; i++) { ent = &conn->vuid_cache->array[i]; if (ent->vuid == vuid) { if (vuid == UID_FIELD_INVALID) { /* * Slow path, we don't care * about the array traversal. */ continue; } free_conn_session_info_if_unused(conn); conn->session_info = ent->session_info; conn->read_only = ent->read_only; conn->share_access = ent->share_access; return(True); } } status = check_user_share_access(conn, session_info, &share_access, &readonly_share); if (!NT_STATUS_IS_OK(status)) { return false; } admin_user = token_contains_name_in_list( session_info->unix_info->unix_name, session_info->info->domain_name, NULL, session_info->security_token, lp_admin_users(snum)); 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_session_info( conn, conn->force_user ? conn->session_info : session_info); if (ent->session_info == NULL) { ent->vuid = UID_FIELD_INVALID; return false; } /* * It's actually OK to call check_user_ok() with * vuid == UID_FIELD_INVALID as called from change_to_user_by_session(). * All this will do is throw away one entry in the cache. */ ent->vuid = vuid; ent->read_only = readonly_share; ent->share_access = share_access; free_conn_session_info_if_unused(conn); conn->session_info = ent->session_info; if (vuid == UID_FIELD_INVALID) { /* * Not strictly needed, just make it really * clear this entry is actually an unused one. */ ent->read_only = false; ent->share_access = 0; ent->session_info = NULL; } conn->read_only = readonly_share; conn->share_access = share_access; if (admin_user) { DEBUG(2,("check_user_ok: user %s is an admin user. " "Setting uid as %d\n", conn->session_info->unix_info->unix_name, sec_initial_uid() )); conn->session_info->unix_token->uid = sec_initial_uid(); } return(True); }