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.
****************************************************************************/
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;
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 */
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;
+}