[PATCH 1/2] smb2_ioctl: add support for FSCTL_SRV_COPYCHUNK_WRITE

David Disseldorp ddiss at samba.org
Thu Oct 17 04:37:00 MDT 2013


FSCTL_SRV_COPYCHUNK can only be used when the client has the copy-chunk
target file open with FILE_WRITE_DATA and FILE_READ_DATA.
FSCTL_SRV_COPYCHUNK_WRITE requires only FILE_WRITE_DATA access on the
target, and is therefore suitable for cp --reflink, which opens the
target file O_WRONLY.

Signed-off-by: David Disseldorp <ddiss at samba.org>
---
 source3/smbd/smb2_ioctl_network_fs.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/source3/smbd/smb2_ioctl_network_fs.c b/source3/smbd/smb2_ioctl_network_fs.c
index 1e1e3e5..c3856b2 100644
--- a/source3/smbd/smb2_ioctl_network_fs.c
+++ b/source3/smbd/smb2_ioctl_network_fs.c
@@ -82,6 +82,7 @@ static void fsctl_srv_copychunk_vfs_done(struct tevent_req *subreq);
 
 static NTSTATUS copychunk_check_handles(struct files_struct *src_fsp,
 					struct files_struct *dst_fsp,
+					bool dst_needs_rw,
 					struct smb_request *smb1req)
 {
 	/*
@@ -98,7 +99,7 @@ static NTSTATUS copychunk_check_handles(struct files_struct *src_fsp,
 			smb_fname_str_dbg(dst_fsp->fsp_name) ));
 		return NT_STATUS_ACCESS_DENIED;
 	}
-	if (!CHECK_READ(dst_fsp, smb1req)) {
+	if (dst_needs_rw && !CHECK_READ(dst_fsp, smb1req)) {
 		DEBUG(5, ("copy chunk no read on dest handle (%s).\n",
 			smb_fname_str_dbg(dst_fsp->fsp_name) ));
 		return NT_STATUS_ACCESS_DENIED;
@@ -137,6 +138,7 @@ static NTSTATUS copychunk_check_handles(struct files_struct *src_fsp,
 static struct tevent_req *fsctl_srv_copychunk_send(TALLOC_CTX *mem_ctx,
 						   struct tevent_context *ev,
 						   struct files_struct *dst_fsp,
+						   bool dst_needs_rw,
 						   DATA_BLOB *in_input,
 						   size_t in_max_output,
 						   struct smbd_smb2_request *smb2req)
@@ -190,6 +192,7 @@ static struct tevent_req *fsctl_srv_copychunk_send(TALLOC_CTX *mem_ctx,
 
 	state->status = copychunk_check_handles(state->src_fsp,
 						state->dst_fsp,
+						dst_needs_rw,
 						smb2req->smb1req);
 	if (!NT_STATUS_IS_OK(state->status)) {
 		tevent_req_nterror(req, state->status);
@@ -444,10 +447,21 @@ struct tevent_req *smb2_ioctl_network_fs(uint32_t ctl_code,
 {
 	struct tevent_req *subreq;
 	NTSTATUS status;
+	bool cc_dst_needs_rw = true;
 
 	switch (ctl_code) {
+	case FSCTL_SRV_COPYCHUNK_WRITE:
+		/*
+		 * [MS-SMB2] 2.2.31
+		 * FSCTL_SRV_COPYCHUNK is issued when a handle has
+		 * FILE_READ_DATA and FILE_WRITE_DATA access to the file;
+		 * FSCTL_SRV_COPYCHUNK_WRITE is issued when a handle only has
+		 * FILE_WRITE_DATA access.
+		 */
+		cc_dst_needs_rw = false;
 	case FSCTL_SRV_COPYCHUNK:
 		subreq = fsctl_srv_copychunk_send(state, ev, state->fsp,
+						  cc_dst_needs_rw,
 						  &state->in_input,
 						  state->in_max_output,
 						  state->smb2req);
-- 
1.8.1.4



More information about the samba-technical mailing list