X-Git-Url: https://git.armaanb.net/?a=blobdiff_plain;f=doas.c;h=71f955a76afc65b7a328ff9b2963f6b8537eaf2f;hb=4356cb6b4cefb142d182784c264ce936a1ec3626;hp=1fd0e9a9c455ab62e32b738019cc2f3fbb14a947;hpb=dbc7d06b5bbf01652744423bd8825ea7b5e92f73;p=opendoas.git diff --git a/doas.c b/doas.c index 1fd0e9a..71f955a 100644 --- a/doas.c +++ b/doas.c @@ -249,6 +249,46 @@ good: } #endif +#ifdef __OpenBSD__ +int +unveilcommands(const char *ipath, const char *cmd) +{ + char *path = NULL, *p; + int unveils = 0; + + if (strchr(cmd, '/') != NULL) { + if (unveil(cmd, "x") != -1) + unveils++; + goto done; + } + + if (!ipath) { + errno = ENOENT; + goto done; + } + path = strdup(ipath); + if (!path) { + errno = ENOENT; + goto done; + } + for (p = path; p && *p; ) { + char buf[PATH_MAX]; + char *cp = strsep(&p, ":"); + + if (cp) { + int r = snprintf(buf, sizeof buf, "%s/%s", cp, cmd); + if (r >= 0 && r < sizeof buf) { + if (unveil(buf, "x") != -1) + unveils++; + } + } + } +done: + free(path); + return (unveils); +} +#endif + int main(int argc, char **argv) { @@ -257,6 +297,7 @@ main(int argc, char **argv) const char *confpath = NULL; char *shargv[] = { NULL, NULL }; char *sh; + const char *p; const char *cmd; char cmdline[LINE_MAX]; #ifdef __OpenBSD__ @@ -411,7 +452,24 @@ main(int argc, char **argv) # endif } + if ((p = getenv("PATH")) != NULL) + formerpath = strdup(p); + if (formerpath == NULL) + formerpath = ""; + # ifdef __OpenBSD__ + if (unveil(_PATH_LOGIN_CONF, "r") == -1 || + unveil(_PATH_LOGIN_CONF ".db", "r") == -1) + err(1, "unveil"); +# endif + if (rule->cmd) { + if (setenv("PATH", safepath, 1) == -1) + err(1, "failed to set PATH '%s'", safepath); + } +# ifdef __OpenBSD__ + if (unveilcommands(getenv("PATH"), cmd) == 0) + goto fail; + if (pledge("stdio rpath getpw exec id", NULL) == -1) err(1, "pledge"); # endif @@ -449,6 +507,7 @@ main(int argc, char **argv) #ifdef HAVE_SETUSERCONTEXT if (setusercontext(NULL, targpw, target, LOGIN_SETGROUP | + LOGIN_SETPATH | LOGIN_SETPRIORITY | LOGIN_SETRESOURCES | LOGIN_SETUMASK | LOGIN_SETUSER) != 0) errx(1, "failed to set user context for target"); @@ -479,11 +538,15 @@ main(int argc, char **argv) syslog(LOG_AUTHPRIV | LOG_INFO, "%s ran command %s as %s from %s", mypw->pw_name, cmdline, targpw->pw_name, cwd); - envp = prepenv(rule); + envp = prepenv(rule, mypw, targpw); + /* setusercontext set path for the next process, so reset it for us */ if (rule->cmd) { if (setenv("PATH", safepath, 1) == -1) err(1, "failed to set PATH '%s'", safepath); + } else { + if (setenv("PATH", formerpath, 1) == -1) + err(1, "failed to set PATH '%s'", formerpath); } execvpe(cmd, argv, envp); if (errno == ENOENT)