[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Fri Oct 25 14:49:02 MDT 2013


The branch, master has been updated
       via  68427f1 torture: add FSCTL_SRV_COPYCHUNK_WRITE access test
       via  a13fda7 smb2_ioctl: add support for FSCTL_SRV_COPYCHUNK_WRITE
      from  ef4054e Revert "smbd: Move oplock/sharemode ops into one place"

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 68427f1e974d324bf82154eb46b3d981f534e0e8
Author: David Disseldorp <ddiss at samba.org>
Date:   Sat Oct 19 03:47:07 2013 +0200

    torture: add FSCTL_SRV_COPYCHUNK_WRITE access test
    
    Check that FSCTL_SRV_COPYCHUNK_WRITE succeeds when the copy-chunk target
    is opened with SEC_RIGHTS_FILE_WRITE only.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Fri Oct 25 22:48:59 CEST 2013 on sn-devel-104

commit a13fda747238c5780d10bdf80b00edd8c2d1f6d3
Author: David Disseldorp <ddiss at samba.org>
Date:   Sat Oct 19 03:47:06 2013 +0200

    smb2_ioctl: add support for FSCTL_SRV_COPYCHUNK_WRITE
    
    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>
    Reviewed-by: Jeremy Allison <jra at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/smb2_ioctl_network_fs.c |   44 +++++++++++++++++++++------
 source4/torture/smb2/ioctl.c         |   53 ++++++++++++++++++++++++++++++++-
 2 files changed, 85 insertions(+), 12 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/smb2_ioctl_network_fs.c b/source3/smbd/smb2_ioctl_network_fs.c
index 1e1e3e5..a1d67f8 100644
--- a/source3/smbd/smb2_ioctl_network_fs.c
+++ b/source3/smbd/smb2_ioctl_network_fs.c
@@ -80,29 +80,37 @@ struct fsctl_srv_copychunk_state {
 };
 static void fsctl_srv_copychunk_vfs_done(struct tevent_req *subreq);
 
-static NTSTATUS copychunk_check_handles(struct files_struct *src_fsp,
+static NTSTATUS copychunk_check_handles(uint32_t ctl_code,
+					struct files_struct *src_fsp,
 					struct files_struct *dst_fsp,
 					struct smb_request *smb1req)
 {
 	/*
 	 * [MS-SMB2] 3.3.5.15.6 Handling a Server-Side Data Copy Request
-	 * If Open.GrantedAccess of the destination file does not
-	 * include FILE_WRITE_DATA, then the request MUST be failed with
-	 * STATUS_ACCESS_DENIED. If Open.GrantedAccess of the
-	 * destination file does not include FILE_READ_DATA access and
-	 * the CtlCode is FSCTL_SRV_COPYCHUNK, then the request MUST be
-	 * failed with STATUS_ACCESS_DENIED.
+	 * The server MUST fail the request with STATUS_ACCESS_DENIED if any of
+	 * the following are true:
+	 * - The Open.GrantedAccess of the destination file does not include
+	 *   FILE_WRITE_DATA or FILE_APPEND_DATA.
 	 */
 	if (!CHECK_WRITE(dst_fsp)) {
 		DEBUG(5, ("copy chunk no write on dest handle (%s).\n",
 			smb_fname_str_dbg(dst_fsp->fsp_name) ));
 		return NT_STATUS_ACCESS_DENIED;
 	}
-	if (!CHECK_READ(dst_fsp, smb1req)) {
+	/*
+	 * - The Open.GrantedAccess of the destination file does not include
+	 *   FILE_READ_DATA, and the CtlCode is FSCTL_SRV_COPYCHUNK.
+	 */
+	if ((ctl_code == FSCTL_SRV_COPYCHUNK)
+	  && !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;
 	}
+	/*
+	 * - The Open.GrantedAccess of the source file does not include
+	 *   FILE_READ_DATA access.
+	 */
 	if (!CHECK_READ(src_fsp, smb1req)) {
 		DEBUG(5, ("copy chunk no read on src handle (%s).\n",
 			smb_fname_str_dbg(src_fsp->fsp_name) ));
@@ -136,6 +144,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,
+						   uint32_t ctl_code,
 						   struct files_struct *dst_fsp,
 						   DATA_BLOB *in_input,
 						   size_t in_max_output,
@@ -150,6 +159,10 @@ static struct tevent_req *fsctl_srv_copychunk_send(TALLOC_CTX *mem_ctx,
 	struct srv_copychunk *chunk;
 	struct fsctl_srv_copychunk_state *state;
 
+	/* handler for both copy-chunk variants */
+	SMB_ASSERT((ctl_code == FSCTL_SRV_COPYCHUNK)
+		|| (ctl_code == FSCTL_SRV_COPYCHUNK_WRITE));
+
 	req = tevent_req_create(mem_ctx, &state,
 				struct fsctl_srv_copychunk_state);
 	if (req == NULL) {
@@ -188,7 +201,8 @@ static struct tevent_req *fsctl_srv_copychunk_send(TALLOC_CTX *mem_ctx,
 
 	state->dst_fsp = dst_fsp;
 
-	state->status = copychunk_check_handles(state->src_fsp,
+	state->status = copychunk_check_handles(ctl_code,
+						state->src_fsp,
 						state->dst_fsp,
 						smb2req->smb1req);
 	if (!NT_STATUS_IS_OK(state->status)) {
@@ -446,8 +460,18 @@ struct tevent_req *smb2_ioctl_network_fs(uint32_t ctl_code,
 	NTSTATUS status;
 
 	switch (ctl_code) {
+	/*
+	 * [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.
+	 */
+	case FSCTL_SRV_COPYCHUNK_WRITE:	/* FALL THROUGH */
 	case FSCTL_SRV_COPYCHUNK:
-		subreq = fsctl_srv_copychunk_send(state, ev, state->fsp,
+		subreq = fsctl_srv_copychunk_send(state, ev,
+						  ctl_code,
+						  state->fsp,
 						  &state->in_input,
 						  state->in_max_output,
 						  state->smb2req);
diff --git a/source4/torture/smb2/ioctl.c b/source4/torture/smb2/ioctl.c
index 75379af..fa9e190 100644
--- a/source4/torture/smb2/ioctl.c
+++ b/source4/torture/smb2/ioctl.c
@@ -1236,8 +1236,7 @@ static bool test_ioctl_copy_chunk_bad_access(struct torture_context *torture,
 
 	/*
 	 * FSCTL_SRV_COPYCHUNK requires read permission on dest,
-	 * FSCTL_SRV_COPYCHUNK_WRITE (not supported by Samba) on the other hand
-	 * does not.
+	 * FSCTL_SRV_COPYCHUNK_WRITE on the other hand does not.
 	 */
 	status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
 	torture_assert_ntstatus_equal(torture, status,
@@ -1251,6 +1250,54 @@ static bool test_ioctl_copy_chunk_bad_access(struct torture_context *torture,
 	return true;
 }
 
+static bool test_ioctl_copy_chunk_write_access(struct torture_context *torture,
+					       struct smb2_tree *tree)
+{
+	struct smb2_handle src_h;
+	struct smb2_handle dest_h;
+	NTSTATUS status;
+	union smb_ioctl ioctl;
+	TALLOC_CTX *tmp_ctx = talloc_new(tree);
+	struct srv_copychunk_copy cc_copy;
+	enum ndr_err_code ndr_ret;
+	bool ok;
+
+	/* no read permission on dest with FSCTL_SRV_COPYCHUNK_WRITE */
+	ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
+				   1, /* 1 chunk */
+				   &src_h, 4096, /* fill 4096 byte src file */
+				   SEC_RIGHTS_FILE_ALL,
+				   &dest_h, 0,	/* 0 byte dest file */
+				   (SEC_RIGHTS_FILE_WRITE
+				    | SEC_RIGHTS_FILE_EXECUTE),
+				   &cc_copy,
+				   &ioctl);
+	if (!ok) {
+		torture_fail(torture, "setup copy chunk error");
+	}
+
+	ioctl.smb2.in.function = FSCTL_SRV_COPYCHUNK_WRITE;
+	cc_copy.chunks[0].source_off = 0;
+	cc_copy.chunks[0].target_off = 0;
+	cc_copy.chunks[0].length = 4096;
+
+	ndr_ret = ndr_push_struct_blob(&ioctl.smb2.in.out, tmp_ctx,
+				       &cc_copy,
+			(ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
+	torture_assert_ndr_success(torture, ndr_ret,
+				   "ndr_push_srv_copychunk_copy");
+
+	status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+	torture_assert_ntstatus_ok(torture, status,
+				   "FSCTL_SRV_COPYCHUNK_WRITE");
+
+	smb2_util_close(tree, src_h);
+	smb2_util_close(tree, dest_h);
+	talloc_free(tmp_ctx);
+
+	return true;
+}
+
 static bool test_ioctl_copy_chunk_src_exceed(struct torture_context *torture,
 					     struct smb2_tree *tree)
 {
@@ -2068,6 +2115,8 @@ struct torture_suite *torture_smb2_ioctl_init(void)
 				     test_ioctl_copy_chunk_src_is_dest_overlap);
 	torture_suite_add_1smb2_test(suite, "copy_chunk_bad_access",
 				     test_ioctl_copy_chunk_bad_access);
+	torture_suite_add_1smb2_test(suite, "copy_chunk_write_access",
+				     test_ioctl_copy_chunk_write_access);
 	torture_suite_add_1smb2_test(suite, "copy_chunk_src_exceed",
 				     test_ioctl_copy_chunk_src_exceed);
 	torture_suite_add_1smb2_test(suite, "copy_chunk_src_exceed_multi",


-- 
Samba Shared Repository


More information about the samba-cvs mailing list