#include #include #include #include #include #include #include #include #include "iolib.h" #include "freedt.h" #include "config.h" const char *progname = "setuidgid"; const char *proghelp = "Usage: setuidgid [OPTIONS] account command ...\n" "Run a command under the uid and gid of an account.\n\n" "-s Also set supplementary groups\n"; int main(int argc, char **argv) { struct passwd *p; int use_supp = 0; while (1) { int c = getopt(argc, argv, "+V?s"); if (c == -1) break; switch (c) { case 's': use_supp = 1; break; case 'V': version(); default: help(); } } if ((argc - optind) < 2) help(); p = getpwnam(argv[optind]); if (!p) die("no such account"); if (setgid(p->pw_gid) < 0) die("unable to setgid"); if (use_supp) { gid_t groups[NGROUPS_MAX]; size_t n = 0; setgrent(); while (1) { char **p; struct group *g = getgrent(); if (g == NULL) break; for (p = g->gr_mem; *p != NULL; p++) { if (strcmp(*p, argv[optind]) == 0) { if (n >= NGROUPS_MAX) die("too many groups"); groups[n++] = g->gr_gid; } } } if (setgroups(n, groups) < 0) die("unable to setgroups"); } else { if (setgroups(1, &p->pw_gid) < 0) die("unable to setgroups"); } if (setuid(p->pw_uid) < 0) die("unable to setuid"); ++optind; execvp(argv[optind], &argv[optind]); die2(argv[optind], "unable to exec"); return 0; /* NOTREACHED */ }