Coordinating Password and Group Files
Larry Reznick
While reviewing some other problems with a client's
system, I found
that the system had some group ID entries in /etc/passwd
that
weren't in the /etc/group file. This set of systems
didn't
have NIS running on them yet, so I had to wonder how
many other systems
had this kind of error? For that matter, where NIS was
running, were
the same kinds of discrepancies present?
Listing 1 shows a script that finds out whether such
a discrepancy
is present on the current system. In the script's beginning,
variables
centralize the passwd and group files because the
data may come either from the real files or from NIS's
maps. Using
variables to control file names that collect the data
allows some
other part of the script to collect the data in a uniform
place no
matter where the data comes from. Just prior to creating
those files,
the script sets a trap for the common signals to kill
those files.
Next, the script runs ypwhich to find out if NIS is
up. If
not, ypwhich exits with an error code detectable by
the shell's
if test. With NIS running, the script assumes that NIS
holds
the password and group maps and directs them to the
central files.
Otherwise, it takes them from their usual locations
and puts them
in the central files. I used cat instead of cp for
the real files solely to correspond in kind with ypcat.
The real meat of the script is the for loop. The for's
grp variable is set to the sorted group IDs in the central
password file. They're sorted to be sure that the list
shows a gid
entry only once, and it has the nice side-effect of
making the output
appear in group sequence.
Group IDs may be arbitrarily small or large numbers.
Few-digit numbers
shouldn't match many-digit numbers by accident. For
example, I don't
want to find gid 7 within 17 and think gid 7 is present
when it isn't. To be sure the gid matches are exact,
I surround each
number in the $grp variable with the same colon delimiters
found in the group file. That forces :7: to match only
that,
not :17:. The resulting formatted numbers are stored
in the
grpfmt variable.
The match variable receives the line egrep finds that
matches this formatted group number. If there is no
such line in the
group file, the match variable receives an empty string.
The
test -n is true when match holds the group ID's
line. If this test is true, the OR (||) operator doesn't
execute the
second part of its command line, the echo command. The
test
is false when match is an empty string, which means
that the
formatted gid wasn't in the group file. If the first
part
of an OR is false, the second part must execute to see
if it's true.
That echoes the error message identifying not only which
gid
is missing, but looking up which users belong to that
group. Such
users' files will show the gid instead of their group
name
in long listings (ls -l).
Once I installed it, I ran this script using a for loop
to
rsh to every system I suspected might have a problem.
For
instance, in csh I could run:
foreach sys (system{1,2,3,4,5})
echo ==== badgrp report for $sys
rsh $sys badgrp
end
Without a very good reason to the contrary, every user
should belong
to a group identified in the group file. This script
caught several
bad group IDs for me.
About the Author
Larry Reznick has been programming professionally since
1978. He is currently
working on systems programming in UNIX, MS-DOS, and
OS/2.
He teaches C, C++, and UNIX language courses
at American River College and at the University of California,
Davis extension.
|