/*----- Static variables --------------------------------------------------*/
static uid_t me;
+static gid_t mygroup;
static struct checkpath cp;
static struct passwd *pw;
+static unsigned flags;
+#define F_PRIVGRP 1u
/*----- Main code ---------------------------------------------------------*/
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
/* --- @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@ --- */
-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\
int shell = 0;
int duff = 0;
int i;
+ gid_t gid;
char *p;
enum {
{ "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' },
{ 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) {
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;