diff options
Diffstat (limited to 'source3/smbd/close.c')
-rw-r--r-- | source3/smbd/close.c | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c index a6610e58f1..25ed9a3c4d 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -275,6 +275,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, NTSTATUS status = NT_STATUS_OK; NTSTATUS tmp_status; struct file_id id; + const UNIX_USER_TOKEN *del_token = NULL; /* Ensure any pending write time updates are done. */ if (fsp->update_write_time_event) { @@ -328,7 +329,8 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, fsp_str_dbg(fsp))); } - if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) { + if (fsp->initial_delete_on_close && + !is_delete_on_close_set(lck, fsp->name_hash)) { bool became_user = False; /* Initial delete on close was set and no one else @@ -339,21 +341,23 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, became_user = True; } fsp->delete_on_close = true; - set_delete_on_close_lck(lck, True, get_current_utok(conn)); + set_delete_on_close_lck(fsp, lck, True, get_current_utok(conn)); if (became_user) { unbecome_user(); } } - delete_file = lck->delete_on_close; + delete_file = is_delete_on_close_set(lck, fsp->name_hash); if (delete_file) { int i; - /* See if others still have the file open. If this is the - * case, then don't delete. If all opens are POSIX delete now. */ + /* See if others still have the file open via this pathname. + If this is the case, then don't delete. If all opens are + POSIX delete now. */ for (i=0; i<lck->num_share_modes; i++) { struct share_mode_entry *e = &lck->share_modes[i]; - if (is_valid_share_mode_entry(e)) { + if (is_valid_share_mode_entry(e) && + e->name_hash == fsp->name_hash) { if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) { continue; } @@ -372,9 +376,8 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, * reference to a file. */ - if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) - || !delete_file - || (lck->delete_token == NULL)) { + if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) || + !delete_file) { TALLOC_FREE(lck); return NT_STATUS_OK; } @@ -391,23 +394,26 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, */ fsp->update_write_time_on_close = false; - if (!unix_token_equal(lck->delete_token, get_current_utok(conn))) { + del_token = get_delete_on_close_token(lck, fsp->name_hash); + SMB_ASSERT(del_token != NULL); + + if (!unix_token_equal(del_token, get_current_utok(conn))) { /* Become the user who requested the delete. */ DEBUG(5,("close_remove_share_mode: file %s. " "Change user to uid %u\n", fsp_str_dbg(fsp), - (unsigned int)lck->delete_token->uid)); + (unsigned int)del_token->uid)); if (!push_sec_ctx()) { smb_panic("close_remove_share_mode: file %s. failed to push " "sec_ctx.\n"); } - set_sec_ctx(lck->delete_token->uid, - lck->delete_token->gid, - lck->delete_token->ngroups, - lck->delete_token->groups, + set_sec_ctx(del_token->uid, + del_token->gid, + del_token->ngroups, + del_token->groups, NULL); changed_user = true; @@ -481,7 +487,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, */ fsp->delete_on_close = false; - set_delete_on_close_lck(lck, False, NULL); + set_delete_on_close_lck(fsp, lck, false, NULL); done: @@ -944,6 +950,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, bool delete_dir = False; NTSTATUS status = NT_STATUS_OK; NTSTATUS status1 = NT_STATUS_OK; + const UNIX_USER_TOKEN *del_token = NULL; /* * NT can set delete_on_close of the last open @@ -978,14 +985,16 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, } send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx, fsp->fsp_name->base_name); - set_delete_on_close_lck(lck, True, get_current_utok(fsp->conn)); + set_delete_on_close_lck(fsp, lck, true, + get_current_utok(fsp->conn)); fsp->delete_on_close = true; if (became_user) { unbecome_user(); } } - delete_dir = lck->delete_on_close; + del_token = get_delete_on_close_token(lck, fsp->name_hash); + delete_dir = (del_token != NULL); if (delete_dir) { int i; @@ -993,7 +1002,8 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, * case, then don't delete. If all opens are POSIX delete now. */ for (i=0; i<lck->num_share_modes; i++) { struct share_mode_entry *e = &lck->share_modes[i]; - if (is_valid_share_mode_entry(e)) { + if (is_valid_share_mode_entry(e) && + e->name_hash == fsp->name_hash) { if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) { continue; } @@ -1004,8 +1014,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, } if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) && - delete_dir && - lck->delete_token) { + delete_dir) { /* Become the user who requested the delete. */ @@ -1013,10 +1022,10 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, smb_panic("close_directory: failed to push sec_ctx.\n"); } - set_sec_ctx(lck->delete_token->uid, - lck->delete_token->gid, - lck->delete_token->ngroups, - lck->delete_token->groups, + set_sec_ctx(del_token->uid, + del_token->gid, + del_token->ngroups, + del_token->groups, NULL); TALLOC_FREE(lck); |