This service will be undergoing maintenance at 00:00 UTC, 2017-10-23 It is expected to last about 30 minutes
Bug 437945 - nis+-based getgrent mistakenly sets errno when there are no more entries
nis+-based getgrent mistakenly sets errno when there are no more entries
Status: CLOSED RAWHIDE
Product: Fedora
Classification: Fedora
Component: glibc (Show other bugs)
rawhide
All Linux
low Severity low
: ---
: ---
Assigned To: Jakub Jelinek
Fedora Extras Quality Assurance
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2008-03-18 07:39 EDT by Jim Meyering
Modified: 2016-11-24 10:53 EST (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2008-04-04 18:40:22 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
bugfix patch (2.79 KB, patch)
2008-03-18 07:39 EDT, Jim Meyering
no flags Details | Diff
the proper bugfix (765 bytes, patch)
2008-03-18 10:22 EDT, Jim Meyering
no flags Details | Diff

  None (edit)
Description Jim Meyering 2008-03-18 07:39:31 EDT
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 07:39:31 EDT
Created attachment 298380 [details]
bugfix patch
Comment 2 Jim Meyering 2008-03-18 10:21:29 EDT
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@redhat.com>

	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 10:22:47 EDT
Created attachment 298395 [details]
the proper bugfix
Comment 4 Ulrich Drepper 2008-03-24 15:29:40 EDT
Fixed upstream with a patch different from the one attached here.
Comment 5 Jakub Jelinek 2008-04-04 18:40:22 EDT
Should be in glibc-2.7.90-12 and above.

Note You need to log in before you can comment on or make changes to this bug.