On 05/02/14 7:31 PM, Philip Guenther wrote:
9On Wed, 5 Feb 2014, Ted Unangst wrote:
On Wed, Feb 05, 2014 at 12:41, Brad Smith wrote:
They do (but through errno). Of course there may be other places where
the internal functions clobber errno before returning to the user code,
but some fixes have been applied already (eg. rev 1.43 of getpwent.c).
Is anyone actually looking into fixing this? This issue was also noticed
when Dovecot was updated to 2.2 and it broke local account authentication.
Test cases? The fix here will fix this test case, but it's probably
one of the more contrived error cases.
There's more needed. There are actually three cases:
1) found a match:
getpwnam(): return non-NULL (Linux and Solaris set errno to 0)
getpwnam_r(): set *pwretp to non-NULL and return 0
2) no match, but no error:
getpwnam(): set errno to zero and return NULL
getpwnam_r(): set *pwretp to NULL and return 0
3) something failed:
getpwnam(): set errno to non-zero-errno-value and return NULL
getpwnam_r(): set *pwretp to NULL and return non-zero-errno-value
On Solaris, getpwnam_r() doesn't change errno; on Linux, getpwnam_r() sets
errno to its return value.
So: we need to
- clear errno in the success and "no match" cases,
- need to set errno in the ERANGE case,
- need to return errno from getpw{uid,nam}_r() on failure, and
- need to preserve errno around calls whose failure doesn't affect the
success or failure of the lookup (e.g., the DB close)
Diff below does that, though I haven't checked the YP lookup closely to
verify whether it might return the errno of the wrong system call on
failure. The one thing this diff does *not* do is set errno to zero when
a match is found. Both Linux and Solaris do that, so maybe we should
too...
Doing some testing with Dovecot and so far seems to be working fine.
--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.