mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +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:
parent
f9ea783989
commit
d04b6e9dd0
@ -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
|
/* Initial delete on close was set and no one else
|
||||||
* wrote a real delete on close. */
|
* 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;
|
fsp->fsp_flags.delete_on_close = true;
|
||||||
set_delete_on_close_lck(fsp, lck,
|
set_delete_on_close_lck(fsp, lck,
|
||||||
fsp->conn->session_info->security_token,
|
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;
|
connection_struct *conn = fsp->conn;
|
||||||
struct share_mode_lock *lck = NULL;
|
struct share_mode_lock *lck = NULL;
|
||||||
bool delete_dir = False;
|
struct close_share_mode_lock_state lck_state = {};
|
||||||
bool changed_user = false;
|
bool changed_user = false;
|
||||||
NTSTATUS status = NT_STATUS_OK;
|
NTSTATUS status = NT_STATUS_OK;
|
||||||
NTSTATUS status1 = 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;
|
NTSTATUS notify_status;
|
||||||
|
|
||||||
SMB_ASSERT(fsp->fsp_flags.is_fsa);
|
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;
|
return NT_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsp->fsp_flags.initial_delete_on_close &&
|
lck_state = (struct close_share_mode_lock_state) {
|
||||||
!is_delete_on_close_set(lck, fsp->name_hash)) {
|
.fsp = fsp,
|
||||||
/* Initial delete on close was set - for
|
.object_type = "directory",
|
||||||
* directories we don't care if anyone else
|
.close_type = close_type,
|
||||||
* wrote a real delete on close. */
|
};
|
||||||
|
|
||||||
send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
|
close_share_mode_lock_prepare(lck, &lck_state);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
* NT can set delete_on_close of the last open
|
||||||
* reference to a file.
|
* reference to a file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
normal_close = (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE);
|
if (!lck_state.delete_object) {
|
||||||
if (!normal_close) {
|
|
||||||
/*
|
|
||||||
* Never try to delete the directory for ERROR_CLOSE
|
|
||||||
*/
|
|
||||||
delete_dir = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!delete_dir) {
|
|
||||||
status = NT_STATUS_OK;
|
status = NT_STATUS_OK;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -1523,32 +1513,26 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
|
|||||||
/*
|
/*
|
||||||
* Ok, we have to delete the directory
|
* 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",
|
if (lck_state.got_tokens &&
|
||||||
fsp_str_dbg(fsp));
|
!unix_token_equal(lck_state.del_token, get_current_utok(conn)))
|
||||||
|
{
|
||||||
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))) {
|
|
||||||
/* Become the user who requested the delete. */
|
/* Become the user who requested the delete. */
|
||||||
|
|
||||||
DBG_INFO("dir %s. Change user to uid %u\n",
|
DBG_INFO("dir %s. Change user to uid %u\n",
|
||||||
fsp_str_dbg(fsp),
|
fsp_str_dbg(fsp),
|
||||||
(unsigned int)del_token->uid);
|
(unsigned int)lck_state.del_token->uid);
|
||||||
|
|
||||||
if (!push_sec_ctx()) {
|
if (!push_sec_ctx()) {
|
||||||
smb_panic("close_directory: failed to push sec_ctx.\n");
|
smb_panic("close_directory: failed to push sec_ctx.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
set_sec_ctx(del_token->uid,
|
set_sec_ctx(lck_state.del_token->uid,
|
||||||
del_token->gid,
|
lck_state.del_token->gid,
|
||||||
del_token->ngroups,
|
lck_state.del_token->ngroups,
|
||||||
del_token->groups,
|
lck_state.del_token->groups,
|
||||||
del_nt_token);
|
lck_state.del_nt_token);
|
||||||
|
|
||||||
changed_user = true;
|
changed_user = true;
|
||||||
}
|
}
|
||||||
@ -1585,9 +1569,8 @@ done:
|
|||||||
pop_sec_ctx();
|
pop_sec_ctx();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!del_share_mode(lck, fsp)) {
|
if (lck_state.cleanup_fn != NULL) {
|
||||||
DEBUG(0, ("close_directory: Could not delete share entry for "
|
lck_state.cleanup_fn(lck, &lck_state);
|
||||||
"%s\n", fsp_str_dbg(fsp)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TALLOC_FREE(lck);
|
TALLOC_FREE(lck);
|
||||||
|
Loading…
Reference in New Issue
Block a user