s4/torture: add a vfs_fruit unconversion test
authorRalph Boehme <slow@samba.org>
Fri, 5 Jul 2019 15:35:50 +0000 (17:35 +0200)
committerJeremy Allison <jra@samba.org>
Fri, 12 Jul 2019 21:31:30 +0000 (21:31 +0000)
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/selftest/tests.py
source4/torture/vfs/fruit.c
source4/torture/vfs/vfs.c

index 78f58bdb30c91acfe7cb6dd698826aa2f8e8f14d..aff51d67d4a428183e047a3b48c756f29780722a 100755 (executable)
@@ -499,6 +499,7 @@ vfs = [
     "vfs.fruit_file_id",
     "vfs.fruit_timemachine",
     "vfs.fruit_conversion",
+    "vfs.unfruit",
 ]
 
 tests = base + raw + smb2 + rpc + unix + local + rap + nbt + libsmbclient + idmap + vfs
@@ -623,6 +624,15 @@ for t in tests:
     elif t == "vfs.fruit_conversion":
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD --option=torture:share2=vfs_fruit_wipe_intentionally_left_blank_rfork --option=torture:delete_empty_adfiles=false', 'wipe_intentionally_left_blank_rfork')
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD --option=torture:share2=vfs_fruit_delete_empty_adfiles --option=torture:delete_empty_adfiles=true', 'delete_empty_adfiles')
+    elif t == "vfs.unfruit":
+        creds = '-U$USERNAME%$PASSWORD'
+        share2 = '--option=torture:share2=tmp'
+        netopt = '--option=torture:net=%s' % net
+        shareopt = '--option=torture:sharename'
+
+        plansmbtorture4testsuite(t, "nt4_dc:local", '//$SERVER_IP/vfs_fruit %s %s %s %s=%s' % (creds, share2, netopt, shareopt, 'vfs_fruit'), 'metadata_netatalk')
+        plansmbtorture4testsuite(t, "nt4_dc:local", '//$SERVER_IP/vfs_fruit_metadata_stream %s %s %s %s=%s' % (creds, share2, netopt, shareopt, 'vfs_fruit_metadata_stream'), 'metadata_stream')
+        plansmbtorture4testsuite(t, "nt4_dc:local", '//$SERVER_IP/vfs_fruit_stream_depot %s %s %s %s=%s' % (creds, share2, netopt, shareopt, 'vfs_fruit_stream_depot'), 'streams_depot')
     elif t == "rpc.schannel_anon_setpw":
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$%', description="anonymous password set")
         plansmbtorture4testsuite(t, "nt4_dc_schannel", '//$SERVER_IP/tmp -U$%', description="anonymous password set (schannel enforced server-side)")
index e3d8539595deff5d37f5aa2440dec8a999eb443a..3a6a198a658d074671841c31475802e3e3840d70 100644 (file)
@@ -7453,3 +7453,254 @@ struct torture_suite *torture_vfs_fruit_conversion(TALLOC_CTX *ctx)
 
        return suite;
 }
+
+/*
+ * The buf below contains the following AppleDouble encoded data:
+ *
+ * -----------------------------------------------------------------------------
+ * MagicNumber: 00051607                                        : AppleDouble
+ * Version    : 00020000                                        : Version 2
+ * Filler     : 4D 61 63 20 4F 53 20 58 20 20 20 20 20 20 20 20 : Mac OS X
+ * Num. of ent: 0002                                            : 2
+ *
+ * -----------------------------------------------------------------------------
+ * Entry ID   : 00000002 : Resource Fork
+ * Offset     : 0000009A : 154
+ * Length     : 00000004 : 4
+ *
+ * -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
+ * 00000000   : 62 61 72 00                                     : bar.
+ *
+ * -----------------------------------------------------------------------------
+ * Entry ID   : 00000009 : Finder Info
+ * Offset     : 00000032 : 50
+ * Length     : 00000068 : 104
+ *
+ * -FInfo-----:
+ * Type       : 464F4F20 : FOO
+ * Creator    : 42415220 : BAR
+ * isAlias    : 0
+ * Invisible  : 0
+ * hasBundle  : 0
+ * nameLocked : 0
+ * Stationery : 0
+ * CustomIcon : 0
+ * Reserved   : 0
+ * Inited     : 0
+ * NoINITS    : 0
+ * Shared     : 0
+ * SwitchLaunc: 0
+ * Hidden Ext : 0
+ * color      : 000      : none
+ * isOnDesk   : 0
+ * Location v : 0000     : 0
+ * Location h : 0000     : 0
+ * Fldr       : 0000     : ..
+ *
+ * -FXInfo----:
+ * Rsvd|IconID: 0000     : 0
+ * Rsvd       : 0000     : ..
+ * Rsvd       : 0000     : ..
+ * Rsvd       : 0000     : ..
+ * AreInvalid : 0
+ * unknown bit: 0
+ * unknown bit: 0
+ * unknown bit: 0
+ * unknown bit: 0
+ * unknown bit: 0
+ * unknown bit: 0
+ * CustomBadge: 0
+ * ObjctIsBusy: 0
+ * unknown bit: 0
+ * unknown bit: 0
+ * unknown bit: 0
+ * unknown bit: 0
+ * RoutingInfo: 0
+ * unknown bit: 0
+ * unknown bit: 0
+ * Rsvd|commnt: 0000     : 0
+ * PutAway    : 00000000 : 0
+ *
+ * -EA--------:
+ * pad        : 0000     :
+ * magic      : 41545452 : ATTR
+ * debug_tag  : 00000000 : 0
+ * total_size : 0000009A : 154
+ * data_start : 00000096 : 150
+ * data_length: 00000004 : 4
+ * reserved[0]: 00000000 : ....
+ * reserved[1]: 00000000 : ....
+ * reserved[2]: 00000000 : ....
+ * flags      : 0000     : ..
+ * num_attrs  : 0001     : 1
+ * -EA ENTRY--:
+ * offset     : 00000096 : 150
+ * length     : 00000004 : 4
+ * flags      : 0000     : ..
+ * namelen    : 13       : 19
+ * -EA NAME---:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
+ * 00000000   : 6F 72 67 2E 73 61 6D 62 61 EF 80 A2 77 6F 6F 68 : org.samba...wooh
+ * 00000010   : 6F 6F 00                                        : oo.
+ * -EA VALUE--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
+ * 00000000   : 62 61 72 00                                     : bar.
+ *
+ * -RAW DUMP--:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F : (ASCII)
+ * 00000000   : 46 4F 4F 20 42 41 52 20 00 00 00 00 00 00 00 00 : FOO BAR ........
+ * 00000010   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
+ * 00000020   : 00 00 41 54 54 52 00 00 00 00 00 00 00 9A 00 00 : baATTR..........
+ * 00000030   : 00 96 00 00 00 04 00 00 00 00 00 00 00 00 00 00 : ................
+ * 00000040   : 00 00 00 00 00 01 00 00 00 96 00 00 00 04 00 00 : ................
+ * 00000050   : 13 6F 72 67 2E 73 61 6D 62 61 EF 80 A2 77 6F 6F : .org.samba...woo
+ * 00000060   : 68 6F 6F 00 62 61 72 00                         : hoo.bar.
+ *
+ * It was created with:
+ *
+ * $ hexdump -ve '"\t" 7/1 "0x%02x, " 1/1 " 0x%02x," "\n"'
+ */
+static char unconvert_adfile_data[] = {
+       0x00, 0x05, 0x16, 0x07, 0x00, 0x02, 0x00, 0x00,
+       0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58,
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+       0x00, 0x98, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+       0x00, 0x09, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00,
+       0x00, 0x66, 0x46, 0x4f, 0x4f, 0x20, 0x42, 0x41,
+       0x52, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x41, 0x54, 0x54, 0x52,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+       0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x04,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+       0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x04,
+       0x00, 0x00, 0x11, 0x6f, 0x72, 0x67, 0x2e, 0x73,
+       0x61, 0x6d, 0x62, 0x61, 0x3a, 0x77, 0x6f, 0x6f,
+       0x68, 0x6f, 0x6f, 0x00, 0x62, 0x61, 0x72, 0x00,
+       0x62, 0x61, 0x72, 0x00
+};
+
+static bool test_unconvert(struct torture_context *tctx,
+                          struct smb2_tree *tree1,
+                          struct smb2_tree *tree2)
+{
+       const char *fname = BASEDIR "\\unconvert";
+       const char *adname = BASEDIR "\\._unconvert";
+       const char *net = NULL;
+       const char *share = NULL;
+       AfpInfo *afpi = NULL;
+       char *cmd = NULL;
+       struct smb2_handle h1;
+       union smb_fileinfo finfo;
+       size_t adsize;
+       NTSTATUS status;
+       int result;
+       bool ret = true;
+
+       torture_assert_not_null_goto(tctx, tree2, ret, done,
+                                    "Need a second share without fruit\n");
+
+       net = torture_setting_string(tctx, "net", NULL);
+       torture_assert_not_null_goto(tctx, net, ret, done,
+                                    "Need path to 'net'");
+
+       share = torture_setting_string(tctx, "sharename", NULL);
+       torture_assert_not_null_goto(tctx, share, ret, done,
+                                    "Need sharename");
+
+       torture_comment(tctx, "Testing unconvert\n");
+
+       smb2_deltree(tree1, BASEDIR);
+
+       status = torture_smb2_testdir(tree1, BASEDIR, &h1);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "torture_smb2_testdir\n");
+       smb2_util_close(tree1, h1);
+
+       ret = torture_setup_file(tctx, tree1, fname, false);
+       torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
+
+       afpi = torture_afpinfo_new(tctx);
+       torture_assert_not_null_goto(tctx, afpi, ret, done,
+                                    "torture_afpinfo_new failed\n");
+
+       memcpy(afpi->afpi_FinderInfo, "FOO BAR ", 8);
+
+       ret = torture_write_afpinfo(tree1, tctx, tctx, fname, afpi);
+       torture_assert_goto(tctx, ret == true, ret, done,
+                           "torture_write_afpinfo failed\n");
+
+       ret = write_stream(tree1, __location__, tctx, tctx,
+                          fname,
+                          /*
+                           * \xef\x80\xa2 is ':' mapped to Unicoe private range
+                           */
+                          ":org.samba" "\xef\x80\xa2" "woohoo",
+                          0, 4, "bar");
+       torture_assert_goto(tctx, ret == true, ret, done,
+                           "write_stream failed\n");
+
+       ret = write_stream(tree1, __location__, tctx, tctx,
+                          fname, AFPRESOURCE_STREAM_NAME,
+                          0, 4, "bar");
+       torture_assert_goto(tctx, ret == true, ret, done,
+                           "write_stream failed\n");
+
+       cmd = talloc_asprintf(tctx,
+                             "%s --recursive vfs stream2adouble %s %s/",
+                             net,
+                             share,
+                             BASEDIR);
+       torture_assert_not_null_goto(tctx, cmd, ret, done,
+                                    "talloc_asprintf failed\n");
+
+       torture_comment(tctx, "cmd: %s\n", cmd);
+
+       result = system(cmd);
+       torture_assert_int_equal_goto(tctx, result, 0, ret, done,
+                           "command failed\n");
+
+       status = torture_smb2_testfile(tree2, adname, &h1);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "torture_smb2_testfile failed\n");
+
+       finfo = (union smb_fileinfo) {
+               .generic.level = RAW_FILEINFO_ALL_INFORMATION,
+               .generic.in.file.handle = h1,
+       };
+
+       status = smb2_getinfo_file(tree2, tctx, &finfo);
+       torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+                                       "torture_smb2_testdir\n");
+       smb2_util_close(tree2, h1);
+
+       adsize = finfo.all_info.out.size;
+       torture_assert_int_equal_goto(tctx, adsize,
+                                     sizeof(unconvert_adfile_data),
+                                     ret, done, "wrong size\n");
+
+       ret = check_stream(tree2, __location__, tctx, tctx,
+                          adname, "", 0, adsize, 0, adsize,
+                          unconvert_adfile_data);
+       torture_assert_goto(tctx, ret == true, ret, done,
+                           "check_stream failed\n");
+
+done:
+//     smb2_deltree(tree1, BASEDIR);
+       return ret;
+}
+
+struct torture_suite *torture_vfs_fruit_unfruit(TALLOC_CTX *ctx)
+{
+       struct torture_suite *suite = torture_suite_create(
+               ctx, "unfruit");
+
+       suite->description = talloc_strdup(
+               suite, "test converting back to AppleDouble");
+
+       torture_suite_add_2ns_smb2_test(suite,
+                                       "unconvert",
+                                       test_unconvert);
+
+       return suite;
+}
index 39cd573c9d6e88016c63e592eddd48446c838114..c26e31f147a84444824437832b47d2100ca2a7a1 100644 (file)
@@ -114,6 +114,7 @@ NTSTATUS torture_vfs_init(TALLOC_CTX *ctx)
        torture_suite_add_suite(suite, torture_vfs_fruit_file_id(suite));
        torture_suite_add_suite(suite, torture_vfs_fruit_timemachine(suite));
        torture_suite_add_suite(suite, torture_vfs_fruit_conversion(suite));
+       torture_suite_add_suite(suite, torture_vfs_fruit_unfruit(suite));
 
        torture_register_suite(ctx, suite);