Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Feb 1996 01:22:38 -0500 (EST)
From:      Bill Paul <wpaul@skynet.ctr.columbia.edu>
To:        current@freebsd.org
Subject:   Proposed change to getpwent and getgrent
Message-ID:  <199602120622.BAA08093@skynet.ctr.columbia.edu>

next in thread | raw e-mail | index | archive | help
Bug bin/517 points out a problem with the NIS +group matching code in
src/lib/libc/gen/getpwent.c clobbering getgrent(3) buffers being held
by user programs. In a nutshell, the getpwent(3) code can call getgrnam()
internally if NIS is enabled and +group overrides are being used in
/etc/master.passwd. This call to getgrnam() scrambles the contents of
the static buffers allocated by the getgrent(3) code; if a user program
has called a getgrent(3) function immediately prior to calling a
getpwent(3) function, it will end up with bogus data.

In other words, calling getgrnam() inside getpwent(3) is bogus because
getgrnam() isn't reentrant.

So, how to fix. I came up with the following choices:

#1 Remove the +group override feature; it's FreeBSD-specific anyway.
   (I implemented the idea after Justin Gibbs suggested it; it's
   not something you'll find on any other platform that supports NIS.)

#2 Add some magic hooks to getgrnam() so that it can be called safely
   from inside getpwent(3) without affecting user programs.

#3 Implement a real reentrant interface to getgrent(3).

#1 is the chicken's way out. I like the +group override mechanism.

I coded and tested several versions of #2, but they all involved
either exporting global symbols from inside getgrent(3) or adding
extra entry points. Exporting global symbols, even with lots of
leading underscores, seemed messy, as did adding an extra
undocumented function call. Besides, this only addresses this one
instance of the problem.

I finally decided that #3 was the best solution. I imagine that
someday, someone will want real multi-threading support, which means
we'll need this sort of thing eventually anyway. So, stealing a
peek at the Solaris getgrent(3) man page, I modified getgrent(3)
to support reentrancy and added three new functions: getgrgid_r(),
getgrnam_r() and getgrent_r(). Anyone who's familiar with Solaris
knows how these work: they accept a pre-allocated group structure,
line buffer and buffer length in addition to their usual arguments.
While I was in the neighborhood, I also did the same to getpwent(3).
The getpwent(3) code calls getgrent_r() internally using its own
pre-allocated buffers, so it no longer clobbers buffers being held
by user programs.

I'd like some people here to peek at the new code before I commit it
since the changes take affect with or without YP being #defined. Even
though it works for me, Murphy's Law says there's probably something
wrong with it that I missed. Comments are welcome.

I have new versions of getgrent.c and getpwent.c in ~wpaul/reentrant
on freefall. There are also context diffs against getpwent.c and
getgrent.c from -current, which is what the changes are based on.
I also threw in new pwd.h and grp.h headers with prototypes for
the new functions. I have the same files available for anon ftp
from skynet.ctr.columbia.edu:/pub/ftp/freebsd/reentrant if others
want to look at them. (Go easy on skynet: it's sitting behind a
SLIP link.)

There's one matter still unresolved which is that getpwent(3) also
calls getnetgrent(3) to resolve netgroups. I suppose I'll have to
whip up a reentrant interface to getnetgrent(3) now too. This will
probably take me a little longer since getnetgrent() is a little more
complicated.

-Bill

-- 
=============================================================================
-Bill Paul            (212) 854-6020 | System Manager
Work:         wpaul@ctr.columbia.edu | Center for Telecommunications Research
Home:  wpaul@skynet.ctr.columbia.edu | Columbia University, New York City
=============================================================================
License error: The license for this .sig file has expired. You must obtain
a new license key before any more witty phrases will appear in this space.
=============================================================================



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199602120622.BAA08093>