diff options
author | Ralph Boehme <slow@samba.org> | 2017-11-15 16:52:48 +0100 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2017-11-29 08:38:06 +0100 |
commit | 1da17204344a99a3bfa289355a996027a21814b8 (patch) | |
tree | e878febcb0ffc13cc1628f5c70e91a87a1e4d401 | |
parent | 84976cb670847f199598995d48bd9c3f3dd0f035 (diff) | |
download | samba-1da17204344a99a3bfa289355a996027a21814b8.tar.gz |
vfs_fruit: proper VFS-stackable conversion of FinderInfo
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
-rw-r--r-- | selftest/knownfail.d/samba3.vfs.fruit | 1 | ||||
-rw-r--r-- | source3/modules/vfs_fruit.c | 89 |
2 files changed, 75 insertions, 15 deletions
diff --git a/selftest/knownfail.d/samba3.vfs.fruit b/selftest/knownfail.d/samba3.vfs.fruit index 1b4894fcf85..8df25bccb79 100644 --- a/selftest/knownfail.d/samba3.vfs.fruit +++ b/selftest/knownfail.d/samba3.vfs.fruit @@ -1,2 +1 @@ ^samba3.vfs.fruit streams_depot.OS X AppleDouble file conversion\(nt4_dc\) -^samba3.vfs.fruit metadata_stream.OS X AppleDouble file conversion\(nt4_dc\) diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c index 01e2f4eaab1..05a5d396fba 100644 --- a/source3/modules/vfs_fruit.c +++ b/source3/modules/vfs_fruit.c @@ -1301,12 +1301,17 @@ static ssize_t ad_read_rsrc_xattr(struct adouble *ad) static ssize_t ad_read_rsrc_adouble(struct adouble *ad, const struct smb_filename *smb_fname) { - 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; @@ -1391,29 +1396,85 @@ 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, smb_fname); - TALLOC_FREE(meta_ad); - if (ret != 0) { + 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 -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; } |