]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
vfs_fruit: proper VFS-stackable conversion of FinderInfo
authorRalph Boehme <slow@samba.org>
Wed, 15 Nov 2017 15:52:48 +0000 (16:52 +0100)
committerKarolin Seeger <kseeger@samba.org>
Tue, 5 Dec 2017 09:32:11 +0000 (10:32 +0100)
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 <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Wed Nov 29 08:38:06 CET 2017 on sn-devel-144

(backported from commit 1da17204344a99a3bfa289355a996027a21814b8)

selftest/knownfail
source3/modules/vfs_fruit.c

index b6a9e6d0766b4596afdd27ddc139ee64d51d2e5c..6e1d0589922d4c1d9e1fe51949f0513dc8dc41d7 100644 (file)
 ^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_rank_none.*
 ^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_security_descriptor.*
 ^samba3.vfs.fruit streams_depot.OS X AppleDouble file conversion\(nt4_dc\)
-^samba3.vfs.fruit metadata_stream.OS X AppleDouble file conversion\(nt4_dc\)
index d038e59f184ffaaa54290fd931a216c661ee7f6c..f7e57d095c904ce44bf475e0a58da8676426c859 100644 (file)
@@ -1287,12 +1287,17 @@ static ssize_t ad_read_rsrc_xattr(struct adouble *ad,
 static ssize_t ad_read_rsrc_adouble(struct adouble *ad,
                                    const char *path)
 {
-       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;
 
@@ -1375,29 +1380,84 @@ 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;
        }
-       p_meta_ad = ad_get_entry(meta_ad, ADEID_FINDERI);
-       if (p_meta_ad == NULL) {
-               TALLOC_FREE(meta_ad);
+
+       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;
        }
 
-       memcpy(p_meta_ad, p_ad, ADEDLEN_FINDERI);
+       size = afpinfo_pack(ai, (char *)aiblob.data);
+       TALLOC_FREE(ai);
+       if (size != AFP_INFO_SIZE) {
+               return -1;
+       }
 
-       ret = ad_set(meta_ad, path);
-       TALLOC_FREE(meta_ad);
-       if (ret != 0) {
+       stream_name = synthetic_smb_fname(talloc_tos(),
+                                         path,
+                                         AFPINFO_STREAM,
+                                         NULL, 0);
+       if (stream_name == NULL) {
+               data_blob_free(&aiblob);
+               DBG_ERR("synthetic_smb_fname failed\n");
+               return -1;
+       }
+
+       DBG_DEBUG("stream_name: %s\n", smb_fname_str_dbg(stream_name));
+
+       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;
 }