1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-02 09:47:23 +03:00

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>
This commit is contained in:
Ralph Boehme 2018-10-02 16:05:28 +02:00 committed by Jeremy Allison
parent 2dbb2d2873
commit 7be979f958
2 changed files with 110 additions and 2 deletions

View File

@ -1,4 +1,3 @@
^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\)
^samba3.vfs.fruit_conversion wipe_intentionally_left_blank_rfork.convert_xattr_and_empty_rfork_then_delete\(nt4_dc\)
^samba3.vfs.fruit_conversion delete_empty_adfiles.convert_xattr_and_empty_rfork_then_delete\(nt4_dc\)

View File

@ -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;