From: Jeremy Allison Date: Mon, 25 Oct 2021 19:32:29 +0000 (-0700) Subject: s3: smbd: Fix logic in rmdir_internals() to cope with dangling symlinks. X-Git-Url: http://git.samba.org/samba.git/?a=commitdiff_plain;h=26fecad2e66e91a3913d88ee2e0889f266e91d89;p=gd%2Fsamba-autobuild%2F.git s3: smbd: Fix logic in rmdir_internals() to cope with dangling symlinks. Still need to add the same logic in can_delete_directory_fsp() before we can delete the knownfail. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14879 Signed-off-by: Jeremy Allison Reviewed-by: Ralph Boehme --- diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 882a7bbbeb3..eae276b2e9c 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -1100,15 +1100,61 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, struct files_struct *fsp) goto err; } - /* - * 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_atname; + smb_atname = synthetic_smb_fname(talloc_tos(), + dname, + NULL, + &smb_dname_full->st, + fsp->fsp_name->twrp, + fsp->fsp_name->flags); + if (smb_atname == NULL) { + TALLOC_FREE(talloced); + TALLOC_FREE(fullname); + TALLOC_FREE(smb_dname_full); + errno = ENOMEM; + goto err; + } + if (is_msdfs_link(fsp, smb_atname)) { + TALLOC_FREE(talloced); + TALLOC_FREE(fullname); + TALLOC_FREE(smb_dname_full); + TALLOC_FREE(smb_atname); + DBG_DEBUG("got msdfs link name %s " + "- can't delete directory %s\n", + dname, + fsp_str_dbg(fsp)); + errno = ENOTEMPTY; + goto err; + } + TALLOC_FREE(smb_atname); + } + + /* 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 delete as "delete veto files = yes" + */ + 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); - continue; + errno = ENOTEMPTY; + goto err; } /* Not a symlink, get a pathref. */