| 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. 
 
 
 |