]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
vfs_acl_common: support real dirfsps in acl_common_remove_object()
authorRalph Boehme <slow@samba.org>
Wed, 20 Jan 2021 15:08:58 +0000 (16:08 +0100)
committerJeremy Allison <jra@samba.org>
Thu, 28 Jan 2021 08:11:49 +0000 (08:11 +0000)
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_acl_common.c

index 5aeb159b6863b40c4234a53ccd8ef0cd9ac2999d..db6f40d3adf19458530ef611a1408df8c9162436 100644 (file)
@@ -1187,6 +1187,7 @@ done:
 }
 
 static int acl_common_remove_object(vfs_handle_struct *handle,
+                                       struct files_struct *dirfsp,
                                        const struct smb_filename *smb_fname,
                                        bool is_directory)
 {
@@ -1194,6 +1195,7 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
        struct file_id id;
        files_struct *fsp = NULL;
        int ret = 0;
+       struct smb_filename *full_fname = NULL;
        struct smb_filename *local_fname = NULL;
        struct smb_filename *parent_dir_fname = NULL;
        int saved_errno = 0;
@@ -1206,8 +1208,15 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
                goto out;
        }
 
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                                 dirfsp,
+                                                 smb_fname);
+       if (full_fname == NULL) {
+               goto out;
+       }
+
        ok = parent_smb_fname(talloc_tos(),
-                             smb_fname,
+                             full_fname,
                              &parent_dir_fname,
                              &local_fname);
        if (!ok) {
@@ -1215,9 +1224,8 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
                goto out;
        }
 
-       DBG_DEBUG("removing %s %s/%s\n", is_directory ? "directory" : "file",
-                 smb_fname_str_dbg(parent_dir_fname),
-                 smb_fname_str_dbg(local_fname));
+       DBG_DEBUG("removing %s %s\n", is_directory ? "directory" : "file",
+                 smb_fname_str_dbg(full_fname));
 
        /* cd into the parent dir to pin it. */
        ret = vfs_ChDir(conn, parent_dir_fname);
@@ -1248,10 +1256,9 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
        }
 
        if (!fsp) {
-               DBG_DEBUG("%s %s/%s not an open file\n",
+               DBG_DEBUG("%s %s not an open file\n",
                          is_directory ? "directory" : "file",
-                         smb_fname_str_dbg(parent_dir_fname),
-                         smb_fname_str_dbg(local_fname));
+                         smb_fname_str_dbg(full_fname));
                saved_errno = EACCES;
                goto out;
        }
@@ -1259,13 +1266,13 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
        become_root();
        if (is_directory) {
                ret = SMB_VFS_NEXT_UNLINKAT(handle,
-                               conn->cwd_fsp,
-                               local_fname,
+                               dirfsp,
+                               smb_fname,
                                AT_REMOVEDIR);
        } else {
                ret = SMB_VFS_NEXT_UNLINKAT(handle,
-                               conn->cwd_fsp,
-                               local_fname,
+                               dirfsp,
+                               smb_fname,
                                0);
        }
        unbecome_root();
@@ -1277,6 +1284,7 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
   out:
 
        TALLOC_FREE(parent_dir_fname);
+       TALLOC_FREE(full_fname);
 
        if (saved_dir_fname) {
                vfs_ChDir(conn, saved_dir_fname);
@@ -1306,6 +1314,7 @@ int rmdir_acl_common(struct vfs_handle_struct *handle,
                /* Failed due to access denied,
                   see if we need to root override. */
                return acl_common_remove_object(handle,
+                                               dirfsp,
                                                smb_fname,
                                                true);
        }
@@ -1340,6 +1349,7 @@ int unlink_acl_common(struct vfs_handle_struct *handle,
                        return -1;
                }
                return acl_common_remove_object(handle,
+                                       dirfsp,
                                        smb_fname,
                                        false);
        }