]> granicus.if.org Git - sudo/commitdiff
Fall back on lstat(2) if d_type in struct dirent is DT_UNKNOWN.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 17 Sep 2012 17:20:30 +0000 (13:20 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 17 Sep 2012 17:20:30 +0000 (13:20 -0400)
Not all file systems support d_type.  Bug #572

plugins/sudoers/sudoreplay.c

index a61c0f5c2bbfc01ea16642109e83d9cb1663efbb..adbc9bab616aa61eece9ddf9171603d3199d4153 100644 (file)
@@ -968,6 +968,11 @@ find_sessions(const char *dir, REGEX_T *re, const char *user, const char *tty)
     size_t sdlen, sessions_len = 0, sessions_size = 36*36;
     int i, len;
     char pathbuf[PATH_MAX], **sessions = NULL;
+#ifdef HAVE_STRUCT_DIRENT_D_TYPE
+    bool checked_type = true;
+#else
+    const bool checked_type = false;
+#endif
     debug_decl(find_sessions, SUDO_DEBUG_UTIL)
 
     d = opendir(dir);
@@ -991,8 +996,14 @@ find_sessions(const char *dir, REGEX_T *re, const char *user, const char *tty)
            (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
            continue;
 #ifdef HAVE_STRUCT_DIRENT_D_TYPE
-       if (dp->d_type != DT_DIR)
-           continue;
+       if (checked_type) {
+           if (dp->d_type != DT_DIR) {
+               /* Not all file systems support d_type. */
+               if (dp->d_type != DT_UNKNOWN)
+                   continue;
+               checked_type = false;
+           }
+       }
 #endif
 
        /* Add name to session list. */
@@ -1021,9 +1032,7 @@ find_sessions(const char *dir, REGEX_T *re, const char *user, const char *tty)
        } else {
            /* Strip off "/log" and recurse if a dir. */
            pathbuf[sdlen + len - 4] = '\0';
-#ifndef HAVE_STRUCT_DIRENT_D_TYPE
-           if (lstat(pathbuf, &sb) == 0 && S_ISDIR(sb.st_mode))
-#endif
+           if (checked_type || (lstat(pathbuf, &sb) == 0 && S_ISDIR(sb.st_mode)))
                find_sessions(pathbuf, re, user, tty);
        }
     }