1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

s4/torture: vfs_fruit: test copy-chunk on streams

Bug: https://bugzilla.samba.org/show_bug.cgi?id=12787

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: David Disseldorp <ddiss@samba.org>
This commit is contained in:
Ralph Boehme 2017-05-12 17:10:07 +02:00 committed by Jeremy Allison
parent b8a5152885
commit 9d30d47b1e

View File

@ -4048,6 +4048,230 @@ done:
return ret;
}
static bool copy_one_stream(struct torture_context *torture,
struct smb2_tree *tree,
TALLOC_CTX *tmp_ctx,
const char *src_sname,
const char *dst_sname)
{
struct smb2_handle src_h = {{0}};
struct smb2_handle dest_h = {{0}};
NTSTATUS status;
union smb_ioctl io;
struct srv_copychunk_copy cc_copy;
struct srv_copychunk_rsp cc_rsp;
enum ndr_err_code ndr_ret;
bool ok = false;
ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
1, /* 1 chunk */
src_sname,
&src_h, 256, /* fill 256 byte src file */
SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
dst_sname,
&dest_h, 0, /* 0 byte dest file */
SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
&cc_copy,
&io);
torture_assert_goto(torture, ok == true, ok, done,
"setup copy chunk error\n");
/* copy all src file data (via a single chunk desc) */
cc_copy.chunks[0].source_off = 0;
cc_copy.chunks[0].target_off = 0;
cc_copy.chunks[0].length = 256;
ndr_ret = ndr_push_struct_blob(
&io.smb2.in.out, tmp_ctx, &cc_copy,
(ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
"ndr_push_srv_copychunk_copy\n");
status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
torture_assert_ntstatus_ok_goto(torture, status, ok, done,
"FSCTL_SRV_COPYCHUNK\n");
ndr_ret = ndr_pull_struct_blob(
&io.smb2.out.out, tmp_ctx, &cc_rsp,
(ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
"ndr_pull_srv_copychunk_rsp\n");
ok = check_copy_chunk_rsp(torture, &cc_rsp,
1, /* chunks written */
0, /* chunk bytes unsuccessfully written */
256); /* total bytes written */
torture_assert_goto(torture, ok == true, ok, done,
"bad copy chunk response data\n");
ok = check_pattern(torture, tree, tmp_ctx, dest_h, 0, 256, 0);
if (!ok) {
torture_fail(torture, "inconsistent file data\n");
}
done:
if (!smb2_util_handle_empty(src_h)) {
smb2_util_close(tree, src_h);
}
if (!smb2_util_handle_empty(dest_h)) {
smb2_util_close(tree, dest_h);
}
return ok;
}
static bool copy_finderinfo_stream(struct torture_context *torture,
struct smb2_tree *tree,
TALLOC_CTX *tmp_ctx,
const char *src_name,
const char *dst_name)
{
struct smb2_handle src_h = {{0}};
struct smb2_handle dest_h = {{0}};
NTSTATUS status;
union smb_ioctl io;
struct srv_copychunk_copy cc_copy;
struct srv_copychunk_rsp cc_rsp;
enum ndr_err_code ndr_ret;
const char *type_creator = "SMB,OLE!";
AfpInfo *info = NULL;
const char *src_name_afpinfo = NULL;
const char *dst_name_afpinfo = NULL;
bool ok = false;
src_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", src_name,
AFPINFO_STREAM);
torture_assert_not_null_goto(torture, src_name_afpinfo, ok, done,
"talloc_asprintf failed\n");
dst_name_afpinfo = talloc_asprintf(tmp_ctx, "%s%s", dst_name,
AFPINFO_STREAM);
torture_assert_not_null_goto(torture, dst_name_afpinfo, ok, done,
"talloc_asprintf failed\n");
info = torture_afpinfo_new(tmp_ctx);
torture_assert_not_null_goto(torture, info, ok, done,
"torture_afpinfo_new failed\n");
memcpy(info->afpi_FinderInfo, type_creator, 8);
ok = torture_write_afpinfo(tree, torture, tmp_ctx, src_name, info);
torture_assert_goto(torture, ok == true, ok, done,
"torture_write_afpinfo failed\n");
ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
1, /* 1 chunk */
src_name_afpinfo,
&src_h, 0,
SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
dst_name_afpinfo,
&dest_h, 0,
SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
&cc_copy,
&io);
torture_assert_goto(torture, ok == true, ok, done,
"setup copy chunk error\n");
/* copy all src file data (via a single chunk desc) */
cc_copy.chunks[0].source_off = 0;
cc_copy.chunks[0].target_off = 0;
cc_copy.chunks[0].length = 60;
ndr_ret = ndr_push_struct_blob(
&io.smb2.in.out, tmp_ctx, &cc_copy,
(ndr_push_flags_fn_t)ndr_push_srv_copychunk_copy);
torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
"ndr_push_srv_copychunk_copy\n");
status = smb2_ioctl(tree, tmp_ctx, &io.smb2);
torture_assert_ntstatus_ok_goto(torture, status, ok, done,
"FSCTL_SRV_COPYCHUNK\n");
ndr_ret = ndr_pull_struct_blob(
&io.smb2.out.out, tmp_ctx, &cc_rsp,
(ndr_pull_flags_fn_t)ndr_pull_srv_copychunk_rsp);
torture_assert_ndr_success_goto(torture, ndr_ret, ok, done,
"ndr_pull_srv_copychunk_rsp\n");
smb2_util_close(tree, src_h);
ZERO_STRUCT(src_h);
smb2_util_close(tree, dest_h);
ZERO_STRUCT(dest_h);
ok = check_copy_chunk_rsp(torture, &cc_rsp,
1, /* chunks written */
0, /* chunk bytes unsuccessfully written */
60); /* total bytes written */
torture_assert_goto(torture, ok == true, ok, done,
"bad copy chunk response data\n");
ok = check_stream(tree, __location__, torture, tmp_ctx,
dst_name, AFPINFO_STREAM,
0, 60, 16, 8, type_creator);
torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
done:
if (!smb2_util_handle_empty(src_h)) {
smb2_util_close(tree, src_h);
}
if (!smb2_util_handle_empty(dest_h)) {
smb2_util_close(tree, dest_h);
}
return ok;
}
static bool test_copy_chunk_streams(struct torture_context *torture,
struct smb2_tree *tree)
{
const char *src_name = "src";
const char *dst_name = "dst";
struct names {
const char *src_sname;
const char *dst_sname;
} names[] = {
{ "src:foo", "dst:foo" },
{ "src" AFPRESOURCE_STREAM, "dst" AFPRESOURCE_STREAM }
};
int i;
TALLOC_CTX *tmp_ctx = NULL;
bool ok = false;
tmp_ctx = talloc_new(tree);
torture_assert_not_null_goto(torture, tmp_ctx, ok, done,
"torture_setup_file\n");
smb2_util_unlink(tree, src_name);
smb2_util_unlink(tree, dst_name);
ok = torture_setup_file(torture, tree, src_name, false);
torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
ok = torture_setup_file(torture, tree, dst_name, false);
torture_assert_goto(torture, ok == true, ok, done, "torture_setup_file\n");
for (i = 0; i < ARRAY_SIZE(names); i++) {
ok = copy_one_stream(torture, tree, tmp_ctx,
names[i].src_sname,
names[i].dst_sname);
torture_assert_goto(torture, ok == true, ok, done,
"copy_one_stream failed\n");
}
ok = copy_finderinfo_stream(torture, tree, tmp_ctx,
src_name, dst_name);
torture_assert_goto(torture, ok == true, ok, done,
"copy_finderinfo_stream failed\n");
done:
smb2_util_unlink(tree, src_name);
smb2_util_unlink(tree, dst_name);
talloc_free(tmp_ctx);
return ok;
}
/*
* Note: This test depends on "vfs objects = catia fruit streams_xattr". For
* some tests torture must be run on the host it tests and takes an additional
@ -4086,6 +4310,7 @@ struct torture_suite *torture_vfs_fruit(TALLOC_CTX *ctx)
torture_suite_add_1smb2_test(suite, "readdir_attr with names with illegal ntfs characters", test_readdir_attr_illegal_ntfs);
torture_suite_add_2ns_smb2_test(suite, "invalid AFP_AfpInfo", test_invalid_afpinfo);
torture_suite_add_1smb2_test(suite, "creating rsrc with read-only access", test_rfork_create_ro);
torture_suite_add_1smb2_test(suite, "copy-chunk streams", test_copy_chunk_streams);
return suite;
}