version 1.21, 2015/07/24 06:36:42 |
version 1.22, 2015/07/26 17:24:02 |
|
|
} |
} |
|
|
static void |
static void |
parseconfig(const char *filename) |
parseconfig(const char *filename, int checkperms) |
{ |
{ |
extern FILE *yyfp; |
extern FILE *yyfp; |
extern int yyparse(void); |
extern int yyparse(void); |
|
|
|
|
yyfp = fopen(filename, "r"); |
yyfp = fopen(filename, "r"); |
if (!yyfp) { |
if (!yyfp) { |
fprintf(stderr, "doas is not enabled.\n"); |
if (checkperms) |
|
fprintf(stderr, "doas is not enabled.\n"); |
|
else |
|
warn("could not open config file"); |
exit(1); |
exit(1); |
} |
} |
|
|
if (fstat(fileno(yyfp), &sb) != 0) |
if (checkperms) { |
err(1, "fstat(\"%s\")", filename); |
if (fstat(fileno(yyfp), &sb) != 0) |
if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) |
err(1, "fstat(\"%s\")", filename); |
errx(1, "%s is writable by group or other", filename); |
if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) |
if (sb.st_uid != 0) |
errx(1, "%s is writable by group or other", filename); |
errx(1, "%s is not owned by root", filename); |
if (sb.st_uid != 0) |
|
errx(1, "%s is not owned by root", filename); |
|
} |
|
|
yyparse(); |
yyparse(); |
fclose(yyfp); |
fclose(yyfp); |
|
|
exit(1); |
exit(1); |
} |
} |
|
|
|
static int |
|
checkconfig(const char *confpath, int argc, char **argv, |
|
uid_t uid, gid_t *groups, int ngroups, uid_t target) { |
|
struct rule *rule; |
|
|
|
setresuid(uid, uid, uid); |
|
parseconfig(confpath, 0); |
|
if (!argc) |
|
exit(0); |
|
|
|
if (permit(uid, groups, ngroups, &rule, target, argv[0], |
|
(const char **)argv + 1)) { |
|
printf("permit%s\n", (rule->options & NOPASS) ? " nopass" : ""); |
|
return 1; |
|
} else { |
|
printf("deny\n"); |
|
return 0; |
|
} |
|
} |
|
|
int |
int |
main(int argc, char **argv, char **envp) |
main(int argc, char **argv, char **envp) |
{ |
{ |
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"; |
|
const char *confpath = NULL; |
char *shargv[] = { NULL, NULL }; |
char *shargv[] = { NULL, NULL }; |
char *sh; |
char *sh; |
const char *cmd; |
const char *cmd; |
|
|
int i, ch; |
int i, ch; |
int sflag = 0; |
int sflag = 0; |
|
|
uid = getuid(); |
|
while ((ch = getopt(argc, argv, "C:su:")) != -1) { |
while ((ch = getopt(argc, argv, "C:su:")) != -1) { |
switch (ch) { |
switch (ch) { |
case 'C': |
case 'C': |
setresuid(uid, uid, uid); |
confpath = optarg; |
parseconfig(optarg); |
break; |
exit(0); |
|
case 'u': |
case 'u': |
if (parseuid(optarg, &target) != 0) |
if (parseuid(optarg, &target) != 0) |
errx(1, "unknown user"); |
errx(1, "unknown user"); |
|
|
argv += optind; |
argv += optind; |
argc -= optind; |
argc -= optind; |
|
|
if ((!sflag && !argc) || (sflag && argc)) |
if (confpath) { |
|
if (sflag) |
|
usage(); |
|
} else if ((!sflag && !argc) || (sflag && argc)) |
usage(); |
usage(); |
|
|
parseconfig("/etc/doas.conf"); |
uid = getuid(); |
|
|
pw = getpwuid(uid); |
pw = getpwuid(uid); |
if (!pw) |
if (!pw) |
err(1, "getpwuid failed"); |
err(1, "getpwuid failed"); |
|
|
argv = shargv; |
argv = shargv; |
argc = 1; |
argc = 1; |
} |
} |
|
|
|
if (confpath) |
|
exit(!checkconfig(confpath, argc, argv, uid, groups, ngroups, |
|
target)); |
|
parseconfig("/etc/doas.conf", 1); |
|
|
cmd = argv[0]; |
cmd = argv[0]; |
if (strlcpy(cmdline, argv[0], sizeof(cmdline)) >= sizeof(cmdline)) |
if (strlcpy(cmdline, argv[0], sizeof(cmdline)) >= sizeof(cmdline)) |