]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
vfs_fruit: filter out AFP_AfpInfo streams with pending delete-on-close
authorRalph Boehme <slow@samba.org>
Thu, 7 Dec 2017 16:32:35 +0000 (17:32 +0100)
committerKarolin Seeger <kseeger@samba.org>
Thu, 25 Jan 2018 14:06:21 +0000 (15:06 +0100)
This is in preperation of fixing the implementation of removing the
AFP_AfpInfo stream by zeroing the FinderInfo out.

We currently remove the stream blob from the underyling filesystem
backing store, but that results in certain operations to fail on any
still open file-handle.

The fix comes in the next commit which will convert to backing store
delete operation to a set delete-on-close on the stream.

This commit adds filtering on streams that have the delete-on-close
set. It is only needed for the fruit:metadata=stream case, as with
fruit:metadata=netatalk the filtering is already done in
fruit_streaminfo_meta_netatalk().

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>
(cherry picked from commit 70d8f7c5d25f35b58620c2db8f57c7c0758267b3)

source3/modules/vfs_fruit.c

index 92e38fbc8a0435c4f5da71618c9803d43f8575c6..18cbd23ba073d9d48c09e17c6eec8dab04806b9f 100644 (file)
@@ -4761,7 +4761,16 @@ static NTSTATUS fruit_streaminfo_meta_stream(
 {
        struct stream_struct *stream = *pstreams;
        unsigned int num_streams = *pnum_streams;
+       struct smb_filename *sname = NULL;
+       char *full_name = NULL;
+       uint32_t name_hash;
+       struct share_mode_lock *lck = NULL;
+       struct file_id id = {0};
+       bool delete_on_close_set;
        int i;
+       int ret;
+       NTSTATUS status;
+       bool ok;
 
        for (i = 0; i < num_streams; i++) {
                if (strequal_m(stream[i].name, AFPINFO_STREAM)) {
@@ -4781,7 +4790,68 @@ static NTSTATUS fruit_streaminfo_meta_stream(
                                                  pnum_streams, pstreams);
        }
 
-       return NT_STATUS_OK;
+       /*
+        * Now check if there's a delete-on-close pending on the stream. If so,
+        * hide the stream. This behaviour was verified against a macOS 10.12
+        * SMB server.
+        */
+
+       sname = synthetic_smb_fname(talloc_tos(),
+                                   smb_fname->base_name,
+                                   AFPINFO_STREAM_NAME,
+                                   NULL, 0);
+       if (sname == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto out;
+       }
+
+       ret = SMB_VFS_NEXT_STAT(handle, sname);
+       if (ret != 0) {
+               status = map_nt_error_from_unix(errno);
+               goto out;
+       }
+
+       id = SMB_VFS_NEXT_FILE_ID_CREATE(handle, &sname->st);
+
+       lck = get_existing_share_mode_lock(talloc_tos(), id);
+       if (lck == NULL) {
+               status = NT_STATUS_OK;
+               goto out;
+       }
+
+       full_name = talloc_asprintf(talloc_tos(),
+                                   "%s%s",
+                                   sname->base_name,
+                                   AFPINFO_STREAM);
+       if (full_name == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto out;
+       }
+
+       status = file_name_hash(handle->conn, full_name, &name_hash);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+
+       delete_on_close_set = is_delete_on_close_set(lck, name_hash);
+       if (delete_on_close_set) {
+               ok = del_fruit_stream(mem_ctx,
+                                     pnum_streams,
+                                     pstreams,
+                                     AFPINFO_STREAM);
+               if (!ok) {
+                       status = NT_STATUS_INTERNAL_ERROR;
+                       goto out;
+               }
+       }
+
+       status  = NT_STATUS_OK;
+
+out:
+       TALLOC_FREE(sname);
+       TALLOC_FREE(lck);
+       TALLOC_FREE(full_name);
+       return status;
 }
 
 static NTSTATUS fruit_streaminfo_meta_netatalk(