version 1.7, 2015/07/18 00:19:38 |
version 1.8, 2015/07/18 06:33:23 |
|
|
static void __dead |
static void __dead |
usage(void) |
usage(void) |
{ |
{ |
fprintf(stderr, "usage: doas [-u user] command [args]\n"); |
fprintf(stderr, "usage: doas [-s] [-u user] command [args]\n"); |
exit(1); |
exit(1); |
} |
} |
|
|
|
|
int i, ch; |
int i, ch; |
const char *safepath = "/bin:/sbin:/usr/bin:/usr/sbin:" |
const char *safepath = "/bin:/sbin:/usr/bin:/usr/sbin:" |
"/usr/local/bin:/usr/local/sbin"; |
"/usr/local/bin:/usr/local/sbin"; |
|
int sflag = 0; |
|
char *shargv[] = { NULL, NULL }; |
|
char *sh; |
|
|
parseconfig("/etc/doas.conf"); |
parseconfig("/etc/doas.conf"); |
|
|
while ((ch = getopt(argc, argv, "u:")) != -1) { |
while ((ch = getopt(argc, argv, "su:")) != -1) { |
switch (ch) { |
switch (ch) { |
case 'u': |
case 'u': |
if (parseuid(optarg, &target) != 0) |
if (parseuid(optarg, &target) != 0) |
errx(1, "unknown user"); |
errx(1, "unknown user"); |
break; |
break; |
|
case 's': |
|
sflag = 1; |
|
break; |
default: |
default: |
usage(); |
usage(); |
break; |
break; |
|
|
argv += optind; |
argv += optind; |
argc -= optind; |
argc -= optind; |
|
|
if (!argc) |
if ((!sflag && !argc) || (sflag && argc)) |
usage(); |
usage(); |
|
|
cmd = argv[0]; |
|
if (strlcpy(cmdline, argv[0], sizeof(cmdline)) >= sizeof(cmdline)) |
|
errx(1, "command line too long"); |
|
for (i = 1; i < argc; i++) { |
|
if (strlcat(cmdline, " ", sizeof(cmdline)) >= sizeof(cmdline)) |
|
errx(1, "command line too long"); |
|
if (strlcat(cmdline, argv[i], sizeof(cmdline)) >= sizeof(cmdline)) |
|
errx(1, "command line too long"); |
|
} |
|
|
|
uid = getuid(); |
uid = getuid(); |
pw = getpwuid(uid); |
pw = getpwuid(uid); |
if (!pw) |
if (!pw) |
|
|
if (ngroups == -1) |
if (ngroups == -1) |
err(1, "can't get groups"); |
err(1, "can't get groups"); |
groups[ngroups++] = getgid(); |
groups[ngroups++] = getgid(); |
|
|
|
if (sflag) { |
|
sh = getenv("SHELL"); |
|
if (sh == NULL || *sh == '\0') |
|
shargv[0] = pw->pw_shell; |
|
else |
|
shargv[0] = sh; |
|
argv = shargv; |
|
argc = 1; |
|
} |
|
|
|
cmd = argv[0]; |
|
if (strlcpy(cmdline, argv[0], sizeof(cmdline)) >= sizeof(cmdline)) |
|
errx(1, "command line too long"); |
|
for (i = 1; i < argc; i++) { |
|
if (strlcat(cmdline, " ", sizeof(cmdline)) >= sizeof(cmdline)) |
|
errx(1, "command line too long"); |
|
if (strlcat(cmdline, argv[i], sizeof(cmdline)) >= sizeof(cmdline)) |
|
errx(1, "command line too long"); |
|
} |
|
|
if (!permit(uid, groups, ngroups, &rule, target, cmd)) { |
if (!permit(uid, groups, ngroups, &rule, target, cmd)) { |
syslog(LOG_AUTHPRIV | LOG_NOTICE, |
syslog(LOG_AUTHPRIV | LOG_NOTICE, |