On Fri, 15 Apr 2022 at 09:32:46 -0600, Todd C. Miller wrote:
> On Thu, 14 Apr 2022 17:52:37 -0500, joshua stein wrote:
> 
> > login_fbtab(3) supports wildcards but only for every file in a 
> > directory (/path/*).
> >
> > This makes it use glob(3) so it can also support more specific 
> > wildcards like /path/file*
> 
> Yes, it is better to use glob(3) than something custom.
> Comments inline.

Thanks, both applied.


diff --git lib/libutil/login_fbtab.c lib/libutil/login_fbtab.c
index 5eacf4f65ff..b81bc8e38e4 100644
--- lib/libutil/login_fbtab.c
+++ lib/libutil/login_fbtab.c
@@ -61,8 +61,8 @@
 #include <sys/stat.h>
 
 #include <errno.h>
-#include <dirent.h>
 #include <limits.h>
+#include <glob.h>
 #include <paths.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -134,49 +134,31 @@ login_fbtab(const char *tty, uid_t uid, gid_t gid)
 static void
 login_protect(const char *path, mode_t mask, uid_t uid, gid_t gid)
 {
-       char    buf[PATH_MAX];
-       size_t  pathlen = strlen(path);
-       DIR     *dir;
-       struct  dirent *ent;
+       glob_t  g;
+       size_t  n;
+       char    *gpath;
 
-       if (pathlen >= sizeof(buf)) {
+       if (strlen(path) >= PATH_MAX) {
                errno = ENAMETOOLONG;
                syslog(LOG_ERR, "%s: %s: %m", _PATH_FBTAB, path);
                return;
        }
 
-       if (strcmp("/*", path + pathlen - 2) != 0) {
-               if (chmod(path, mask) && errno != ENOENT)
-                       syslog(LOG_ERR, "%s: chmod(%s): %m", _PATH_FBTAB, path);
-               if (chown(path, uid, gid) && errno != ENOENT)
-                       syslog(LOG_ERR, "%s: chown(%s): %m", _PATH_FBTAB, path);
-       } else {
-               /*
-                * This is a wildcard directory (/path/to/whatever/ * ).
-                * Make a copy of path without the trailing '*' (but leave
-                * the trailing '/' so we can append directory entries.)
-                */
-               memcpy(buf, path, pathlen - 1);
-               buf[pathlen - 1] = '\0';
-               if ((dir = opendir(buf)) == NULL) {
-                       syslog(LOG_ERR, "%s: opendir(%s): %m", _PATH_FBTAB,
-                           path);
-                       return;
-               }
+       if (glob(path, GLOB_NOSORT, NULL, &g) != 0) {
+               if (errno != ENOENT)
+                       syslog(LOG_ERR, "%s: glob(%s): %m", _PATH_FBTAB, path);
+               globfree(&g);
+               return;
+       }
 
-               while ((ent = readdir(dir)) != NULL) {
-                       if (strcmp(ent->d_name, ".")  != 0 &&
-                           strcmp(ent->d_name, "..") != 0) {
-                               buf[pathlen - 1] = '\0';
-                               if (strlcat(buf, ent->d_name, sizeof(buf))
-                                   >= sizeof(buf)) {
-                                       errno = ENAMETOOLONG;
-                                       syslog(LOG_ERR, "%s: %s: %m",
-                                           _PATH_FBTAB, path);
-                               } else
-                                       login_protect(buf, mask, uid, gid);
-                       }
-               }
-               closedir(dir);
+       for (n = 0; n < g.gl_matchc; n++) {
+               gpath = g.gl_pathv[n];
+
+               if (chmod(gpath, mask) && errno != ENOENT)
+                       syslog(LOG_ERR, "%s: chmod(%s): %m", _PATH_FBTAB, 
gpath);
+               if (chown(gpath, uid, gid) && errno != ENOENT)
+                       syslog(LOG_ERR, "%s: chown(%s): %m", _PATH_FBTAB, 
gpath);
        }
+
+       globfree(&g);
 }

Reply via email to