74 lines
1.5 KiB
C
74 lines
1.5 KiB
C
#include <errno.h>
|
|
#include <grp.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
static void
|
|
usage(const char *argv0)
|
|
{
|
|
fprintf(stderr, "usage: %s --uid UID --gid GID -- cmd...\n", argv0);
|
|
}
|
|
|
|
static unsigned long
|
|
parse_ulong(const char *text)
|
|
{
|
|
char *end = NULL;
|
|
unsigned long value;
|
|
|
|
errno = 0;
|
|
value = strtoul(text, &end, 10);
|
|
if (errno != 0 || end == text || *end != '\0')
|
|
exit(2);
|
|
|
|
return value;
|
|
}
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
uid_t uid = (uid_t)-1;
|
|
gid_t gid = (gid_t)-1;
|
|
gid_t groups[1];
|
|
int i;
|
|
|
|
for (i = 1; i < argc; i++) {
|
|
if (strcmp(argv[i], "--uid") == 0 && i + 1 < argc) {
|
|
uid = (uid_t)parse_ulong(argv[++i]);
|
|
} else if (strcmp(argv[i], "--gid") == 0 && i + 1 < argc) {
|
|
gid = (gid_t)parse_ulong(argv[++i]);
|
|
} else if (strcmp(argv[i], "--") == 0) {
|
|
i++;
|
|
break;
|
|
} else {
|
|
usage(argv[0]);
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
if (uid == (uid_t)-1 || gid == (gid_t)-1 || i >= argc) {
|
|
usage(argv[0]);
|
|
return 2;
|
|
}
|
|
|
|
groups[0] = gid;
|
|
if (setgroups(1, groups) != 0) {
|
|
perror("setgroups");
|
|
return 1;
|
|
}
|
|
if (setgid(gid) != 0) {
|
|
perror("setgid");
|
|
return 1;
|
|
}
|
|
if (setuid(uid) != 0) {
|
|
perror("setuid");
|
|
return 1;
|
|
}
|
|
|
|
execvp(argv[i], &argv[i]);
|
|
perror("execvp");
|
|
return 1;
|
|
}
|