s4/torture: more tests for copy-chunk across shares
authorRalph Boehme <slow@samba.org>
Tue, 6 Jun 2017 12:36:38 +0000 (14:36 +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>
source4/torture/smb2/ioctl.c

index 3ccf7be2d8cf79a79f5f9958124272c6e92d0526..9585c110f48dd793ee2660f6b75f38c3bbd6cd83 100644 (file)
@@ -2067,6 +2067,168 @@ done:
        return ok;
 }
 
+/* Test closing the src handle */
+static bool test_copy_chunk_across_shares2(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;
+       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");
+
+       status = smb2_util_close(tree, src_h);
+       torture_assert_ntstatus_ok_goto(tctx, status, ok, done,
+                           "smb2_util_close failed\n");
+       ZERO_STRUCT(src_h);
+
+       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_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
+                                          ok, done, "smb2_ioctl failed\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;
+}
+
+/* Test offset works */
+static bool test_copy_chunk_across_shares3(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,
+                                  2, /* 2 chunks */
+                                  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;
+
+       /* second chunk appends the same data to the first */
+       cc_copy.chunks[1].source_off = 0;
+       cc_copy.chunks[1].target_off = 4096;
+       cc_copy.chunks[1].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, "smb2_ioctl failed\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,
+                                 2,    /* chunks written */
+                                 0,    /* chunk bytes unsuccessfully written */
+                                 8192); /* total bytes written */
+       torture_assert_goto(tctx, ok == true, ok, done,
+                           "check_copy_chunk_rsp failed\n");
+
+       ok = check_pattern(tctx, tree2, mem_ctx, dest_h, 0, 4096, 0);
+       torture_assert_goto(tctx, ok == true, ok, done,
+                           "check_pattern failed\n");
+
+       ok = check_pattern(tctx, tree2, mem_ctx, dest_h, 4096, 4096, 0);
+       torture_assert_goto(tctx, ok == true, ok, done,
+                           "check_pattern failed\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,
@@ -6512,6 +6674,10 @@ struct torture_suite *torture_smb2_ioctl_init(TALLOC_CTX *ctx)
                                     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, "copy_chunk_across_shares2",
+                                    test_copy_chunk_across_shares2);
+       torture_suite_add_1smb2_test(suite, "copy_chunk_across_shares3",
+                                    test_copy_chunk_across_shares3);
        torture_suite_add_1smb2_test(suite, "compress_file_flag",
                                     test_ioctl_compress_file_flag);
        torture_suite_add_1smb2_test(suite, "compress_dir_inherit",