From: Volker Lendecke Date: Wed, 28 Dec 2022 23:07:21 +0000 (+0100) Subject: smbd: Move smb_posix_unlink() to smb1_trans2.c X-Git-Tag: talloc-2.4.0~99 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cabef7246977b19398affb0a323e22b0062c8dac;p=thirdparty%2Fsamba.git smbd: Move smb_posix_unlink() to smb1_trans2.c Most of this is direct cut&paste without reformatting. Don't pass SMB_POSIX_PATH_UNLINK through smbd_do_setfilepathinfo(), directly handle it in call_trans2setpathinfo() where we know we have a path. Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- diff --git a/source3/smbd/smb1_trans2.c b/source3/smbd/smb1_trans2.c index 35743f7cfd0..2cd855c0455 100644 --- a/source3/smbd/smb1_trans2.c +++ b/source3/smbd/smb1_trans2.c @@ -2907,6 +2907,144 @@ static NTSTATUS smb_posix_open(connection_struct *conn, return NT_STATUS_OK; } +/**************************************************************************** + Delete a file with POSIX semantics. +****************************************************************************/ + +struct smb_posix_unlink_state { + struct smb_filename *smb_fname; + struct files_struct *fsp; + NTSTATUS status; +}; + +static void smb_posix_unlink_locked(struct share_mode_lock *lck, + void *private_data) +{ + struct smb_posix_unlink_state *state = private_data; + char del = 1; + bool other_nonposix_opens; + + other_nonposix_opens = has_other_nonposix_opens(lck, state->fsp); + if (other_nonposix_opens) { + /* Fail with sharing violation. */ + state->status = NT_STATUS_SHARING_VIOLATION; + return; + } + + /* + * Set the delete on close. + */ + state->status = smb_set_file_disposition_info(state->fsp->conn, + &del, + 1, + state->fsp, + state->smb_fname); +} + +static NTSTATUS smb_posix_unlink(connection_struct *conn, + struct smb_request *req, + const char *pdata, + int total_data, + struct smb_filename *smb_fname) +{ + struct smb_posix_unlink_state state = {}; + NTSTATUS status = NT_STATUS_OK; + files_struct *fsp = NULL; + uint16_t flags = 0; + int info = 0; + int create_options = 0; + struct smb2_create_blobs *posx = NULL; + + if (!CAN_WRITE(conn)) { + return NT_STATUS_DOS(ERRSRV, ERRaccess); + } + + if (total_data < 2) { + return NT_STATUS_INVALID_PARAMETER; + } + + flags = SVAL(pdata,0); + + if (!VALID_STAT(smb_fname->st)) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) && + !VALID_STAT_OF_DIR(smb_fname->st)) { + return NT_STATUS_NOT_A_DIRECTORY; + } + + DEBUG(10,("smb_posix_unlink: %s %s\n", + (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file", + smb_fname_str_dbg(smb_fname))); + + if (S_ISDIR(smb_fname->st.st_ex_mode)) { + create_options |= FILE_DIRECTORY_FILE; + } + + status = make_smb2_posix_create_ctx(talloc_tos(), &posx, 0777); + if (!NT_STATUS_IS_OK(status)) { + DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n", + nt_errstr(status)); + return status; + } + + status = SMB_VFS_CREATE_FILE( + conn, /* conn */ + req, /* req */ + NULL, /* dirfsp */ + smb_fname, /* fname */ + DELETE_ACCESS, /* access_mask */ + (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */ + FILE_SHARE_DELETE), + FILE_OPEN, /* create_disposition*/ + create_options, /* create_options */ + 0, /* file_attributes */ + 0, /* oplock_request */ + NULL, /* lease */ + 0, /* allocation_size */ + 0, /* private_flags */ + NULL, /* sd */ + NULL, /* ea_list */ + &fsp, /* result */ + &info, /* pinfo */ + posx, /* in_context_blobs */ + NULL); /* out_context_blobs */ + + TALLOC_FREE(posx); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* + * Don't lie to client. If we can't really delete due to + * non-POSIX opens return SHARING_VIOLATION. + */ + + state = (struct smb_posix_unlink_state) { + .smb_fname = smb_fname, + .fsp = fsp, + }; + + status = share_mode_do_locked_vfs_allowed(fsp->file_id, + smb_posix_unlink_locked, + &state); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("share_mode_do_locked_vfs_allowed(%s) failed - %s\n", + fsp_str_dbg(fsp), nt_errstr(status)); + close_file_free(req, &fsp, NORMAL_CLOSE); + return NT_STATUS_INVALID_PARAMETER; + } + + status = state.status; + if (!NT_STATUS_IS_OK(status)) { + close_file_free(req, &fsp, NORMAL_CLOSE); + return status; + } + return close_file_free(req, &fsp, NORMAL_CLOSE); +} + static void call_trans2setpathinfo( connection_struct *conn, struct smb_request *req, @@ -3020,6 +3158,11 @@ static void call_trans2setpathinfo( smb_fname, &data_return_size); break; + + case SMB_POSIX_PATH_UNLINK: + status = smb_posix_unlink( + conn, req, *ppdata, total_data, smb_fname); + break; } if (info_level_handled) { diff --git a/source3/smbd/smb2_trans2.c b/source3/smbd/smb2_trans2.c index ff95b24017e..e057da1885a 100644 --- a/source3/smbd/smb2_trans2.c +++ b/source3/smbd/smb2_trans2.c @@ -6310,140 +6310,6 @@ static NTSTATUS smb_set_file_unix_info2(connection_struct *conn, return NT_STATUS_OK; } -/**************************************************************************** - Delete a file with POSIX semantics. -****************************************************************************/ - -struct smb_posix_unlink_state { - struct smb_filename *smb_fname; - struct files_struct *fsp; - NTSTATUS status; -}; - -static void smb_posix_unlink_locked(struct share_mode_lock *lck, - void *private_data) -{ - struct smb_posix_unlink_state *state = private_data; - char del = 1; - bool other_nonposix_opens; - - other_nonposix_opens = has_other_nonposix_opens(lck, state->fsp); - if (other_nonposix_opens) { - /* Fail with sharing violation. */ - state->status = NT_STATUS_SHARING_VIOLATION; - return; - } - - /* - * Set the delete on close. - */ - state->status = smb_set_file_disposition_info(state->fsp->conn, - &del, - 1, - state->fsp, - state->smb_fname); -} - -static NTSTATUS smb_posix_unlink(connection_struct *conn, - struct smb_request *req, - const char *pdata, - int total_data, - struct smb_filename *smb_fname) -{ - struct smb_posix_unlink_state state = {}; - NTSTATUS status = NT_STATUS_OK; - files_struct *fsp = NULL; - uint16_t flags = 0; - int info = 0; - int create_options = 0; - struct smb2_create_blobs *posx = NULL; - - if (total_data < 2) { - return NT_STATUS_INVALID_PARAMETER; - } - - flags = SVAL(pdata,0); - - if (!VALID_STAT(smb_fname->st)) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - - if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) && - !VALID_STAT_OF_DIR(smb_fname->st)) { - return NT_STATUS_NOT_A_DIRECTORY; - } - - DEBUG(10,("smb_posix_unlink: %s %s\n", - (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file", - smb_fname_str_dbg(smb_fname))); - - if (S_ISDIR(smb_fname->st.st_ex_mode)) { - create_options |= FILE_DIRECTORY_FILE; - } - - status = make_smb2_posix_create_ctx(talloc_tos(), &posx, 0777); - if (!NT_STATUS_IS_OK(status)) { - DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n", - nt_errstr(status)); - return status; - } - - status = SMB_VFS_CREATE_FILE( - conn, /* conn */ - req, /* req */ - NULL, /* dirfsp */ - smb_fname, /* fname */ - DELETE_ACCESS, /* access_mask */ - (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */ - FILE_SHARE_DELETE), - FILE_OPEN, /* create_disposition*/ - create_options, /* create_options */ - 0, /* file_attributes */ - 0, /* oplock_request */ - NULL, /* lease */ - 0, /* allocation_size */ - 0, /* private_flags */ - NULL, /* sd */ - NULL, /* ea_list */ - &fsp, /* result */ - &info, /* pinfo */ - posx, /* in_context_blobs */ - NULL); /* out_context_blobs */ - - TALLOC_FREE(posx); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* - * Don't lie to client. If we can't really delete due to - * non-POSIX opens return SHARING_VIOLATION. - */ - - state = (struct smb_posix_unlink_state) { - .smb_fname = smb_fname, - .fsp = fsp, - }; - - status = share_mode_do_locked_vfs_allowed(fsp->file_id, - smb_posix_unlink_locked, - &state); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("share_mode_do_locked_vfs_allowed(%s) failed - %s\n", - fsp_str_dbg(fsp), nt_errstr(status)); - close_file_free(req, &fsp, NORMAL_CLOSE); - return NT_STATUS_INVALID_PARAMETER; - } - - status = state.status; - if (!NT_STATUS_IS_OK(status)) { - close_file_free(req, &fsp, NORMAL_CLOSE); - return status; - } - return close_file_free(req, &fsp, NORMAL_CLOSE); -} - static NTSTATUS smbd_do_posix_setfilepathinfo(struct connection_struct *conn, struct smb_request *req, TALLOC_CTX *mem_ctx, @@ -6543,20 +6409,6 @@ static NTSTATUS smbd_do_posix_setfilepathinfo(struct connection_struct *conn, } #endif - case SMB_POSIX_PATH_UNLINK: - { - if (smb_fname == NULL) { - /* We must have a pathname for this. */ - return NT_STATUS_INVALID_LEVEL; - } - - status = smb_posix_unlink(conn, req, - pdata, - total_data, - smb_fname); - break; - } - default: return NT_STATUS_INVALID_LEVEL; }