]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
vfs_fruit: Don't expect a pathref fsp in unlinkat
authorVolker Lendecke <vl@samba.org>
Fri, 3 Jan 2025 11:33:43 +0000 (12:33 +0100)
committerJeremy Allison <jra@samba.org>
Thu, 23 Jan 2025 23:08:38 +0000 (23:08 +0000)
The unix syscall unlinkat does not expect a file descriptor for the
to-be-removed object. SMB_VFS_UNLINKAT should also not expect
that. Put the special case into vfs_fruit.

This is required to simplify delete_all_streams next, which should not
have to do an openat_pathref_fsp() on all streams just for the
vfs_fruit case.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_fruit.c

index cf179adb182116ac4c805787e3eced13b1bf2707..2afa1ab18e2d9b68128a8f627b20e29af9e21644 100644 (file)
@@ -1953,12 +1953,41 @@ static int fruit_unlink_meta_stream(vfs_handle_struct *handle,
 }
 
 static int fruit_unlink_meta_netatalk(vfs_handle_struct *handle,
+                                     struct files_struct *dirfsp,
                                      const struct smb_filename *smb_fname)
 {
-       SMB_ASSERT(smb_fname->fsp != NULL);
-       SMB_ASSERT(fsp_is_alternate_stream(smb_fname->fsp));
-       return SMB_VFS_FREMOVEXATTR(smb_fname->fsp->base_fsp,
-                                  AFPINFO_EA_NETATALK);
+       struct smb_filename *base_name = NULL;
+       struct files_struct *base_fsp = NULL;
+       int ret = -1;
+
+       if (smb_fname->fsp == NULL) {
+               NTSTATUS status;
+
+               base_name = cp_smb_filename_nostream(talloc_tos(), smb_fname);
+               if (base_name == NULL) {
+                       errno = ENOMEM;
+                       goto done;
+               }
+
+               status = openat_pathref_fsp(dirfsp, base_name);
+               if (!NT_STATUS_IS_OK(status)) {
+                       errno = map_errno_from_nt_status(status);
+                       goto done;
+               }
+               base_fsp = base_name->fsp;
+       } else {
+               SMB_ASSERT(fsp_is_alternate_stream(smb_fname->fsp));
+               base_fsp = smb_fname->fsp->base_fsp;
+       }
+
+       ret = SMB_VFS_FREMOVEXATTR(base_fsp, AFPINFO_EA_NETATALK);
+done:
+       {
+               int err = errno;
+               TALLOC_FREE(base_name);
+               errno = err;
+       }
+       return ret;
 }
 
 static int fruit_unlink_meta(vfs_handle_struct *handle,
@@ -1979,7 +2008,7 @@ static int fruit_unlink_meta(vfs_handle_struct *handle,
                break;
 
        case FRUIT_META_NETATALK:
-               rc = fruit_unlink_meta_netatalk(handle, smb_fname);
+               rc = fruit_unlink_meta_netatalk(handle, dirfsp, smb_fname);
                break;
 
        default: