From 81fca59b6d9f53cc082dc71d44fa0e90d55c1287 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 22 Jan 2021 19:09:44 -0800 Subject: [PATCH] s3: smbd: When deleting files or directories we must call become_user_without_service() to get the current user token before writing it into the share record. This undoes the change in commit 367c0d191083240ccf9a59f1dc196da2d8ba17e4. That commit thought (as did I, because I reviewed it) that calling: smbXsrv_session_info_lookup(conn->sconn->client, fsp->vuid, &session_info); to get the session info was enough to get the Windows and UNIX tokens for the current user. Unfortunately this isn't the case. We *must* go through become_user_without_service() which calls into check_user_ok(). That is the only place that deals with the horrible "force user/force group" semantics on a share definition. Without it, the returned session_info from smbXsrv_session_info_lookup() is for the logged on user, not the forced (impersonated) user or group for the share. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14617 Signed-off-by: Jeremy Allison --- source3/smbd/close.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 97d13473082..b1eaf6d5a5b 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -342,21 +342,25 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, if (fsp->fsp_flags.initial_delete_on_close && !is_delete_on_close_set(lck, fsp->name_hash)) { - struct auth_session_info *session_info = NULL; /* Initial delete on close was set and no one else * wrote a real delete on close. */ - status = smbXsrv_session_info_lookup(conn->sconn->client, - fsp->vuid, - &session_info); - if (!NT_STATUS_IS_OK(status)) { - return NT_STATUS_INTERNAL_ERROR; + /* + * We must use become_user_without_service() + * as this copes with 'force user' semantics + * inside check_user_ok(). + */ + bool ok = become_user_without_service(fsp->conn, fsp->vuid); + if (!ok) { + smb_panic("close_remove_share_mode: unable to " + "become user.\n"); } fsp->fsp_flags.delete_on_close = true; set_delete_on_close_lck(fsp, lck, - session_info->security_token, - session_info->unix_token); + get_current_nttok(conn), + get_current_utok(conn)); + unbecome_user_without_service(); } delete_file = is_delete_on_close_set(lck, fsp->name_hash) && @@ -1175,24 +1179,24 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, } if (fsp->fsp_flags.initial_delete_on_close) { - struct auth_session_info *session_info = NULL; - /* Initial delete on close was set - for * directories we don't care if anyone else * wrote a real delete on close. */ - status = smbXsrv_session_info_lookup(fsp->conn->sconn->client, - fsp->vuid, - &session_info); - if (!NT_STATUS_IS_OK(status)) { - return NT_STATUS_INTERNAL_ERROR; + /* + * We must use become_user_without_service() + * as this copes with 'force user' semantics + * inside check_user_ok(). + */ + bool ok = become_user_without_service(fsp->conn, fsp->vuid); + if (!ok) { + smb_panic("close_directory: unable to become user.\n"); } - send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx, fsp->fsp_name->base_name); set_delete_on_close_lck(fsp, lck, - session_info->security_token, - session_info->unix_token); + get_current_nttok(fsp->conn), + get_current_utok(fsp->conn)); fsp->fsp_flags.delete_on_close = true; } -- 2.27.0