diff --git a/doas.1 b/doas.1 index 7360be3..009ba1d 100644 --- a/doas.1 +++ b/doas.1 @@ -97,6 +97,10 @@ Execute the shell from .Ev SHELL or .Pa /etc/passwd . +.It Fl i +Execute the shell from the target's +.Pa /etc/passwd +entry. .It Fl u Ar user Execute the command as .Ar user . diff --git a/doas.c b/doas.c index e253905..e9a6cfb 100644 --- a/doas.c +++ b/doas.c @@ -37,7 +37,7 @@ static void __dead usage(void) { - fprintf(stderr, "usage: doas [-Lns] [-C config] [-u user]" + fprintf(stderr, "usage: doas [-Lnsi] [-C config] [-u user]" " command [args]\n"); exit(1); } @@ -250,6 +250,7 @@ main(int argc, char **argv) int ngroups; int i, ch, rv; int sflag = 0; + int iflag = 0; int nflag = 0; char cwdpath[PATH_MAX]; const char *cwd; @@ -261,7 +262,7 @@ main(int argc, char **argv) uid = getuid(); - while ((ch = getopt(argc, argv, "+C:Lnsu:")) != -1) { + while ((ch = getopt(argc, argv, "+C:Lnsiu:")) != -1) { switch (ch) { case 'C': confpath = optarg; @@ -282,6 +283,9 @@ main(int argc, char **argv) case 's': sflag = 1; break; + case 'i': + iflag = 1; + break; default: usage(); break; @@ -291,9 +295,9 @@ main(int argc, char **argv) argc -= optind; if (confpath) { - if (sflag) + if (sflag || iflag) usage(); - } else if ((!sflag && !argc) || (sflag && argc)) + } else if ((!sflag && !iflag && !argc) || (sflag && argc) || (sflag && iflag) || (iflag && argc)) usage(); rv = mygetpwuid_r(uid, &mypwstore, &mypw); @@ -306,7 +310,17 @@ main(int argc, char **argv) err(1, "can't get groups"); groups[ngroups++] = getgid(); - if (sflag) { + rv = mygetpwuid_r(target, &targpwstore, &targpw); + if (rv != 0) + err(1, "getpwuid_r failed"); + if (targpw == NULL) + errx(1, "no passwd entry for target"); + + if (iflag) { + shargv[0] = targpw->pw_shell; + argv = shargv; + argc = 1; + } else if (sflag) { sh = getenv("SHELL"); if (sh == NULL || *sh == '\0') { shargv[0] = mypw->pw_shell; @@ -368,12 +382,6 @@ main(int argc, char **argv) err(1, "failed to set PATH '%s'", safepath); } - rv = mygetpwuid_r(target, &targpwstore, &targpw); - if (rv != 0) - err(1, "getpwuid_r failed"); - if (targpw == NULL) - errx(1, "no passwd entry for target"); - #if defined(USE_PAM) pamauth(targpw->pw_name, mypw->pw_name, !nflag, rule->options & NOPASS, rule->options & PERSIST);