This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Question on /etc/nsswitch.conf


On Thu, Sep 28, 2017 at 12:13:43PM +0200, Florian Weimer wrote:
> On 09/27/2017 11:50 PM, Yury Norov wrote:
> > Hi all,
> > 
> > Recently Linaro issued the toolchain for arm64/ilp32 [1], and
> > running LTP compiled with it, I found multiple regressions. I
> > tracked them down to function family getpw*(). The problem is
> > that they return NULL, and don't set any errno.
> > 
> > #include <sys/types.h>
> > #include <pwd.h>
> > #include <errno.h>
> > #include <stdio.h>
> > #include <stddef.h>
> > #include <unistd.h>
> > 
> > int main(void)
> > {
> >          struct passwd *pwent;
> >          uid_t uid = getuid();
> >          printf("uid  == %d, errno = %d\n", uid,
> >                          errno);
> > 
> >          pwent = getpwuid(uid);
> >          printf("pwent  == %p, errno == %d\n", pwent, errno);
> > 
> >          return 0;
> > }
> > 
> > Steve Ellcey noticed that it's related to the "passwd: compat"
> > record in /etc/nsswitch.conf. On my testing system (Ubuntu 14.04) I replaced the
> > file with one coming in glibc sources (passwd is "db_files" there), and it fixed
> > the problem.
> > 
> > By this email I'd like to report the issue to community and ask some
> > questions:
> >   - I think it shuld be a bug if function returns NULL instead the pointer
> >     to the structure, and doesn't set errno. The POSIX [2] is not
> >     specific here: "If getpwuid() returns a null pointer and errno is
> >     set to non-zero, an error occurred". But if getpwuid() returns null,
> >     it is an error from user point of view (LTP treats is like this for
> >     example). But Glibc doesn't set errno, and POSIX doesn't restrict it
> >     explicitly.
> 
> POSIX requires that if the user does not exist, NULL is returned.  But this
> is not an error, so errno is not set.
> 
> Callers need to set errno to zero before calling those NSS functions.
> (Currently, many of them incorrectly set errno to zero on success, which is
> not allowed by POSIX.)  If LTP tests do not do this, these LTP tests need to
> be fixed.
> 
> Does this address your concerns?
> 
> Florian

Yes, it is, thanks. It means that getpwuid(), getpwnam() etc are
broken because with NUll in return value and untouched errno they
report that no user record found in passwd. Whilst the record exists.

Below is the problem function from LTP, for reference. It doesn't
reset errno before calling getpwnam(), but this is different issue.

Yury

struct passwd *safe_getpwnam(const char *file, const int lineno,
                             void (*cleanup_fn) (void), const char *name)
{
        struct passwd *rval;

        rval = getpwnam(name);
        if (rval == NULL) {
                tst_brkm(TBROK | TERRNO, cleanup_fn,
                         "%s:%d: getpwnam(%s) failed",
                         file, lineno, name);
        }

        return rval;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]