]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Pass src_dirfsp, src_relname and raw newname to rename_internals_fsp()
authorVolker Lendecke <vl@samba.org>
Wed, 17 Sep 2025 22:51:05 +0000 (15:51 -0700)
committerRalph Boehme <slow@samba.org>
Tue, 21 Oct 2025 17:33:29 +0000 (17:33 +0000)
Will make way for some simplification soon

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/smbd/proto.h
source3/smbd/smb1_nttrans.c
source3/smbd/smb1_reply.c
source3/smbd/smb2_reply.c
source3/smbd/smb2_trans2.c

index 3687f1132d0c3f123fa1991f847fd7566d57110a..3529274c833248f5b505b3a89580b69187179b3a 100644 (file)
@@ -940,20 +940,25 @@ ssize_t sendfile_short_send(struct smbXsrv_connection *xconn,
                            size_t headersize,
                            size_t smb_maxcnt);
 NTSTATUS rename_internals_fsp(connection_struct *conn,
+                             struct files_struct *src_dirfsp,
                              files_struct *fsp,
+                             struct smb_filename *smb_fname_src_rel,
                              struct share_mode_lock **lck,
                              struct smb_filename *smb_fname_dst_in,
                              const char *dst_original_lcomp,
                              uint32_t attrs,
+                             const char *newname,
                              bool replace_if_exists);
 NTSTATUS rename_internals(TALLOC_CTX *ctx,
                          connection_struct *conn,
                          struct smb_request *req,
                          struct files_struct *src_dirfsp,
                          struct smb_filename *smb_fname_src,
+                         struct smb_filename *smb_fname_src_rel,
                          struct smb_filename *smb_fname_dst,
                          const char *dst_original_lcomp,
                          uint32_t attrs,
+                         const char *newname,
                          bool replace_if_exists,
                          uint32_t access_mask);
 NTSTATUS copy_file(TALLOC_CTX *ctx,
index f6c8323a0dc86105737b993a1fef335e0344396c..67ee61c7d73a4b8a4b1c161bd66a5ee1aa4eccfc 100644 (file)
@@ -1583,9 +1583,11 @@ void reply_ntrename(struct smb_request *req)
                                          req,
                                          src_dirfsp,
                                          smb_fname_old,
+                                         smb_fname_old_rel,
                                          smb_fname_new,
                                          dst_original_lcomp,
                                          attrs,
+                                         newname,
                                          false,
                                          DELETE_ACCESS);
 
index dc4e2533c5da5044e9cc11e044537e4b1211be01..1408d260aea57d081fc0ec31cc3e4039f70f1d08 100644 (file)
@@ -6342,6 +6342,7 @@ void reply_mv(struct smb_request *req)
        TALLOC_CTX *ctx = talloc_tos();
        struct files_struct *src_dirfsp = NULL;
        struct smb_filename *smb_fname_src = NULL;
+       struct smb_filename *smb_fname_src_rel = NULL;
        struct files_struct *dst_dirfsp = NULL;
        struct smb_filename *smb_fname_dst = NULL;
        const char *dst_original_lcomp = NULL;
@@ -6395,13 +6396,15 @@ void reply_mv(struct smb_request *req)
                reply_nterror(req, status);
                goto out;
        }
-       status = filename_convert_dirfsp(ctx,
-                                        conn,
-                                        name,
-                                        src_ucf_flags,
-                                        src_twrp,
-                                        &src_dirfsp,
-                                        &smb_fname_src);
+       status = filename_convert_dirfsp_rel(ctx,
+                                            conn,
+                                            conn->cwd_fsp,
+                                            name,
+                                            src_ucf_flags,
+                                            src_twrp,
+                                            &src_dirfsp,
+                                            &smb_fname_src,
+                                            &smb_fname_src_rel);
 
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -6470,9 +6473,11 @@ void reply_mv(struct smb_request *req)
                                  req,
                                  src_dirfsp, /* src_dirfsp */
                                  smb_fname_src,
+                                 smb_fname_src_rel,
                                  smb_fname_dst,
                                  dst_original_lcomp,
                                  attrs,
+                                 newname,
                                  false,
                                  DELETE_ACCESS);
        if (!NT_STATUS_IS_OK(status)) {
index 786c7c9998b80bd792f037c4e31f946d2ea55574..cf7830e3912a3fd9e2676c5e0da38bae351da416 100644 (file)
@@ -1348,11 +1348,14 @@ static void notify_rename(struct connection_struct *conn,
 ****************************************************************************/
 
 NTSTATUS rename_internals_fsp(connection_struct *conn,
+                             struct files_struct *src_dirfsp,
                              files_struct *fsp,
+                             struct smb_filename *smb_fname_src_rel,
                              struct share_mode_lock **_lck,
                              struct smb_filename *smb_fname_dst_in,
                              const char *dst_original_lcomp,
                              uint32_t attrs,
+                             const char *newname,
                              bool replace_if_exists)
 {
        TALLOC_CTX *ctx = talloc_tos();
@@ -1795,9 +1798,11 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
                          struct smb_request *req,
                          struct files_struct *src_dirfsp,
                          struct smb_filename *smb_fname_src,
+                         struct smb_filename *smb_fname_src_rel,
                          struct smb_filename *smb_fname_dst,
                          const char *dst_original_lcomp,
                          uint32_t attrs,
+                         const char *newname,
                          bool replace_if_exists,
                          uint32_t access_mask)
 {
@@ -1892,11 +1897,14 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
        }
 
        status = rename_internals_fsp(conn,
+                                     src_dirfsp,
                                      fsp,
+                                     smb_fname_src_rel,
                                      NULL,
                                      smb_fname_dst,
                                      dst_original_lcomp,
                                      attrs,
+                                     newname,
                                      replace_if_exists);
 
        close_file_free(req, &fsp, NORMAL_CLOSE);
index bd9e9d1fedeeea90a9d1239142b3af362b894532..90ba94578f24ff38bf314296eae6acc183d46857 100644 (file)
@@ -4359,6 +4359,8 @@ static NTSTATUS smb2_file_rename_information(connection_struct *conn,
 {
        char *newname = NULL;
        bool overwrite;
+       struct smb_filename *smb_fname_src_parent = NULL;
+       struct smb_filename *smb_fname_src_rel = NULL;
        struct files_struct *dst_dirfsp = NULL;
        struct smb_filename *smb_fname_dst = NULL;
        char *dst_original_lcomp = NULL;
@@ -4386,15 +4388,29 @@ static NTSTATUS smb2_file_rename_information(connection_struct *conn,
                  fsp_str_dbg(fsp),
                  smb_fname_str_dbg(smb_fname_dst));
 
+       status = parent_pathref(talloc_tos(),
+                               conn->cwd_fsp,
+                               fsp->fsp_name,
+                               &smb_fname_src_parent,
+                               &smb_fname_src_rel);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        status = rename_internals_fsp(conn,
+                                     smb_fname_src_parent->fsp,
                                      fsp,
+                                     smb_fname_src_rel,
                                      lck,
                                      smb_fname_dst,
                                      dst_original_lcomp,
                                      (FILE_ATTRIBUTE_HIDDEN |
                                       FILE_ATTRIBUTE_SYSTEM),
+                                     newname,
                                      overwrite);
 
+       TALLOC_FREE(smb_fname_src_rel);
+       TALLOC_FREE(smb_fname_src_parent);
        TALLOC_FREE(smb_fname_dst);
        return status;
 }
@@ -4554,6 +4570,8 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
        uint32_t root_fid;
        uint32_t len;
        char *newname = NULL;
+       struct smb_filename *smb_fname_src_parent = NULL;
+       struct smb_filename *smb_fname_src_rel = NULL;
        struct files_struct *dst_dirfsp = NULL;
        struct smb_filename *smb_fname_dst = NULL;
        const char *dst_original_lcomp = NULL;
@@ -4702,6 +4720,28 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
                }
        }
 
+       status = parent_pathref(ctx,
+                               conn->cwd_fsp,
+                               fsp->fsp_name,
+                               &smb_fname_src_parent,
+                               &smb_fname_src_rel);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+
+       if (!fsp_is_alternate_stream(fsp)) {
+               /*
+                * The smb1-level rename information is always
+                * relative to the directory of the src name.
+                */
+               newname = full_path_from_dirfsp_at_basename(
+                       ctx, smb_fname_src_parent->fsp, newname);
+               if (newname == NULL) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto out;
+               }
+       }
+
        if (fsp->fsp_flags.is_fsa) {
                DBG_DEBUG("SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
                          fsp_fnum_dbg(fsp),
@@ -4718,11 +4758,14 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
                }
 
                status = rename_internals_fsp(conn,
+                                             smb_fname_src_parent->fsp,
                                              fsp,
+                                             smb_fname_src_rel,
                                              NULL,
                                              smb_fname_dst,
                                              dst_original_lcomp,
                                              0,
+                                             newname,
                                              overwrite);
        } else {
                DBG_DEBUG("SMB_FILE_RENAME_INFORMATION %s -> %s\n",
@@ -4731,11 +4774,13 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
                status = rename_internals(ctx,
                                          conn,
                                          req,
-                                         NULL, /* src_dirfsp */
+                                         smb_fname_src_parent->fsp,
                                          smb_fname_src,
+                                         smb_fname_src_rel,
                                          smb_fname_dst,
                                          dst_original_lcomp,
                                          0,
+                                         newname,
                                          overwrite,
                                          FILE_WRITE_ATTRIBUTES);
        }