The branch, master has been updated
       via  1da1720 vfs_fruit: proper VFS-stackable conversion of FinderInfo
       via  84976cb vfs_fruit: add AfpInfo prototypes
       via  7b00b55 s4/torture: fruit: in test_adouble_conversion() also check 
stream list and AFPINFO_STREAM
       via  ebbffd8 s4/torture: fruit: remove use of localdir from 
test_adouble_conversion test
       via  3f9b45a selftest: add "fruit:veto_appledouble = no" to fruit shares
       via  ac88084 s4/torture: let write_stream() deal with stream=NULL
       via  e28dd6a selftest: run AppleDouble sidecar-file conversion test runs 
against all fruit shares
       via  9af9c5c s4/torture: use torture_assert_goto in a vfs.fruit test
       via  75a3c0f s4/torture: rework stream names tests usage of local xattr 
call
       via  3c1bdaf selftest: add localdir option to fruit subtests
       via  06542b2 selftest: reorder arguments for fruit tests
      from  8b6f581 systemd: Start processes in forground and without a process 
group

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 1da17204344a99a3bfa289355a996027a21814b8
Author: Ralph Boehme <[email protected]>
Date:   Wed Nov 15 16:52:48 2017 +0100

    vfs_fruit: proper VFS-stackable conversion of FinderInfo
    
    This fixes the problem that conversion failed with
    fruit:metadata=stream. Before we were calling ad_set() which stores the
    metadata in the Netatalk compatible format.
    
    Rewrite to fully go through the VFS by calling SMB_VFS_CREATE_FILE() and
    SMB_VFS_PWRITE().
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13155
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    
    Autobuild-User(master): Jeremy Allison <[email protected]>
    Autobuild-Date(master): Wed Nov 29 08:38:06 CET 2017 on sn-devel-144

commit 84976cb670847f199598995d48bd9c3f3dd0f035
Author: Ralph Boehme <[email protected]>
Date:   Wed Nov 15 16:52:16 2017 +0100

    vfs_fruit: add AfpInfo prototypes
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13155
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 7b00b558761b6564928289efcf835e9b9cc86a89
Author: Ralph Boehme <[email protected]>
Date:   Fri Nov 17 12:57:14 2017 +0100

    s4/torture: fruit: in test_adouble_conversion() also check stream list and 
AFPINFO_STREAM
    
    This reveals that the conversion doesn't work properly with
    fruit:metadata=stream.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13155
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit ebbffd80862d7d7b025eca219bc0c8f818585ac9
Author: Ralph Boehme <[email protected]>
Date:   Fri Nov 17 12:53:42 2017 +0100

    s4/torture: fruit: remove use of localdir from test_adouble_conversion test
    
    The previous use of localdir and torture_setup_local_file() was
    motivated by the fact that by default vfs_fruit rejects access to files
    with a "._" prefix.
    
    Since a previous commit allowed SMB access to ._ files, rewrite the
    test_adouble_conversion() test to create the ._ AppleDouble file over
    SMB.
    
    This also renders torture_setup_local_file() obsolete.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13155
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 3f9b45a410384904d64bdd0d68ff2a5bc25bd3e9
Author: Ralph Boehme <[email protected]>
Date:   Fri Nov 17 13:52:25 2017 +0100

    selftest: add "fruit:veto_appledouble = no" to fruit shares
    
    This is needed for a subsequent commit that modifies an existing test to
    write a ._ file over SMB instead of using the ugly local creation hack.
    
    SMB acces of ._ files requires "fruit:veto_appledouble = no", so let's
    set it.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13155
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit ac880848a905a3840b69af2cb1d842d307401a07
Author: Ralph Boehme <[email protected]>
Date:   Fri Nov 17 08:13:10 2017 +0100

    s4/torture: let write_stream() deal with stream=NULL
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13155
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit e28dd6a0ce753a880b2512eb62661411b20f763b
Author: Ralph Boehme <[email protected]>
Date:   Wed Nov 15 18:39:53 2017 +0100

    selftest: run AppleDouble sidecar-file conversion test runs against all 
fruit shares
    
    This needs for work in all possible fruit configs, so test it.
    
    This currently fails with stream_depot, as we don't propely copy over
    the resourcefork data from the ._ file to the stream.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13155
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 9af9c5c073d88b126aebd4a2d7a1a1971527fbf4
Author: Ralph Boehme <[email protected]>
Date:   Fri Nov 17 12:41:49 2017 +0100

    s4/torture: use torture_assert_goto in a vfs.fruit test
    
    No change in behavior.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13155
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 75a3c0f3b1f843ba9a7838aa7a1c311fc262f8c7
Author: Ralph Boehme <[email protected]>
Date:   Thu Nov 16 07:58:34 2017 +0100

    s4/torture: rework stream names tests usage of local xattr call
    
    Previously this test, that tests for correct conversion of ':' in stream
    names, only worked with streams_xattr with "fruit:metadata" set to
    "netatalk".
    
    In order to have test coverage for fruit shares with other configs,
    split the test into two:
    
    one test creates the stream over SMB and run against all shares, the
    other one is the unmodified existing test and is only run against the
    share with streams_xattr and fruit:metadata=netatalk.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13155
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 3c1bdafde6419c266941624f57cf768e57e2bd98
Author: Ralph Boehme <[email protected]>
Date:   Wed Nov 15 18:38:41 2017 +0100

    selftest: add localdir option to fruit subtests
    
    A subsequent commits modifies an existing tests that needs $localdir to
    also run against "vfs_fruit_metadata_stream" and
    "vfs_fruit_stream_depot". This reveals test failures, those will be
    fixed in a subsequent commit.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13155
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 06542b2c4c000e5397f0990713de7f7bb67cc0bd
Author: Ralph Boehme <[email protected]>
Date:   Wed Nov 15 18:36:54 2017 +0100

    selftest: reorder arguments for fruit tests
    
    This just puts the auth option first matching the first test with the
    "vfs_fruit" share directly above the modified lines.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13155
    
    Signed-off-by: Ralph Boehme <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 selftest/knownfail.d/samba3.vfs.fruit |   1 +
 selftest/target/Samba3.pm             |   3 +
 source3/modules/vfs_fruit.c           |  93 +++++++++++++---
 source3/selftest/tests.py             |   4 +-
 source4/torture/vfs/fruit.c           | 198 +++++++++++++++++++---------------
 5 files changed, 198 insertions(+), 101 deletions(-)
 create mode 100644 selftest/knownfail.d/samba3.vfs.fruit


Changeset truncated at 500 lines:

diff --git a/selftest/knownfail.d/samba3.vfs.fruit 
b/selftest/knownfail.d/samba3.vfs.fruit
new file mode 100644
index 0000000..8df25bc
--- /dev/null
+++ b/selftest/knownfail.d/samba3.vfs.fruit
@@ -0,0 +1 @@
+^samba3.vfs.fruit streams_depot.OS X AppleDouble file conversion\(nt4_dc\)
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index f0e6a63..afbc795 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -1926,18 +1926,21 @@ sub provision($$$$$$$$$)
        fruit:metadata = netatalk
        fruit:locking = netatalk
        fruit:encoding = native
+       fruit:veto_appledouble = no
 
 [vfs_fruit_metadata_stream]
        path = $shrdir
        vfs objects = fruit streams_xattr acl_xattr
        fruit:resource = file
        fruit:metadata = stream
+       fruit:veto_appledouble = no
 
 [vfs_fruit_stream_depot]
        path = $shrdir
        vfs objects = fruit streams_depot acl_xattr
        fruit:resource = stream
        fruit:metadata = stream
+       fruit:veto_appledouble = no
 
 [vfs_wo_fruit]
        path = $shrdir
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 15e42fb..05a5d39 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -482,6 +482,10 @@ static int ad_fset(struct adouble *ad, files_struct *fsp);
 static int adouble_path(TALLOC_CTX *ctx,
                        const struct smb_filename *smb_fname__in,
                        struct smb_filename **ppsmb_fname_out);
+static AfpInfo *afpinfo_new(TALLOC_CTX *ctx);
+static ssize_t afpinfo_pack(const AfpInfo *ai, char *buf);
+static AfpInfo *afpinfo_unpack(TALLOC_CTX *ctx, const void *data);
+
 
 /**
  * Return a pointer to an AppleDouble entry
@@ -1297,12 +1301,17 @@ static ssize_t ad_read_rsrc_xattr(struct adouble *ad)
 static ssize_t ad_read_rsrc_adouble(struct adouble *ad,
                                const struct smb_filename *smb_fname)
 {
-       struct adouble *meta_ad = NULL;
        SMB_STRUCT_STAT sbuf;
        char *p_ad = NULL;
-       char *p_meta_ad = NULL;
+       AfpInfo *ai = NULL;
+       DATA_BLOB aiblob;
+       struct smb_filename *stream_name = NULL;
+       files_struct *fsp = NULL;
        ssize_t len;
        size_t size;
+       ssize_t nwritten;
+       NTSTATUS status;
+       int saved_errno = 0;
        int ret;
        bool ok;
 
@@ -1387,29 +1396,85 @@ static ssize_t ad_read_rsrc_adouble(struct adouble *ad,
                return -1;
        }
 
-       meta_ad = ad_init(talloc_tos(), ad->ad_handle, ADOUBLE_META);
-       if (meta_ad == NULL) {
+       p_ad = ad_get_entry(ad, ADEID_FINDERI);
+       if (p_ad == NULL) {
                return -1;
        }
 
-       p_ad = ad_get_entry(ad, ADEID_FINDERI);
-       if (p_ad == NULL) {
-               TALLOC_FREE(meta_ad);
+       ai = afpinfo_new(talloc_tos());
+       if (ai == NULL) {
+               return -1;
+       }
+
+       memcpy(ai->afpi_FinderInfo, p_ad, ADEDLEN_FINDERI);
+
+       aiblob = data_blob_talloc(talloc_tos(), NULL, AFP_INFO_SIZE);
+       if (aiblob.data == NULL) {
+               TALLOC_FREE(ai);
+               return -1;
+       }
+
+       size = afpinfo_pack(ai, (char *)aiblob.data);
+       TALLOC_FREE(ai);
+       if (size != AFP_INFO_SIZE) {
                return -1;
        }
-       p_meta_ad = ad_get_entry(meta_ad, ADEID_FINDERI);
-       if (p_meta_ad == NULL) {
-               TALLOC_FREE(meta_ad);
+
+       stream_name = synthetic_smb_fname(talloc_tos(),
+                                         smb_fname->base_name,
+                                         AFPINFO_STREAM,
+                                         NULL,
+                                         smb_fname->flags);
+       if (stream_name == NULL) {
+               data_blob_free(&aiblob);
+               DBG_ERR("synthetic_smb_fname failed\n");
                return -1;
        }
 
-       memcpy(p_meta_ad, p_ad, ADEDLEN_FINDERI);
+       DBG_DEBUG("stream_name: %s\n", smb_fname_str_dbg(stream_name));
 
-       ret = ad_set(meta_ad, smb_fname);
-       TALLOC_FREE(meta_ad);
-       if (ret != 0) {
+       status = SMB_VFS_CREATE_FILE(
+               ad->ad_handle->conn,            /* conn */
+               NULL,                           /* req */
+               0,                              /* root_dir_fid */
+               stream_name,                    /* fname */
+               FILE_GENERIC_WRITE,             /* access_mask */
+               FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */
+               FILE_OPEN_IF,                   /* create_disposition */
+               0,                              /* create_options */
+               0,                              /* file_attributes */
+               INTERNAL_OPEN_ONLY,             /* oplock_request */
+               NULL,                           /* lease */
+               0,                              /* allocation_size */
+               0,                              /* private_flags */
+               NULL,                           /* sd */
+               NULL,                           /* ea_list */
+               &fsp,                           /* result */
+               NULL,                           /* psbuf */
+               NULL, NULL);                    /* create context */
+       TALLOC_FREE(stream_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("SMB_VFS_CREATE_FILE failed\n");
+               return -1;
+       }
+
+       nwritten = SMB_VFS_PWRITE(fsp,
+                                 aiblob.data,
+                                 aiblob.length,
+                                 0);
+       if (nwritten == -1) {
+               DBG_ERR("SMB_VFS_PWRITE failed\n");
+               saved_errno = errno;
+               close_file(NULL, fsp, ERROR_CLOSE);
+               errno = saved_errno;
+               return -1;
+       }
+
+       status = close_file(NULL, fsp, NORMAL_CLOSE);
+       if (!NT_STATUS_IS_OK(status)) {
                return -1;
        }
+       fsp = NULL;
 
        return len;
 }
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 3e5cffd..b16416c 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -486,8 +486,8 @@ for t in tests:
         plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp 
-U$USERNAME%$PASSWORD')
     elif t == "vfs.fruit":
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/vfs_fruit 
-U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/nt4_dc/share 
--option=torture:share2=vfs_wo_fruit', 'metadata_netatalk')
-        plansmbtorture4testsuite(t, "nt4_dc", 
'//$SERVER_IP/vfs_fruit_metadata_stream --option=torture:share2=vfs_wo_fruit 
-U$USERNAME%$PASSWORD', 'metadata_stream')
-        plansmbtorture4testsuite(t, "nt4_dc", 
'//$SERVER_IP/vfs_fruit_stream_depot 
--option=torture:share2=vfs_wo_fruit_stream_depot -U$USERNAME%$PASSWORD', 
'streams_depot')
+        plansmbtorture4testsuite(t, "nt4_dc", 
'//$SERVER_IP/vfs_fruit_metadata_stream -U$USERNAME%$PASSWORD 
--option=torture:localdir=$SELFTEST_PREFIX/nt4_dc/share 
--option=torture:share2=vfs_wo_fruit', 'metadata_stream')
+        plansmbtorture4testsuite(t, "nt4_dc", 
'//$SERVER_IP/vfs_fruit_stream_depot -U$USERNAME%$PASSWORD 
--option=torture:localdir=$SELFTEST_PREFIX/nt4_dc/share 
--option=torture:share2=vfs_wo_fruit_stream_depot', 'streams_depot')
     elif t == "vfs.fruit_netatalk":
         plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/vfs_fruit 
-U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/nt4_dc/share')
     elif t == "vfs.fruit_file_id":
diff --git a/source4/torture/vfs/fruit.c b/source4/torture/vfs/fruit.c
index ace561d..04f04e2 100644
--- a/source4/torture/vfs/fruit.c
+++ b/source4/torture/vfs/fruit.c
@@ -1140,7 +1140,7 @@ static bool write_stream(struct smb2_tree *tree,
        NTSTATUS status;
        const char *full_name;
 
-       full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname);
+       full_name = talloc_asprintf(mem_ctx, "%s%s", fname, sname ? sname : "");
        if (full_name == NULL) {
            torture_comment(tctx, "talloc_asprintf error\n");
            return false;
@@ -1210,49 +1210,6 @@ static bool torture_setup_local_xattr(struct 
torture_context *tctx,
        return ret;
 }
 
-static bool torture_setup_local_file(struct torture_context *tctx,
-                                    const char *path_option,
-                                    const char *name,
-                                    const char *buf,
-                                    size_t size)
-{
-       int fd;
-       const char *spath;
-       char *path;
-       ssize_t rsize;
-
-       spath = torture_setting_string(tctx, path_option, NULL);
-       if (spath == NULL) {
-               printf("No sharepath for option %s\n", path_option);
-               return false;
-       }
-
-       path = talloc_asprintf(tctx, "%s/%s", spath, name);
-       if (path == NULL) {
-               return false;
-       }
-
-       fd = creat(path, S_IRWXU);
-       TALLOC_FREE(path);
-       if (fd == -1) {
-               return false;
-       }
-
-       if ((buf == NULL) || (size == 0)) {
-               close(fd);
-               return true;
-       }
-
-       rsize = write(fd, buf, size);
-       if (rsize != size) {
-               return false;
-       }
-
-       close(fd);
-
-       return true;
-}
-
 /**
  * Create a file or directory
  **/
@@ -1996,50 +1953,63 @@ static bool test_adouble_conversion(struct 
torture_context *tctx,
 {
        TALLOC_CTX *mem_ctx = talloc_new(tctx);
        const char *fname = BASEDIR "\\test_adouble_conversion";
-       const char *fname_local = BASEDIR "/test_adouble_conversion";
-       const char *adname_local = BASEDIR "/._test_adouble_conversion";
+       const char *adname = BASEDIR "/._test_adouble_conversion";
        NTSTATUS status;
        struct smb2_handle testdirh;
        bool ret = true;
        const char *data = "This resource fork intentionally left blank";
        size_t datalen = strlen(data);
-       const char *localdir = NULL;
-
-       localdir = torture_setting_string(tctx, "localdir", NULL);
-       if (localdir == NULL) {
-               torture_skip(tctx, "Need localdir for test");
-       }
+       const char *streams[] = {
+               "::$DATA",
+               AFPINFO_STREAM,
+               AFPRESOURCE_STREAM,
+               ":com.apple.metadata" "\xef\x80\xa2" "_kMDItemUserTags:$DATA",
+               ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
+       };
 
-       smb2_util_unlink(tree, fname);
+       smb2_deltree(tree, BASEDIR);
 
        status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
        CHECK_STATUS(status, NT_STATUS_OK);
        smb2_util_close(tree, testdirh);
 
-       ret = torture_setup_local_file(tctx, "localdir", fname_local,
-                                      NULL, 0);
-       if (ret == false) {
-               goto done;
-       }
+       ret = torture_setup_file(tctx, tree, fname, false);
+       torture_assert_goto(tctx, ret == true, ret, done,
+                           "torture_setup_file failed\n");
 
-       ret = torture_setup_local_file(tctx, "localdir", adname_local,
-                                      osx_adouble_w_xattr,
-                                      sizeof(osx_adouble_w_xattr));
-       if (ret == false) {
-               goto done;
-       }
+       ret = torture_setup_file(tctx, tree, adname, false);
+       torture_assert_goto(tctx, ret == true, ret, done,
+                           "torture_setup_file failed\n");
+
+       ret = write_stream(tree, __location__, tctx, mem_ctx,
+                          adname, NULL,
+                          0, sizeof(osx_adouble_w_xattr), osx_adouble_w_xattr);
+       torture_assert_goto(tctx, ret == true, ret, done,
+                           "write_stream failed\n");
 
        torture_comment(tctx, "(%s) test OS X AppleDouble conversion\n",
            __location__);
 
-       ret &= check_stream(tree, __location__, tctx, mem_ctx,
-                           fname, AFPRESOURCE_STREAM,
-                           16, datalen, 0, datalen, data);
+       ret = check_stream(tree, __location__, tctx, mem_ctx,
+                          fname, AFPRESOURCE_STREAM,
+                          16, datalen, 0, datalen, data);
+       torture_assert_goto(tctx, ret == true, ret, done,
+                           "check AFPRESOURCE_STREAM failed\n");
 
-       ret &= check_stream(tree, __location__, tctx, mem_ctx,
-                           fname,
-                           ":foo" "\xef\x80\xa2" "bar:$DATA", /* 
"foo:bar:$DATA" */
-                           0, 3, 0, 3, "baz");
+       ret = check_stream(tree, __location__, tctx, mem_ctx,
+                          fname, AFPINFO_STREAM,
+                          0, 60, 16, 8, "TESTSLOW");
+       torture_assert_goto(tctx, ret == true, ret, done,
+                           "check AFPINFO_STREAM failed\n");
+
+       ret = check_stream(tree, __location__, tctx, mem_ctx, fname,
+                          ":foo" "\xef\x80\xa2" "bar:$DATA", /* 
"foo:bar:$DATA" */
+                          0, 3, 0, 3, "baz");
+       torture_assert_goto(tctx, ret == true, ret, done,
+                           "check foo:bar stream failed\n");
+
+       ret = check_stream_list(tree, tctx, fname, 5, streams, false);
+       torture_assert_goto(tctx, ret == true, ret, done, "check_stream_list");
 
 done:
        smb2_deltree(tree, BASEDIR);
@@ -2867,15 +2837,8 @@ static bool test_stream_names(struct torture_context 
*tctx,
        /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
        const char *streams[] = {
                ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
-               ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
                "::$DATA"
        };
-       const char *localdir = NULL;
-
-       localdir = torture_setting_string(tctx, "localdir", NULL);
-       if (localdir == NULL) {
-               torture_skip(tctx, "Need localdir for test");
-       }
 
        sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
 
@@ -2904,12 +2867,7 @@ static bool test_stream_names(struct torture_context 
*tctx,
        CHECK_STATUS(status, NT_STATUS_OK);
        smb2_util_close(tree, create.out.file.handle);
 
-       ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR 
"/stream_names.txt",
-                                       "user.DosStream.bar:baz:$DATA",
-                                       "data", strlen("data"));
-       CHECK_VALUE(ret, true);
-
-       ret = check_stream_list(tree, tctx, fname, 3, streams, false);
+       ret = check_stream_list(tree, tctx, fname, 2, streams, false);
        CHECK_VALUE(ret, true);
 
 done:
@@ -4024,6 +3982,9 @@ static bool test_readdir_attr_illegal_ntfs(struct 
torture_context *tctx,
 
                if (!strcmp(found, ".") || !strcmp(found, ".."))
                        continue;
+               if (strncmp(found, "._", 2) == 0) {
+                       continue;
+               }
                break;
        }
 
@@ -4422,10 +4383,77 @@ struct torture_suite *torture_vfs_fruit(TALLOC_CTX *ctx)
        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);
+       torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", 
test_adouble_conversion);
 
        return suite;
 }
 
+static bool test_stream_names_local(struct torture_context *tctx,
+                                   struct smb2_tree *tree)
+{
+       TALLOC_CTX *mem_ctx = talloc_new(tctx);
+       NTSTATUS status;
+       struct smb2_create create;
+       struct smb2_handle h;
+       const char *fname = BASEDIR "\\stream_names.txt";
+       const char *sname1;
+       bool ret;
+       /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */
+       const char *streams[] = {
+               ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */
+               ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */
+               "::$DATA"
+       };
+       const char *localdir = NULL;
+
+       localdir = torture_setting_string(tctx, "localdir", NULL);
+       if (localdir == NULL) {
+               torture_skip(tctx, "Need localdir for test");
+       }
+
+       sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]);
+
+       /* clean slate ...*/
+       smb2_util_unlink(tree, fname);
+       smb2_deltree(tree, fname);
+       smb2_deltree(tree, BASEDIR);
+
+       status = torture_smb2_testdir(tree, BASEDIR, &h);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       smb2_util_close(tree, h);
+
+       torture_comment(tctx, "(%s) testing stream names\n", __location__);
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_FILE_WRITE_DATA;
+       create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       create.in.share_access =
+               NTCREATEX_SHARE_ACCESS_DELETE|
+               NTCREATEX_SHARE_ACCESS_READ|
+               NTCREATEX_SHARE_ACCESS_WRITE;
+       create.in.create_disposition = NTCREATEX_DISP_CREATE;
+       create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
+       create.in.fname = sname1;
+
+       status = smb2_create(tree, mem_ctx, &create);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       smb2_util_close(tree, create.out.file.handle);
+
+       ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR 
"/stream_names.txt",
+                                       "user.DosStream.bar:baz:$DATA",
+                                       "data", strlen("data"));
+       CHECK_VALUE(ret, true);
+
+       ret = check_stream_list(tree, tctx, fname, 3, streams, false);
+       CHECK_VALUE(ret, true);
+
+done:
+       status = smb2_util_unlink(tree, fname);
+       smb2_deltree(tree, BASEDIR);
+       talloc_free(mem_ctx);
+
+       return ret;
+}
+
 struct torture_suite *torture_vfs_fruit_netatalk(TALLOC_CTX *ctx)
 {
        struct torture_suite *suite = torture_suite_create(
@@ -4434,7 +4462,7 @@ struct torture_suite 
*torture_vfs_fruit_netatalk(TALLOC_CTX *ctx)
        suite->description = talloc_strdup(suite, "vfs_fruit tests for Netatalk 
interop that require fruit:metadata=netatalk");
 
        torture_suite_add_1smb2_test(suite, "read netatalk metadata", 
test_read_netatalk_metadata);
-       torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", 
test_adouble_conversion);
+       torture_suite_add_1smb2_test(suite, "stream names with locally created 
xattr", test_stream_names_local);
 
        return suite;
 }


-- 
Samba Shared Repository

Reply via email to