tmpdir: Allow trusting of particular groups.
[checkpath] / tmpdir.c
index 8e704e6..e4cdde5 100644 (file)
--- a/tmpdir.c
+++ b/tmpdir.c
@@ -27,6 +27,7 @@
 /*----- Header files ------------------------------------------------------*/
 
 #include <errno.h>
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -35,6 +36,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <pwd.h>
+#include <grp.h>
 
 #include <mLib/alloc.h>
 #include <mLib/dstr.h>
@@ -265,6 +267,7 @@ Options supported:\n\
 -b, --bourne           Output a `TMPDIR' setting for Bourne shell users.\n\
 -c, --cshell           Output a `TMPDIR' setting for C shell users.\n\
 -v, --verbose          Report problems to standard error.\n\
+-g, --group NAME       Trust group NAME to be honest and true.\n\
 -C, --check PATH       Check whether PATH is good, setting exit status.\n\
 \n\
 The default action is to examine the caller's shell and output a suitable\n\
@@ -273,6 +276,46 @@ setting for that shell type.\n\
        fp);
 }
 
+/* --- @allowgroup@ --- *
+ *
+ * Arguments:  @const char *gname@ = trust group @gname@
+ *
+ * Returns:    ---
+ *
+ * Use:                Adds the gid corresponding to @gname@ (which may be a number)
+ *             to the list of things we trust.
+ */
+
+static void allowgroup(const char *gname)
+{
+  struct group *gr;
+  const char *p;
+  gid_t g;
+
+  /* --- Check for numeric group spec --- */
+
+  for (p = gname; *p; p++) {
+    if (!isdigit((unsigned char)*p))
+      goto lookup;
+  }
+  g = atoi(gname);
+  goto insert;
+
+  /* --- Look up a group by name --- */
+
+lookup:
+  if ((gr = getgrnam(gname)) == 0)
+    die(1, "group %s not found", gname);
+  g = gr->gr_gid;
+
+  /* --- Insert the group into the table --- */
+
+insert:
+  if (cp.cp_gids >= N(cp.cp_gid))
+    die(1, "too many groups");
+  cp.cp_gid[cp.cp_gids++] = g;
+}
+
 /* --- @main@ --- *
  *
  * Arguments:  @int argc@ = number of command line arguments
@@ -299,10 +342,12 @@ int main(int argc, char *argv[])
 
   ego(argv[0]);
   me = getuid();
-  cp.cp_what = CP_WRWORLD | CP_WRGRP | CP_WROTHUSR | CP_STICKYOK | CP_REPORT;
+  cp.cp_what = (CP_WRWORLD | CP_WROTHGRP | CP_WROTHUSR |
+               CP_STICKYOK | CP_REPORT);
   cp.cp_verbose = 0;
   cp.cp_report = report;
   checkpath_setids(&cp);
+  cp.cp_gids = 0;                      /* ignore group membership */
   pw = getpwuid(me);
   if (!pw)
     die(1, "you don't exist");
@@ -319,9 +364,11 @@ int main(int argc, char *argv[])
       { "check",       OPTF_ARGREQ,    0,      'C' },
       { "verify",      OPTF_ARGREQ,    0,      'C' },
       { "verbose",     0,              0,      'v' },
+      { "trust-groups",        0,              0,      't' },
+      { "group",       OPTF_ARGREQ,    0,      'g' },
       { 0,             0,              0,      0 }
     };
-    int i = mdwopt(argc, argv, "hVu bcvc:", opts, 0, 0, 0);
+    int i = mdwopt(argc, argv, "hVu bcvtg:c:", opts, 0, 0, 0);
 
     if (i < 0)
       break;
@@ -344,6 +391,9 @@ int main(int argc, char *argv[])
       case 'C':
        return (!fullcheck(optarg));
        break;
+      case 'g':
+       allowgroup(optarg);
+       break;
       case 'v':
        cp.cp_verbose++;
        break;