]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Assume O_NOFOLLOW exists in unlink_directory_r()
authorAki Tuomi <aki.tuomi@open-xchange.com>
Thu, 26 Feb 2026 16:53:46 +0000 (18:53 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Tue, 3 Mar 2026 19:32:15 +0000 (19:32 +0000)
This flag is a FreeBSD extension, which was added in Linux
2.1.126, and has subsequently been standardized in
POSIX.1-2008.

src/lib/unlink-directory.c

index 52a6e697454ef78fc0015eff10abb01be979ed06..66725ad1200d43730aacd3cd0b2ff971366c1b15 100644 (file)
@@ -70,7 +70,6 @@ unlink_directory_r(const char *dir, enum unlink_directory_flags flags,
        struct stat st;
         int dir_fd, old_errno;
 
-#ifdef O_NOFOLLOW
        dir_fd = open(dir, O_RDONLY | O_NOFOLLOW);
        if (dir_fd == -1) {
                unlink_directory_error(error, NULL,
@@ -78,47 +77,6 @@ unlink_directory_r(const char *dir, enum unlink_directory_flags flags,
                                       dir);
                return -1;
        }
-#else
-       struct stat st2;
-
-       if (lstat(dir, &st) < 0) {
-               unlink_directory_error(error_r, NULL, ERROR_FORMAT, "lstat", dir);
-               return -1;
-       }
-
-       if (!S_ISDIR(st.st_mode)) {
-               if ((st.st_mode & S_IFMT) != S_IFLNK) {
-                       unlink_directory_error(error_r, NULL, "%s is not a directory: %s", dir);
-                       errno = ENOTDIR;
-               } else {
-                       /* be compatible with O_NOFOLLOW */
-                       errno = ELOOP;
-                       unlink_directory_error(error_r, NULL, "%s is a symlink, not a directory: %s", dir);
-               }
-               return -1;
-       }
-
-       dir_fd = open(dir, O_RDONLY);
-       if (dir_fd == -1) {
-               unlink_directory_error(error_r, NULL, "open(%s, O_RDONLY) failed: %m", dir);
-               return -1;
-       }
-
-       if (fstat(dir_fd, &st2) < 0) {
-               i_close_fd(&dir_fd);
-               unlink_directory_error(error_r, NULL, ERROR_FORMAT, "fstat", dir);
-               return -1;
-       }
-
-       if (st.st_ino != st2.st_ino ||
-           !CMP_DEV_T(st.st_dev, st2.st_dev)) {
-               /* directory was just replaced with something else. */
-               i_close_fd(&dir_fd);
-               errno = ENOTDIR;
-               unlink_directory_error(error_r, NULL, "%s race condition: directory was just replaced", dir);
-               return -1;
-       }
-#endif
        if (fchdir(dir_fd) < 0) {
                 i_close_fd(&dir_fd);
                unlink_directory_error(error, NULL, ERROR_FORMAT, "fchdir", dir);