home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
c
/
cops_104.zip
/
cops_104
/
perl
/
passwd.chk
< prev
next >
Wrap
Text File
|
1992-03-10
|
5KB
|
134 lines
#!/bin/sh -- need to mention perl here to avoid recursion
'true' || eval 'exec perl -S $0 $argv:q';
eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
& eval 'exec /usr/local/bin/perl -S $0 $argv:q'
if 0;
#
# passwd.chk
#
# composer@chem.bu.edu
#
# Check password file -- /etc/passwd -- for incorrect number of fields,
# duplicate uid's, non-alphanumeric uids, and non-numeric group id's.
#
# Mechanism: This script ensures that each line of the passwd file (in
# $etc, line 47) has 7 fields and is non-blank, as well as examining the
# file for any duplicate users. It then checks to ensure that the first
# character of the login name is alphanumeric, and that all uid and gid
# numbers are indeed numeric and non-negative. It also checks the
# validity of the home directory.
#
# For yellow pages passwords, it does the same checking, but in order to
# get a listing of all members of the password file, it does a "ypcat
# passwd" and uses the output from that as a passwd file.
#
# The /etc/passwd file has a very specific format, making the task fairly
# simple. Normally it has lines with 7 fields, each field separated by a
# colon (:). The first field is the user id, the second field is the
# encrypted password (an asterix (*) means the group has no password,
# otherwise the first two characters are the salt), the third field is the
# user id number, the fourth field is the group id number, the fifth field
# is the GECOS field (basically holds miscellaneous information, varying
# from site to site), the sixth field is the home directory of the user,
# and lastly the seventh field is the login shell of the user. No blank
# lines should be present. Uid's will be flagged if over 8 chars, unless
# the $OVER_8 variable (line 45) is set to "YES".
#
# If a line begins with a plus sign (+), it is a yellow pages entry. See
# passwd(5) for more information, if this applies to your site.
#
require 'pathconf.pl';
require 'pass.cache.pl';
package passwd_chk;
# Used for Sun C2 security group file. 'FALSE' (default) will flag
# valid C2 passwd syntax as an error, 'TRUE' attempts to validate it.
# Thanks to Pete Troxell for pointing this out.
$C2='FALSE' if ! defined($C2);
# Some systems allow long uids; set this to 'TRUE', if so (thanks
# to Pete Shipley (lot of petes around here, eh?)):
$OVER_8='NO' if ! defined($OVER_8);
#
# Important files:
$etc_passwd = $'PASSWD || '/etc/passwd';
# Check $etc_passwd for potential problems, or use the alternate method
# set in cops.cf:
if (!"$'GET_PASSWD") {
open(Passwd, $etc_passwd) ||
warn "$0: Can't open $etc_passwd: $!\n";
}
else {
open(Passwd, "$'GET_PASSWD|") ||
warn "$0: Can't open $etc_passwd: $!\n";
}
&chk_passwd_file_format('Passwd');
close Passwd;
# check ypcat passwd for potential problems... (same checks)
if (-s $'YPCAT && -x _) {
open(YPasswd, "$'YPCAT passwd 2>/dev/null |")
|| die "$0: Can't popen $'YPCAT: $!\n";
&chk_passwd_file_format('YPasswd');
close YPasswd;
}
sub chk_passwd_file_format {
local($file) = @_;
local($W) = "Warning! $file file,";
undef %users;
while (<$file>) {
# should really check for correct YP syntax
next if /^[-+]/; # skipping YP lines for now
print "$W line $., is blank\n", next if /^\s*$/;
# make code a little more readable .. use names..
($user,$pass,$uid,$gid,$gcos,$home,$shell) = split(?:?);
$users{$user}++; # keep track of dups
print "$W line $., does not have 7 fields:\n\t$_" if (@_ != 7);
print "$W line $., nonalphanumeric username:\n\t$_"
if $user !~ /^[_A-Za-z0-9-]+$/;
print "$W line $., numeric username:\n\t$_"
if $user =~ /^\d+$/;
print "$W line $., login name > 8 characters:\n\t$_"
if ( ! $OVER_8 && length($user) > 8);
print "$W line $., no password:\n\t$_" unless $pass;
print "$W line $., invalid password field for C2:\n\t$_"
if ($C2 && $pass =~ /^##/ && "##$user" ne $pass);
if ($uid !~ /^\d+$/) {
if ($uid < 0) {
print "$W line $., negative user id (uid):\n\t$_";
} else {
print "$W line $., nonnumeric user id (uid):\n\t$_";
}
}
# what about checks for certain ranges of UIDs .. -composer
print "$W line $., user $user has uid == 0 and is not root\n\t$_"
if $uid == 0 && $user ne "root";
print "$W line $., nonnumeric group id (gid):\n\t$_"
unless $gid =~ /^\d+$/;
print "$W line $., invalid home directory:\n\t$_"
unless $home =~ m:^/:;
}
# find duplicate usernames
# not the best way, but it works ...
$dup_warned = 0;
for (sort keys %users) {
(print "Warning! Duplicate username(s) found in $file:\n"),
$dup_warned++ if !$dup_warned && $users{$_} > 1;
print "$_ " if $users{$_} > 1;
}
print "\n" if $dup_warned;
}
1;
# end of passwd.chk file