On Mon, Dec 3, 2012 at 7:42 PM, Wietse Venema <wie...@porcupine.org> wrote:
> Dan Lists:
>> >> Does postfix need to treat the EINVAL as if the user does not exist?
>> >> Is there a way to change the behavior of getpwnam*?
>> >
>> > EINVAL is not a documented result code.
>> > http://pubs.opengroup.org/onlinepubs/009695399/functions/getpwnam.html
>> >
>> > Postfix is built accoirding to standards, not by tinkering with
>> > library calls and guessing what the result means.
>>
>> I just ran my test program on FreeBSD 7.3, and it has the same result
>> as on FreeBSD 8.3:
>
> If an errno value is not defined in any standard API documentation,
> why would one one errno value mean that a user does not exist, while
> some other errno value means that the library function was unable
> to complete a request?  Postfix is written according to standard
> APIs not by randomly experimenting with function calls and guessing
> what the result means.
>
> You mention FreeBSD. They don't even bother to document EINVAL as
> a "user does not exist" result.  I looked at the Linux manpage and
> it is clear that they tried harder to document getpwnam_r(), but
> they also gave up. This function's API is a stinking mess.
>
>> I downgraded postfix from 2.9.3 to 2.8.11 on the FreeBSD 8.3 box and
>> everything works as expected.
>
> 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).
>
> You can force Postfix to use getpwnam() if you know that you
> will never use *SQL or LDAP etc. datbases:
>
>     $ make makefiles CCARGS=-DNO_POSIX_GETPW_R
>     $ make

We are using mysql databases.

> Alternatively, I can try to implement a configurable getpwnam_r()
> errno whitelist. This way I am off the hook, and you jump the
> hoops if you like.

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.

On FreeBSD it looks like errno can be EINVAL, ERANGE, or inherited from open(2),
dbopen(3), socket(2), or connect(2).   EINVAL appears to be the only
one that is returned when when it should be an invalid user.   The
rest probably should be treated as temporary errors.

Reply via email to