The branch, v4-9-test has been updated via 21e3e8b vfs_fruit: move check in ad_convert() to ad_convert_*() subfunctions via 9304dfa vfs_fruit: make call to ad_convert_truncate() optional via 01353f6 vfs_fruit: add out arg "converted_xattr" to ad_convert_xattr via 0807a89 vfs_fruit: add check for OS X filler in FinderInfo conversion via bee12e2 vfs_fruit: call ad_convert_move_reso() from ad_convert_xattr() via 5480048 vfs_fruit: let the ad_convert_*() subfunction update the on-disk AppleDoube header as needed via 655e147 vfs_fruit: let the ad_convert_*() subfunctions mmap as needed via 84374fb vfs_fruit: fix error returns in ad_convert_xattr() via 393a773 vfs_fruit: use ADEDOFF_RFORK_DOT_UND offset macro in ad_convert_move_reso() via b228d66 vfs_fruit: split out moving of the resource fork via c651989 vfs_fruit: use ADEDOFF_RFORK_DOT_UND offset macro in ad_convert_truncate() via d9c79be vfs_fruit: split out truncating from ad_convert() via 50dfdfa vfs_fruit: move FinderInfo lenght check to ad_convert() via fb345c2 vfs_fruit: move FinderInfo conversion to helper function and call it from ad_convert() via 10232d0 vfs_fruit: move storing of modified struct adouble to ad_convert() via 4679371 vfs_fruit: remove unneeded fd argument from ad_convert() via f109097 vfs_fruit: do direct return from error checks in ad_convert() via a942683 vfs_fruit: move setting ADEID_FINDERI length to ad_convert_xattr() via 6ee5df2 vfs_fruit: store filler bytes from AppleDouble file header in struct adouble via b275922 vfs_fruit: fix two comments via 4772ba8 s4:torture: FinderInfo conversion test with AppleDouble without xattr data from a1a4e54 lib: Avoid the use of open_memstream in tevent_req_profile_string
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-9-test - Log ----------------------------------------------------------------- commit 21e3e8b3cee9f48de0659e14135136ee3c1e7faf Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Ralph Böhme <s...@samba.org> Autobuild-Date(master): Thu Oct 11 01:30:13 CEST 2018 on sn-devel-144 (cherry picked from commit 31daab88e6a415e72ead69844e3eccf5dc02e53c) Autobuild-User(v4-9-test): Karolin Seeger <ksee...@samba.org> Autobuild-Date(v4-9-test): Thu Oct 18 16:16:16 CEST 2018 on sn-devel-144 commit 9304dfae00abe593fb5bc2815311437159b5072d Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 9cf087a474bb2d7d29ca0daeaef412f6b545d0e0) commit 01353f6d2829ca67e3a16312d77967ce16ef4eaa Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit acb72c1ea7fecc9a7e8eb0219096b1bbdfd8850e) commit 0807a89698963e402cc71c1ecce5a693ef4c0885 Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 5598e6bc3583a88f474afa2996d1f9362d1bd9fb) commit bee12e2e14041118048ac1788e0e2f0eda7b7fbd Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 70d3ae5a89fc62db192c44b92a5b7fb67a93d88e) commit 548004896a50af01f5c7c57a32f762310c55bbf2 Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 1692ca5fd8ae2560dae6828f3c5c05a65c530726) commit 655e147cd9be5aba993a1d213f9dda16b6df1aec Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 918c6c59901d0bf939dcc178b661b6ae8201e903) commit 84374fbb3983deb371da27967dede672ec963d5b Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit f91e0c857a5a44a5eab7696fafda758044739978) commit 393a773ad374eff1533429f1cdd4a124fe54cac2 Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 93b7e0562159eae40e196f6be8d82283f0be2888) commit b228d661362f976a469662a83eaed28a6d7105bf Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 4c7e1de46f4287818ef525c8939029ccb09adf65) commit c65198980ceddc1f57652a7921b223551bffc5a5 Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit b948681b2bbaba202843858857fb9edbb543bdf2) commit d9c79bedd95b73a67a51145a7ef7d571d6e786f1 Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 98bd7c0a46f72b097011a5c59e899ac4862ff651) commit 50dfdfac17739631f6fd1c5f99a9eea82d41e97f Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 4f1174b6eb2257d789a1eb9c925ccc561bab2f16) commit fb345c2b36405eed944a9a444dbf6a7b9b5967dd Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit d27d0326c3c8cb6d217e6c8056fae2c98ef82803) commit 10232d0da022e6387426b865759eaf002f8d5272 Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit b355a09576563d0f681d0bf830d0e2c769533399) commit 4679371f8c1aaa227636cb6ed8f45e4b551ef285 Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 99cc9ef82b50b57149f71a40d4b22a3fc32a5a97) commit f1090976484d5d491080bd52063080557ea68ce1 Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 8bc36d723ff41afe768f42b833aa951e1ee8fb38) commit a9426833a87dce1f5b559e1d9db4c8bd97a961af Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit d161e047710322491802d75f47598f96727cd004) commit 6ee5df28cb354496a0da2b54576d97c5cfa52864 Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 8ee7e6135e39520f486e8f8f4ba36009c9113229) commit b2759221039da901eb39f1707413e3f70af4973b Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 7e010abbaad79643f31361de47340c218fa39505) commit 4772ba81be2bd7f7c01907758bf89427027ee7ed Author: Ralph Boehme <s...@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 <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit 8b9728480f6ab22da0831400796f3c39ec543df8) ----------------------------------------------------------------------- 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 1102059..58ef3cc 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