X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/checkpath/blobdiff_plain/972ca7cda65ce3fc9f150c20a56ad4836f3a7414..refs/heads/mdw/privgrp:/tmpdir.c diff --git a/tmpdir.c b/tmpdir.c index 18eb440..4c6f4b2 100644 --- a/tmpdir.c +++ b/tmpdir.c @@ -53,8 +53,11 @@ /*----- 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 ---------------------------------------------------------*/ @@ -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); - 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 @@ -258,7 +264,7 @@ static void report(unsigned what, int verbose, /* --- @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@ --- */ @@ -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\ +-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\ @@ -312,6 +320,7 @@ int main(int argc, char *argv[]) int shell = 0; int duff = 0; int i; + gid_t gid; 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' }, + { "private-group", 0, 0, 'T' }, { "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 } }; - 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) { @@ -366,6 +376,13 @@ int main(int argc, char *argv[]) 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;