diff options
author | Ralph Boehme <slow@samba.org> | 2018-10-02 16:05:28 +0200 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2018-11-02 10:30:10 +0100 |
commit | 24fd9ddc3607c7e38df30823f737bc1dd7502ebf (patch) | |
tree | 9ece17efcc6775c8be2692f50dd89da5201e7938 /source3 | |
parent | 1a378c1238499e6d03447f17cf12ee24f9b3fb0f (diff) | |
download | samba-24fd9ddc3607c7e38df30823f737bc1dd7502ebf.tar.gz |
vfs_fruit: detect empty resource forks in ad_convert()
For some reason the macOS client often writes AppleDouble files with a
non-zero sized resource fork, but the resource fork data is just
boilerplate data with the following string close to the start
This resource fork intentionally left blank
A dump with apple_dump looks like this:
Entry ID : 00000002 : Resource Fork
Offset : 00000052 : 82
Length : 0000011E : 286
-RAW DUMP--: 0 1 2 3 4 5 6 7 8 9 A B C D E F : (ASCII)
00000000 : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
00000010 : 54 68 69 73 20 72 65 73 6F 75 72 63 65 20 66 6F : This resource fo
00000020 : 72 6B 20 69 6E 74 65 6E 74 69 6F 6E 61 6C 6C 79 : rk intentionally
00000030 : 20 6C 65 66 74 20 62 6C 61 6E 6B 20 20 20 00 00 : left blank ..
00000040 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
00000050 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
00000060 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
00000070 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
00000080 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
00000090 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
000000A0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
000000B0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
000000C0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
000000D0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
000000E0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
000000F0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
00000100 : 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 1E : ................
00000110 : 00 00 00 00 00 00 00 00 00 1C 00 1E FF FF : ..............
We can safely discard this Resource Fork data.
Bug: https://bugzilla.samba.org/show_bug.cgi?id=13642
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 7be979f958295474f0c0df6a4db0b5bca9a6676d)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/modules/vfs_fruit.c | 111 |
1 files changed, 110 insertions, 1 deletions
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c index c9028a93d62..e38d48bea02 100644 --- a/source3/modules/vfs_fruit.c +++ b/source3/modules/vfs_fruit.c @@ -468,6 +468,45 @@ static const uint32_t set_eid[] = { AD_DEV, AD_INO, AD_SYN, AD_ID }; +static char empty_resourcefork[] = { + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, + 0x54, 0x68, 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, + 0x6F, 0x75, 0x72, 0x63, 0x65, 0x20, 0x66, 0x6F, + 0x72, 0x6B, 0x20, 0x69, 0x6E, 0x74, 0x65, 0x6E, + 0x74, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x6C, 0x79, + 0x20, 0x6C, 0x65, 0x66, 0x74, 0x20, 0x62, 0x6C, + 0x61, 0x6E, 0x6B, 0x20, 0x20, 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, + 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, 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, 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, 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, + 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, 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, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1C, 0x00, 0x1E, 0xFF, 0xFF +}; + struct fio { /* tcon config handle */ struct fruit_config_data *config; @@ -1282,6 +1321,70 @@ static bool ad_convert_truncate(struct adouble *ad, return true; } +static bool ad_convert_blank_rfork(struct adouble *ad, + bool *blank) +{ + struct fruit_config_data *config = NULL; + uint8_t *map = MAP_FAILED; + size_t maplen; + int cmp; + ssize_t len; + int rc; + bool ok; + + *blank = false; + + SMB_VFS_HANDLE_GET_DATA(ad->ad_handle, config, + struct fruit_config_data, return false); + + if (!config->wipe_intentionally_left_blank_rfork) { + return true; + } + + if (ad_getentrylen(ad, ADEID_RFORK) != sizeof(empty_resourcefork)) { + 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; + } + + cmp = memcmp(map + ADEDOFF_RFORK_DOT_UND, + empty_resourcefork, + sizeof(empty_resourcefork)); + rc = munmap(map, maplen); + if (rc != 0) { + DBG_ERR("munmap failed: %s\n", strerror(errno)); + return false; + } + + if (cmp != 0) { + return true; + } + + ad_setentrylen(ad, ADEID_RFORK, 0); + + ok = ad_pack(ad); + if (!ok) { + return false; + } + + len = sys_pwrite(ad->ad_fd, ad->ad_data, AD_DATASZ_DOT_UND, 0); + if (len != AD_DATASZ_DOT_UND) { + return false; + } + + *blank = true; + return true; +} + /** * Convert from Apple's ._ file to Netatalk * @@ -1296,13 +1399,19 @@ static int ad_convert(struct adouble *ad, { bool ok; bool converted_xattr = false; + bool blank; ok = ad_convert_xattr(ad, smb_fname, &converted_xattr); if (!ok) { return -1; } - if (converted_xattr) { + ok = ad_convert_blank_rfork(ad, &blank); + if (!ok) { + return -1; + } + + if (converted_xattr || blank) { ok = ad_convert_truncate(ad, smb_fname); if (!ok) { return -1; |