]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: smbd: rmdir_internals(), fix the initial directory scan pass to use is_visible_fsp().
authorJeremy Allison <jra@samba.org>
Fri, 4 Jun 2021 19:16:17 +0000 (12:16 -0700)
committerRalph Boehme <slow@samba.org>
Wed, 9 Jun 2021 13:14:30 +0000 (13:14 +0000)
Add the same symlink accomodation as before.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/smbd/close.c

index 9b53c4a088c2bbcaa00eaf2b83f5be7254369715..439308294af586613f6e05d149dabb43ae19e49b 100644 (file)
@@ -1050,25 +1050,93 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, struct files_struct *fsp)
        }
 
        while ((dname = ReadDirName(dir_hnd, &dirpos, &st, &talloced)) != NULL) {
+               struct smb_filename *smb_dname_full = NULL;
+               struct smb_filename *direntry_fname = NULL;
+               char *fullname = NULL;
+
                if (ISDOT(dname) || ISDOTDOT(dname)) {
                        TALLOC_FREE(talloced);
                        continue;
                }
-               if (!is_visible_file(conn,
-                                    dir_hnd,
-                                    dname,
-                                    &st,
-                                    false))
-               {
+               if (IS_VETO_PATH(conn, dname)) {
+                       TALLOC_FREE(talloced);
+                       continue;
+               }
+
+               fullname = talloc_asprintf(talloc_tos(),
+                                          "%s/%s",
+                                          smb_dname->base_name,
+                                          dname);
+
+               if (fullname == NULL) {
+                       TALLOC_FREE(talloced);
+                       errno = ENOMEM;
+                       goto err;
+               }
+
+               smb_dname_full = synthetic_smb_fname(talloc_tos(),
+                                                    fullname,
+                                                    NULL,
+                                                    NULL,
+                                                    smb_dname->twrp,
+                                                    smb_dname->flags);
+               if (smb_dname_full == NULL) {
+                       TALLOC_FREE(talloced);
+                       TALLOC_FREE(fullname);
+                       errno = ENOMEM;
+                       goto err;
+               }
+
+               ret = SMB_VFS_LSTAT(conn, smb_dname_full);
+               if (ret != 0) {
+                       int saved_errno = errno;
+                       TALLOC_FREE(talloced);
+                       TALLOC_FREE(fullname);
+                       TALLOC_FREE(smb_dname_full);
+                       errno = saved_errno;
+                       goto err;
+               }
+
+               /*
+                * is_visible_fsp() always returns true
+                * for the symlink/MSDFS case.
+                */
+               if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
                        TALLOC_FREE(talloced);
+                       TALLOC_FREE(fullname);
+                       TALLOC_FREE(smb_dname_full);
                        continue;
                }
-               if (!IS_VETO_PATH(conn, dname)) {
+
+               /* Not a symlink, get a pathref. */
+               status = synthetic_pathref(talloc_tos(),
+                                          dirfsp,
+                                          dname,
+                                          NULL,
+                                          &smb_dname_full->st,
+                                          smb_dname->twrp,
+                                          smb_dname->flags,
+                                          &direntry_fname);
+               if (!NT_STATUS_IS_OK(status)) {
                        TALLOC_FREE(talloced);
-                       errno = ENOTEMPTY;
+                       TALLOC_FREE(fullname);
+                       TALLOC_FREE(smb_dname_full);
+                       errno = map_errno_from_nt_status(status);
                        goto err;
                }
+
+               if (!is_visible_fsp(direntry_fname->fsp, false)) {
+                       TALLOC_FREE(talloced);
+                       TALLOC_FREE(fullname);
+                       TALLOC_FREE(smb_dname_full);
+                       TALLOC_FREE(direntry_fname);
+                       continue;
+               }
+
                TALLOC_FREE(talloced);
+               TALLOC_FREE(fullname);
+               TALLOC_FREE(smb_dname_full);
+               TALLOC_FREE(direntry_fname);
        }
 
        /* We only have veto files/directories.