vfs_acl_common: use parent_smb_fname()
[samba.git] / source3 / modules / vfs_acl_common.c
index 6ddb983964e53fa6a5b63c999fdb3d9b257b6b81..43167be77a3a005110f528969750223c25386f93 100644 (file)
@@ -1092,12 +1092,11 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
        struct file_id id;
        files_struct *fsp = NULL;
        int ret = 0;
-       char *parent_dir = NULL;
-       const char *final_component = NULL;
-       struct smb_filename local_fname = {0};
-       struct smb_filename parent_dir_fname = {0};
+       struct smb_filename *local_fname = NULL;
+       struct smb_filename *parent_dir_fname = NULL;
        int saved_errno = 0;
        struct smb_filename *saved_dir_fname = NULL;
+       bool ok;
 
        saved_dir_fname = vfs_GetWd(talloc_tos(),conn);
        if (saved_dir_fname == NULL) {
@@ -1105,39 +1104,40 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
                goto out;
        }
 
-       if (!parent_dirname(talloc_tos(), smb_fname->base_name,
-                       &parent_dir, &final_component)) {
+       ok = parent_smb_fname(talloc_tos(),
+                             smb_fname,
+                             &parent_dir_fname,
+                             &local_fname);
+       if (!ok) {
                saved_errno = ENOMEM;
                goto out;
        }
 
        DBG_DEBUG("removing %s %s/%s\n", is_directory ? "directory" : "file",
-                 parent_dir, final_component);
-
-       parent_dir_fname = (struct smb_filename) { .base_name = parent_dir };
+                 smb_fname_str_dbg(parent_dir_fname),
+                 smb_fname_str_dbg(local_fname));
 
        /* cd into the parent dir to pin it. */
-       ret = vfs_ChDir(conn, &parent_dir_fname);
+       ret = vfs_ChDir(conn, parent_dir_fname);
        if (ret == -1) {
                saved_errno = errno;
                goto out;
        }
 
-       local_fname.base_name = discard_const_p(char, final_component);
-
        /* Must use lstat here. */
-       ret = SMB_VFS_LSTAT(conn, &local_fname);
+       ret = SMB_VFS_LSTAT(conn, local_fname);
        if (ret == -1) {
                saved_errno = errno;
                goto out;
        }
 
        /* Ensure we have this file open with DELETE access. */
-       id = vfs_file_id_from_sbuf(conn, &local_fname.st);
+       id = vfs_file_id_from_sbuf(conn, &local_fname->st);
        for (fsp = file_find_di_first(conn->sconn, id); fsp;
                     fsp = file_find_di_next(fsp)) {
                if (fsp->access_mask & DELETE_ACCESS &&
-                               fsp->delete_on_close) {
+                   fsp->fsp_flags.delete_on_close)
+               {
                        /* We did open this for delete,
                         * allow the delete as root.
                         */
@@ -1148,18 +1148,22 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
        if (!fsp) {
                DBG_DEBUG("%s %s/%s not an open file\n",
                          is_directory ? "directory" : "file",
-                         parent_dir, final_component);
+                         smb_fname_str_dbg(parent_dir_fname),
+                         smb_fname_str_dbg(local_fname));
                saved_errno = EACCES;
                goto out;
        }
 
        become_root();
        if (is_directory) {
-               ret = SMB_VFS_NEXT_RMDIR(handle, &local_fname);
+               ret = SMB_VFS_NEXT_UNLINKAT(handle,
+                               conn->cwd_fsp,
+                               local_fname,
+                               AT_REMOVEDIR);
        } else {
                ret = SMB_VFS_NEXT_UNLINKAT(handle,
                                conn->cwd_fsp,
-                               &local_fname,
+                               local_fname,
                                0);
        }
        unbecome_root();
@@ -1170,7 +1174,7 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
 
   out:
 
-       TALLOC_FREE(parent_dir);
+       TALLOC_FREE(parent_dir_fname);
 
        if (saved_dir_fname) {
                vfs_ChDir(conn, saved_dir_fname);
@@ -1183,12 +1187,16 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
 }
 
 int rmdir_acl_common(struct vfs_handle_struct *handle,
-                    const struct smb_filename *smb_fname)
+               struct files_struct *dirfsp,
+               const struct smb_filename *smb_fname)
 {
        int ret;
 
        /* Try the normal rmdir first. */
-       ret = SMB_VFS_NEXT_RMDIR(handle, smb_fname);
+       ret = SMB_VFS_NEXT_UNLINKAT(handle,
+                       dirfsp,
+                       smb_fname,
+                       AT_REMOVEDIR);
        if (ret == 0) {
                return 0;
        }