On Tue, Dec 4, 2012 at 5:48 AM, Wietse Venema <wie...@porcupine.org> wrote:
>> Taking a quick look at the source, it looks like 2.8 does not use the
>> thread-safe getpwnam_r.   It does not appear that postfix is threaded,
>> so it should be safe to not use getpwnam_r.
>
> It has NOTHING TO TO WITH THREADS.
>
> Postfix avoids using using getpwnam() because it is fundamentally
> broken on lots of systems (reporting "user does not exist" after
> failure to complete the request).
>
> Sheesh.

"The functions getpwent_r(), getpwnam_r(), and getpwuid_r() are
thread-safe versions of getpwent(), getpwnam(), and getpwuid(),
respectively."

getpnam() returns NULL if the entry is not found or if an error
occurs.  If an error does occur, errno will be set. It works like that
on Linux, FreeBSD, and Solaris.

err=getpwnam_r(name, pwd, buffer, bufsize, &result);
if( err ){
    printf("Error is %d\n", err);
}

is the same as

result=getpwnam(name);
if( !result && errno ){
    printf("Error is %d\n", errno);
}

For this particular problem, err or errno would be EINVAL.  So using
getpwnam_r or using getwpnam and checking errno would both result in
this problem.  I think the best thing would be to ignore EINVAL, at
least on FreeBSD. Perhaps something like:

        err = getpwnam_r(name, &pwbuf, pwstore, sizeof(pwstore), &pwd);
#if defined(__FreeBSD__)
        if( err == EINVAL )
            err=0;
#endif
        if (err != 0)
        ...

Reply via email to