Files
fruix/tests/daemon/freebsd-drop-exec.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;
}