]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Move copy_internals to smb2_nttrans.c
authorDavid Mulder <dmulder@suse.com>
Fri, 11 Mar 2022 19:06:38 +0000 (12:06 -0700)
committerJeremy Allison <jra@samba.org>
Thu, 7 Apr 2022 17:37:29 +0000 (17:37 +0000)
Signed-off-by: David Mulder <dmulder@suse.com>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/smbd/nttrans.c
source3/smbd/proto.h
source3/smbd/smb2_nttrans.c

index bce77a41e0db4a0b08025f5b411eab031fba1c53..7d9a94a63173d4be6b1b0734129c181c31617b75 100644 (file)
@@ -1386,183 +1386,6 @@ void reply_ntcancel(struct smb_request *req)
        return;
 }
 
-/****************************************************************************
- Copy a file.
-****************************************************************************/
-
-NTSTATUS copy_internals(TALLOC_CTX *ctx,
-                       connection_struct *conn,
-                       struct smb_request *req,
-                       struct smb_filename *smb_fname_src,
-                       struct smb_filename *smb_fname_dst,
-                       uint32_t attrs)
-{
-       files_struct *fsp1,*fsp2;
-       uint32_t fattr;
-       int info;
-       off_t ret=-1;
-       NTSTATUS status = NT_STATUS_OK;
-       struct smb_filename *parent = NULL;
-       struct smb_filename *pathref = NULL;
-
-       if (!CAN_WRITE(conn)) {
-               status = NT_STATUS_MEDIA_WRITE_PROTECTED;
-               goto out;
-       }
-
-        /* Source must already exist. */
-       if (!VALID_STAT(smb_fname_src->st)) {
-               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
-               goto out;
-       }
-
-       /* Ensure attributes match. */
-       fattr = fdos_mode(smb_fname_src->fsp);
-       if ((fattr & ~attrs) & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) {
-               status = NT_STATUS_NO_SUCH_FILE;
-               goto out;
-       }
-
-       /* Disallow if dst file already exists. */
-       if (VALID_STAT(smb_fname_dst->st)) {
-               status = NT_STATUS_OBJECT_NAME_COLLISION;
-               goto out;
-       }
-
-       /* No links from a directory. */
-       if (S_ISDIR(smb_fname_src->st.st_ex_mode)) {
-               status = NT_STATUS_FILE_IS_A_DIRECTORY;
-               goto out;
-       }
-
-       DEBUG(10,("copy_internals: doing file copy %s to %s\n",
-                 smb_fname_str_dbg(smb_fname_src),
-                 smb_fname_str_dbg(smb_fname_dst)));
-
-        status = SMB_VFS_CREATE_FILE(
-               conn,                                   /* conn */
-               req,                                    /* req */
-               smb_fname_src,                          /* fname */
-               FILE_READ_DATA|FILE_READ_ATTRIBUTES|
-                       FILE_READ_EA,                   /* access_mask */
-               (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
-                   FILE_SHARE_DELETE),
-               FILE_OPEN,                              /* create_disposition*/
-               0,                                      /* create_options */
-               FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
-               NO_OPLOCK,                              /* oplock_request */
-               NULL,                                   /* lease */
-               0,                                      /* allocation_size */
-               0,                                      /* private_flags */
-               NULL,                                   /* sd */
-               NULL,                                   /* ea_list */
-               &fsp1,                                  /* result */
-               &info,                                  /* pinfo */
-               NULL, NULL);                            /* create context */
-
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
-        status = SMB_VFS_CREATE_FILE(
-               conn,                                   /* conn */
-               req,                                    /* req */
-               smb_fname_dst,                          /* fname */
-               FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|
-                       FILE_WRITE_EA,                  /* access_mask */
-               (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
-                   FILE_SHARE_DELETE),
-               FILE_CREATE,                            /* create_disposition*/
-               0,                                      /* create_options */
-               fattr,                                  /* file_attributes */
-               NO_OPLOCK,                              /* oplock_request */
-               NULL,                                   /* lease */
-               0,                                      /* allocation_size */
-               0,                                      /* private_flags */
-               NULL,                                   /* sd */
-               NULL,                                   /* ea_list */
-               &fsp2,                                  /* result */
-               &info,                                  /* pinfo */
-               NULL, NULL);                            /* create context */
-
-       if (!NT_STATUS_IS_OK(status)) {
-               close_file_free(NULL, &fsp1, ERROR_CLOSE);
-               goto out;
-       }
-
-       if (smb_fname_src->st.st_ex_size) {
-               ret = vfs_transfer_file(fsp1, fsp2, smb_fname_src->st.st_ex_size);
-       }
-
-       /*
-        * As we are opening fsp1 read-only we only expect
-        * an error on close on fsp2 if we are out of space.
-        * Thus we don't look at the error return from the
-        * close of fsp1.
-        */
-       close_file_free(NULL, &fsp1, NORMAL_CLOSE);
-
-       /* Ensure the modtime is set correctly on the destination file. */
-       set_close_write_time(fsp2, smb_fname_src->st.st_ex_mtime);
-
-       status = close_file_free(NULL, &fsp2, NORMAL_CLOSE);
-       if (!NT_STATUS_IS_OK(status)) {
-               DBG_WARNING("close_file_free() failed: %s\n",
-                           nt_errstr(status));
-               /*
-                * We can't do much but leak the fsp
-                */
-               goto out;
-       }
-
-       /* Grrr. We have to do this as open_file_ntcreate adds FILE_ATTRIBUTE_ARCHIVE when it
-          creates the file. This isn't the correct thing to do in the copy
-          case. JRA */
-
-       status = SMB_VFS_PARENT_PATHNAME(conn,
-                                        talloc_tos(),
-                                        smb_fname_dst,
-                                        &parent,
-                                        NULL);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-       if (smb_fname_dst->fsp == NULL) {
-               status = synthetic_pathref(parent,
-                                       conn->cwd_fsp,
-                                       smb_fname_dst->base_name,
-                                       smb_fname_dst->stream_name,
-                                       NULL,
-                                       smb_fname_dst->twrp,
-                                       smb_fname_dst->flags,
-                                       &pathref);
-
-               /* should we handle NT_STATUS_OBJECT_NAME_NOT_FOUND specially here ???? */
-               if (!NT_STATUS_IS_OK(status)) {
-                       TALLOC_FREE(parent);
-                       goto out;
-               }
-               file_set_dosmode(conn, pathref, fattr, parent, false);
-               smb_fname_dst->st.st_ex_mode = pathref->st.st_ex_mode;
-       } else {
-               file_set_dosmode(conn, smb_fname_dst, fattr, parent, false);
-       }
-       TALLOC_FREE(parent);
-
-       if (ret < (off_t)smb_fname_src->st.st_ex_size) {
-               status = NT_STATUS_DISK_FULL;
-               goto out;
-       }
- out:
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(3,("copy_internals: Error %s copy file %s to %s\n",
-                       nt_errstr(status), smb_fname_str_dbg(smb_fname_src),
-                       smb_fname_str_dbg(smb_fname_dst)));
-       }
-
-       return status;
-}
-
 /****************************************************************************
  Reply to a NT rename request.
 ****************************************************************************/
index 29525f2a7363795d92743aaf21d554555e1dba23..0b21dc2f42f0ed34f2c353751ae4e5e7f8fa6f2a 100644 (file)
@@ -685,12 +685,6 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn,
                                        uint32_t max_data_count,
                                        uint8_t **ppmarshalled_sd,
                                        size_t *psd_size);
-NTSTATUS copy_internals(TALLOC_CTX *ctx,
-                       connection_struct *conn,
-                       struct smb_request *req,
-                       struct smb_filename *smb_fname_src,
-                       struct smb_filename *smb_fname_dst,
-                       uint32_t attrs);
 #ifdef HAVE_SYS_QUOTAS
 
 struct smb2_query_quota_info;
@@ -714,6 +708,12 @@ NTSTATUS set_sd(files_struct *fsp, struct security_descriptor *psd,
                        uint32_t security_info_sent);
 NTSTATUS set_sd_blob(files_struct *fsp, uint8_t *data, uint32_t sd_len,
                        uint32_t security_info_sent);
+NTSTATUS copy_internals(TALLOC_CTX *ctx,
+                       connection_struct *conn,
+                       struct smb_request *req,
+                       struct smb_filename *smb_fname_src,
+                       struct smb_filename *smb_fname_dst,
+                       uint32_t attrs);
 
 /* The following definitions come from smbd/open.c  */
 
index 932dec7623376d6383acd3bfb2fd2c949377266f..1b650d06960c6a6d42c737f9492811c0b9be60f8 100644 (file)
@@ -189,3 +189,180 @@ NTSTATUS set_sd_blob(files_struct *fsp, uint8_t *data, uint32_t sd_len,
 
        return set_sd(fsp, psd, security_info_sent);
 }
+
+/****************************************************************************
+ Copy a file.
+****************************************************************************/
+
+NTSTATUS copy_internals(TALLOC_CTX *ctx,
+                       connection_struct *conn,
+                       struct smb_request *req,
+                       struct smb_filename *smb_fname_src,
+                       struct smb_filename *smb_fname_dst,
+                       uint32_t attrs)
+{
+       files_struct *fsp1,*fsp2;
+       uint32_t fattr;
+       int info;
+       off_t ret=-1;
+       NTSTATUS status = NT_STATUS_OK;
+       struct smb_filename *parent = NULL;
+       struct smb_filename *pathref = NULL;
+
+       if (!CAN_WRITE(conn)) {
+               status = NT_STATUS_MEDIA_WRITE_PROTECTED;
+               goto out;
+       }
+
+        /* Source must already exist. */
+       if (!VALID_STAT(smb_fname_src->st)) {
+               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               goto out;
+       }
+
+       /* Ensure attributes match. */
+       fattr = fdos_mode(smb_fname_src->fsp);
+       if ((fattr & ~attrs) & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) {
+               status = NT_STATUS_NO_SUCH_FILE;
+               goto out;
+       }
+
+       /* Disallow if dst file already exists. */
+       if (VALID_STAT(smb_fname_dst->st)) {
+               status = NT_STATUS_OBJECT_NAME_COLLISION;
+               goto out;
+       }
+
+       /* No links from a directory. */
+       if (S_ISDIR(smb_fname_src->st.st_ex_mode)) {
+               status = NT_STATUS_FILE_IS_A_DIRECTORY;
+               goto out;
+       }
+
+       DEBUG(10,("copy_internals: doing file copy %s to %s\n",
+                 smb_fname_str_dbg(smb_fname_src),
+                 smb_fname_str_dbg(smb_fname_dst)));
+
+        status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               req,                                    /* req */
+               smb_fname_src,                          /* fname */
+               FILE_READ_DATA|FILE_READ_ATTRIBUTES|
+                       FILE_READ_EA,                   /* access_mask */
+               (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
+                   FILE_SHARE_DELETE),
+               FILE_OPEN,                              /* create_disposition*/
+               0,                                      /* create_options */
+               FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
+               NO_OPLOCK,                              /* oplock_request */
+               NULL,                                   /* lease */
+               0,                                      /* allocation_size */
+               0,                                      /* private_flags */
+               NULL,                                   /* sd */
+               NULL,                                   /* ea_list */
+               &fsp1,                                  /* result */
+               &info,                                  /* pinfo */
+               NULL, NULL);                            /* create context */
+
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+
+        status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               req,                                    /* req */
+               smb_fname_dst,                          /* fname */
+               FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|
+                       FILE_WRITE_EA,                  /* access_mask */
+               (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
+                   FILE_SHARE_DELETE),
+               FILE_CREATE,                            /* create_disposition*/
+               0,                                      /* create_options */
+               fattr,                                  /* file_attributes */
+               NO_OPLOCK,                              /* oplock_request */
+               NULL,                                   /* lease */
+               0,                                      /* allocation_size */
+               0,                                      /* private_flags */
+               NULL,                                   /* sd */
+               NULL,                                   /* ea_list */
+               &fsp2,                                  /* result */
+               &info,                                  /* pinfo */
+               NULL, NULL);                            /* create context */
+
+       if (!NT_STATUS_IS_OK(status)) {
+               close_file_free(NULL, &fsp1, ERROR_CLOSE);
+               goto out;
+       }
+
+       if (smb_fname_src->st.st_ex_size) {
+               ret = vfs_transfer_file(fsp1, fsp2, smb_fname_src->st.st_ex_size);
+       }
+
+       /*
+        * As we are opening fsp1 read-only we only expect
+        * an error on close on fsp2 if we are out of space.
+        * Thus we don't look at the error return from the
+        * close of fsp1.
+        */
+       close_file_free(NULL, &fsp1, NORMAL_CLOSE);
+
+       /* Ensure the modtime is set correctly on the destination file. */
+       set_close_write_time(fsp2, smb_fname_src->st.st_ex_mtime);
+
+       status = close_file_free(NULL, &fsp2, NORMAL_CLOSE);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_WARNING("close_file_free() failed: %s\n",
+                           nt_errstr(status));
+               /*
+                * We can't do much but leak the fsp
+                */
+               goto out;
+       }
+
+       /* Grrr. We have to do this as open_file_ntcreate adds FILE_ATTRIBUTE_ARCHIVE when it
+          creates the file. This isn't the correct thing to do in the copy
+          case. JRA */
+
+       status = SMB_VFS_PARENT_PATHNAME(conn,
+                                        talloc_tos(),
+                                        smb_fname_dst,
+                                        &parent,
+                                        NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+       if (smb_fname_dst->fsp == NULL) {
+               status = synthetic_pathref(parent,
+                                       conn->cwd_fsp,
+                                       smb_fname_dst->base_name,
+                                       smb_fname_dst->stream_name,
+                                       NULL,
+                                       smb_fname_dst->twrp,
+                                       smb_fname_dst->flags,
+                                       &pathref);
+
+               /* should we handle NT_STATUS_OBJECT_NAME_NOT_FOUND specially here ???? */
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(parent);
+                       goto out;
+               }
+               file_set_dosmode(conn, pathref, fattr, parent, false);
+               smb_fname_dst->st.st_ex_mode = pathref->st.st_ex_mode;
+       } else {
+               file_set_dosmode(conn, smb_fname_dst, fattr, parent, false);
+       }
+       TALLOC_FREE(parent);
+
+       if (ret < (off_t)smb_fname_src->st.st_ex_size) {
+               status = NT_STATUS_DISK_FULL;
+               goto out;
+       }
+ out:
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(3,("copy_internals: Error %s copy file %s to %s\n",
+                       nt_errstr(status), smb_fname_str_dbg(smb_fname_src),
+                       smb_fname_str_dbg(smb_fname_dst)));
+       }
+
+       return status;
+}