From:	MERC::"uunet!Dayton.SAIC.COM!ake" 14-MAY-1992 01:40:30.19
To:	everhart
CC:	
Subj:	COPS 18/18

#!/bin/sh
# this is p4.shar.18 (part 18 of a multipart archive)
# do not concatenate these parts, unpack them in order with /bin/sh
# file cops_104/perl/stat.pl continued
#
if test ! -r _shar_seq_.tmp; then
	echo 'Please unpack part 1 first!'
	exit 1
fi
(read Scheck
 if test "$Scheck" != 18; then
	echo Please unpack part "$Scheck" next!
	exit 1
 else
	exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
	echo 'x - still skipping cops_104/perl/stat.pl'
else
echo 'x - continuing file cops_104/perl/stat.pl'
sed 's/^X//' << 'SHAR_EOF' >> 'cops_104/perl/stat.pl' &&
X;# Usage:
X;#	require 'stat.pl';
X;#	@ary = stat(foo);
X;#	$st_dev = @ary[$ST_DEV];
X;#
X$ST_DEV =	0 + $[;
X$ST_INO =	1 + $[;
X$ST_MODE =	2 + $[;
X$ST_NLINK =	3 + $[;
X$ST_UID =	4 + $[;
X$ST_GID =	5 + $[;
X$ST_RDEV =	6 + $[;
X$ST_SIZE =	7 + $[;
X$ST_ATIME =	8 + $[;
X$ST_MTIME =	9 + $[;
X$ST_CTIME =	10 + $[;
X$ST_BLKSIZE =	11 + $[;
X$ST_BLOCKS =	12 + $[;
X
X;# Usage:
X;#	require 'stat.pl';
X;#	do Stat('foo');		# sets st_* as a side effect
X;#
Xsub Stat {
X    ($st_dev,$st_ino,$st_mode,$st_nlink,$st_uid,$st_gid,$st_rdev,$st_size,
X	$st_atime,$st_mtime,$st_ctime,$st_blksize,$st_blocks) = stat(shift(@_));
X}
X
X1;
SHAR_EOF
echo 'File cops_104/perl/stat.pl is complete' &&
chmod 0700 cops_104/perl/stat.pl ||
echo 'restore of cops_104/perl/stat.pl failed'
Wc_c="`wc -c < 'cops_104/perl/stat.pl'`"
test 653 -eq "$Wc_c" ||
	echo 'cops_104/perl/stat.pl: original size 653, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= cops_104/perl/suckline.pl ==============
if test -f 'cops_104/perl/suckline.pl' -a X"$1" != X"-c"; then
	echo 'x - skipping cops_104/perl/suckline.pl (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting cops_104/perl/suckline.pl (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cops_104/perl/suckline.pl' &&
X#
X#  As title implies... :-)
X#
Xsub main'suckline {
X    local($file, $_) = @_;
X#   local($package) = caller;
X
X#   $file =~ s/^([^']+)$/$package'$1/; 
X    {
X	if (s/\\\n?$//) {
X	    $_ .= <$file>;
X	    redo;
X	}
X    } 
X    $_;
X}
X
X1;
SHAR_EOF
chmod 0700 cops_104/perl/suckline.pl ||
echo 'restore of cops_104/perl/suckline.pl failed'
Wc_c="`wc -c < 'cops_104/perl/suckline.pl'`"
test 229 -eq "$Wc_c" ||
	echo 'cops_104/perl/suckline.pl: original size 229, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= cops_104/perl/suid.chk ==============
if test -f 'cops_104/perl/suid.chk' -a X"$1" != X"-c"; then
	echo 'x - skipping cops_104/perl/suid.chk (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting cops_104/perl/suid.chk (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cops_104/perl/suid.chk' &&
X#!/bin/sh -- need to mention perl here to avoid recursion
X'true' || eval 'exec perl -S $0 $argv:q';
Xeval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
X& eval 'exec /usr/local/bin/perl -S $0 $argv:q'
X        if 0;
X
X#
X#  Usage: suid.chk [-n] [-s secure_dir] [search_starting_directory]
X#
X#   Shell script intended to be run periodically by cron in order
X#   to spot changes in files with the suid or sgid bits set.
X#
X#	suid.chk	840919		Prentiss Riddle
X#
X#     This changes into the $SECURE directory first, then 
X#   uses find(1) to search the directories in $SEARCH for all
X#   files with the 4000 or 2000 permission bits set.  $STOP is a file
X#   containing "ls -gildsa" output for known setuid or setgid programs.
X#   Any additions or changes to this list represent potential security
X#   problems, so they are reported.
X#
X#  Modified 8/15/89, Dan Farmer:
X#	Just changed the program/doc names and some of the temp
X#  files to make it fit in with the rest of the programs....
X#  Modified 12/26/90, df
X#       Now flags SUID shell scripts and world writeable SUID files, too.
X#
X#  Rewritten in perl, 1/17/91, df
X#  Major hacks by tchrist 5/14/91
X#
X
Xrequire "hostname.pl";
Xrequire "is_able.pl";
Xrequire "file_owner.pl";
Xrequire "pathconf.pl";
Xrequire "chk_strings.pl";
Xrequire "pass.cache.pl";
Xpackage suid_chk; # name space protection
X$debug=0;
X
X#
X# Getopts stuff
X$usage = "Usage: $0 [-n] [-s secure_dir] [starting_directory]\n";
Xrequire 'getopts.pl';
X# Process the command args; Either specify verbose or an alternate config file:
Xdie $usage unless &'Getopts('ns:');
X
X$suid_dir = $'SECURE || '.';
Xif (defined($'opt_s)) { $suid_dir = $'opt_s; }
X
X# Do NFS stuff?  Yes unless opt:
Xif (defined($'opt_n)) { $skip_nfs = 1; }
Xelse { $skip_nfs = 0; }
X
X$STOP="$suid_dir/suid.stop" unless defined $STOP;
X$FINDARGS="" unless defined $FINDARGS;
X$LSARGS=" -glids" unless defined $LSARGS;
X
X$TEMPOLD="$suid_dir/fsold$$";
X$TEMPCUR="$suid_dir/fscur$$";
X$TEMPNEW="$suid_dir/fsnew$$";
X$TEMPGON="$suid_dir/fsgon$$";
X$TEMPM="$suid_dir/fsm$$";
X
Xif (@ARGV > 1) { die $usage; }
Xelsif (@ARGV == 1) { $start_dir = shift; }
X
X# these may be terribly rash assumptions....
X$start_dir="/" unless defined $start_dir;
X$find_can_ls = 1 unless defined $find_can_ls;
X
X$NONFS = '-type d \( -fstype nfs -prune \) -o' if $skip_nfs;  
X$find_ls = $find_can_ls ? '-ls' : "-exec $'LS $LSARGS {} \\;";
X
Xdie "Error -- Security directory $suid_dir doesn't exist\n"
X    unless -d $suid_dir;
Xunless (-d $suid_dir) {
X    mkdir($suid_dir, 0700) || die "can't mkdir $suid_dir: $!";
X} 
Xchdir $suid_dir || die "can't chdir $suid_dir: $!\n";
X
X# find the setuid programs and sort
X&run("$'FIND $start_dir $FINDARGS $NONFS -type f \\( -perm -4000 -o -perm -2000 \\) $find_ls | $'SORT > $TEMPCUR");
X
X# compare with the sorted stop list
X# create stop file if needed
Xif (! -f $STOP) { open(S,">$STOP"); close(S); }
X
X&run("$'SORT <$STOP >$TEMPOLD");
X&run("$'COMM -13 $TEMPOLD $TEMPCUR | $'SORT +8 >$TEMPNEW");
X&run("$'COMM -23 $TEMPOLD $TEMPCUR | $'SORT +8 >$TEMPGON");
X
Xlocal($is_able'silent) = 1;
Xlocal($chk_strings'recurse) = 0 unless defined $chk_strings'recurse;
X
X# report changes
Xif (-s $TEMPNEW || -s $TEMPGON) {
X    if (-s $TEMPNEW) {
X	open TEMPNEW || die "Can't open $TEMPNEW: $!\n";
X	while (<TEMPNEW>) {
X	    ($file) = /(\S+)$/;
X
X	    # don't want SUID files to be world writable!
X	    # although *reasonable* systems clear the bit on write
X	    print "Warning!  SUID file $file is _World_ writable!\n" 
X		if &'is_able ($file, "w", "w"); 
X		    
X	    if (-r $file && -f _ && -T $file) {
X		print "Warning!  ", &'Owner($file) ? '' : 'ROOT-owned ', 
X		    "SUID file $file is a non-binary, executable file!\n";
X	    }
X
X	    &'chk_strings($file) if -r _;
X	}
X	close TEMPNEW;
X    }
X
X    if (-s $TEMPNEW) {
X	open TEMPNEW || die "Can't reopen $TEMPNEW: $!\n";
X	print "\nThese files are newly setuid/setgid:\n\n";
X	print while <TEMPNEW>;
X    }
X
X    if (-s $TEMPGON) {
X	open TEMPGON || die "Can't reopen $TEMPGON: $!\n";
X	print "\nThese files are no longer setuid/setgid:\n\n";
X	print while <TEMPGON>;
X    }
X
X}
X
Xunlink $TEMPOLD, $TEMPCUR, $TEMPNEW, $TEMPGON;
X
Xsub run {
X    print "running: $_[0]\n" if $debug;
X    system $_[0];
X    warn "command $_[0] returned $?" if $?;
X} 
X
X#  end it all....
X
X1;
SHAR_EOF
chmod 0700 cops_104/perl/suid.chk ||
echo 'restore of cops_104/perl/suid.chk failed'
Wc_c="`wc -c < 'cops_104/perl/suid.chk'`"
test 4240 -eq "$Wc_c" ||
	echo 'cops_104/perl/suid.chk: original size 4240, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= cops_104/perl/suid.stop ==============
if test -f 'cops_104/perl/suid.stop' -a X"$1" != X"-c"; then
	echo 'x - skipping cops_104/perl/suid.stop (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting cops_104/perl/suid.stop (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cops_104/perl/suid.stop' &&
SHAR_EOF
chmod 0700 cops_104/perl/suid.stop ||
echo 'restore of cops_104/perl/suid.stop failed'
Wc_c="`wc -c < 'cops_104/perl/suid.stop'`"
test 0 -eq "$Wc_c" ||
	echo 'cops_104/perl/suid.stop: original size 0, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= cops_104/perl/user.chk ==============
if test -f 'cops_104/perl/user.chk' -a X"$1" != X"-c"; then
	echo 'x - skipping cops_104/perl/user.chk (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting cops_104/perl/user.chk (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cops_104/perl/user.chk' &&
X#!/bin/sh -- need to mention perl here to avoid recursion
X'true' || eval 'exec perl -S $0 $argv:q';
Xeval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
X& eval 'exec /usr/local/bin/perl -S $0 $argv:q'
X        if 0;
X
X#
X#  This combines user.chk and home.chk.  It searches for home directories
X# and various user startup files for world writability, as well as flagging
X# any .rhosts and .netrc files that are readable.  You can change the
X# files checked by changing @ftable and @readables, respectively.
X# 
X
X#
X# check for writable files in all user's homes
X#
Xrequire "pass.cache.pl";
Xrequire "is_able.pl";
X
X# files checked for:
X@ftable = ("rhosts", "profile", "login", "logout", "cshrc",
X	   "bashrc", "bash_profile", "inputrc", "screenrc",
X	   "kshrc", "tcshrc", "netrc", "forward", "dbxinit",
X	   "distfile", "exrc", "emacsrc", "remote", "mh_profile",
X	   "xinitrc", "xsession", "Xdefaults", "Xresources", "rninit");
X
X@readables = ("netrc", "rhosts");
X
Xlocal(%done);
X
X# what's the point of doing a keys and using $i ??
X# why not just do "for $dir (values %uname2dir) {" ????
Xfor $i (keys %uname2dir) {
X    $dir = $uname2dir{$i};
X    #   I don't want to hear about every file in their home dir, if 
X    # is WW, but still need to check the .netrc file for readability...
X    next unless $dir;
X    next if $done{$dir}++;
X    if (-e $dir) { 
X        if (&is_able($dir, "w", "w")) {
X            for $r (@readables) {
X                if (-s "$dir/.$r") {
X                    &is_able("$dir/.$r", "w", "r");
X		}
X	    }
X            next;
X	}
X        for $file (@ftable) {
X            $foo_file = $dir . "/.$file";
X            if (-e $foo_file) {
X                &is_able($foo_file, "w", "w");
X                for $r (@readables) {
X                    if ($file eq $r && -s $foo_file) {
X                        &is_able($foo_file, "w", "r");
X		    }
X		}
X	    }
X	}
X    }
X}
X
X1;
SHAR_EOF
chmod 0700 cops_104/perl/user.chk ||
echo 'restore of cops_104/perl/user.chk failed'
Wc_c="`wc -c < 'cops_104/perl/user.chk'`"
test 1870 -eq "$Wc_c" ||
	echo 'cops_104/perl/user.chk: original size 1870, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= cops_104/perl/yagrip.pl ==============
if test -f 'cops_104/perl/yagrip.pl' -a X"$1" != X"-c"; then
	echo 'x - skipping cops_104/perl/yagrip.pl (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting cops_104/perl/yagrip.pl (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cops_104/perl/yagrip.pl' &&
X#Yet Another Getopt Routine In Perl
X# jgreely@cis.ohio-state.edu, 89/11/1
X#usage:
X#&getopt("f:bar") ||
X#	die &usage("script","f:bar","oo","[files ...]");
X#
Xsub getopt {
X	local($_,$flag,$opt,$f,$r,@temp) = @_;
X	@temp = split(/(.):/);
X	while ($#temp >= $[) {
X		$flag .= shift(@temp);
X		$opt .= shift(@temp);
X	}
X	while ($_ = $ARGV[0], /^-(.)(.*)/ && shift(@ARGV)) {
X		($f,$r) = ($1,$2);
X		last if $f eq '-';
X		if (index($flag,$f) >= $[) {
X			eval "\$opt_$f++;";
X			$r =~ /^(.)(.*)/,redo if $r ne '';
X		}elsif (index($opt,$f) >= $[) {
X			$r = $r eq '' ? shift(@ARGV) : $r;
X			eval "\$opt_$f = \$r;";
X		}else{
X			print STDERR "Unrecognized switch \"-$f\".\n";
X			return 0;
X		}
X	}
X	return 1;
X}
X
X#usage: usage:
X# &usage(progname,arglist,@names,@last);
X#ex:
X# &usage("script","f:bar","oo","[file ...]");
X#would return
X# "usage: script [-f oo] [-bar] [file ...]"
X#
Xsub usage {
X	local($prog,$_,@list) = @_;
X	local($string,$flag,@string,@temp,@last) = ();
X	@temp = split(/(.):/);
X	push(@string,"usage:",$prog);
X	while ($#temp >= $[) {
X		if (($flag = shift(@temp)) ne '') {
X			push(@string,"[-$flag]");
X		}
X		if (($flag = shift(@temp)) ne '') {
X			push(@string,sprintf("[-%s %s]",$flag,shift(@list)));
X		}
X	}
X	push(@string,@list) if $#list >= $[;
X	return join(' ',@string) . "\n";
X}
X1;
SHAR_EOF
chmod 0600 cops_104/perl/yagrip.pl ||
echo 'restore of cops_104/perl/yagrip.pl failed'
Wc_c="`wc -c < 'cops_104/perl/yagrip.pl'`"
test 1274 -eq "$Wc_c" ||
	echo 'cops_104/perl/yagrip.pl: original size 1274, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= cops_104/perl/prl.patch ==============
if test -f 'cops_104/perl/prl.patch' -a X"$1" != X"-c"; then
	echo 'x - skipping cops_104/perl/prl.patch (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting cops_104/perl/prl.patch (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cops_104/perl/prl.patch' &&
X> > The 4.0.3 patch was, as far as I know, never released, and it certainly wasn't
X> > rolled into 4.1.1. The above was the last I heard about the bug until I
X> > complained again after we installed 4.1.1.
X
X>   Hmm.  I looked up the bug, and found some proposed fixes by dan
X> trinkle of purdue, but I'm not sure that they really do anything but
X> slow the attackers down.  Again, I'll look at this and get back to you.
X
XThere's a bug in Dan's patch which allows a cracker to get the maps iff the last
Xlegitimate request to ypserv was to the same map as the map the cracker is
Xrequesting. I understand from a dark hint in one of Brad Powell's messages that
Xthis problem was discovered by Sun Engineering.
X
XApart from that, Dan's patch should block any attacks apart from
Xhost spoofing ones. Of course, if the attacker is clever enough to spoof hosts,
Xyou will have to `take up arms against a sea of troubles'.
X
X>   Indeed.  It's unbelievable that you can write to the things so easily
X> and make the machine forget it's identity or something equally obnoxious.
X> It's interesting to me that the system crackers seem to be getting
X> more sophisticated; I'm wondering what, if anything, computer manufacturers
X> will be doing with this?  I suppose that there will always be hosts that
X> are poorly set up regardless of what you do.  I'd like to see something
X> like the self-cleaning oven paridigm -- the more you use your system,
X> the more secure it gets :-)
X
XThe getty hack was demonstrated to us by a student here (a German). I don't
Xknow how well-know the problem is in German {h,cr}acker circles. As far as
Xself-cleaning goes, I think systems are more like colour CRT's than
Xself-cleaning ovens. They positively *attract* dirt and grime.
X
XA small bunch of patches for pcops are attached.
X
XThe things changed are:
X	1) '_' added to the allowed characters in login names & group names
X	2) The pattern for allowed login and group names made the same
X	3) Search for rexd rather than rexecd in /etc/inetd.conf. Perhaps
X	   rexecd is also a security hole, but rexd(8)/on(1) is a gaping
X	   cavernous one.
X	4) Assorted hacking to get suid checking to work sort-of portably.
X	   The test for NFS fs's is:
X		       ($dev < 0 || $dev >= 16384)
X	   Ultrix and AIX use large, rather than -'ve major devs for NFS mounts.
X	   Apart from the added test and the argument parsing, the code in
X	   suidfind.pl was generated by find2perl.
X	   Using the -xdev test, and a list of the local mounts in /etc/fstab
X	   is probably a better strategy than the above hack. Ultrix find
X	   doesn't have -xdev, either, so I think find2perl is the way to go
X	   on this.
X
Xregards,
X
Xpeter
X
X*** group.chk.orig	Sun Jun 23 15:35:27 1991
X--- group.chk	Fri Dec  6 13:42:55 1991
X***************
X*** 92,98 ****
X  	$groups{$group}++;   # keep track of dups
X  	print "$W line $., does not have 4 fields:\n\t$_" if (@_ != 4);
X  	print "$W line $., nonalphanumeric group name:\n\t$_"
X! 	    if $group !~ /^[A-Za-z0-9-]+$/;
X  	if ($pass && $pass ne '*') {
X  	    if ( ! $C2 || $yp ) {
X  		print "$W line $., group has password:\n\t$_"
X--- 92,98 ----
X  	$groups{$group}++;   # keep track of dups
X  	print "$W line $., does not have 4 fields:\n\t$_" if (@_ != 4);
X  	print "$W line $., nonalphanumeric group name:\n\t$_"
X! 	    if $group !~ /^[_A-Za-z0-9-]+$/;
X  	if ($pass && $pass ne '*') {
X  	    if ( ! $C2 || $yp ) {
X  		print "$W line $., group has password:\n\t$_"
X*** passwd.chk.orig	Sun Jun 23 15:35:45 1991
X--- passwd.chk	Fri Dec  6 13:42:53 1991
X***************
X*** 93,99 ****
X  	$users{$user}++;    # keep track of dups
X  	print "$W line $., does not have 7 fields:\n\t$_" if (@_ != 7);
X  	print "$W line $., nonalphanumeric username:\n\t$_"
X! 	    if $user !~ /^[A-Za-z0-9]+$/;
X  	print "$W line $., numeric username:\n\t$_"
X  	    if $user =~ /^\d+$/;
X  	print "$W line $., login name > 8 characters:\n\t$_"
X--- 93,99 ----
X  	$users{$user}++;    # keep track of dups
X  	print "$W line $., does not have 7 fields:\n\t$_" if (@_ != 7);
X  	print "$W line $., nonalphanumeric username:\n\t$_"
X! 	    if $user !~ /^[_A-Za-z0-9-]+$/;
X  	print "$W line $., numeric username:\n\t$_"
X  	    if $user =~ /^\d+$/;
X  	print "$W line $., login name > 8 characters:\n\t$_"
X*** misc.chk.orig	Sun Jun 23 15:35:35 1991
X--- misc.chk	Tue Dec  3 14:09:43 1991
X***************
X*** 58,64 ****
X  		 ( -f '/etc/servers' && '/etc/servers') ||
X  		 'BOGUS';
X  	}
X! $rexd="rexecd";
X  
X  # tmp and target file (for tftp test)
X  $target="/etc/motd";
X--- 58,64 ----
X  		 ( -f '/etc/servers' && '/etc/servers') ||
X  		 'BOGUS';
X  	}
X! $rexd="rexd";
X  
X  # tmp and target file (for tftp test)
X  $target="/etc/motd";
X*** suid.chk.orig	Fri Aug 30 17:17:49 1991
X--- suid.chk	Tue Dec  3 16:51:41 1991
X***************
X*** 43,55 ****
X  $usage = "Usage: $0 [-n] [-s secure_dir] [starting_directory]\n";
X  require 'getopts.pl';
X  # Process the command args; Either specify verbose or an alternate config file:
X! die $usage unless &`Getopts('ns:');
X  
X  $suid_dir = $'SECURE || '.';
X! if (defined($opt_s)) { $suid_dir = $opt_s; }
X  
X  # Do NFS stuff?  Yes unless opt:
X! if (defined($opt_n)) { $skip_nfs = $opt_n; }
X  else { $skip_nfs = 0; }
X  
X  $STOP="$suid_dir/suid.stop";
X--- 43,55 ----
X  $usage = "Usage: $0 [-n] [-s secure_dir] [starting_directory]\n";
X  require 'getopts.pl';
X  # Process the command args; Either specify verbose or an alternate config file:
X! die $usage unless &'Getopts('ns:');
X  
X  $suid_dir = $'SECURE || '.';
X! if (defined($'opt_s)) { $suid_dir = $'opt_s; }
X  
X  # Do NFS stuff?  Yes unless opt:
X! if (defined($'opt_n)) { $skip_nfs = $'opt_n; }
X  else { $skip_nfs = 0; }
X  
X  $STOP="$suid_dir/suid.stop";
X***************
X*** 64,83 ****
X  
X  # these may be terribly rash assumptions....
X  $start_dir="/" unless defined $start_dir;
X- $find_can_ls = 1 unless defined $find_can_ls;
X  
X- $NONFS = '-type d \( -fstype nfs -prune \) -o' if $skip_nfs;  
X- $find_ls = $find_can_ls ? '-ls' : "-exec $'LS -gilds {} \\;";
X- 
X  die "Error -- Security directory $suid_dir doesn't exist\n"
X      unless -d $suid_dir;
X  unless (-d $suid_dir) {
X      mkdir($suid_dir, 0700) || die "can't mkdir $suid_dir: $!";
X! } 
X  chdir $suid_dir || die "can't chdir $suid_dir: $!\n";
X  
X  # find the setuid programs and sort
X! &run("$'FIND $start_dir $NONFS -type f \\( -perm -4000 -o -perm -2000
X\\) $find_ls | $'SORT > $TEMPCUR");
X  
X  # compare with the sorted stop list
X  # create stop file if needed
X--- 64,82 ----
X  
X  # these may be terribly rash assumptions....
X  $start_dir="/" unless defined $start_dir;
X  
X  die "Error -- Security directory $suid_dir doesn't exist\n"
X      unless -d $suid_dir;
X  unless (-d $suid_dir) {
X      mkdir($suid_dir, 0700) || die "can't mkdir $suid_dir: $!";
X! }
X! 
X  chdir $suid_dir || die "can't chdir $suid_dir: $!\n";
X  
X  # find the setuid programs and sort
X! 
X! &run("$suid_dir/suidfind.pl".($skip_nfs ? " -n " : " ").$start_dir
X! 	. "| $'SORT > $TEMPCUR");
X  
X  # compare with the sorted stop list
X  # create stop file if needed
X*** /dev/null	Mon Dec 23 11:46:59 1991
X--- suidfind.pl	Tue Dec  3 10:39:42 1991
X***************
X*** 0 ****
X--- 1,123 ----
X+ #!/bin/sh -- need to mention perl here to avoid recursion
X+ 'true' || eval 'exec perl -S $0 $argv:q';
X+ eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
X+ & eval 'exec /usr/local/bin/perl -S $0 $argv:q'
X+         if 0;
X+ 
X+ #
X+ #  Usage: suidfind.pl [-n] [-s secure_dir] [search_starting_directory]
X+ #
X+ 
X+ require "getopts.pl";
X+ 
X+ die $usage unless &Getopts('n');
X+ 
X+ # Do NFS stuff?  Yes unless opt:
X+ if (defined($opt_n)) { $skip_nfs = $opt_n; }
X+ else { $skip_nfs = 0; }
X+ 
X+ if (@ARGV > 1) { die $usage; }
X+ elsif (@ARGV == 1) { $start_dir = shift; }
X+ 
X+ # these may be terribly rash assumptions....
X+ $start_dir="/" unless defined $start_dir;
X+ 
X+ @rwx = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
X+ @moname = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
X+ 
X+ while (($name, $pw, $uid) = getpwent) {
X+     $user{$uid} = $name unless $user{$uid};
X+ }
X+ 
X+ while (($name, $pw, $gid) = getgrent) {
X+     $group{$gid} = $name unless $group{$gid};
X+ }
X+ 
X+ require "find.pl";
X+ 
X+ # Traverse desired filesystems
X+ 
X+ &find($start_dir);
X+ 
X+ exit;
X+ 
X+ sub wanted {
X+     (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
X+     -d _ &&
X+     (	$skip_nfs &&
X+ 	($dev < 0 || $dev >= 16384) &&
X+ 	($prune = 1)
X+     )
X+     ||
X+     -f _ &&
X+     (
X+ 	($mode & 04000) == 04000
X+ 	||
X+ 	($mode & 02000) == 02000
X+     ) &&
X+     &ls;
X+ }
X+ 
X+ sub ls {
X+     ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
X+       $atime,$mtime,$ctime,$blksize,$blocks) = lstat(_);
X+ 
X+     $pname = $name;
X+ 
X+     if (defined $blocks) {
X+ 	$blocks = int(($blocks + 1) / 2);
X+     }
X+     else {
X+ 	$blocks = int(($size + 1023) / 1024);
X+     }
X+ 
X+     if    (-f _) { $perms = '-'; }
X+     elsif (-d _) { $perms = 'd'; }
X+     elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
X+     elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
X+     elsif (-p _) { $perms = 'p'; }
X+     elsif (-S _) { $perms = 's'; }
X+     else         { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
X+ 
X+     $tmpmode = $mode;
X+     $tmp = $rwx[$tmpmode & 7];
X+     $tmpmode >>= 3;
X+     $tmp = $rwx[$tmpmode & 7] . $tmp;
X+     $tmpmode >>= 3;
X+     $tmp = $rwx[$tmpmode & 7] . $tmp;
X+     substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
X+     substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
X+     substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
X+     $perms .= $tmp;
X+ 
X+     $user = $user{$uid} || $uid;
X+     $group = $group{$gid} || $gid;
X+ 
X+     ($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
X+     $moname = $moname[$mon];
X+     if (-M _ > 365.25 / 2) {
X+ 	$timeyear = '19' . $year;
X+     }
X+     else {
X+ 	$timeyear = sprintf("%02d:%02d", $hour, $min);
X+     }
X+ 
X+     printf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
X+ 	    $ino,
X+ 		 $blocks,
X+ 		      $perms,
X+ 			    $nlink,
X+ 				$user,
X+ 				     $group,
X+ 					  $sizemm,
X+ 					      $moname,
X+ 						 $mday,
X+ 						     $timeyear,
X+ 							 $pname;
X+     1;
X+ }
X+ 
X+ sub sizemm {
X+     sprintf("%3d, %3d", ($rdev >> 8) & 255, $rdev & 255);
X+ }
X+ 
SHAR_EOF
chmod 0600 cops_104/perl/prl.patch ||
echo 'restore of cops_104/perl/prl.patch failed'
Wc_c="`wc -c < 'cops_104/perl/prl.patch'`"
test 10121 -eq "$Wc_c" ||
	echo 'cops_104/perl/prl.patch: original size 10121, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= cops_104/perl/README.sgi ==============
if test -f 'cops_104/perl/README.sgi' -a X"$1" != X"-c"; then
	echo 'x - skipping cops_104/perl/README.sgi (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting cops_104/perl/README.sgi (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cops_104/perl/README.sgi' &&
X
X  Here's a rumored way (courtesy of Mac Allen jma21624@usav01.glaxo.com) of
Xfixing problems with SGI machines and perl... you might give this a shot
Xif you're having troubles -- the mysteries of perl, and all that.
X
X -- dan
X
X=================================================
XSubject: Kuang Un-Hang
X
XI just figured out one way of fixing the kuang hang:
X
X#!/usr/bin/perl
X$x= `./kuang.pl`;
Xprint $x;
X
XI originally did this as a way of running shell scripts I wrote to extend
XCOPS with custom stuff, like sulog.chk, login.chk, etc.  The original
Xkuang perl script is in kuang.pl now, and it writes to the report when
Xrun from cops.cf.
X
X- Mac Allen jma21624@usav01.glaxo.com
X
SHAR_EOF
chmod 0600 cops_104/perl/README.sgi ||
echo 'restore of cops_104/perl/README.sgi failed'
Wc_c="`wc -c < 'cops_104/perl/README.sgi'`"
test 672 -eq "$Wc_c" ||
	echo 'cops_104/perl/README.sgi: original size 672, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= cops_104/README.2.sh ==============
if test -f 'cops_104/README.2.sh' -a X"$1" != X"-c"; then
	echo 'x - skipping cops_104/README.2.sh (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting cops_104/README.2.sh (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cops_104/README.2.sh' &&
X
X  This file covers the configuration and execution of the shell/C
Xversion of COPS.  As a rough time estimate, it took about 6.5 minutes on
Xmy host (a SPARCstation 2) to make the programs and generate a report
X(not including the SUID checker, which does a find on "/").
X
X1) How to Configure COPS
X-------------------------
X
X  System V users, other Non-BSD systems, or sites with commands in
Xstrange places may have to run a shell script called "reconfig" to
Xchange the pathnames of the executable programs called when using COPS.
XIn general, if your system does not use the paths listed in the shell
Xscripts, try running "reconfig".  COPS should run fine then, if it can
Xfind all of the commands (reconfig will tell you if it cannot).  If
Xtrouble persists, you will have to change the paths to your executable
Xfiles (awk, sed, etc) by hand.  A drag, I know.  If in doubt, run the
Xshell script.  It can't hurt.  Or at least shouldn't.  If it does hurt,
Xyou're probably in trouble anyway.
X
X  With all the varieties of unix, there are a few types that may need
Xextra help to run the system.  There are "readme" files for several
Xsystems in the distribution (see the files "readme.*" in the "docs"
Xdirectory).  If you have any troubles, drop me a line and I'll see what
XI can do about working out a patch/fix/workaround with you.  Some
Xproblems might arise with some SYSV machines (heck, or any machine :-)),
Xdue to weird files and names for stuff.  What can I say?  Portability
Xis a problem.
X
X  C2 (as in NCSC standards -- B1, C2, etc.), NIS/YP, or shadow password
Xusers can also look at "readme.*" files for suggestions on how to best
Xrun/utilize COPS.
X
X2) Running COPS for the First Time
X-----------------------------------
X
X   Since most of COPS was written and tested on just a few machines (at
Xleast compared to the total number out there!), you may have significant
Xdifferences that were not anticipated -- unfortunately (or fortunately)
XUNIX is not quite standardized yet.  However, I haven't run into a UNIX
Xthat I haven't been able to get it running on, with just a small amount
Xof change (at least for the shell version -- perl is another story :-(
X), so feel free to mail to me for help.  Note that the following info is
Xfor the shell version only -- read "README.perl" for information on how
Xto install and run the perl version.
X
X   COPS is run by simply typing "cops".  "cops" is a Bourne shell script
Xthat runs each of the programs, accumulates the output, and then either
Xmails any results or stores them in a file.  "suid.chk" (and possibly
X"crc.chk") is the only package that is meant to be run separately, both
Xbecause it can take a long time to run and because it needs a privileged
Xaccount (i.e. root) to run it; look at "suid.man" for more information.
XBy all means, however, do not ignore the SUID checker!  Run it at least
Xonce a week, more (daily?) if possible; intruders often leave SUID files
Xto gain privileges later.  You should also run "crc.chk".  It can either
Xbe run as a standalone program (preferred), or as part of the COPS
Xpackage; read the file "CRC.README" and the man page for more
Xinformation.
X
X   To run COPS for the first time, follow these steps:
X
X   -- Look at the disclaimer, file "disclaimer".  Don't sue me.
X
X   -- Type "make" to compile the C programs and to make the shell programs
X      executable, "make man" to create the formatted manual pages, or "make
X      all" to make both the programs and documentation.
X
X      A couple of potential (hopefully minor problems), probably only
X      for SysV based machines:
X
X      If you don't have the "-ms" package for nroff (i.e. you, get an
X      error message about it after typing "make"), just remove the "-ms"
X      flag -- change line 15 of the "docs/makefile" file, from:
X
X      ROFFLAGS   = -ms
X        to
X      ROFFLAGS   =
X
X      The password checking program may fail to compile.  If so, try 
X      uncommenting line 29 in "makefile" -- this will enable the
X      "BRAINDEADFLAGS = -lcrypt" flag.  If this doesn't work, you can
X      either work it out (and tell me about your solution) or e-mail me,
X      and we'll work it together.
X
X   -- Read the technical report (in the "docs" directory) to understand
X      what COPS is doing and what is going on -- "COPS.report".  Although
X      this is out of date, this does give a look at the philosophies,
X      design, and general outlay of the COPS system and UNIX security.
X      This can be forsaken by those who just want to get to the results/see
X      some action (people like me), but it might prove interesting to some. 
X
X   -- Change lines 93 and 94 in the "cops" shell file.  They are
X      originally:
X
X        SECURE=/usr/foo/bar
X        SECURE_USERS="foo@bar.edu"
X
X      SECURE should be the same directory as the directory that contains 
X      the COPS programs, and SECURE_USERS should be your own login id,
X      or whomever you designate as the recipient of the output.
X
X      Alternately, you can use the "-s" flag to "cops" to specify the
X      secure directory, and the "-m" flag will make cops both mail the
X      report (see next item) and specify the user to be mailed to.
X
X   -- Set "MMAIL=NO" in the "cops" shell file (line 42; it is this by
X      default).  This will prevent a large mail file of warnings from
X      choking the mailer.  All of the output will be put into a file
X      called "year_month_day" (obviously, that's like: "1991_Dec_31",
X      not actually the words, "year_month_day" :-)), which is
X      automatically placed by COPS in a directory that has the same name
X      as the host it was run on (e.g., your own hostname.)  Hence, the
X      final report will be in "./hostname/year_month_day".
X
X      If you prefer to have the report mailed (don't do this the first
X      time) set this variable to YES and the report will be mailed to
X      $SECURE_USERS, or use the "-m" flag and specify the user on the
X      command line.
X
X   -- Look at the directory and file configuration file, "is_able.lst" 
X      This contains critical files that COPS checks for group- and
X      world-writability and readability.  Add or delete whatever files
X      or directories you wish; if a file doesn't exist, COPS will ignore
X      it. (If you don't know or are uncertain what files/directories are 
X      important, what is given there is a good set to start with on most
X      systems.)
X
X   -- If you allow anonymous ftp access to your system, add a "-a" flag
X      to "ftp.chk" on line 193 of "cops".  Right now, it is set up so
X      that key files and directories are expected to be owned by root;
X      however, it has provisions for two owners, $primary and $secondary
X      -- some may wish to change the second to "ftp", or some other
X      user. Read the man page for ftp.chk or look at "ftp.chk" for
X      further notes. 
X
X   -- You may wish to comment out the password checker (line 200 in the 
X      "cops" shell file), for immediate gratification.  However, it is 
X      generally a very bad idea to do this unless you plan to use
X      another password cracker, such as "crack" (see the "extensions"
X      directory for more info).  If you are using yellow pages/NIS, read
X      "readme.yp" for tips on how to check passwords with it; if you are
X      using shadow passwords, read "readme.shadow".
X
X   -- Uncomment out the crc checker, "crc.chk" (lines 218-220 and
X      224-226), if you desire to run it as part of the normal COPS run --
X      highly recommended!
X
X   You should be ready to roll.  COPS is run by simply typing "cops"
X(you may wish to put it in the background).  If you followed my advice
Xand set "MMAIL=NO" in the "cops" shell file, after COPS is finished
Xthere will be a report file created ("year_month_day") that includes the
Xtime and machine it was created on.  Otherwise, COPS will mail the
Xreport to the user(s) listed on the line 'SECURE_USERS="foo@bar.edu"'
X(or by the -m flag.)  There is a file called "warnings" which contains most
Xof the warning messages that COPS uses, a brief explanation of how the
Xmessage might pertain to your system, and finally a suggestion as how to
X"fix" any problem.
X
XWARNING NOTE: Change the shell script "cops" to reflect who you want the
Xoutput sent to and where the location of the program is BEFORE running the
Xprogram!
SHAR_EOF
chmod 0600 cops_104/README.2.sh ||
echo 'restore of cops_104/README.2.sh failed'
Wc_c="`wc -c < 'cops_104/README.2.sh'`"
test 8275 -eq "$Wc_c" ||
	echo 'cops_104/README.2.sh: original size 8275, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= cops_104/README.2.pl ==============
if test -f 'cops_104/README.2.pl' -a X"$1" != X"-c"; then
	echo 'x - skipping cops_104/README.2.pl (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting cops_104/README.2.pl (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cops_104/README.2.pl' &&
X
X  This file covers the configuration and execution of the perl version
Xof COPS (or p-COPS).  It requires a version of perl > 3.18 to work.  For
Xa rough time estimate, it took about 1.25 minutes on my host (a
XSPARCstation 2) to generate a report (not including the SUID checker,
Xwhich does a find on "/").  p-COPS is roughly functionally equivalent to
Xthe shell/C version (sans the CRC checker), but has some important
Xdifferences:
X
XAdvantages:
X
Xo  Perl is a real language (not that C isn't -- I'm comparing it mostly 
X   to shell programming.)  It has almost no arbitrary limitations,
X   unlike shell (amount of data a variable can hold, etc.)  All the
X   information that COPS finds (especially from the password file, which
X   is a major source of the security problems in a UN*X system) can be
X   easily passed between modules.  As a result, the programs are more
X   modular, easier to debug, and a lot more fun to write.
X
Xo  Perl is faster (even though the "hard" things are done mostly in C in
X   the shell/C version, a lot of time is wasted due to the fact that
X   almost no data sharing is done) and doesn't require any compilation
X   (aside from the perl interpreter itself.)  This last point is  
X   particularily nice for sites with multiple architectures.
X
Xo  p-COPS has a pair of very nice features -- the configuration file and 
X   the recursive searching for writable files.  The config file is a big
X   win: no more digging through code, trying to change some variable
X   value and it gives control over which modules are run and many other
X   important options. 
X
XDisadvantages:
Xo  Perl.  It's a relatively new language that is changing frequently.
X   The code, greatly boosted in complexity and efficiency by tom 
X   christiansen's hard work, can cause core dumps and other problems
X   on some platforms.  On others, it works fine.  Also, since perl is
X   changing, future versions of perl might break previously working
X   code.  It all rests in larry wall's capable hands.  Caveat Usor. 
X
Xo  p-COPS has not been tested thoroughly.  It seems to work, on some
X   machines, but is sure to contain more bugs than the simpler shell/C
X   version. 
X
X  Ok -- now you're warned.  I highly suggest giving it a try -- here's
Xhow to use p-COPS:
X
X1) How to Configure p-COPS
X---------------------------
X
X  Although most of the programs in p-COPS are written entirely in perl,
Xsome shell programs are used for simplicity (diff, ypcat, etc.)  This
Xshouldn't be a problem, but System V users, other Non-BSD systems, or
Xsites with commands in strange places should run a program called
X"reconfig.pl" to change the pathnames of the executable programs called
Xwhen using COPS.  If your system does not use the paths listed in the
Xperl programs, try running it; COPS should run fine then, if it can find
Xall of the commands (reconfig should tell you if it cannot). If trouble
Xpersists, you will have to edit the configuration file "cops.cf" to
Xchange the paths to your executable files by hand.  A drag, I know.  If
Xin doubt, run reconfig.pl.  It can't hurt.  Or at least shouldn't.  If
Xit does hurt, you're probably in touble anyway.
X
X2) Running p-COPS for the 1st Time
X---------------------------------
X
X   Since most of p-COPS was written and tested mostly on just a few
Xmachines (at least compared to the total number out there!), you may
Xhave significant differences that were not anticipated -- unfortunately
X(or fortunately) perl and UNIX are not quite standardized yet.
X
X   p-COPS is run by going into the "perl" subdirectory and typing
X"cops".  "cops" is a perl program that looks inside the configuration
Xfile ("cops.cf"), runs each of the programs listed there, accumulates
Xthe output, and then either mails any results or stores them in a file.
X"suid.chk" is the only package that is usually meant to be run
Xseparately (although it can be run via the config file), simply because
Xit can take a long time to run, and because it needs a privileged
Xaccount to run it; look at "suid.man" for more information.  By all
Xmeans, however, do not ignore the SUID checker!  Run it at least once a
Xweek, if possible more (daily?); intruders into a system often leave
XSUID files to gain privileges later.  The program "crc.chk" (part of the
Xshell/C version of COPS) should also be run; read the file "CRC.README",
Xand the man page for more information.
X
X   -- Read the technical report to understand what COPS is doing and
X      what is going on -- "cops.report".  This gives a look at the 
X      philosophies, design, and general outlay of the COPS system and
X      UNIX security.  This can be forsaken by those who just want to get
X      to the results/see some action (people like me), but it might
X      prove interesting to some.
X
X   -- On line 12 in the configuration file, "cops.cf":
X
X        $SECURE_USERS="foo@bar.edu";
X
X      $SECURE_USERS should be your own login id, or that of whomever
X      you designate as the recipient of the output.
X
X   -- Set "$MMAIL=0" in the "cops.cf" file (line 10; this is the default).
X      This will prevent a large mail file from choking the mailer.  All of
X      the output will be put into a file called "year_month_day" (obviously,
X      that's like: "1992_Dec_31", not actually the words,
X      "year_month_day" :-)), which is automatically placed by COPS
X      in a directory that has the same name as the host it was run on
X      (e.g., your own hostname).  Hence, the final report will be in
X      "./hostname/year_month_day".  Setting this variable to 1 will
X      cause the report to be mailed to $SECURE_USERS.
X
X   -- Look at the directory and file configuration file, "is_able.lst" 
X      This contains critical files that COPS checks for group and world 
X      writability and readability.  Add or delete whatever files/
X      directories you wish; if a file doesn't exist, COPS will
X      effectively ignore it.  (If you don't know or are uncertain what
X      files/directories are important, what is given there is a good set
X      to start with on most systems.)
X
X   -- If you allow anonymous ftp access to your system, add a "-a" flag 
X      to "ftp.chk" on line 83 of "cops.cf".  Right now, it is set up so 
X      that key files and directories are expected to be owned by root; 
X      however, it has provisions for two owners, $primary and $secondary
X      -- you may wish to change the second to "ftp", or some other user. 
X      Read the man page for ftp.chk, or look at "ftp.chk" for further
X      notes. 
X
X   -- You may wish to comment out the password checker (line 72 in the 
X      "cops.cf" file), if you wish for immediate gratification.
X      However, it is an abysmal idea to do this in general (unless you
X      use another password cracker, like "crack" (see the "extensions"
X      directory for more info.)  If you are using yellow pages/NIS, read
X      "readme.yp" for tips on how to check passwords with it; if you are
X      using shadow passwords, read "readme.shadow".
X
X   -- Run the crc checker, "crc.chk" if you desire; unfortunately, this
X      hasn't been ported to perl yet, so you'll have to either use the
X      shell version or wait for the port (or write it and send it to me...)
X
X  You should be ready to roll.  COPS is run by simply typing "cops" (you
Xmay wish to put it in the background).  If you followed my advice and
Xset "$MMAIL=0" in the "cops.cf" configuration file, after COPS is
Xfinished there will be a report file created ("year_month_day") that
Xlists the time and machine it was created on.  Otherwise, COPS mails the
Xreport to the user(s) listed on the line '$SECURE_USERS="foo@bar.edu"'.
XThere is a file "warnings" (in the "../docs" directory), which contains
Xthe warning messages COPS uses, as well as a brief explanation of how
Xthe message might pertain to your system and finally a suggestion as
Xhow to "fix" any problem.
X
X   WARNING NOTE: Change the configuration file "cops.cf" to reflect who
Xyou want the output sent to and where the location of the program is
XBEFORE running the program.
X
X
X2) Further notes and use of p-COPS, plus things for "perl literates"
X---------------------------------------------------------------------
X
X   The only important thing you have to set in the "cops" main file (or
Xvia the "-s" flag) is the secure directory, which by default is ".".
XThis is where COPS will look for the config file and all the programs.
XAlso, if something is flagged as world-writable, and the file itself is
Xnot writable but the parent directory is, then there will be an asterix
Xafter the warning (e.g. /usr/foo/bar is World Writable! (*).)
X
XAs said in the config file -- "cops.cf" (a "#" sign denotes comments):
X
X# anything beginning with /^\s*[$@%&]/ will be eval'd
X
X  In general, you can put variables and programs that will be run inside
Xthe config file.  Variables look startlingly like they do in normal perl
X(look at the "PROGRAMS" section below for more on running programs);
Xe.g.:
X
X$MMAIL 		= 0; 		# send mail instead of generating reports
X$ONLY_DIFF 	= 0;  		# only send diff from last time
X$SECURE_USERS   = "root"; 	# user to receive mailed report
X
X   Setting something to "0" (without quotes is fine) generally means
Xthat the option is not used.  "1" (or non-zero values, if you feel
Xgutsy) is used for a positive/true/whatever value.  The variables in
Xgeneral should be very similar to their normal COPS counterparts; in
Xthis case, setting $MMAIL to 1 would mean to mail info to the user listed
Xin SECURE_USERS.  If $ONLY_DIFF is 1, it will only mail reports if change
Xhas occurred.
X
X  In general, variables in the main package are for COPS itself, whereas
Xthose with package qualifiers are for a particular routine or for
Xauxiliary routines.  For instance, the following lines:
X
X# this one says to ignore warnings about paths matching these regexps
X@chk_strings'ignores = ( '^/tmp/?', '^/(var|usr)/tmp/?' );
X
X  "chk_strings" is a routine that checks for writable programs within
Xother programs, usually executed by root, such as /etc/rc and crontab.
XThis line says to ignore any files that start with a "/tmp", "/var/tmp",
Xor "/usr/tmp".  If you have a file or set of files that always are
Xreturning writable that are inside your rc and cron files, then you can
Xput exceptions here.  One possibility is that you don't care about files
Xcreated by other programs, so that anything after a ">" should be
Xignored.  You might add something like '>.*' to ignore files like
X"/usr/bar/snowcone", in a line like "/foo/bar/command >
X/usr/bar/snowcone".
X
X   Next, there is a nifty option that does recursive searching inside
Xthe files chk_strings looks at.  This is neat... get it working by
Xsetting this to 1:
X
X$chk_strings'recurse = 1;
X
X  So, if you have a line like this in /etc/rc:
X
X/usr/bin/foo > /dev/console
X
X  It will examine "/usr/bin/foo" for programs inside of it -- and it
Xwill keep going until it has exhausted all possibilities.  So you can
Xget warning messages like:
X
XWarning!  File /foo/bar (inside /usr/local/X11R4/bin/X inside
X/usr/local/X11R4/bin/xdm inside /etc/rc.local) is _World_ writable!
X
X  Fun stuff.  No one can hide, now...
X
XPROGRAMS
X=========
X
X  Running a program within p-COPS is easy; you just have the program
Xwith any options by itself on a line.  Semi-colons are not welcome here.
XE.g.:
X
X# first test the security of the root account
Xroot.chk
X
X  Some variables specific to the various programs are here as well, e.g.:
X
X# now of the various devices.  -g means to check group writability, too
X$MTAB    = '/etc/fstab';
X$EXPORTS = '/etc/exports';
X$TAB_STYLE = 'new';
Xdev.chk -g 
X
X  This is specifying the export files, etc., and saying that you should
Xuse the "new" format style in the exports file.  Ultrix, etc. uses the
Xold style.  Suid.chk eats up time -- consider the "-n" flag for systems
Xthat have big NFS mounted disks.  And that's it -- the rest should be
Xsimilar to the shell version of cops, and theoretically should give you
Xsimilar or the same results.
X
X  Good luck!  Send bugs, flames, etc. to zen@death.corp.sun.com
X
X -- dan
SHAR_EOF
chmod 0600 cops_104/README.2.pl ||
echo 'restore of cops_104/README.2.pl failed'
Wc_c="`wc -c < 'cops_104/README.2.pl'`"
test 11991 -eq "$Wc_c" ||
	echo 'cops_104/README.2.pl: original size 11991, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= cops_104/README.FIRST ==============
if test -f 'cops_104/README.FIRST' -a X"$1" != X"-c"; then
	echo 'x - skipping cops_104/README.FIRST (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting cops_104/README.FIRST (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cops_104/README.FIRST' &&
X
X  Here is a fast overview of how to learn to use COPS; steps may be deleted,
Xignored, or added at your discretion.
X
X0)  It requires a unix system with a C compiler; the perl stuff
X(optional) requires a perl version >= 3.44.  Better yet, >= 4.10.
X
X1)  If you're upgrading from an older version, read "coverfile" for an
Xoverview of the changes from last time.
X
X2)  Read "README.1", either "README.2.sh" or "README.2.pl", depending
Xon which version you're going to run, and then "README.3".
X1b) If applicible, look at the readme files in the "docs" directory
X(e.g. "readme.svr4", etc.)  Alternately, read "quickstart" for a crash
Xcourse in installing/running COPS.
X
X3)  Run "reconfig" if uncertain about the pathnames to the system
Xexecutables that your system uses, or if you think they are at all
Xdifferent than sun/generic BSD systems.
X
X4)  "make" or "make install" (if installing, change line 7 in "makefile"
Xto specify where you want things to go.)  If you'd like to try the fast
Xcrypt stuff (stolen from Crack), uncomment lines 94-95, comment out
Xthe normal line (93).
X
X5)  Change the "is_able.lst" and "crc_list" files to better represent
Xyour type of system.
X
X6)  Run COPS.  Usually something like "./cops -v -s . -b cops_errs" or
Xwhatnot.  Also run "suid.chk".
X
X7)  Read "docs/warnings" file for interpretations of results.
X7b) If on a network and have more than one report, you may with to
Xrun the CARP report analyzer (see the "carp" subdirectory; *ONLY*
Xuseable with "cops -v" output files!)
X
X8)  Fix problems that were flagged, examine the error log (cops_errs in
Xthe above example) to see if cops had any troubles with anything, and
Xfinally decide if you want to modify the exception filter (typically
X"cops_filter", run with the -f flag; e.g. "cops -f cops_filter").
X
X9)  Read various man pages, extra docs, and look at source code to see
Xif anything needs modifying or tweaking.
X
X10)  Look at the extra stuff included.  In particular, if you have lots
Xof users, look at the "checkacct" stuff, in the directory of the same
Xname.  Also look at the "extra_src" directory for miscellaneous goodies.
X
X11)  Put COPS in your system's cron/at (or repeat 5 manually), repeat #7
Xas deemed neccessary.
X
X
X g'luck...
X -- dan
X
SHAR_EOF
chmod 0600 cops_104/README.FIRST ||
echo 'restore of cops_104/README.FIRST failed'
Wc_c="`wc -c < 'cops_104/README.FIRST'`"
test 2227 -eq "$Wc_c" ||
	echo 'cops_104/README.FIRST: original size 2227, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= cops_104/suid.stop ==============
if test -f 'cops_104/suid.stop' -a X"$1" != X"-c"; then
	echo 'x - skipping cops_104/suid.stop (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting cops_104/suid.stop (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cops_104/suid.stop' &&
X-rwsr-xr-x  1 root     bin         10240 Jun 13 13:13 /bin/chgrp
X-rwsr-xr-x  1 root     bin         12288 Jun 13 13:13 /bin/df
X-rws--s---  1 root     term        22528 Aug 13 13:13 /bin/login
X-rws------  1 root     bin         21504 Jun 13 13:13 /bin/login.old
X-rwsr-xr-x  1 root     bin         22528 Jun 13 13:13 /bin/mail
X-rwsr-xr-x  1 root     bin         14336 Jun 13 13:13 /bin/passwd
X-rwxr-sr-x  1 root     MEM         22528 Jun 13 13:13 /bin/ps
X-rwsr-xr-x  1 root     bin         16384 Jun 13 13:13 /bin/su
X-rwxr-sr-x  1 root     MEM         14336 Jun 13 13:13 /etc/dmesg
X-rwsr-x---  1 root     operator    29696 Jun 13 13:13 /etc/dump
SHAR_EOF
chmod 0755 cops_104/suid.stop ||
echo 'restore of cops_104/suid.stop failed'
Wc_c="`wc -c < 'cops_104/suid.stop'`"
test 644 -eq "$Wc_c" ||
	echo 'cops_104/suid.stop: original size 644, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
rm -f _shar_seq_.tmp
echo You have unpacked the last part
exit 0
