1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

vfs_fruit: set delete-on-close for empty finderinfo

We previously removed the stream from the underlying filesystem stream
backing store when the client zeroes out FinderInfo in the AFP_AfpInfo
stream, but this causes certain operations to fail (eg stat) when trying
to access the stream over any file-handle open on that stream.

So instead of deleting, set delete-on-close on the stream. The previous
commit already implemented not to list list streams with delete-on-close
set which is necessary to implemenent correct macOS semantics for this
particular stream.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=13181

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>

Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Tue Jan  9 17:09:12 CET 2018 on sn-devel-144

(backported from commit e61e9e98e9)

Autobuild-User(v4-6-test): Karolin Seeger <kseeger@samba.org>
Autobuild-Date(v4-6-test): Thu Jan 25 19:25:24 CET 2018 on sn-devel-144
This commit is contained in:
Ralph Boehme 2017-12-06 22:09:52 +01:00 committed by Karolin Seeger
parent 9e47e9e28c
commit 301555830d
2 changed files with 36 additions and 26 deletions

View File

@ -1,2 +0,0 @@
^samba3.vfs.fruit metadata_stream.delete AFP_AfpInfo by writing all 0\(nt4_dc\)
^samba3.vfs.fruit streams_depot.delete AFP_AfpInfo by writing all 0\(nt4_dc\)

View File

@ -4065,26 +4065,35 @@ static ssize_t fruit_pwrite_meta_stream(vfs_handle_struct *handle,
size_t n, off_t offset)
{
AfpInfo *ai = NULL;
int ret;
size_t nwritten;
bool ok;
ai = afpinfo_unpack(talloc_tos(), data);
if (ai == NULL) {
return -1;
}
if (ai_empty_finderinfo(ai)) {
ret = SMB_VFS_NEXT_UNLINK(handle, fsp->fsp_name);
if (ret != 0 && errno != ENOENT && errno != ENOATTR) {
DBG_ERR("Can't delete metadata for %s: %s\n",
fsp_str_dbg(fsp), strerror(errno));
TALLOC_FREE(ai);
return -1;
}
nwritten = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
if (nwritten != n) {
return -1;
}
if (!ai_empty_finderinfo(ai)) {
return n;
}
return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
ok = set_delete_on_close(
fsp,
true,
handle->conn->session_info->security_token,
handle->conn->session_info->unix_token);
if (!ok) {
DBG_ERR("set_delete_on_close on [%s] failed\n",
fsp_str_dbg(fsp));
return -1;
}
return n;
}
static ssize_t fruit_pwrite_meta_netatalk(vfs_handle_struct *handle,
@ -4095,26 +4104,13 @@ static ssize_t fruit_pwrite_meta_netatalk(vfs_handle_struct *handle,
AfpInfo *ai = NULL;
char *p = NULL;
int ret;
bool ok;
ai = afpinfo_unpack(talloc_tos(), data);
if (ai == NULL) {
return -1;
}
if (ai_empty_finderinfo(ai)) {
ret = SMB_VFS_REMOVEXATTR(handle->conn,
fsp->fsp_name->base_name,
AFPINFO_EA_NETATALK);
if (ret != 0 && errno != ENOENT && errno != ENOATTR) {
DBG_ERR("Can't delete metadata for %s: %s\n",
fsp_str_dbg(fsp), strerror(errno));
return -1;
}
return n;
}
ad = ad_fget(talloc_tos(), handle, fsp, ADOUBLE_META);
if (ad == NULL) {
ad = ad_init(talloc_tos(), handle, ADOUBLE_META);
@ -4139,6 +4135,22 @@ static ssize_t fruit_pwrite_meta_netatalk(vfs_handle_struct *handle,
}
TALLOC_FREE(ad);
if (!ai_empty_finderinfo(ai)) {
return n;
}
ok = set_delete_on_close(
fsp,
true,
handle->conn->session_info->security_token,
handle->conn->session_info->unix_token);
if (!ok) {
DBG_ERR("set_delete_on_close on [%s] failed\n",
fsp_str_dbg(fsp));
return -1;
}
return n;
}