On Tue, May 21, 2019 at 01:07:10PM -0400, Ted Unangst wrote: > I have a coming change which will need to access both the calling user and > target users' passwd entries. In order to accomplish this, we need to switch > to the reentrant flavor of getpwuid. No behaviorial change, but I think this > is clearer and less error prone as well, versus reusing a pointer to static > storage.
ok lteo@ > Index: doas.c > =================================================================== > RCS file: /home/cvs/src/usr.bin/doas/doas.c,v > retrieving revision 1.74 > diff -u -p -r1.74 doas.c > --- doas.c 17 Jan 2019 05:35:35 -0000 1.74 > +++ doas.c 21 May 2019 17:04:04 -0000 > @@ -289,13 +289,15 @@ main(int argc, char **argv) > const char *cmd; > char cmdline[LINE_MAX]; > char myname[_PW_NAME_LEN + 1]; > - struct passwd *pw; > + char mypwbuf[_PW_BUF_LEN], targpwbuf[_PW_BUF_LEN]; > + struct passwd mypwstore, targpwstore; > + struct passwd *mypw, *targpw; > const struct rule *rule; > uid_t uid; > uid_t target = 0; > gid_t groups[NGROUPS_MAX + 1]; > int ngroups; > - int i, ch; > + int i, ch, rv; > int sflag = 0; > int nflag = 0; > char cwdpath[PATH_MAX]; > @@ -346,10 +348,10 @@ main(int argc, char **argv) > } else if ((!sflag && !argc) || (sflag && argc)) > usage(); > > - pw = getpwuid(uid); > - if (!pw) > - err(1, "getpwuid failed"); > - if (strlcpy(myname, pw->pw_name, sizeof(myname)) >= sizeof(myname)) > + rv = getpwuid_r(uid, &mypwstore, mypwbuf, sizeof(mypwbuf), &mypw); > + if (rv != 0 || mypw == NULL) > + err(1, "getpwuid_r failed"); > + if (strlcpy(myname, mypw->pw_name, sizeof(myname)) >= sizeof(myname)) > errx(1, "pw_name too long"); > ngroups = getgroups(NGROUPS_MAX, groups); > if (ngroups == -1) > @@ -359,7 +361,7 @@ main(int argc, char **argv) > if (sflag) { > sh = getenv("SHELL"); > if (sh == NULL || *sh == '\0') { > - shargv[0] = strdup(pw->pw_shell); > + shargv[0] = strdup(mypw->pw_shell); > if (shargv[0] == NULL) > err(1, NULL); > } else > @@ -415,11 +417,11 @@ main(int argc, char **argv) > if (pledge("stdio rpath getpw exec id", NULL) == -1) > err(1, "pledge"); > > - pw = getpwuid(target); > - if (!pw) > + rv = getpwuid_r(target, &targpwstore, targpwbuf, sizeof(targpwbuf), > &targpw); > + if (rv != 0 || targpw == NULL) > errx(1, "no passwd entry for target"); > > - if (setusercontext(NULL, pw, target, LOGIN_SETGROUP | > + if (setusercontext(NULL, targpw, target, LOGIN_SETGROUP | > LOGIN_SETPRIORITY | LOGIN_SETRESOURCES | LOGIN_SETUMASK | > LOGIN_SETUSER) != 0) > errx(1, "failed to set user context for target"); > @@ -436,7 +438,7 @@ main(int argc, char **argv) > err(1, "pledge"); > > syslog(LOG_AUTHPRIV | LOG_INFO, "%s ran command %s as %s from %s", > - myname, cmdline, pw->pw_name, cwd); > + myname, cmdline, targpw->pw_name, cwd); > > envp = prepenv(rule); > >