tmpdir: Allow trusting of particular groups.
[checkpath] / tmpdir.c
index 137127a..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>
@@ -225,6 +227,13 @@ static char *goodtmp(void)
   return (0);
 }
 
+/* --- @report@ --- */
+
+static void report(unsigned what, int verbose,
+                  const char *p, const char *msg,
+                  void *arg)
+  { moan("%s", msg); }
+
 /* --- @usage@ --- */
 
 static void usage(FILE *fp)
@@ -257,7 +266,9 @@ Options supported:\n\
 \n\
 -b, --bourne           Output a `TMPDIR' setting for Bourne shell users.\n\
 -c, --cshell           Output a `TMPDIR' setting for C shell users.\n\
--v, --verify PATH      Check whether PATH is good, setting exit status.\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\
 setting for that shell type.\n\
@@ -265,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
@@ -291,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.cp_what = (CP_WRWORLD | CP_WROTHGRP | CP_WROTHUSR |
+               CP_STICKYOK | CP_REPORT);
   cp.cp_verbose = 0;
-  cp.cp_report = 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");
@@ -308,10 +361,14 @@ int main(int argc, char *argv[])
       { "usage",       0,              0,      'u' },
       { "bourne",      0,              0,      'b' },
       { "cshell",      0,              0,      'c' },
-      { "verify",      OPTF_ARGREQ,    0,      'v' },
+      { "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 bcv:", opts, 0, 0, 0);
+    int i = mdwopt(argc, argv, "hVu bcvtg:c:", opts, 0, 0, 0);
 
     if (i < 0)
       break;
@@ -331,9 +388,15 @@ int main(int argc, char *argv[])
       case 'c':
        shell = sh_csh;
        break;
-      case 'v':
+      case 'C':
        return (!fullcheck(optarg));
        break;
+      case 'g':
+       allowgroup(optarg);
+       break;
+      case 'v':
+       cp.cp_verbose++;
+       break;
       default:
        duff = 1;
        break;