summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2017-11-15 16:52:48 +0100
committerKarolin Seeger <kseeger@samba.org>2017-12-05 10:32:11 +0100
commit3679be1eae506f88cb845fe845fa069cd9258b25 (patch)
tree407728d1561fd8da4908c20755e5a3e99d22be5c
parent0282d52e6905eb0e7e3a01bb5328bff89e84c227 (diff)
downloadsamba-3679be1eae506f88cb845fe845fa069cd9258b25.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 (backported from commit 1da17204344a99a3bfa289355a996027a21814b8)
-rw-r--r--selftest/knownfail1
-rw-r--r--source3/modules/vfs_fruit.c88
2 files changed, 74 insertions, 15 deletions
diff --git a/selftest/knownfail b/selftest/knownfail
index b6a9e6d0766..6e1d0589922 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -308,4 +308,3 @@
^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_rank_none.*
^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_security_descriptor.*
^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 d038e59f184..f7e57d095c9 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -1287,12 +1287,17 @@ static ssize_t ad_read_rsrc_xattr(struct adouble *ad,
static ssize_t ad_read_rsrc_adouble(struct adouble *ad,
const char *path)
{
- 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;
@@ -1375,29 +1380,84 @@ 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, path);
- TALLOC_FREE(meta_ad);
- if (ret != 0) {
+ stream_name = synthetic_smb_fname(talloc_tos(),
+ path,
+ AFPINFO_STREAM,
+ NULL, 0);
+ 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;
}