s4:torture: add a file-id related test
authorRalph Boehme <slow@samba.org>
Fri, 30 Aug 2019 12:49:24 +0000 (14:49 +0200)
committerRalph Boehme <slow@samba.org>
Tue, 10 Sep 2019 19:05:28 +0000 (19:05 +0000)
Note I'm using the share vfs_fruit_xattr because I need a share with both a
streams and a acl_* VFS object.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
selftest/knownfail.d/samba3.smb2.create [new file with mode: 0644]
source3/selftest/tests.py
source4/selftest/tests.py
source4/torture/smb2/create.c
source4/torture/smb2/smb2.c

diff --git a/selftest/knownfail.d/samba3.smb2.create b/selftest/knownfail.d/samba3.smb2.create
new file mode 100644 (file)
index 0000000..89455da
--- /dev/null
@@ -0,0 +1 @@
+^samba3.smb2.fileid.fileid\(nt4_dc\)
index 4e6b23f4c98611bfeea4b25f12c82d32705f1ff3..dfae2c57a1d3220d532eeed71672d1a61fe7b377 100755 (executable)
@@ -717,6 +717,8 @@ for t in tests:
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/delete_readonly -U$USERNAME%$PASSWORD --option=torture:delete_readonly=true')
         plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
+    elif t == "smb2.fileid":
+        plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/vfs_fruit_xattr -U$USERNAME%$PASSWORD')
     elif t == "rpc.wkssvc":
         plansmbtorture4testsuite(t, "ad_member", '//$SERVER/tmp -U$DC_USERNAME%$DC_PASSWORD')
     elif t == "rpc.srvsvc":
index 6d0efcc42b8953cfe39b023ebbb647d63b389c80..6b2f8b3e4b50773cbd032260f1768e8e6780d252 100755 (executable)
@@ -345,6 +345,7 @@ smb2_s3only = [
     "smb2.kernel-oplocks",
     "smb2.durable-v2-delay",
     "smb2.aio_delay",
+    "smb2.fileid",
 ]
 smb2 = [x for x in smbtorture4_testsuites("smb2.") if x not in smb2_s3only]
 
index e6181c240cc8f925b7485f521d1aa1aa49aaf296..3fd99de0a3a11a636d30e8c3f339adf1d3a9039d 100644 (file)
@@ -1905,6 +1905,204 @@ done:
        return ret;
 }
 
+static bool test_fileid(struct torture_context *tctx,
+                       struct smb2_tree *tree)
+{
+       TALLOC_CTX *mem_ctx = talloc_new(tctx);
+       const char *fname = DNAME "\\foo";
+       const char *sname = DNAME "\\foo:bar";
+       struct smb2_handle testdirh;
+       struct smb2_handle h1;
+       struct smb2_create create;
+       union smb_fileinfo finfo;
+       union smb_setfileinfo sinfo;
+       struct smb2_find f;
+       unsigned int count;
+       union smb_search_data *d;
+       uint64_t fileid;
+       uint64_t stream_fileid;
+       NTSTATUS status;
+       bool ret = true;
+
+       smb2_deltree(tree, DNAME);
+
+       status = torture_smb2_testdir(tree, DNAME, &testdirh);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "torture_smb2_testdir failed\n");
+
+       create = (struct smb2_create) {
+               .in.desired_access = SEC_FILE_ALL,
+               .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
+               .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
+               .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
+               .in.fname = fname,
+               .in.query_on_disk_id = true,
+       };
+
+       status = smb2_create(tree, tctx, &create);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "test file could not be created\n");
+       h1 = create.out.file.handle;
+
+       fileid = BVAL(&create.out.on_disk_id, 0);
+
+       finfo = (union smb_fileinfo) {
+               .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
+               .generic.in.file.handle = h1,
+       };
+
+       status = smb2_getinfo_file(tree, tctx, &finfo);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "torture_smb2_testdir\n");
+
+       torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, fileid,
+                                     ret, done, "bad fileid\n");
+
+       f = (struct smb2_find) {
+               .in.file.handle = testdirh,
+               .in.pattern = "foo",
+               .in.max_response_size = 0x1000,
+               .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
+       };
+
+       status = smb2_find_level(tree, tree, &f, &count, &d);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "smb2_find_level failed\n");
+
+       torture_assert_u64_equal_goto(tctx,
+                                     d->id_both_directory_info.file_id,
+                                     fileid,
+                                     ret, done, "bad fileid\n");
+
+       smb2_util_close(tree, h1);
+
+       create = (struct smb2_create) {
+               .in.desired_access = SEC_FILE_ALL,
+               .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
+               .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
+               .in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF,
+               .in.fname = sname,
+               .in.query_on_disk_id = true,
+       };
+
+       status = smb2_create(tree, tctx, &create);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "test file could not be created\n");
+       h1 = create.out.file.handle;
+
+       stream_fileid = BVAL(&create.out.on_disk_id, 0);
+       torture_assert_u64_equal_goto(tctx, stream_fileid, fileid,
+                                     ret, done, "bad fileid\n");
+
+       finfo = (union smb_fileinfo) {
+               .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
+               .generic.in.file.handle = h1,
+       };
+
+       status = smb2_getinfo_file(tree, tctx, &finfo);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "smb2_getinfo_file failed\n");
+
+       torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, fileid,
+                                     ret, done, "bad fileid\n");
+
+       f = (struct smb2_find) {
+               .in.file.handle = testdirh,
+               .in.pattern = "foo",
+               .in.max_response_size = 0x1000,
+               .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
+               .in.continue_flags = SMB2_CONTINUE_FLAG_RESTART,
+       };
+
+       status = smb2_find_level(tree, tree, &f, &count, &d);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "smb2_find_level failed\n");
+
+       torture_assert_u64_equal_goto(tctx,
+                                     d->id_both_directory_info.file_id,
+                                     fileid,
+                                     ret, done, "bad fileid\n");
+
+       status = smb2_util_write(tree, h1, "foo", 0, strlen("foo"));
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "smb2_util_write failed\n");
+
+       sinfo = (union smb_setfileinfo) {
+               .basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION,
+               .basic_info.in.file.handle = h1,
+       };
+       unix_to_nt_time(&sinfo.basic_info.in.write_time, time(NULL));
+
+       status = smb2_setinfo_file(tree, &sinfo);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "smb2_setinfo_file failed\n");
+
+       finfo = (union smb_fileinfo) {
+               .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
+               .generic.in.file.handle = h1,
+       };
+
+       status = smb2_getinfo_file(tree, tctx, &finfo);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "smb2_getinfo_file failed\n");
+
+       torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, fileid,
+                                     ret, done, "bad fileid\n");
+
+       smb2_util_close(tree, h1);
+
+       create = (struct smb2_create) {
+               .in.desired_access = SEC_FILE_ALL,
+               .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
+               .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
+               .in.create_disposition = NTCREATEX_DISP_OPEN,
+               .in.fname = fname,
+               .in.query_on_disk_id = true,
+       };
+
+       status = smb2_create(tree, tctx, &create);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "test file could not be created\n");
+       h1 = create.out.file.handle;
+
+       finfo = (union smb_fileinfo) {
+               .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
+               .generic.in.file.handle = h1,
+       };
+
+       status = smb2_getinfo_file(tree, tctx, &finfo);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "torture_smb2_testdir\n");
+
+       torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, fileid,
+                                     ret, done, "bad fileid\n");
+
+       f = (struct smb2_find) {
+               .in.file.handle = testdirh,
+               .in.pattern = "foo",
+               .in.max_response_size = 0x1000,
+               .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
+               .in.continue_flags = SMB2_CONTINUE_FLAG_RESTART,
+       };
+
+       status = smb2_find_level(tree, tree, &f, &count, &d);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "smb2_find_level failed\n");
+
+       torture_assert_u64_equal_goto(tctx,
+                                     d->id_both_directory_info.file_id,
+                                     fileid,
+                                     ret, done, "bad fileid\n");
+
+       smb2_util_close(tree, h1);
+
+done:
+       smb2_util_close(tree, testdirh);
+       smb2_deltree(tree, DNAME);
+       talloc_free(mem_ctx);
+       return ret;
+}
+
 /*
    basic testing of SMB2 read
 */
@@ -1942,3 +2140,17 @@ struct torture_suite *torture_smb2_twrp_init(TALLOC_CTX *ctx)
 
        return suite;
 }
+
+/*
+   basic testing of SMB2 File-IDs
+*/
+struct torture_suite *torture_smb2_fileid_init(TALLOC_CTX *ctx)
+{
+       struct torture_suite *suite = torture_suite_create(ctx, "fileid");
+
+       torture_suite_add_1smb2_test(suite, "fileid", test_fileid);
+
+       suite->description = talloc_strdup(suite, "SMB2-CREATE tests");
+
+       return suite;
+}
index e57dba3c1d94548d0a07c067e07a73e922dffa2b..7cca19e65d327db4da582db02228f98493b3d337 100644 (file)
@@ -155,6 +155,7 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx)
        torture_suite_add_suite(suite, torture_smb2_aio_delay_init(suite));
        torture_suite_add_suite(suite, torture_smb2_create_init(suite));
        torture_suite_add_suite(suite, torture_smb2_twrp_init(suite));
+       torture_suite_add_suite(suite, torture_smb2_fileid_init(suite));
        torture_suite_add_suite(suite, torture_smb2_acls_init(suite));
        torture_suite_add_suite(suite, torture_smb2_notify_init(suite));
        torture_suite_add_suite(suite, torture_smb2_notify_inotify_init(suite));