s4/torture: add a test for copy-chunk across shares
authorRalph Boehme <slow@samba.org>
Mon, 5 Jun 2017 06:31:19 +0000 (08:31 +0200)
committerRalph Boehme <slow@samba.org>
Mon, 3 Jul 2017 17:59:08 +0000 (19:59 +0200)
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
selftest/knownfail.d/smb2.ioctl.copy-chunk-across-shares [new file with mode: 0644]
source4/torture/smb2/ioctl.c

diff --git a/selftest/knownfail.d/smb2.ioctl.copy-chunk-across-shares b/selftest/knownfail.d/smb2.ioctl.copy-chunk-across-shares
new file mode 100644 (file)
index 0000000..4a1f859
--- /dev/null
@@ -0,0 +1,2 @@
+^samba3.smb2.ioctl.copy_chunk_across_shares
+^samba3.smb2.ioctl fs_specific.copy_chunk_across_shares
index d9b7f4a6b5d635c9da459bdd38b4e6ee2d6f9ab3..3ccf7be2d8cf79a79f5f9958124272c6e92d0526 100644 (file)
@@ -1984,6 +1984,89 @@ done:
        return ok;
 }
 
        return ok;
 }
 
+static bool test_copy_chunk_across_shares(struct torture_context *tctx,
+                                         struct smb2_tree *tree)
+{
+       TALLOC_CTX *mem_ctx = NULL;
+       struct smb2_tree *tree2 = NULL;
+       struct smb2_handle src_h = {{0}};
+       struct smb2_handle dest_h = {{0}};
+       union smb_ioctl ioctl;
+       struct srv_copychunk_copy cc_copy;
+       struct srv_copychunk_rsp cc_rsp;
+       enum ndr_err_code ndr_ret;
+       NTSTATUS status;
+       bool ok = false;
+
+       mem_ctx = talloc_new(tctx);
+       torture_assert_not_null_goto(tctx, mem_ctx, ok, done,
+                                    "talloc_new\n");
+
+       ok = torture_smb2_tree_connect(tctx, tree->session, tctx, &tree2);
+       torture_assert_goto(tctx, ok == true, ok, done,
+                           "torture_smb2_tree_connect failed\n");
+
+       ok = test_setup_copy_chunk(tctx, tree, tree2, mem_ctx,
+                                  1, /* 1 chunk */
+                                  FNAME,
+                                  &src_h, 4096, /* fill 4096 byte src file */
+                                  SEC_RIGHTS_FILE_ALL,
+                                  FNAME2,
+                                  &dest_h, 0,  /* 0 byte dest file */
+                                  SEC_RIGHTS_FILE_ALL,
+                                  &cc_copy,
+                                  &ioctl);
+       torture_assert_goto(tctx, ok == true, ok, done,
+                           "test_setup_copy_chunk failed\n");
+
+       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, mem_ctx, &cc_copy,
+               (ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
+       torture_assert_ndr_success_goto(tctx, ndr_ret, ok, done,
+                                       "ndr_push_srv_copychunk_copy\n");
+
+       status = smb2_ioctl(tree2, mem_ctx, &ioctl.smb2);
+       torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
+                                       "FSCTL_SRV_COPYCHUNK\n");
+
+       ndr_ret = ndr_pull_struct_blob(
+               &ioctl.smb2.out.out, mem_ctx, &cc_rsp,
+               (ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
+
+       torture_assert_ndr_success_goto(tctx, ndr_ret, ok, done,
+                                  "ndr_pull_srv_copychunk_rsp\n");
+
+       ok = check_copy_chunk_rsp(tctx, &cc_rsp,
+                                 1,    /* chunks written */
+                                 0,    /* chunk bytes unsuccessfully written */
+                                 4096); /* total bytes written */
+       torture_assert_goto(tctx, ok == true, ok, done,
+                           "bad copy chunk response data\n");
+
+       ok = check_pattern(tctx, tree2, mem_ctx, dest_h, 0, 4096, 0);
+       torture_assert_goto(tctx, ok == true, ok, done,
+                           "inconsistent file data\n");
+
+done:
+       TALLOC_FREE(mem_ctx);
+       if (!smb2_util_handle_empty(src_h)) {
+               smb2_util_close(tree, src_h);
+       }
+       if (!smb2_util_handle_empty(dest_h)) {
+               smb2_util_close(tree2, dest_h);
+       }
+       smb2_util_unlink(tree, FNAME);
+       smb2_util_unlink(tree2, FNAME2);
+       if (tree2 != NULL) {
+               smb2_tdis(tree2);
+       }
+       return ok;
+}
+
 static NTSTATUS test_ioctl_compress_fs_supported(struct torture_context *torture,
                                                 struct smb2_tree *tree,
                                                 TALLOC_CTX *mem_ctx,
 static NTSTATUS test_ioctl_compress_fs_supported(struct torture_context *torture,
                                                 struct smb2_tree *tree,
                                                 TALLOC_CTX *mem_ctx,
@@ -6427,6 +6510,8 @@ struct torture_suite *torture_smb2_ioctl_init(TALLOC_CTX *ctx)
                                     test_ioctl_copy_chunk_zero_length);
        torture_suite_add_1smb2_test(suite, "copy-chunk streams",
                                     test_copy_chunk_streams);
                                     test_ioctl_copy_chunk_zero_length);
        torture_suite_add_1smb2_test(suite, "copy-chunk streams",
                                     test_copy_chunk_streams);
+       torture_suite_add_1smb2_test(suite, "copy_chunk_across_shares",
+                                    test_copy_chunk_across_shares);
        torture_suite_add_1smb2_test(suite, "compress_file_flag",
                                     test_ioctl_compress_file_flag);
        torture_suite_add_1smb2_test(suite, "compress_dir_inherit",
        torture_suite_add_1smb2_test(suite, "compress_file_flag",
                                     test_ioctl_compress_file_flag);
        torture_suite_add_1smb2_test(suite, "compress_dir_inherit",