Bug 437945

Summary: nis+-based getgrent mistakenly sets errno when there are no more entries
Product: [Fedora] Fedora Reporter: Jim Meyering <meyering>
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED RAWHIDE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: low Docs Contact:
Priority: low    
Version: rawhideCC: drepper, fweimer
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2008-04-04 22:40:22 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
bugfix patch
none
the proper bugfix none

Description Jim Meyering 2008-03-18 11:39:31 UTC
Description of problem:
nis+-based getgrent mistakenly sets errno when there are no more entries
This is the root cause of a bug reported against coreutils:

  http://savannah.gnu.org/bugs/?22505

Version-Release number of selected component (if applicable):
glibc-2.7.90-9.x86_64 (but also affects at least RHEL4.6 and FC5)

How reproducible: every time

Here's code to demonstrate the bug:

cat <<\EOF > getgrent-test.c
#include <sys/types.h>
#include <grp.h>
#include <errno.h>
#include <stdio.h>

static int
count_groups (void)
{
  int count = 0;

  setgrent ();
  while (1)
    {
      errno = 0;
      struct group *grp = getgrent ();
      if (!grp)
        break;
      ++count;
    }

  if (errno != 0)
    {
      perror ("getgrent failed");
      count = -1;
    }

  int saved_errno = errno;
  endgrent ();
  errno = saved_errno;

  return count;
}

int
main ()
{
  return count_groups () < 0;
}
EOF
gcc -O -W -Wall getgrent-test.c && ./a.out && echo ok
======================================

When I run that on a rawhide system on which /etc/nsswitch.conf has this:

  group: files

I get an exit status of 0, as expected.
However, when I change nsswitch.conf, appending " nisplus"
(and I haven't configured NIS+ at all):

  group: files nisplus

and run ./a.out again, I get this output:

  getgrent failed: No such file or directory
  [Exit 1]




Additional info:

Comment 1 Jim Meyering 2008-03-18 11:39:31 UTC
Created attachment 298380 [details]
bugfix patch

Comment 2 Jim Meyering 2008-03-18 14:21:29 UTC
The patch I posted minutes ago is worth applying, but was not
relevant to the getgrent bug.  Sorry about the mix-up.

Here's the patch that is likely to actually solve the problem.

2008-03-18  Jim Meyering  <meyering>

	nis+/getgrent: don't set errno when there are no more entries
	* nis/nis_call.c (__libc_lock_define_initialized): Don't let
	ENOENT from failure to stat "/var/nis/NIS_COLD_START" affect
	leak out to confuse the getgrent caller, who must be able to
	distinguish a return value of NULL indicating no more values
	and a return value of NULL indicating an error occurred.

Comment 3 Jim Meyering 2008-03-18 14:22:47 UTC
Created attachment 298395 [details]
the proper bugfix

Comment 4 Ulrich Drepper 2008-03-24 19:29:40 UTC
Fixed upstream with a patch different from the one attached here.

Comment 5 Jakub Jelinek 2008-04-04 22:40:22 UTC
Should be in glibc-2.7.90-12 and above.