1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

s3:smbd: make use of close_share_mode_lock_{prepare,cleanup}() in close_directory()

It's good to have this in common as close_remove_share_mode()
and in the end we'll avoid get_existing_share_mode_lock()
and call them via share_mode_entry_prepare_{lock,unlock}(),
so that they can run under a tdb chainlock.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15125

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Stefan Metzmacher 2022-08-30 05:31:41 +00:00 committed by Jeremy Allison
parent f9ea783989
commit d04b6e9dd0

View File

@ -335,6 +335,11 @@ static void close_share_mode_lock_prepare(struct share_mode_lock *lck,
/* Initial delete on close was set and no one else
* wrote a real delete on close. */
if (fsp->fsp_flags.is_directory) {
send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
fsp->fsp_name->base_name);
}
fsp->fsp_flags.delete_on_close = true;
set_delete_on_close_lck(fsp, lck,
fsp->conn->session_info->security_token,
@ -1453,14 +1458,10 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
{
connection_struct *conn = fsp->conn;
struct share_mode_lock *lck = NULL;
bool delete_dir = False;
struct close_share_mode_lock_state lck_state = {};
bool changed_user = false;
NTSTATUS status = NT_STATUS_OK;
NTSTATUS status1 = NT_STATUS_OK;
const struct security_token *del_nt_token = NULL;
const struct security_unix_token *del_token = NULL;
bool got_tokens;
bool normal_close;
NTSTATUS notify_status;
SMB_ASSERT(fsp->fsp_flags.is_fsa);
@ -1485,37 +1486,26 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
return NT_STATUS_INVALID_PARAMETER;
}
if (fsp->fsp_flags.initial_delete_on_close &&
!is_delete_on_close_set(lck, fsp->name_hash)) {
/* Initial delete on close was set - for
* directories we don't care if anyone else
* wrote a real delete on close. */
lck_state = (struct close_share_mode_lock_state) {
.fsp = fsp,
.object_type = "directory",
.close_type = close_type,
};
send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
fsp->fsp_name->base_name);
set_delete_on_close_lck(fsp, lck,
fsp->conn->session_info->security_token,
fsp->conn->session_info->unix_token);
fsp->fsp_flags.delete_on_close = true;
}
close_share_mode_lock_prepare(lck, &lck_state);
delete_dir = is_delete_on_close_set(lck, fsp->name_hash) &&
!has_other_nonposix_opens(lck, fsp);
/*
* We don't have directory leases yet, so assert it in order
* to skip release_file_oplock().
*/
SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
/*
* NT can set delete_on_close of the last open
* reference to a file.
*/
normal_close = (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE);
if (!normal_close) {
/*
* Never try to delete the directory for ERROR_CLOSE
*/
delete_dir = false;
}
if (!delete_dir) {
if (!lck_state.delete_object) {
status = NT_STATUS_OK;
goto done;
}
@ -1523,32 +1513,26 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
/*
* Ok, we have to delete the directory
*/
lck_state.cleanup_fn = close_share_mode_lock_cleanup;
DBG_INFO("dir %s. Delete on close was set - deleting directory.\n",
fsp_str_dbg(fsp));
got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
&del_nt_token, &del_token);
SMB_ASSERT(got_tokens);
/* Become the user who requested the delete. */
if (!unix_token_equal(del_token, get_current_utok(conn))) {
if (lck_state.got_tokens &&
!unix_token_equal(lck_state.del_token, get_current_utok(conn)))
{
/* Become the user who requested the delete. */
DBG_INFO("dir %s. Change user to uid %u\n",
fsp_str_dbg(fsp),
(unsigned int)del_token->uid);
(unsigned int)lck_state.del_token->uid);
if (!push_sec_ctx()) {
smb_panic("close_directory: failed to push sec_ctx.\n");
}
set_sec_ctx(del_token->uid,
del_token->gid,
del_token->ngroups,
del_token->groups,
del_nt_token);
set_sec_ctx(lck_state.del_token->uid,
lck_state.del_token->gid,
lck_state.del_token->ngroups,
lck_state.del_token->groups,
lck_state.del_nt_token);
changed_user = true;
}
@ -1585,9 +1569,8 @@ done:
pop_sec_ctx();
}
if (!del_share_mode(lck, fsp)) {
DEBUG(0, ("close_directory: Could not delete share entry for "
"%s\n", fsp_str_dbg(fsp)));
if (lck_state.cleanup_fn != NULL) {
lck_state.cleanup_fn(lck, &lck_state);
}
TALLOC_FREE(lck);