s3: smbd: Allow rmdir_internals() to cope with veto'ed symlinks.
authorJeremy Allison <jra@samba.org>
Thu, 3 Jun 2021 18:15:50 +0000 (11:15 -0700)
committerRalph Boehme <slow@samba.org>
Wed, 9 Jun 2021 13:14:30 +0000 (13:14 +0000)
We are only dealing with VETO'ed objects
here. If it's a symlink, just delete the
link without caring what it is pointing
to as this operation is safe.

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

index 0113bed781cf649ea060364dc3c0a45c4ad4f660..9b53c4a088c2bbcaa00eaf2b83f5be7254369715 100644 (file)
@@ -1125,25 +1125,44 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, struct files_struct *fsp)
                        goto err_break;
                }
 
-               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)) {
-                       errno = map_errno_from_nt_status(status);
-                       goto err_break;
-               }
+               /*
+                * We are only dealing with VETO'ed objects
+                * here. If it's a symlink, just delete the
+                * link without caring what it is pointing
+                * to.
+                */
+               if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
+                       direntry_fname = synthetic_smb_fname(talloc_tos(),
+                                                       dname,
+                                                       NULL,
+                                                       &smb_dname_full->st,
+                                                       smb_dname->twrp,
+                                                       smb_dname->flags);
+                       if (direntry_fname == NULL) {
+                               errno = ENOMEM;
+                               goto err_break;
+                       }
+               } else {
+                       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)) {
+                               errno = map_errno_from_nt_status(status);
+                               goto err_break;
+                       }
 
-               if (!is_visible_fsp(direntry_fname->fsp, false)) {
-                       TALLOC_FREE(fullname);
-                       TALLOC_FREE(smb_dname_full);
-                       TALLOC_FREE(talloced);
-                       TALLOC_FREE(direntry_fname);
-                       continue;
+                       if (!is_visible_fsp(direntry_fname->fsp, false)) {
+                               TALLOC_FREE(fullname);
+                               TALLOC_FREE(smb_dname_full);
+                               TALLOC_FREE(talloced);
+                               TALLOC_FREE(direntry_fname);
+                               continue;
+                       }
                }
 
                unlink_flags = 0;