s6-applyuidgid.c (2093B)
1 /* ISC license. */ 2 3 #include <unistd.h> 4 #include <grp.h> 5 #include <limits.h> 6 #include <stdlib.h> 7 8 #include <skalibs/types.h> 9 #include <skalibs/setgroups.h> 10 #include <skalibs/strerr.h> 11 #include <skalibs/sgetopt.h> 12 #include <skalibs/djbunix.h> 13 #include <skalibs/exec.h> 14 15 #define USAGE "s6-applyuidgid [ -z ] [ -u uid ] [ -g gid ] [ -G gidlist ] [ -U ] prog..." 16 #define dieusage() strerr_dieusage(100, USAGE) 17 18 int main (int argc, char const *const *argv) 19 { 20 uid_t uid = 0 ; 21 gid_t gid = 0 ; 22 gid_t gids[NGROUPS_MAX+1] ; 23 size_t gidn = (size_t)-1 ; 24 int unexport = 0 ; 25 PROG = "s6-applyuidgid" ; 26 { 27 subgetopt l = SUBGETOPT_ZERO ; 28 for (;;) 29 { 30 int opt = subgetopt_r(argc, argv, "zUu:g:G:", &l) ; 31 if (opt == -1) break ; 32 switch (opt) 33 { 34 case 'z' : unexport = 1 ; break ; 35 case 'u' : if (!uid0_scan(l.arg, &uid)) dieusage() ; break ; 36 case 'g' : if (!gid0_scan(l.arg, &gid)) dieusage() ; break ; 37 case 'G' : if (!gid_scanlist(gids, NGROUPS_MAX, l.arg, &gidn) && *l.arg) dieusage() ; break ; 38 case 'U' : 39 { 40 char const *x = getenv("UID") ; 41 if (!x) strerr_dienotset(100, "UID") ; 42 if (!uid0_scan(x, &uid)) strerr_dieinvalid(100, "UID") ; 43 x = getenv("GID") ; 44 if (!x) strerr_dienotset(100, "GID") ; 45 if (!gid0_scan(x, &gid)) strerr_dieinvalid(100, "GID") ; 46 x = getenv("GIDLIST") ; 47 if (!x) strerr_dienotset(100, "GIDLIST") ; 48 if (!gid_scanlist(gids, NGROUPS_MAX+1, x, &gidn) && *x) 49 strerr_dieinvalid(100, "GIDLIST") ; 50 break ; 51 } 52 default : dieusage() ; 53 } 54 } 55 argc -= l.ind ; argv += l.ind ; 56 } 57 if (!argc) dieusage() ; 58 59 if (gidn != (size_t)-1 && setgroups_and_gid(gid ? gid : getegid(), gidn, gids) < 0) 60 strerr_diefu1sys(111, "set supplementary group list") ; 61 if (gid && setgid(gid) < 0) 62 strerr_diefu1sys(111, "setgid") ; 63 if (uid && setuid(uid) < 0) 64 strerr_diefu1sys(111, "setuid") ; 65 66 if (unexport) xmexec_n(argv, "UID\0GID\0GIDLIST", 16, 3) ; 67 else xexec(argv) ; 68 }