[SCM] Samba Shared Repository - branch master updated

Ralph Böhme slow at samba.org
Wed Oct 10 23:31:02 UTC 2018


The branch, master has been updated
       via  31daab8 vfs_fruit: move check in ad_convert() to ad_convert_*() subfunctions
       via  9cf087a vfs_fruit: make call to ad_convert_truncate() optional
       via  acb72c1 vfs_fruit: add out arg "converted_xattr" to ad_convert_xattr
       via  5598e6b vfs_fruit: add check for OS X filler in FinderInfo conversion
       via  70d3ae5 vfs_fruit: call ad_convert_move_reso() from ad_convert_xattr()
       via  1692ca5 vfs_fruit: let the ad_convert_*() subfunction update the on-disk AppleDoube header as needed
       via  918c6c5 vfs_fruit: let the ad_convert_*() subfunctions mmap as needed
       via  f91e0c8 vfs_fruit: fix error returns in ad_convert_xattr()
       via  93b7e05 vfs_fruit: use ADEDOFF_RFORK_DOT_UND offset macro in ad_convert_move_reso()
       via  4c7e1de vfs_fruit: split out moving of the resource fork
       via  b948681 vfs_fruit: use ADEDOFF_RFORK_DOT_UND offset macro in ad_convert_truncate()
       via  98bd7c0 vfs_fruit: split out truncating from ad_convert()
       via  4f1174b vfs_fruit: move FinderInfo lenght check to ad_convert()
       via  d27d032 vfs_fruit: move FinderInfo conversion to helper function and call it from ad_convert()
       via  b355a09 vfs_fruit: move storing of modified struct adouble to ad_convert()
       via  99cc9ef vfs_fruit: remove unneeded fd argument from ad_convert()
       via  8bc36d7 vfs_fruit: do direct return from error checks in ad_convert()
       via  d161e04 vfs_fruit: move setting ADEID_FINDERI length to ad_convert_xattr()
       via  8ee7e61 vfs_fruit: store filler bytes from AppleDouble file header in struct adouble
       via  7e010ab vfs_fruit: fix two comments
       via  8b97284 s4:torture: FinderInfo conversion test with AppleDouble without xattr data
      from  131f98e tests/python/ldap: use int instead of long for time_t

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


- Log -----------------------------------------------------------------
commit 31daab88e6a415e72ead69844e3eccf5dc02e53c
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Oct 9 10:15:37 2018 +0200

    vfs_fruit: move check in ad_convert() to ad_convert_*() subfunctions
    
    Currently the whole conversion is skipped if the FinderInfo entry in the
    AppleDouble file is of the default size (ie not containing xattrs).
    
    That also means we never converted FinderInfo from the AppleDouble file
    to stream format. This change finally fixes this.
    
    Note that this keeps failing with streams_depot, much like the existing
    known-fail of "samba3.vfs.fruit streams_depot.OS X AppleDouble file
    conversion". Fixing the conversion to work with vfs_streams_depot is a
    task for another day.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Thu Oct 11 01:30:13 CEST 2018 on sn-devel-144

commit 9cf087a474bb2d7d29ca0daeaef412f6b545d0e0
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Oct 8 18:47:32 2018 +0200

    vfs_fruit: make call to ad_convert_truncate() optional
    
    Call ad_convert_truncate() based on whether the previous call
    ad_convert_xattr() returned converted_xattr=true.
    
    Upcoming fixes for a different Samba bug (#13642) will hook into calling
    ad_convert_truncate() in other cases, this also prepares for that.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit acb72c1ea7fecc9a7e8eb0219096b1bbdfd8850e
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Oct 8 18:43:51 2018 +0200

    vfs_fruit: add out arg "converted_xattr" to ad_convert_xattr
    
    Used to let the caller know if a conversion has been done. Currently not
    used in the caller, that comes next.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 5598e6bc3583a88f474afa2996d1f9362d1bd9fb
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Oct 8 12:51:37 2018 +0200

    vfs_fruit: add check for OS X filler in FinderInfo conversion
    
    This ensures that the function only acts on AppleDouble files created by
    macOS and not AppleDouble files created by us that are already in the
    correct format (only using the Resource Fork).
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 70d3ae5a89fc62db192c44b92a5b7fb67a93d88e
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Oct 5 22:05:43 2018 +0200

    vfs_fruit: call ad_convert_move_reso() from ad_convert_xattr()
    
    ad_convert_xattr() is the place that triggers the need to move the
    resource fork, so it should also call ad_convert_move_reso().
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 1692ca5fd8ae2560dae6828f3c5c05a65c530726
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Oct 5 17:07:45 2018 +0200

    vfs_fruit: let the ad_convert_*() subfunction update the on-disk AppleDoube header as needed
    
    Another step in simplifying ad_convert() itself. It means that we may
    write to disk twice, but is only ever done once per AppleDouble file.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 918c6c59901d0bf939dcc178b661b6ae8201e903
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Oct 5 16:59:18 2018 +0200

    vfs_fruit: let the ad_convert_*() subfunctions mmap as needed
    
    This may mean that we mmap twice when we convert an AppleDouble file,
    but this is the only sane way to cleanly modularize ad_convert().
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit f91e0c857a5a44a5eab7696fafda758044739978
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Oct 5 16:52:32 2018 +0200

    vfs_fruit: fix error returns in ad_convert_xattr()
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 93b7e0562159eae40e196f6be8d82283f0be2888
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Oct 5 19:15:04 2018 +0200

    vfs_fruit: use ADEDOFF_RFORK_DOT_UND offset macro in ad_convert_move_reso()
    
    We really want the fixed size offset here, not a calculated one. Note
    that "ad_getentryoff(ad, ADEID_FINDERI) + ADEDLEN_FINDERI" is equal to
    ADEDOFF_RFORK_DOT_UND.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 4c7e1de46f4287818ef525c8939029ccb09adf65
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Oct 5 16:44:53 2018 +0200

    vfs_fruit: split out moving of the resource fork
    
    No change in behaviour.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit b948681b2bbaba202843858857fb9edbb543bdf2
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Oct 5 19:15:04 2018 +0200

    vfs_fruit: use ADEDOFF_RFORK_DOT_UND offset macro in ad_convert_truncate()
    
    We really want the fixed size offset here, not a calculated one. Note
    that "ad_getentryoff(ad, ADEID_RFORK)" is equal to ADEDOFF_RFORK_DOT_UND
    in this case.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 98bd7c0a46f72b097011a5c59e899ac4862ff651
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Oct 5 19:13:16 2018 +0200

    vfs_fruit: split out truncating from ad_convert()
    
    This may look a little ill-advised as this increases line count, but
    the goal here is modularizing ad_convert() itself and making it as slick
    as possible helps achieving that goal.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 4f1174b6eb2257d789a1eb9c925ccc561bab2f16
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Oct 5 16:26:46 2018 +0200

    vfs_fruit: move FinderInfo lenght check to ad_convert()
    
    The final step in consolidating all conversion related work in
    ad_convert(). No change in behaviour.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit d27d0326c3c8cb6d217e6c8056fae2c98ef82803
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Oct 5 16:25:27 2018 +0200

    vfs_fruit: move FinderInfo conversion to helper function and call it from ad_convert()
    
    No change in behaviour.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit b355a09576563d0f681d0bf830d0e2c769533399
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Oct 5 16:14:40 2018 +0200

    vfs_fruit: move storing of modified struct adouble to ad_convert()
    
    ad_convert() modified it, so let ad_convert() also save it to disk. No
    change in behaviour.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 99cc9ef82b50b57149f71a40d4b22a3fc32a5a97
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Oct 4 08:51:28 2018 +0200

    vfs_fruit: remove unneeded fd argument from ad_convert()
    
    Use the struct adouble member ad_fd instead of passing it as an
    argument. Who did that in the first place? :)
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 8bc36d723ff41afe768f42b833aa951e1ee8fb38
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Oct 4 08:23:59 2018 +0200

    vfs_fruit: do direct return from error checks in ad_convert()
    
    Subsequent commits will move the mmap() into the subfunctions. This
    change just prepares for that.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit d161e047710322491802d75f47598f96727cd004
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Oct 2 14:51:05 2018 +0200

    vfs_fruit: move setting ADEID_FINDERI length to ad_convert_xattr()
    
    ad_convert_xattr() does the conversion of the xattr data in the
    AppleDouble file, so we should update it's size there and should not
    defer it to the caller.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 8ee7e6135e39520f486e8f8f4ba36009c9113229
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Oct 5 15:12:44 2018 +0200

    vfs_fruit: store filler bytes from AppleDouble file header in struct adouble
    
    This can later be used to distinguish between macOS created AppleDouble
    files and AppleDouble files created by Samba or Netatalk.
    
    macOS:    "Mac OS X        "
    Samba:    "Netatalk        "
    Netatalk: "Netatalk        "
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 7e010abbaad79643f31361de47340c218fa39505
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Sep 11 14:05:43 2018 +0200

    vfs_fruit: fix two comments
    
    Thanks to the recent addition of ad_convert_xattr() we now correctly
    handle this case.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 8b9728480f6ab22da0831400796f3c39ec543df8
Author: Ralph Boehme <slow at samba.org>
Date:   Sun Oct 7 18:26:47 2018 +0200

    s4:torture: FinderInfo conversion test with AppleDouble without xattr data
    
    This testcase demonstrates that the AppleDouble conversion in vfs_fruit
    doesn't correctly convert the FinderInfo data from the AppleDouble file
    to a stream.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13649
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 selftest/knownfail.d/samba3.vfs.fruit |   1 +
 source3/modules/vfs_fruit.c           | 414 +++++++++++++++++++++-------------
 source4/torture/vfs/fruit.c           | 258 +++++++++++++++++++++
 3 files changed, 519 insertions(+), 154 deletions(-)


Changeset truncated at 500 lines:

diff --git a/selftest/knownfail.d/samba3.vfs.fruit b/selftest/knownfail.d/samba3.vfs.fruit
index 8df25bc..6307e2b 100644
--- a/selftest/knownfail.d/samba3.vfs.fruit
+++ b/selftest/knownfail.d/samba3.vfs.fruit
@@ -1 +1,2 @@
 ^samba3.vfs.fruit streams_depot.OS X AppleDouble file conversion\(nt4_dc\)
+^samba3.vfs.fruit streams_depot.OS X AppleDouble file conversion without embedded xattr\(nt4_dc\)
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 894c361..30fab85 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -262,6 +262,7 @@ typedef enum {ADOUBLE_META, ADOUBLE_RSRC} adouble_type_t;
 #define ADEDLEN_VERSION     4
 #define ADEDLEN_FILLER      16
 #define AD_FILLER_TAG       "Netatalk        " /* should be 16 bytes */
+#define AD_FILLER_TAG_OSX   "Mac OS X        " /* should be 16 bytes */
 #define ADEDLEN_NENTRIES    2
 #define AD_HEADER_LEN       (ADEDLEN_MAGIC + ADEDLEN_VERSION + \
 			     ADEDLEN_FILLER + ADEDLEN_NENTRIES) /* 26 */
@@ -414,6 +415,7 @@ struct adouble {
 	adouble_type_t            ad_type;
 	uint32_t                  ad_magic;
 	uint32_t                  ad_version;
+	uint8_t                   ad_filler[ADEDLEN_FILLER];
 	struct ad_entry           ad_eid[ADEID_MAX];
 	char                     *ad_data;
 	struct ad_xattr_header    adx_header;
@@ -837,6 +839,8 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries,
 		return false;
 	}
 
+	memcpy(ad->ad_filler, ad->ad_data + ADEDOFF_FILLER, ADEDLEN_FILLER);
+
 	adentries = RSVAL(ad->ad_data, ADEDOFF_NENTRIES);
 	if (adentries != nentries) {
 		DEBUG(1, ("invalid number of entries: %zu\n",
@@ -938,14 +942,77 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries,
 	return true;
 }
 
+static bool ad_convert_move_reso(struct adouble *ad,
+				 const struct smb_filename *smb_fname)
+{
+	char *map = MAP_FAILED;
+	size_t maplen;
+	ssize_t len;
+	int rc;
+	bool ok;
+
+	if (ad_getentrylen(ad, ADEID_RFORK) == 0) {
+		return true;
+	}
+
+	maplen = ad_getentryoff(ad, ADEID_RFORK) +
+		ad_getentrylen(ad, ADEID_RFORK);
+
+	/* FIXME: direct use of mmap(), vfs_aio_fork does it too */
+	map = mmap(NULL, maplen, PROT_READ|PROT_WRITE, MAP_SHARED,
+		   ad->ad_fd, 0);
+	if (map == MAP_FAILED) {
+		DBG_ERR("mmap AppleDouble: %s\n", strerror(errno));
+		return false;
+	}
+
+
+	memmove(map + ADEDOFF_RFORK_DOT_UND,
+		map + ad_getentryoff(ad, ADEID_RFORK),
+		ad_getentrylen(ad, ADEID_RFORK));
+
+	rc = munmap(map, maplen);
+	if (rc != 0) {
+		DBG_ERR("munmap failed: %s\n", strerror(errno));
+		return false;
+	}
+
+	ad_setentryoff(ad, ADEID_RFORK, ADEDOFF_RFORK_DOT_UND);
+
+	ok = ad_pack(ad);
+	if (!ok) {
+		DBG_WARNING("ad_pack [%s] failed\n", smb_fname->base_name);
+		return false;
+	}
+
+	len = sys_pwrite(ad->ad_fd, ad->ad_data, AD_DATASZ_DOT_UND, 0);
+	if (len != AD_DATASZ_DOT_UND) {
+		DBG_ERR("%s: bad size: %zd\n", smb_fname->base_name, len);
+		return false;
+	}
+
+	return true;
+}
+
 static bool ad_convert_xattr(struct adouble *ad,
 			     const struct smb_filename *smb_fname,
-			     char *map)
+			     bool *converted_xattr)
 {
 	static struct char_mappings **string_replace_cmaps = NULL;
+	char *map = MAP_FAILED;
+	size_t maplen;
 	uint16_t i;
+	ssize_t len;
 	int saved_errno = 0;
 	NTSTATUS status;
+	int rc;
+	bool ok;
+
+	*converted_xattr = false;
+
+	if (ad_getentrylen(ad, ADEID_FINDERI) == ADEDLEN_FINDERI) {
+		return true;
+	}
 
 	if (ad->adx_header.adx_num_attrs == 0) {
 		return true;
@@ -963,6 +1030,17 @@ static bool ad_convert_xattr(struct adouble *ad,
 		TALLOC_FREE(mappings);
 	}
 
+	maplen = ad_getentryoff(ad, ADEID_RFORK) +
+		ad_getentrylen(ad, ADEID_RFORK);
+
+	/* FIXME: direct use of mmap(), vfs_aio_fork does it too */
+	map = mmap(NULL, maplen, PROT_READ|PROT_WRITE, MAP_SHARED,
+		   ad->ad_fd, 0);
+	if (map == MAP_FAILED) {
+		DBG_ERR("mmap AppleDouble: %s\n", strerror(errno));
+		return false;
+	}
+
 	for (i = 0; i < ad->adx_header.adx_num_attrs; i++) {
 		struct ad_xattr_entry *e = &ad->adx_entries[i];
 		char *mapped_name = NULL;
@@ -981,14 +1059,16 @@ static bool ad_convert_xattr(struct adouble *ad,
 		    !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED))
 		{
 			DBG_ERR("string_replace_allocate failed\n");
-			return -1;
+			ok = false;
+			goto fail;
 		}
 
 		tmp = mapped_name;
 		mapped_name = talloc_asprintf(talloc_tos(), ":%s", tmp);
 		TALLOC_FREE(tmp);
 		if (mapped_name == NULL) {
-			return -1;
+			ok = false;
+			goto fail;
 		}
 
 		stream_name = synthetic_smb_fname(talloc_tos(),
@@ -999,7 +1079,8 @@ static bool ad_convert_xattr(struct adouble *ad,
 		TALLOC_FREE(mapped_name);
 		if (stream_name == NULL) {
 			DBG_ERR("synthetic_smb_fname failed\n");
-			return -1;
+			ok = false;
+			goto fail;
 		}
 
 		DBG_DEBUG("stream_name: %s\n", smb_fname_str_dbg(stream_name));
@@ -1026,7 +1107,8 @@ static bool ad_convert_xattr(struct adouble *ad,
 		TALLOC_FREE(stream_name);
 		if (!NT_STATUS_IS_OK(status)) {
 			DBG_ERR("SMB_VFS_CREATE_FILE failed\n");
-			return -1;
+			ok = false;
+			goto fail;
 		}
 
 		nwritten = SMB_VFS_PWRITE(fsp,
@@ -1038,16 +1120,168 @@ static bool ad_convert_xattr(struct adouble *ad,
 			saved_errno = errno;
 			close_file(NULL, fsp, ERROR_CLOSE);
 			errno = saved_errno;
-			return -1;
+			ok = false;
+			goto fail;
 		}
 
 		status = close_file(NULL, fsp, NORMAL_CLOSE);
 		if (!NT_STATUS_IS_OK(status)) {
-			return -1;
+			ok = false;
+			goto fail;
 		}
 		fsp = NULL;
 	}
 
+	ad_setentrylen(ad, ADEID_FINDERI, ADEDLEN_FINDERI);
+
+	ok = ad_pack(ad);
+	if (!ok) {
+		DBG_WARNING("ad_pack [%s] failed\n", smb_fname->base_name);
+		goto fail;
+	}
+
+	len = sys_pwrite(ad->ad_fd, ad->ad_data, AD_DATASZ_DOT_UND, 0);
+	if (len != AD_DATASZ_DOT_UND) {
+		DBG_ERR("%s: bad size: %zd\n", smb_fname->base_name, len);
+		ok = false;
+		goto fail;
+	}
+
+	ok = ad_convert_move_reso(ad, smb_fname);
+	if (!ok) {
+		goto fail;
+	}
+
+	*converted_xattr = true;
+	ok = true;
+
+fail:
+	rc = munmap(map, maplen);
+	if (rc != 0) {
+		DBG_ERR("munmap failed: %s\n", strerror(errno));
+		return false;
+	}
+
+	return ok;
+}
+
+static bool ad_convert_finderinfo(struct adouble *ad,
+				  const struct smb_filename *smb_fname)
+{
+	char *p_ad = NULL;
+	AfpInfo *ai = NULL;
+	DATA_BLOB aiblob;
+	struct smb_filename *stream_name = NULL;
+	files_struct *fsp = NULL;
+	size_t size;
+	ssize_t nwritten;
+	NTSTATUS status;
+	int saved_errno = 0;
+	int cmp;
+
+	cmp = memcmp(ad->ad_filler, AD_FILLER_TAG_OSX, ADEDLEN_FILLER);
+	if (cmp != 0) {
+		return true;
+	}
+
+	p_ad = ad_get_entry(ad, ADEID_FINDERI);
+	if (p_ad == NULL) {
+		return false;
+	}
+
+	ai = afpinfo_new(talloc_tos());
+	if (ai == NULL) {
+		return false;
+	}
+
+	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 false;
+	}
+
+	size = afpinfo_pack(ai, (char *)aiblob.data);
+	TALLOC_FREE(ai);
+	if (size != AFP_INFO_SIZE) {
+		return false;
+	}
+
+	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 false;
+	}
+
+	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 false;
+	}
+
+	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 false;
+	}
+
+	status = close_file(NULL, fsp, NORMAL_CLOSE);
+	if (!NT_STATUS_IS_OK(status)) {
+		return false;
+	}
+	fsp = NULL;
+
+	return true;
+}
+
+static bool ad_convert_truncate(struct adouble *ad,
+				const struct smb_filename *smb_fname)
+{
+	int rc;
+
+	/*
+	 * FIXME: direct ftruncate(), but we don't have a fsp for the
+	 * VFS call
+	 */
+	rc = ftruncate(ad->ad_fd, ADEDOFF_RFORK_DOT_UND +
+		       ad_getentrylen(ad, ADEID_RFORK));
+	if (rc != 0) {
+		return false;
+	}
+
 	return true;
 }
 
@@ -1055,60 +1289,37 @@ static bool ad_convert_xattr(struct adouble *ad,
  * Convert from Apple's ._ file to Netatalk
  *
  * Apple's AppleDouble may contain a FinderInfo entry longer then 32
- * bytes containing packed xattrs. Netatalk can't deal with that, so
- * we simply discard the packed xattrs.
+ * bytes containing packed xattrs.
  *
  * @return -1 in case an error occurred, 0 if no conversion was done, 1
  * otherwise
  **/
 static int ad_convert(struct adouble *ad,
-		      const struct smb_filename *smb_fname,
-		      int fd)
+		      const struct smb_filename *smb_fname)
 {
-	int rc = 0;
-	char *map = MAP_FAILED;
-	size_t origlen;
 	bool ok;
+	bool converted_xattr = false;
 
-	origlen = ad_getentryoff(ad, ADEID_RFORK) +
-		ad_getentrylen(ad, ADEID_RFORK);
-
-	/* FIXME: direct use of mmap(), vfs_aio_fork does it too */
-	map = mmap(NULL, origlen, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
-	if (map == MAP_FAILED) {
-		DEBUG(2, ("mmap AppleDouble: %s\n", strerror(errno)));
-		rc = -1;
-		goto exit;
-	}
-
-	ok = ad_convert_xattr(ad, smb_fname, map);
+	ok = ad_convert_xattr(ad, smb_fname, &converted_xattr);
 	if (!ok) {
-		munmap(map, origlen);
 		return -1;
 	}
 
-	if (ad_getentrylen(ad, ADEID_RFORK) > 0) {
-		memmove(map + ad_getentryoff(ad, ADEID_FINDERI) + ADEDLEN_FINDERI,
-			map + ad_getentryoff(ad, ADEID_RFORK),
-			ad_getentrylen(ad, ADEID_RFORK));
+	if (converted_xattr) {
+		ok = ad_convert_truncate(ad, smb_fname);
+		if (!ok) {
+			return -1;
+		}
 	}
 
-	ad_setentrylen(ad, ADEID_FINDERI, ADEDLEN_FINDERI);
-	ad_setentryoff(ad, ADEID_RFORK,
-		       ad_getentryoff(ad, ADEID_FINDERI) + ADEDLEN_FINDERI);
-
-	/*
-	 * FIXME: direct ftruncate(), but we don't have a fsp for the
-	 * VFS call
-	 */
-	rc = ftruncate(fd, ad_getentryoff(ad, ADEID_RFORK)
-		       + ad_getentrylen(ad, ADEID_RFORK));
-
-exit:
-	if (map != MAP_FAILED) {
-		munmap(map, origlen);
+	ok = ad_convert_finderinfo(ad, smb_fname);
+	if (!ok) {
+		DBG_ERR("Failed to convert [%s]\n",
+			smb_fname_str_dbg(smb_fname));
+		return -1;
 	}
-	return rc;
+
+	return 0;
 }
 
 /**
@@ -1304,15 +1515,8 @@ static ssize_t ad_read_rsrc_adouble(struct adouble *ad,
 {
 	SMB_STRUCT_STAT sbuf;
 	char *p_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;
+	ssize_t len;
 	int ret;
 	bool ok;
 
@@ -1368,115 +1572,17 @@ static ssize_t ad_read_rsrc_adouble(struct adouble *ad,
 		return -1;
 	}
 
-	if (ad_getentrylen(ad, ADEID_FINDERI) == ADEDLEN_FINDERI) {
-		return len;
-	}
-
 	/*
 	 * Try to fixup AppleDouble files created by OS X with xattrs
-	 * appended to the ADEID_FINDERI entry. We simply remove the
-	 * xattrs blob, this means any fancy xattr that was stored
-	 * there is lost.
+	 * appended to the ADEID_FINDERI entry.
 	 */
 
-	ret = ad_convert(ad, smb_fname, ad->ad_fd);
+	ret = ad_convert(ad, smb_fname);
 	if (ret != 0) {
 		DBG_WARNING("Failed to convert [%s]\n", smb_fname->base_name);
 		return len;
 	}
 
-	ok = ad_pack(ad);
-	if (!ok) {
-		DBG_WARNING("ad_pack [%s] failed\n", smb_fname->base_name);
-		return -1;
-	}
-
-	len = sys_pwrite(ad->ad_fd, ad->ad_data, AD_DATASZ_DOT_UND, 0);
-	if (len != AD_DATASZ_DOT_UND) {
-		DBG_ERR("%s: bad size: %zd\n", smb_fname->base_name, len);
-		return -1;
-	}
-
-	p_ad = ad_get_entry(ad, ADEID_FINDERI);
-	if (p_ad == NULL) {
-		return -1;
-	}
-
-	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;
-	}
-
-	stream_name = synthetic_smb_fname(talloc_tos(),
-					  smb_fname->base_name,
-					  AFPINFO_STREAM,
-					  NULL,


-- 
Samba Shared Repository



More information about the samba-cvs mailing list