1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
15 static const char usage[] =
16 "Usage: %s -u user_id [-g grp_id ] [ -G ] command\n"
17 " -u user_id switch to UID user_id\n"
18 " -g grp_id switch to GID grp_id\n"
19 " -G clear supplementary groups\n";
21 void Usage_and_abort(const char *name)
23 fprintf(stderr, usage, name);
27 int main(int argc, char **argv)
29 char **my_argv, *name = argv[0];
34 int clear_supp_groups = 0;
39 Usage_and_abort(name);
42 while ((c = getopt (argc, argv, "+u:g:hG")) != -1) {
45 user_id = (uid_t)atoi(optarg);
52 grp_id = (gid_t)atoi(optarg);
57 clear_supp_groups = 1;
62 Usage_and_abort(name);
68 Usage_and_abort(name);
71 fputs("Must specify command to run.\n", stderr);
72 Usage_and_abort(name);
75 // assemble the command
76 my_argv = (char**)malloc(sizeof(char*)*(argc+1-optind));
77 if (my_argv == NULL) {
78 fprintf(stderr, "Error in allocating memory. (%s)\n",
83 for (i = optind; i < argc; i++) {
84 my_argv[i-optind] = argv[i];
85 //printf("%s\n",my_argv[i-optind]);
87 my_argv[i-optind] = NULL;
94 status = setregid(grp_id, grp_id);
96 fprintf(stderr, "Cannot change grp_ID to %d, errno=%d (%s)\n",
97 grp_id, errno, strerror(errno) );
101 if (clear_supp_groups) {
102 status = setgroups(0, NULL);
104 perror("clearing supplementary groups");
110 status = setreuid(user_id, user_id );
112 fprintf(stderr,"Cannot change user_ID to %d, errno=%d (%s)\n",
113 user_id, errno, strerror(errno) );
117 fprintf(stderr, "running as UID %d, GID %d%s:", user_id, grp_id,
118 clear_supp_groups ? ", cleared groups" : "");
120 for (i = 0; i < argc - optind; i++)
121 fprintf(stderr, " [%s]", my_argv[i]);
123 fprintf(stderr, "\n");
126 // The command to be run
127 execvp(my_argv[0], my_argv);
128 fprintf(stderr, "execvp fails running %s\n", my_argv[0]);