diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index fae5dfb4713..de3b5a0103a 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -955,15 +955,6 @@ void reply_printqueue(struct smb_request *req); void reply_printwrite(struct smb_request *req); void reply_mkdir(struct smb_request *req); void reply_rmdir(struct smb_request *req); -NTSTATUS rename_internals(TALLOC_CTX *ctx, - connection_struct *conn, - struct smb_request *req, - struct smb_filename *smb_fname_src, - struct smb_filename *smb_fname_dst, - const char *dst_original_lcomp, - uint32_t attrs, - bool replace_if_exists, - uint32_t access_mask); void reply_mv(struct smb_request *req); NTSTATUS copy_file(TALLOC_CTX *ctx, connection_struct *conn, @@ -1036,6 +1027,15 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, const char *dst_original_lcomp, uint32_t attrs, bool replace_if_exists); +NTSTATUS rename_internals(TALLOC_CTX *ctx, + connection_struct *conn, + struct smb_request *req, + struct smb_filename *smb_fname_src, + struct smb_filename *smb_fname_dst, + const char *dst_original_lcomp, + uint32_t attrs, + bool replace_if_exists, + uint32_t access_mask); /* The following definitions come from smbd/seal.c */ diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 19fd20f3c7a..c8f1d637077 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -5920,119 +5920,6 @@ void reply_rmdir(struct smb_request *req) return; } -/**************************************************************************** - The guts of the rename command, split out so it may be called by the NT SMB - code. -****************************************************************************/ - -NTSTATUS rename_internals(TALLOC_CTX *ctx, - connection_struct *conn, - struct smb_request *req, - struct smb_filename *smb_fname_src, - struct smb_filename *smb_fname_dst, - const char *dst_original_lcomp, - uint32_t attrs, - bool replace_if_exists, - uint32_t access_mask) -{ - NTSTATUS status = NT_STATUS_OK; - int create_options = 0; - struct smb2_create_blobs *posx = NULL; - struct files_struct *fsp = NULL; - bool posix_pathname = (smb_fname_src->flags & SMB_FILENAME_POSIX_PATH); - bool case_sensitive = posix_pathname ? true : conn->case_sensitive; - bool case_preserve = posix_pathname ? true : conn->case_preserve; - bool short_case_preserve = posix_pathname ? true : - conn->short_case_preserve; - - if (posix_pathname) { - 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)); - goto out; - } - } - - DBG_NOTICE("case_sensitive = %d, " - "case_preserve = %d, short case preserve = %d, " - "directory = %s, newname = %s, " - "last_component_dest = %s\n", - case_sensitive, case_preserve, - short_case_preserve, - smb_fname_str_dbg(smb_fname_src), - smb_fname_str_dbg(smb_fname_dst), - dst_original_lcomp); - - ZERO_STRUCT(smb_fname_src->st); - - status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_src); - if (!NT_STATUS_IS_OK(status)) { - if (!NT_STATUS_EQUAL(status, - NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - goto out; - } - /* - * Possible symlink src. - */ - if (!(smb_fname_src->flags & SMB_FILENAME_POSIX_PATH)) { - goto out; - } - if (!S_ISLNK(smb_fname_src->st.st_ex_mode)) { - goto out; - } - } - - if (S_ISDIR(smb_fname_src->st.st_ex_mode)) { - create_options |= FILE_DIRECTORY_FILE; - } - - status = SMB_VFS_CREATE_FILE( - conn, /* conn */ - req, /* req */ - smb_fname_src, /* fname */ - access_mask, /* access_mask */ - (FILE_SHARE_READ | /* share_access */ - FILE_SHARE_WRITE), - 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 */ - NULL, /* pinfo */ - posx, /* in_context_blobs */ - NULL); /* out_context_blobs */ - - if (!NT_STATUS_IS_OK(status)) { - DBG_NOTICE("Could not open rename source %s: %s\n", - smb_fname_str_dbg(smb_fname_src), - nt_errstr(status)); - goto out; - } - - status = rename_internals_fsp(conn, - fsp, - smb_fname_dst, - dst_original_lcomp, - attrs, - replace_if_exists); - - close_file_free(req, &fsp, NORMAL_CLOSE); - - DBG_NOTICE("Error %s rename %s -> %s\n", - nt_errstr(status), smb_fname_str_dbg(smb_fname_src), - smb_fname_str_dbg(smb_fname_dst)); - - out: - TALLOC_FREE(posx); - return status; -} - /**************************************************************************** Reply to a mv. ****************************************************************************/ diff --git a/source3/smbd/smb2_reply.c b/source3/smbd/smb2_reply.c index f8a1e870d93..12afec877cb 100644 --- a/source3/smbd/smb2_reply.c +++ b/source3/smbd/smb2_reply.c @@ -1709,3 +1709,116 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, return status; } + +/**************************************************************************** + The guts of the rename command, split out so it may be called by the NT SMB + code. +****************************************************************************/ + +NTSTATUS rename_internals(TALLOC_CTX *ctx, + connection_struct *conn, + struct smb_request *req, + struct smb_filename *smb_fname_src, + struct smb_filename *smb_fname_dst, + const char *dst_original_lcomp, + uint32_t attrs, + bool replace_if_exists, + uint32_t access_mask) +{ + NTSTATUS status = NT_STATUS_OK; + int create_options = 0; + struct smb2_create_blobs *posx = NULL; + struct files_struct *fsp = NULL; + bool posix_pathname = (smb_fname_src->flags & SMB_FILENAME_POSIX_PATH); + bool case_sensitive = posix_pathname ? true : conn->case_sensitive; + bool case_preserve = posix_pathname ? true : conn->case_preserve; + bool short_case_preserve = posix_pathname ? true : + conn->short_case_preserve; + + if (posix_pathname) { + 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)); + goto out; + } + } + + DBG_NOTICE("case_sensitive = %d, " + "case_preserve = %d, short case preserve = %d, " + "directory = %s, newname = %s, " + "last_component_dest = %s\n", + case_sensitive, case_preserve, + short_case_preserve, + smb_fname_str_dbg(smb_fname_src), + smb_fname_str_dbg(smb_fname_dst), + dst_original_lcomp); + + ZERO_STRUCT(smb_fname_src->st); + + status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_src); + if (!NT_STATUS_IS_OK(status)) { + if (!NT_STATUS_EQUAL(status, + NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + goto out; + } + /* + * Possible symlink src. + */ + if (!(smb_fname_src->flags & SMB_FILENAME_POSIX_PATH)) { + goto out; + } + if (!S_ISLNK(smb_fname_src->st.st_ex_mode)) { + goto out; + } + } + + if (S_ISDIR(smb_fname_src->st.st_ex_mode)) { + create_options |= FILE_DIRECTORY_FILE; + } + + status = SMB_VFS_CREATE_FILE( + conn, /* conn */ + req, /* req */ + smb_fname_src, /* fname */ + access_mask, /* access_mask */ + (FILE_SHARE_READ | /* share_access */ + FILE_SHARE_WRITE), + 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 */ + NULL, /* pinfo */ + posx, /* in_context_blobs */ + NULL); /* out_context_blobs */ + + if (!NT_STATUS_IS_OK(status)) { + DBG_NOTICE("Could not open rename source %s: %s\n", + smb_fname_str_dbg(smb_fname_src), + nt_errstr(status)); + goto out; + } + + status = rename_internals_fsp(conn, + fsp, + smb_fname_dst, + dst_original_lcomp, + attrs, + replace_if_exists); + + close_file_free(req, &fsp, NORMAL_CLOSE); + + DBG_NOTICE("Error %s rename %s -> %s\n", + nt_errstr(status), smb_fname_str_dbg(smb_fname_src), + smb_fname_str_dbg(smb_fname_dst)); + + out: + TALLOC_FREE(posx); + return status; +}