]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
vfs: Fix Bug 15791, vfs_acl_tdb unlinkat()
authorVolker Lendecke <vl@samba.org>
Tue, 28 Jan 2025 13:03:49 +0000 (14:03 +0100)
committerJule Anger <janger@samba.org>
Mon, 31 Mar 2025 12:13:03 +0000 (12:13 +0000)
Bug: https://bugzilla.samba.org/show_bug.cgi?id=15791
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
(cherry picked from commit 93a6d36239dd2ce2b3863945f8b9b59cb6aa911a)

Autobuild-User(v4-22-test): Jule Anger <janger@samba.org>
Autobuild-Date(v4-22-test): Mon Mar 31 12:13:03 UTC 2025 on atb-devel-224

source3/modules/vfs_acl_tdb.c

index 4a7965c7e9f9426d959b1da537247094c0a7ca6f..b054f159f87515ff4404e3ba1079b0fbf9712d4f 100644 (file)
@@ -195,38 +195,43 @@ static int unlinkat_acl_tdb(vfs_handle_struct *handle,
                        const struct smb_filename *smb_fname,
                        int flags)
 {
-       struct smb_filename *smb_fname_tmp = NULL;
-       struct db_context *db = acl_db;
-       int ret = -1;
-
-       smb_fname_tmp = cp_smb_filename_nostream(talloc_tos(), smb_fname);
-       if (smb_fname_tmp == NULL) {
-               errno = ENOMEM;
-               goto out;
-       }
+       struct stat_ex st = {};
+       int ret;
 
-       ret = vfs_stat(handle->conn, smb_fname_tmp);
-       if (ret == -1) {
-               goto out;
+       if (!is_named_stream(smb_fname)) {
+               if (VALID_STAT(smb_fname->st)) {
+                       st = smb_fname->st;
+               } else {
+                       ret = SMB_VFS_NEXT_FSTATAT(handle,
+                                                  dirfsp,
+                                                  smb_fname,
+                                                  &st,
+                                                  AT_SYMLINK_NOFOLLOW);
+                       if (ret == -1) {
+                               return ret;
+                       }
+               }
        }
 
        if (flags & AT_REMOVEDIR) {
-               ret = rmdir_acl_common(handle,
-                               dirfsp,
-                               smb_fname_tmp);
+               ret = rmdir_acl_common(handle, dirfsp, smb_fname);
        } else {
-               ret = unlink_acl_common(handle,
-                               dirfsp,
-                               smb_fname_tmp,
-                               flags);
+               ret = unlink_acl_common(handle, dirfsp, smb_fname, flags);
        }
 
        if (ret == -1) {
-               goto out;
+               return -1;
        }
 
-       acl_tdb_delete(handle, db, &smb_fname_tmp->st);
- out:
+       if (is_named_stream(smb_fname)) {
+               /*
+                * ACLs only stored for basenames
+                */
+               return ret;
+       }
+
+       acl_tdb_delete(handle, acl_db, &st);
+
        return ret;
 }