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);
>  
> 

Reply via email to