#include <string.h>
#include <sys/param.h>
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <grp.h>
#include <limits.h>
#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 */
}
syntax highlighted by Code2HTML, v. 0.9.1