chiark / gitweb /
chkpath.c, tmpdir.c, utils.c: Add option to trust private groups.
[checkpath] / tmpdir.c
index 18eb4400c34b8ba95c36489fd9850de9c1fff76a..4c6f4b2d8cb8248c95a739cb002a033b45868ca9 100644 (file)
--- a/tmpdir.c
+++ b/tmpdir.c
 /*----- Static variables --------------------------------------------------*/
 
 static uid_t me;
 /*----- Static variables --------------------------------------------------*/
 
 static uid_t me;
+static gid_t mygroup;
 static struct checkpath cp;
 static struct passwd *pw;
 static struct checkpath cp;
 static struct passwd *pw;
+static unsigned flags;
+#define F_PRIVGRP 1u
 
 /*----- Main code ---------------------------------------------------------*/
 
 
 /*----- Main code ---------------------------------------------------------*/
 
@@ -122,8 +125,11 @@ static int ok(const char *p, int *f)
     complain(p, "not a directory", 0);
   else if (st.st_uid != me)
     complain(p, "not owner", 0);
     complain(p, "not a directory", 0);
   else if (st.st_uid != me)
     complain(p, "not owner", 0);
-  else if (st.st_mode & (S_IRWXG | S_IRWXO))
-    complain(p, "non-owner access permitted", 0);
+  else if (st.st_mode & S_IRWXO)
+    complain(p, "other access permitted", 0);
+  else if (!((flags & F_PRIVGRP) && st.st_gid != mygroup) &&
+          (st.st_mode & S_IRWXG))
+    complain(p, "other-group access permitted", 0);
   else if (~st.st_mode & S_IRWXU)
     complain(p, "owner lacks permissions", 0);
   else
   else if (~st.st_mode & S_IRWXU)
     complain(p, "owner lacks permissions", 0);
   else
@@ -258,7 +264,7 @@ static void report(unsigned what, int verbose,
 /* --- @usage@ --- */
 
 static void usage(FILE *fp)
 /* --- @usage@ --- */
 
 static void usage(FILE *fp)
-  { fprintf(fp, "Usage: %s [-bcv] [-C PATH] [-g NAME]\n", QUIS); }
+  { fprintf(fp, "Usage: %s [-Tbcv] [-C PATH] [-g NAME]\n", QUIS); }
 
 /* --- @version@ --- */
 
 
 /* --- @version@ --- */
 
@@ -286,6 +292,8 @@ Options supported:\n\
 -u, --usage            Display a terse usage summary.\n\
 \n\
 -C, --check PATH       Check whether PATH is good, setting exit status.\n\
 -u, --usage            Display a terse usage summary.\n\
 \n\
 -C, --check PATH       Check whether PATH is good, setting exit status.\n\
+-T, --private-group    Accept paths writable by primary group if it has\n\
+                       no other members.\n\
 -b, --bourne           Output a `TMPDIR' setting for Bourne shell users.\n\
 -c, --cshell           Output a `TMPDIR' setting for C shell users.\n\
 -g, --group NAME       Trust group NAME to be honest and true.\n\
 -b, --bourne           Output a `TMPDIR' setting for Bourne shell users.\n\
 -c, --cshell           Output a `TMPDIR' setting for C shell users.\n\
 -g, --group NAME       Trust group NAME to be honest and true.\n\
@@ -312,6 +320,7 @@ int main(int argc, char *argv[])
   int shell = 0;
   int duff = 0;
   int i;
   int shell = 0;
   int duff = 0;
   int i;
+  gid_t gid;
   char *p;
 
   enum {
   char *p;
 
   enum {
@@ -342,6 +351,7 @@ int main(int argc, char *argv[])
       { "usage",       0,              0,      'u' },
       { "check",       OPTF_ARGREQ,    0,      'C' },
       { "verify",      OPTF_ARGREQ,    0,      'C' },
       { "usage",       0,              0,      'u' },
       { "check",       OPTF_ARGREQ,    0,      'C' },
       { "verify",      OPTF_ARGREQ,    0,      'C' },
+      { "private-group", 0,            0,      'T' },
       { "bourne",      0,              0,      'b' },
       { "cshell",      0,              0,      'c' },
       { "group",       OPTF_ARGREQ,    0,      'g' },
       { "bourne",      0,              0,      'b' },
       { "cshell",      0,              0,      'c' },
       { "group",       OPTF_ARGREQ,    0,      'g' },
@@ -350,7 +360,7 @@ int main(int argc, char *argv[])
       { 0,             0,              0,      0 }
     };
 
       { 0,             0,              0,      0 }
     };
 
-    i = mdwopt(argc, argv, "hVu" "C:bcg:v", opts, 0, 0, 0);
+    i = mdwopt(argc, argv, "hVu" "C:Tbcg:qv", opts, 0, 0, 0);
     if (i < 0)
       break;
     switch (i) {
     if (i < 0)
       break;
     switch (i) {
@@ -366,6 +376,13 @@ int main(int argc, char *argv[])
       case 'C':
        return (!fullcheck(optarg));
        break;
       case 'C':
        return (!fullcheck(optarg));
        break;
+      case 'T':
+       if (!private_group(&gid, cp.cp_verbose)) {
+         mygroup = gid; flags |= F_PRIVGRP;
+         if (checkpath_addgid(&cp, gid))
+           die(1, "too many groups");
+       }
+       break;
       case 'b':
        shell = sh_bourne;
        break;
       case 'b':
        shell = sh_bourne;
        break;