]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Make can_delete_directory_fsp() look cleaner in strace
authorVolker Lendecke <vl@samba.org>
Thu, 5 Dec 2024 15:50:12 +0000 (16:50 +0100)
committerVolker Lendecke <vl@samba.org>
Tue, 17 Dec 2024 12:30:31 +0000 (12:30 +0000)
I'm not sure, but it might be that we don't have a full fd coming into
can_delete_directory_fsp() without O_PATH. We open a real fd for
readdir() in all cases, which we can use for sure in openat &
friends. Use that as dirfsp for openat.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Pavel Filipenský <pfilipensky@samba.org>
source3/smbd/dir.c

index 788d154f4c7aee4a28e7a6cbdc8bb43d1a5538c2..7cf79222c2f961dabfc9cece3a0409422e456e71 100644 (file)
@@ -1547,11 +1547,13 @@ NTSTATUS can_delete_directory_fsp(files_struct *fsp)
        struct connection_struct *conn = fsp->conn;
        bool delete_veto = lp_delete_veto_files(SNUM(conn));
        struct smb_Dir *dir_hnd = NULL;
+       struct files_struct *dirfsp = NULL;
 
        status = OpenDir_from_pathref(talloc_tos(), fsp, NULL, 0, &dir_hnd);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
+       dirfsp = dir_hnd_fetch_fsp(dir_hnd);
 
        while ((dname = ReadDirName(dir_hnd, &talloced))) {
                struct smb_filename *direntry_fname = NULL;
@@ -1569,8 +1571,8 @@ NTSTATUS can_delete_directory_fsp(files_struct *fsp)
                                                     dname,
                                                     NULL,
                                                     NULL,
-                                                    fsp->fsp_name->twrp,
-                                                    fsp->fsp_name->flags);
+                                                    dirfsp->fsp_name->twrp,
+                                                    dirfsp->fsp_name->flags);
                TALLOC_FREE(talloced);
                dname = NULL;
 
@@ -1580,7 +1582,7 @@ NTSTATUS can_delete_directory_fsp(files_struct *fsp)
                }
 
                status = openat_pathref_fsp_lcomp(
-                       fsp,
+                       dirfsp,
                        direntry_fname,
                        UCF_POSIX_PATHNAMES /* no ci fallback */);
 
@@ -1604,13 +1606,13 @@ NTSTATUS can_delete_directory_fsp(files_struct *fsp)
                        int ret;
 
                        if (lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) &&
-                           is_msdfs_link(fsp, direntry_fname))
+                           is_msdfs_link(dirfsp, direntry_fname))
                        {
 
                                DBG_DEBUG("got msdfs link name %s "
                                          "- can't delete directory %s\n",
                                          direntry_fname->base_name,
-                                         fsp_str_dbg(fsp));
+                                         fsp_str_dbg(dirfsp));
 
                                status = NT_STATUS_DIRECTORY_NOT_EMPTY;
 
@@ -1620,7 +1622,7 @@ NTSTATUS can_delete_directory_fsp(files_struct *fsp)
 
                        /* Not a DFS link - could it be a dangling symlink ? */
                        ret = SMB_VFS_FSTATAT(conn,
-                                             fsp,
+                                             dirfsp,
                                              direntry_fname,
                                              &direntry_fname->st,
                                              0 /* 0 means follow symlink */);
@@ -1654,15 +1656,17 @@ NTSTATUS can_delete_directory_fsp(files_struct *fsp)
                status = NT_STATUS_DIRECTORY_NOT_EMPTY;
                break;
        }
-       TALLOC_FREE(dir_hnd);
 
        if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(dir_hnd);
                return status;
        }
 
-       if (have_file_open_below(fsp)) {
+       if (have_file_open_below(dirfsp)) {
+               TALLOC_FREE(dir_hnd);
                return NT_STATUS_ACCESS_DENIED;
        }
 
+       TALLOC_FREE(dir_hnd);
        return NT_STATUS_OK;
 }