espie found a bug. we reset PATH in the parent too soon, and then it's not possible to change it back via setenv.
instead of trying to move code around, save a copy of the path before we mess with it and make it available later. this lets setenv { PATH=$PATH } work. Index: doas.c =================================================================== RCS file: /cvs/src/usr.bin/doas/doas.c,v retrieving revision 1.77 diff -u -p -r1.77 doas.c --- doas.c 16 Jun 2019 18:16:34 -0000 1.77 +++ doas.c 17 Jun 2019 19:06:14 -0000 @@ -286,6 +286,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]; char mypwbuf[_PW_BUF_LEN], targpwbuf[_PW_BUF_LEN]; @@ -401,6 +402,11 @@ main(int argc, char **argv) authuser(mypw->pw_name, login_style, rule->options & PERSIST); } + + if ((p = getenv("PATH")) != NULL) + formerpath = strdup(p); + if (formerpath == NULL) + formerpath = ""; if (unveil(_PATH_LOGIN_CONF, "r") == -1) err(1, "unveil"); Index: doas.h =================================================================== RCS file: /cvs/src/usr.bin/doas/doas.h,v retrieving revision 1.14 diff -u -p -r1.14 doas.h --- doas.h 16 Jun 2019 18:16:34 -0000 1.14 +++ doas.h 17 Jun 2019 19:06:14 -0000 @@ -29,6 +29,8 @@ extern struct rule **rules; extern int nrules; extern int parse_errors; +extern const char *formerpath; + struct passwd; char **prepenv(const struct rule *, const struct passwd *, Index: env.c =================================================================== RCS file: /cvs/src/usr.bin/doas/env.c,v retrieving revision 1.8 diff -u -p -r1.8 env.c --- env.c 17 Jun 2019 16:01:26 -0000 1.8 +++ env.c 17 Jun 2019 19:06:14 -0000 @@ -28,6 +28,8 @@ #include "doas.h" +const char *formerpath; + struct envnode { RB_ENTRY(envnode) node; const char *key; @@ -198,8 +200,12 @@ fillenv(struct env *env, const char **en /* assign value or inherit from environ */ if (eq) { val = eq + 1; - if (*val == '$') - val = getenv(val + 1); + if (*val == '$') { + if (strcmp(val + 1, "PATH") == 0) + val = formerpath; + else + val = getenv(val + 1); + } } else { val = getenv(name); }