#!/usr/bin/perl -w # $Id: passwdgroup.check,v 1.2 2005/06/17 19:31:42 dean Exp $ # Copyright (c) 2005 Dean Gaudet # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. use strict; my %shells = ( '/bin/true' => 1, '/bin/false' => 1, '/bin/sync' => 1, ); open(SHELLS, "/etc/shells") or die "unable to open /etc/shells for reading: $!\n"; while() { chomp; s/#.*//; next if /^$/; $shells{$_} = 1; } close(SHELLS); my (%uid, %user); while (my ($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell,$expire) = getpwent) { if (exists $user{$uid}) { print "duplicate uid $uid, earlier name $user{$uid}, this time $name\n"; } else { $user{$uid} = $name; } if (exists $uid{$name}) { print "duplicate user name $name, earlier uid $uid{$name}, this time $uid\n"; } else { $uid{$name} = $uid; } if ($uid >= 500 && $gid != $uid) { print "user $name, uid $uid != gid $gid\n"; } if (!-d $dir) { print "user $name home dir $dir doesn't exist\n"; } if (!defined($shells{$shell})) { print "user $name has incorrect shell $shell\n"; } } my (%gid, %group); while (my ($name,$passwd,$gid,$members) = getgrent) { if (exists $group{$gid}) { print "duplicate gid $gid, earlier name $group{$gid}, this time $name\n"; } else { $group{$gid} = $name; } if (exists $gid{$name}) { print "duplicate group name $name, earlier gid $gid{$name}, this time $gid\n"; } else { $gid{$name} = $gid; } foreach my $m (split(/ /,$members)) { defined($uid{$m}) or print "group $name member $m does not exist\n"; } if ($gid >= 500 && !defined($user{$gid})) { print "gid $gid exists but uid $gid doesn't\n"; } } setpwent; while (my ($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell,$expire) = getpwent) { if (!defined($group{$gid})) { print "user $name undefined gid $gid\n"; } elsif ($uid >= 500 && $group{$gid} ne $name) { print "uid $uid has name $name, mismatching gid $gid name $group{$gid}\n"; } } open(S, ") { if (my ($name) = split(/:/)) { defined($uid{$name}) or print "shadow entry $name not in passwd file\n"; } } close(S);