torture: add FSCTL_SRV_COPYCHUNK_WRITE access test
authorDavid Disseldorp <ddiss@samba.org>
Sat, 19 Oct 2013 01:47:07 +0000 (03:47 +0200)
committerJeremy Allison <jra@samba.org>
Fri, 25 Oct 2013 20:48:59 +0000 (22:48 +0200)
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@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Fri Oct 25 22:48:59 CEST 2013 on sn-devel-104

source4/torture/smb2/ioctl.c

index 75379af..fa9e190 100644 (file)
@@ -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",