]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: smbd: Fix logic in can_delete_directory_fsp() to cope with dangling symlinks.
authorJeremy Allison <jra@samba.org>
Mon, 25 Oct 2021 19:36:57 +0000 (12:36 -0700)
committerRalph Boehme <slow@samba.org>
Fri, 29 Oct 2021 14:02:34 +0000 (14:02 +0000)
Remove knownfail.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14879

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
selftest/knownfail.d/rmdir_dangle_symlink [deleted file]
source3/smbd/dir.c

diff --git a/selftest/knownfail.d/rmdir_dangle_symlink b/selftest/knownfail.d/rmdir_dangle_symlink
deleted file mode 100644 (file)
index c775dc5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-^samba3.blackbox.test_dangle_rmdir.rmdir can delete directory containing dangling symlink\(fileserver\)
index 174f07b11591b49468ae156082f4a779290d2b51..4d61bb0d56d54caebc0373fac868c5aa63e2224b 100644 (file)
@@ -1922,16 +1922,59 @@ NTSTATUS can_delete_directory_fsp(files_struct *fsp)
                        break;
                }
 
-               /*
-                * is_visible_fsp() always returns true
-                * for the symlink/MSDFS case.
-                */
-
                if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
+                       /* Could it be an msdfs link ? */
+                       if (lp_host_msdfs() &&
+                           lp_msdfs_root(SNUM(conn))) {
+                               struct smb_filename *smb_dname;
+                               smb_dname = synthetic_smb_fname(talloc_tos(),
+                                                       dname,
+                                                       NULL,
+                                                       &smb_dname_full->st,
+                                                       fsp->fsp_name->twrp,
+                                                       fsp->fsp_name->flags);
+                               if (smb_dname == NULL) {
+                                       TALLOC_FREE(talloced);
+                                       TALLOC_FREE(fullname);
+                                       TALLOC_FREE(smb_dname_full);
+                                       status = NT_STATUS_NO_MEMORY;
+                                       break;
+                               }
+                               if (is_msdfs_link(fsp, smb_dname)) {
+                                       TALLOC_FREE(talloced);
+                                       TALLOC_FREE(fullname);
+                                       TALLOC_FREE(smb_dname_full);
+                                       TALLOC_FREE(smb_dname);
+                                       DBG_DEBUG("got msdfs link name %s "
+                                               "- can't delete directory %s\n",
+                                               dname,
+                                               fsp_str_dbg(fsp));
+                                       status = NT_STATUS_DIRECTORY_NOT_EMPTY;
+                                       break;
+                               }
+                               TALLOC_FREE(smb_dname);
+                       }
+                       /* Not a DFS link - could it be a dangling symlink ? */
+                       ret = SMB_VFS_STAT(conn, smb_dname_full);
+                       if (ret == -1 && (errno == ENOENT || errno == ELOOP)) {
+                               /*
+                                * Dangling symlink.
+                                * Allow if "delete veto files = yes"
+                                */
+                               if (lp_delete_veto_files(SNUM(conn))) {
+                                       TALLOC_FREE(talloced);
+                                       TALLOC_FREE(fullname);
+                                       TALLOC_FREE(smb_dname_full);
+                                       continue;
+                               }
+                       }
+                       DBG_DEBUG("got symlink name %s - "
+                               "can't delete directory %s\n",
+                               dname,
+                               fsp_str_dbg(fsp));
                        TALLOC_FREE(talloced);
                        TALLOC_FREE(fullname);
                        TALLOC_FREE(smb_dname_full);
-                       DBG_DEBUG("got name %s - can't delete\n", dname);
                        status = NT_STATUS_DIRECTORY_NOT_EMPTY;
                        break;
                }