home *** CD-ROM | disk | FTP | other *** search
- From: df@sei.cmu.edu (Dan Farmer)
- Newsgroups: alt.sources
- Subject: alpha perl-cops, part 1 of 3
- Message-ID: <25550@as0c.sei.cmu.edu>
- Date: 17 May 91 04:46:08 GMT
-
- Submitted-by: df@death.cert.sei.cmu.edu
- Archive-name: alpha p-cops/part01
-
- #!/bin/sh
- # This is alpha p-cops, a shell archive (produced by shar 3.49)
- # To extract the files from this archive, save it to a file, remove
- # everything above the "!/bin/sh" line above, and type "sh file_name".
- #
- # made 05/17/1991 04:38 UTC by df@death.cert.sei.cmu.edu
- # Source directory /usr/users/df/COPS/perl
- #
- # existing files will NOT be overwritten unless -c is specified
- #
- # This is part 1 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 7064 -rwx------ p-cops.alpha/ftp.chk
- # 1776 -rwx------ p-cops.alpha/get-cf
- # 1292 -rwx------ p-cops.alpha/chk_strings
- # 3559 -rwx------ p-cops.alpha/chk_strings.pl
- # 2129 -rwx------ p-cops.alpha/cops.cf
- # 2399 -rwx------ p-cops.alpha/cron.chk
- # 6390 -rwx------ p-cops.alpha/cops
- # 463 -rwx------ p-cops.alpha/fgrep.pl
- # 413 -rwx------ p-cops.alpha/file_mode.pl
- # 398 -rwx------ p-cops.alpha/file_owner.pl
- # 2739 -rwx------ p-cops.alpha/dev.chk
- # 902 -rwx------ p-cops.alpha/getopts.pl
- # 2960 -rwx------ p-cops.alpha/glob.pl
- # 5060 -rwx------ p-cops.alpha/group.chk
- # 444 -rwx------ p-cops.alpha/hostname.pl
- # 1591 -rwx------ p-cops.alpha/is_able.chk
- # 1603 -rwx------ p-cops.alpha/is_able.lst
- # 2835 -rwx------ p-cops.alpha/is_able.pl
- # 14688 -rwx------ p-cops.alpha/kuang
- # 4413 -rwx------ p-cops.alpha/misc.chk
- # 6730 -rw------- p-cops.alpha/kuang.1
- # 10420 -rwx------ p-cops.alpha/pass.cache.pl
- # 6684 -rwx------ p-cops.alpha/pass.chk
- # 5989 -rwx------ p-cops.alpha/passwd.chk
- # 677 -rwx------ p-cops.alpha/pathconf.pl
- # 644 -rwx------ p-cops.alpha/pathconf.sh
- # 1014 -rwx------ p-cops.alpha/rc.chk
- # 3296 -rwx------ p-cops.alpha/reconfig.pl
- # 2048 -rwx------ p-cops.alpha/user.chk
- # 653 -rwx------ p-cops.alpha/stat.pl
- # 229 -rwx------ p-cops.alpha/suckline.pl
- # 4477 -rwx------ p-cops.alpha/suid.chk
- # 5959 -rwx------ p-cops.alpha/root.chk
- # 4848 -rwx------ p-cops.alpha/README.perl
- # 6206 -rwx------ p-cops.alpha/root.chk.old
- # 9306 -rw------- p-cops.alpha/README.kuang
- # 0 -rwx------ p-cops.alpha/suid.stop
- # 9915 -rw------- p-cops.alpha/pwgrid.pl
- # 6147 -rwx------ p-cops.alpha/root.chk.new
- # 2768 -rw------- p-cops.alpha/rules.pl
- #
- if test -r _shar_seq_.tmp; then
- echo 'Must unpack archives in sequence!'
- echo Please unpack part `cat _shar_seq_.tmp` next
- exit 1
- fi
- # ============= p-cops.alpha/ftp.chk ==============
- if test ! -d 'p-cops.alpha'; then
- echo 'x - creating directory p-cops.alpha'
- mkdir 'p-cops.alpha'
- fi
- if test -f 'p-cops.alpha/ftp.chk' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/ftp.chk (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/ftp.chk (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/ftp.chk' &&
- #!/bin/sh # need to mention perl here to avoid recursion
- #
- # Usage: ftp.chk
- #
- # This shell script checks to see if you've set up (mainly anonymous)
- # ftp correctly. There seems to be some different types of ftp's
- # around; for instance, some allow "chmod" -- and if the home dir is
- # owned by "ftp", you're toast. So I've tried to err on the side of
- # safety...
- #
- # See the man page for a more detailed description, here's what this
- # checks for:
- #
- # - User ftp exists in the password file.
- # - root (or all root equivalents) are in ftpusers file.
- # - Home directory for ftp should exist, and not be /
- # - The ~ftp/etc/{passwd|group} should not be the same as the real ones.
- # - Various critical files/directories should exist, and have correct
- # permissions and owners; variables "$primary" and "$secondary" can be set
- # to whomever you want owning the files:
- #
- # File/Dir Perms Owner Other
- # ========= ====== ====== ======
- # ~ftp non-w.w. root
- # or
- # ~ftp 555 ftp if no chmod command exists
- #
- # All of these are ftp owned iff no chmod exists...
- #
- # ~ftp/bin non-w.w. root/ftp
- # ~ftp/bin/ls 111 root/ftp
- # ~ftp/etc non-w.w. root/ftp
- # ~ftp/etc/passwd non-w.w. root/ftp 0 size or nonexistant
- # ~ftp/etc/group non-w.w. root/ftp 0 size or nonexistant
- # ~ftp/pub non-w.w. root/ftp
- # ~ftp/incoming world-writable root/ftp This can be set to "pub"
- # ~ftp/.rhosts non-w.w. root 0 size, is optional
- # ~ftp/* non-w.w. other dirs/files in ~ftp
- #
- #
- # NOTE:
- #
- # if you know where perl is and your system groks #!, put its
- # pathname at the top to make this a tad faster.
- #
- # the following magic is from the perl man page
- # and should work to get us to run with perl
- # even if invoked as an sh or csh or foosh script.
- # notice we don't use full path cause we don't
- # know where the user has perl on their system.
- #
- eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
- & eval 'exec perl -S $0 $argv:q'
- X if $running_under_some_stupid_shell_instead_of_perl;
- X
- require 'is_able.pl';
- require 'file_mode.pl';
- require 'glob.pl';
- require 'fgrep.pl';
- require 'pass.cache.pl';
- require 'file_owner.pl';
- require 'pathconf.pl';
- X
- $CMP="/bin/cmp" unless defined $CMP;
- X
- package ftp;
- X
- # Primary and secondary owners of the ftp files/dirs; if you *don't* have
- # chmod, you can probably change the secondary owner to "ftp". If you have
- # chmod in your ftp, definitely have secondary to some other account (root
- # is fine for this.)
- local($primary)="root" unless defined $primary;
- local($secondary)="ftp" unless defined $secondary;
- X
- # some might have this as ftpd; is the account in /etc/passwd
- local($ftpuid)="ftp";
- X
- # system files
- local($ftpusers)="/etc/ftpusers";
- local($passwd)="/etc/passwd" unless defined $PASSWD;
- local($group)="/etc/group" unless defined $GROUP;
- X
- # ftp's home:
- $ftproot = &'uname2dir($ftpuid);
- $anonymous = $ftproot ne '';
- X
- local($ftprhosts)="$ftproot/.rhosts";
- local($ftpbin)="$ftproot/bin";
- local($ftpls)="$ftpbin/ls";
- local($ftpetc)="$ftproot/etc";
- local($ftppasswd)="$ftpetc/passwd";
- local($ftpgroup)="$ftpetc/group";
- X
- local($W) = 'Warning! ' unless defined $W;
- X
- # the pub/incoming stuff; by default, pub is *not* world writable, incoming
- # is; if you want pub to be world writable, just change incoming to "pub"
- local($incoming)="pub";
- X
- @crit_files=($ftpgroup,
- X $ftppasswd,
- X $ftpls);
- X
- if (-s $ftpusers) {
- X # check to see if root (or root equivalents) is in ftpusers file
- X @all_roots = split(" ", $'uid2names{0});
- X if (@all_roots ne "") {
- X for $i (@all_roots) {
- X if (length($user2passwd{$i}) == 13 && ! &'fgrep($ftpusers, "^$i$")) {
- X print "Warning! $i should be in $ftpusers!\n";
- X }
- X }
- X }
- }
- X
- # do the anonymous ftp checking stuff now?
- die unless $anonymous;
- X
- # if the user ftp doesn't exist, no-anon stuff....
- # if $TEST -z $ftproot -a "$anonymous" = "yes" ; then
- X
- die "${W}Need user $ftpuid for anonymous ftp to work!\n" if ($ftpuid eq "");
- X
- # if the user ftp doesn't exist, no-anon stuff....
- if (! -d $ftproot || $ftproot eq "") {
- X die "${W}Home directory for ftp doesn\'t exist!\n";
- }
- if ($ftproot eq "/") {
- X print "${W}$ftproot ftp\'s home directory should not be \"/\"!\n";
- }
- X
- # want to check all the critical files and directories for correct
- # ownership. Some versions of ftp don't need much of anything... no
- # etc directory or password/group files.
- # others need etc directory & password/group files. Experiment.
- #
- push(@crit_files, $ftpbin, $ftpetc);
- for $i (@crit_files) {
- X $owner = &'Owner($i);
- X
- X if ($owner eq 'BOGUS') {
- X print "${W}Critical anon-ftp file $i is missing!\n";
- X next;
- X }
- X
- X $owner = $'uid2names{$owner};
- X
- X if ($owner ne $primary && $owner ne $secondary) {
- X print "${W}$i should be owned by $primary or $secondary, not $owner!\n";
- X }
- }
- X
- # Don't want the passwd and group files to be the real ones!
- if (&'Owner($ftppasswd) ne 'BOGUS' &&
- X $passwd ne $ftppasswd &&
- X system "$CMP -s $passwd $ftppasswd")
- {
- X print "${W}$ftppasswd and $passwd are the same!\n";
- }
- X
- if (&'Owner($ftpgroup) ne 'BOGUS' &&
- X $group ne $ftpgroup &&
- X system "$CMP -s $passwd $ftpgroup")
- {
- X print "${W}$ftpgroup and $group are the same!\n";
- }
- X
- # ftproot is special; if owned by root; should be !world writable;
- # if owned by ftp, should be mode 555
- X
- if (&'Owner($ftproot) ne BOGUS) {
- X $owner = $'uid2names{&'Owner($ftproot)};
- X $perms=&'Mode($ftproot);
- X if ($owner ne $primary && $owner ne $secondary) {
- X print "${W}$ftproot should be owned by $primary or $secondary, not $owner!\n";
- X }
- X
- X # ftp-root should not be world-writable:
- X &'is_able($ftproot, "w", "w");
- X
- X # if ftp owns root-dir, then mode should be 555:
- X if ($owner eq $ftpuid && $perms ne 00555) {
- X print "${W}$ftproot should be mode 555!\n";
- X }
- }
- X
- #
- # check the .rhosts file:
- if (-f $ftprhosts) {
- X if (-s $ftprhosts) {
- X print "${W}$ftprhosts should be be empty!\n";
- X }
- X $owner=$'uid2names{&'Owner($ftprhosts)};
- X if ($owner ne $primary && $owner ne $secondary) {
- X print "${W}$ftprhosts should be owned by $primary or $secondary!\n";
- X }
- }
- X
- # finally, some permissions of miscellaneous files:
- if (($perms=&'Mode($ftpls)) & 0666) {
- X printf "${W}Incorrect permissions (%04o) on $ftpls!\n", $perms;
- }
- X
- if (($perms=&'Mode($ftppasswd)) & 0333) {
- X printf "${W}Incorrect permissions (%04o) on $ftppasswd!\n", $perms;
- }
- X
- X
- if (($perms=&'Mode($ftpgroup)) & 0333) {
- X printf "${W}Incorrect permissions (%04o) on $ftpgroup!\n", $perms;
- }
- X
- # Finally, the ~ftp/{pub|incoming|whatever} stuff:
- opendir(FTPDIR, $ftproot) || die "can't opendir $ftproot: $!";
- X
- @all_dirs=grep(-d, readdir(FTPDIR));
- X
- local($is_able'silent) = 1;
- for $i (@all_dirs) {
- X if ($i ne $incoming && &'is_able($ftproot . "/$i", "w", "w")) {
- X print "${W}Anon-ftp directory $i is World Writable!\n";
- X }
- }
- X
- 1;
- # end of script
- SHAR_EOF
- chmod 0700 p-cops.alpha/ftp.chk ||
- echo 'restore of p-cops.alpha/ftp.chk failed'
- Wc_c="`wc -c < 'p-cops.alpha/ftp.chk'`"
- test 7064 -eq "$Wc_c" ||
- echo 'p-cops.alpha/ftp.chk: original size 7064, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/get-cf ==============
- if test -f 'p-cops.alpha/get-cf' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/get-cf (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/get-cf (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/get-cf' &&
- #! /usr/local/bin/perl
- X
- @dot_files = (
- X ".login", ".logout", ".cshrc", # csh, cshe or tcsh
- X ".profile", # ksh, sh
- X ".env", # ksh
- X ".alias", ".aliases", # common for all shells
- X "user.ps", ".user.ps", "tools.ps", ".tools.ps",
- X "startup.ps", ".startup.ps", # NeWS
- X ".mgrc", # MGR
- X ".X11init", ".awmrc", ".twmrc", ".xinitrc", # X11
- X ".emacs" # emacs
- );
- X
- %seen = {};
- X
- open(HOST, "/bin/hostname |") || die "can't get the hostname";
- chop($hostname=<HOST>);
- close(HOST);
- X
- user_loop:
- X for (($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell) = getpwent();
- X $name ne "";
- X ($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell) = getpwent()) {
- X
- X #
- X # If the user has a home directory on this server, get the info
- X # about the directory, his CF's and so on.
- X #
- X if ($dir =~ m,^/n/$hostname/,) {
- X if (! -d $dir) {
- X printf(stderr "home directory '%s' for user '%s' doesn't exist.\n",
- X $dir,
- X $name);
- X next user_loop;
- X }
- X
- X ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
- X $atime,$mtime,$ctime,$blksize,$blocks)
- X = stat(_);
- X $mode = $mode & 07777;
- X
- X &spit_it_out("d", $uid, $gid, $mode, $dir);
- X
- X foreach $file (@dot_files) {
- X $path = "$dir/$file";
- X
- X if (-f $path) {
- X ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
- X $atime,$mtime,$ctime,$blksize,$blocks)
- X = stat(_);
- X $mode = $mode & 07777;
- X
- X &spit_it_out("f", $uid, $gid, $mode, $dir);
- X }
- X }
- X }
- X }
- X
- X
- X
- X
- sub spit_it_out {
- X local($type, $uid, $gid, $mode, $name) = @_;
- X
- X if (defined($seen{$name})) {
- X return;
- X }
- X
- X printf("%s %d %d 0%o %s\n", $type, $uid, $gid, $mode, $name);
- X $seen{$name} = 1;
- }
- X
- SHAR_EOF
- chmod 0700 p-cops.alpha/get-cf ||
- echo 'restore of p-cops.alpha/get-cf failed'
- Wc_c="`wc -c < 'p-cops.alpha/get-cf'`"
- test 1776 -eq "$Wc_c" ||
- echo 'p-cops.alpha/get-cf: original size 1776, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/chk_strings ==============
- if test -f 'p-cops.alpha/chk_strings' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/chk_strings (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/chk_strings (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/chk_strings' &&
- #!/bin/sh # need to mention perl here to avoid recursion
- #
- # Usage: chk_strings filename
- #
- # This will check pathnames inside executable files for writability,
- # The big string "@ignores" is a list of files that are ignored by
- # this; you can set it to whatever you want -- default is:
- # '^/tmp/?' and '^/(var|usr)/tmp/?'
- #
- # No program root EVER runs should be show up here.
- #
- # NOTE:
- # If you know where perl is and your system groks #!, put its
- # pathname at the top to make this a tad faster.
- #
- # the following magic is from the perl man page
- # and should work to get us to run with perl
- # even if invoked as an sh or csh or foosh script.
- # notice we don't use full path cause we don't
- # know where the user has perl on their system.
- #
- eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
- & eval 'exec perl -S $0 $argv:q'
- X if $running_under_some_stupid_shell_instead_of_perl;
- X
- package main;
- X
- $| = 1;
- X
- require 'getopts.pl';
- require 'chk_strings.pl';
- X
- die "Usage: $0 [-fr] file ...\n" unless &Getopts('rd') && @ARGV;
- X
- package chk_strings;
- X
- $debug = $'opt_d;
- $recurse = $'opt_r;
- @ignores = ( '^/tmp/?', '^/(var|usr)/tmp/?' )
- X unless defined @ignores;
- X
- #%paths = (); # faster than local
- X
- for (@'ARGV) {
- X (warn("$0: $_: $!\n"), next) unless -e;
- X &'chk_strings($_);
- }
- SHAR_EOF
- chmod 0700 p-cops.alpha/chk_strings ||
- echo 'restore of p-cops.alpha/chk_strings failed'
- Wc_c="`wc -c < 'p-cops.alpha/chk_strings'`"
- test 1292 -eq "$Wc_c" ||
- echo 'p-cops.alpha/chk_strings: original size 1292, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/chk_strings.pl ==============
- if test -f 'p-cops.alpha/chk_strings.pl' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/chk_strings.pl (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/chk_strings.pl (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/chk_strings.pl' &&
- #
- # This is a big one. Support routines to check for strings
- # that look like pathnames and make sure they're not writable.
- # Will recurse if $recurse is set. the shell version can't do
- # this (yet). call &ignore with list of regexps that you don't
- # care about. (or set @ignores)
- #
- # originally by Tom Christiansen <tchrist@convex.com>
- # since hacked on by parties various and sundry.
- X
- require 'is_able.pl';
- require 'file_mode.pl';
- require 'pathconf.pl';
- X
- package chk_strings;
- X
- X
- $'STRINGS = $'STRINGS || '/usr/ucb/strings';
- X
- for ( '/dev/null', '/dev/tty' ) {
- X $seen{$_}++;
- }
- X
- sub main'chk_strings {
- X local($ARGV) = @_;
- X local($_);
- X local($word);
- X local(*STRINGS); # XXX: might run out of fd's on deep recursion! -tchrist
- X local(%paths, $text);
- X local($STRINGS) = "$'STRINGS $ARGV |";
- X
- X &ignore(@ignores) if defined @ignores && !$already_ignored;
- X
- X $STRINGS="< $ARGV", $text=1 if -T $ARGV;
- X print "Opening via: $STRINGS\n" if $debug;
- X
- X open (STRINGS, $STRINGS);
- X while (<STRINGS>) {
- X next unless m#/#; # was m#/.*/#;
- #---------------------------------------------------------------------------
- # Comments and modifications by Martin Foord (maf%dbsm.oz.au@munnari.oz.au).
- X #s/#.*$// if $text; # strip out comments if -T file
- X # Comments start in the shell at the beginning of a word or at the
- X # beggining of a line
- X if ($text) {
- X s/\s+#.*$//;
- X s/^#.*$//;
- X }
- X
- X # Get rid of semicolons, they can hang around on filenames ...
- X s/;//g;
- #---------------------------------------------------------------------------
- X
- X s/"([^"]*)"/ $1 /g;
- X s/'([^']*)'/ $1 /g;
- X # See my comments below on how to deal with this stuff ... (line 64).
- X #s/`([^`]*)`/ $1 /g;
- X
- X
- X s!([<>])\s+/!$1/!g; # "> /foo" goes to ">foo";
- X
- X s/=/ /g; # warning -- mangled files with = in them
- X for $word (split) {
- X if ($word =~ m#:/#) {
- X @paths{split(/:/, $word)} = ();
- X } elsif ($word =~ m#^[<>]?/#) {
- X print "push $word\n" if $debug;
- X $paths{$word}++;
- X }
- X }
- X }
- X close (STRINGS);
- X push(@files, $ARGV);
- X
- X for (keys %paths) {
- X s/\)$//;
- X s/^\(//;
- X s#^/+#/#;
- X s#^(/.*)/$#$1#; # get rid of trailing slash
- X
- #---------------------------------------------------------------------------
- # Comments and modifications by Martin Foord (maf%dbsm.oz.au@munnari.oz.au).
- X # It's best to evaluate what's in backquotes rather than remove them
- X # as in the substitution above, due to files which
- X # look like this /var/yp/`domainname` (eg in my /etc/rc.local).
- X s`\`(.+)\``$1`; # eval what's in backquotes.
- X chop if /\n$/; # fang off \n if there ...
- #---------------------------------------------------------------------------
- X next if &ignored($_);
- X s/^[<>]//;
- X next if $_ eq '';
- X next unless !$seen{$_}++ && -e && !-S _;
- X print "checking $_\n" if $debug;
- X if ($how = &'is_writable($_)) {
- X print "Warning! File $_ (inside ",
- X join(' inside ', reverse @files), ") is _World_ $how!\n";
- X } elsif ($recurse && (&'Mode($_) & 0111) && -f _) {
- X print "recursing $_\n" if $debug;
- X &'chk_strings($_);
- X }
- X }
- X pop(@files);
- }
- X
- sub ignore {
- X local($_);
- X local($prog);
- X
- X $already_ignored = 1;
- X
- X $prog = <<'EOCODE';
- X
- sub ignored {
- X local($return) = 1;
- X local($prog);
- X local($_) = @_;
- X {
- EOCODE
- X for (@_) {
- X $prog .= "\tlast if m\201${_}\201;\n";
- X }
- X $prog .= <<'EOCODE';
- X $return = 0;
- X }
- X print "$_ IGNORED\n" if $debug && $return;
- X $return;
- }
- EOCODE
- X
- X print $prog if $debug;
- X eval $prog;
- X die $@ if $@;
- }
- X
- sub ignored {}; # in case they never ignore anything
- X
- 1;
- SHAR_EOF
- chmod 0700 p-cops.alpha/chk_strings.pl ||
- echo 'restore of p-cops.alpha/chk_strings.pl failed'
- Wc_c="`wc -c < 'p-cops.alpha/chk_strings.pl'`"
- test 3559 -eq "$Wc_c" ||
- echo 'p-cops.alpha/chk_strings.pl: original size 3559, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/cops.cf ==============
- if test -f 'p-cops.alpha/cops.cf' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/cops.cf (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/cops.cf (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/cops.cf' &&
- #
- # COPS CONFIGURATION FILE
- #
- # put user variables here: anything beginning with /^\s*[$@%&]/ will be eval'd
- # in general, variables in package main are for cops itself, whereas
- # those with package qualifiers are for a particular chk routine or
- # for auxiliary routines.
- X
- # COPS main variables follow...
- $NMAIL = 0; # send mail instead of generating reports
- $ONLY_DIFF = 0; # only send diff from last time
- $SECURE_USERS = "root"; # user to receive mailed report
- $C2 = 0; # Sun c2 security package
- X
- # these don't really work for pass.cache yet
- $IGNORE_YP = 0;
- $PASSWD = '/etc/passwd';
- $GROUP = '/etc/group';
- X
- ###############################################################
- # many things call &chk_strings (including {cron,misc,rc,root}.chk)
- # the following two variable settings affects its behaviour...
- # this one says to ignore warnings about paths matching these regexps
- X
- @chk_strings'ignores = ( '^/tmp/?', '^/(var|usr)/tmp/?' );
- X
- # this will take a bit longer, but can find dangerous things much better
- # the shell cops can't do this.... sigh
- X
- $chk_strings'recurse = 0;
- X
- # if we want stat failure warnings from is_able...
- X
- $is_able'noisy = 0;
- X
- ###############################################################
- # finally the checks to execute. these can also all be run
- # stand-alone from the shell.
- X
- # first test the security of the root account
- root.chk
- X
- # now of the various devices. -g means to check group writability, too
- $MTAB = '/etc/fstab';
- $EXPORTS = '/etc/exports';
- $TAB_STYLE = 'new';
- dev.chk -g
- X
- # exaustive tests for things that shouldn't be readable/writable etc
- is_able.chk
- X
- # check for insecuities in /etc/rc*
- rc.chk
- X
- # and in cron
- cron.chk
- X
- # some consistency and idiocy (null or trivial passwds) in /etc/passwd
- passwd.chk
- pass.chk
- X
- # consistency checks in /etc/group
- group.chk
- X
- # make sure user accounts don't have trojanable dot files
- user.chk
- X
- # check ftp security
- $ftp'primary = "root";
- $ftp'secondary = "ftp";
- ftp.chk
- X
- # and anything else we forgot
- X
- # Sys V types use /etc/servers here:
- $misc'inetd = "/etc/inetd";
- misc.chk
- X
- # Kuang!
- kuang
- X
- # SUID checking
- # suid.chk
- SHAR_EOF
- chmod 0700 p-cops.alpha/cops.cf ||
- echo 'restore of p-cops.alpha/cops.cf failed'
- Wc_c="`wc -c < 'p-cops.alpha/cops.cf'`"
- test 2129 -eq "$Wc_c" ||
- echo 'p-cops.alpha/cops.cf: original size 2129, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/cron.chk ==============
- if test -f 'p-cops.alpha/cron.chk' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/cron.chk (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/cron.chk (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/cron.chk' &&
- #!/bin/sh # need to mention perl here to avoid recursion
- #
- # Usage: cron.chk.pl [-rd]
- #
- # This checks pathnames and files inside the cron files /usr/lib/crontab
- # for writability.
- #
- # Mechanism: The commands inside the file /usr/lib/crontab are executed
- # by root. This perl script uses chk_strings.pl for chking for writable
- # files/dirs.
- #
- # cron.chk.pl will try to find a file in /usr/lib/crontab first (bsd),
- # and then if it isn't there, it will look in the any alternate
- # possible locations next -- right now, /usr/spool/cron/crontab -- to
- # see if a directory exists, and, if it does, it checks all the cron
- # files in turn.
- #
- # WARNING!
- #
- # Spurious messages can occur; a more stringent method (if perhaps less
- # careful of a check) would be to test just the 6th field, instead of
- # all the fields after the fifth. Also throwing away /tmp, etc. could
- # be a mistake.
- #
- # NOTE:
- # if you know where perl is and your system groks #!, put its
- # pathname at the top to make this a tad faster.
- #
- # the following magic is from the perl man page
- # and should work to get us to run with perl
- # even if invoked as an sh or csh or foosh script.
- # notice we don't use full path cause we don't
- # know where the user has perl on their system.
- #
- eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
- & eval 'exec perl -S $0 $argv:q'
- X if $running_under_some_stupid_shell_instead_of_perl;
- X
- package main;
- X
- require 'getopts.pl';
- require 'glob.pl';
- require 'chk_strings.pl';
- require 'pathconf.pl';
- X
- # should also add args to override default crontab locations
- die "Usage: $0 [-rd]\n" unless &Getopts('rd') && !@ARGV;
- X
- $chk_strings'debug = $opt_d;
- $chk_strings'recurse = $opt_r;
- X
- package cron_chk;
- X
- # Possible location of crontab file:
- $cron = "/usr/lib/crontab";
- # alternate reality locations of crontab file:
- @alt_cron = ("/usr/spool/cron/crontabs");
- X
- if ( ! -s $cron) {
- X for (@alt_cron) {
- X # are there ever multiple crontab directories?
- X (@crons = &'glob("$_/*")), last if -d;
- X }
- X die "No crontabs?\n" if ! @crons;
- }
- @crons = ($cron) unless @crons;
- X
- # ignore /tmp /dev/null and tty stuff
- # &'chk_strings ignores all of above
- # STILL NEED to ignore stuff after `>'
- # when we add @ignore stuff to &'chk_strings
- X
- # finally, do the checking -- maybe for one, maybe for lots of cron-ites:
- for (@crons) {
- X if (! -e) {
- X warn "$0: $_: $!\n";
- X next;
- X }
- X &'chk_strings($_);
- }
- X
- 1;
- SHAR_EOF
- chmod 0700 p-cops.alpha/cron.chk ||
- echo 'restore of p-cops.alpha/cron.chk failed'
- Wc_c="`wc -c < 'p-cops.alpha/cron.chk'`"
- test 2399 -eq "$Wc_c" ||
- echo 'p-cops.alpha/cron.chk: original size 2399, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/cops ==============
- if test -f 'p-cops.alpha/cops' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/cops (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/cops (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/cops' &&
- #!/bin/sh # need to mention perl here to avoid recursion
- #
- # Usage: cops [-v] [-c config file] [-s secure_dir] [architecture]
- #
- # This will change into the $SECURE/architecture directory, suck lots
- # of info and configuration stuff out of "cops.cf", and runs all of the
- # security programs in that file. If any of the programs find any
- # security problems, it either sends mail to everyone in the $SECURE_USERS
- # list (see "cops.cf"), or saves the results in a file
- # $SECURE/architecture/hostname. It then destroys all temporary files,
- # and exits the program. Programs that are run (besides this one):
- #
- # root.chk dev.chk group.chk
- # rc.chk passwd.chk is_able.chk
- # pass.chk user.chk cron.chk
- # misc.chk ftp.chk
- #
- # This -v (verbose) flag prints out the name each program to
- # the results file as it is executed. The -s and -c flags allow you
- # to specify the $SECURE directory and $CONFIG file, respectively.
- #
- # NOTE:
- # If you know where perl is and your system groks #!, put its
- # pathname at the top to make this a tad faster.
- #
- # the following magic is from the perl man page
- # and should work to get us to run with perl
- # even if invoked as an sh or csh or foosh script.
- # notice we don't use full path cause we don't
- # know where the user has perl on their system.
- #
- eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
- & eval 'exec perl -S $0 $argv:q'
- X if $running_under_some_stupid_shell_instead_of_perl;
- X
- ######################################
- # perl COPS main driver.
- # tchrist@convex.com
- ######################################
- X
- # security sanity settings
- #
- $ENV{'IFS'} = '' if $ENV{'IFS'};
- $ENV{'PATH'} = '/bin:/usr/bin:/usr/ucb';
- $| = 1;
- umask 077;
- X
- #
- # Getopts stuff
- $usage = "Usage: $0 [-v] [-c config_file] [-s secure_dir] architecture\n";
- require 'getopts.pl';
- # Process the command args; Either specify verbose or an alternate config file:
- die $usage unless &Getopts('vc:s:');
- X
- if (defined($opt_v)) { $verbose = $opt_v;}
- else { $verbose = 0; }
- X
- if (defined($opt_s)) { $SECURE = $LIBCOPS = $opt_s; }
- else { $SECURE = $LIBCOPS = '.'; }
- X
- if (defined($opt_c)) { $CONFIG = $opt_c; }
- else {$CONFIG = "$SECURE/cops.cf"; }
- X
- if (@ARGV > 1) {
- X die $usage;
- } elsif (@ARGV == 1) {
- X $SECURE = shift;
- X die "Architecture directory $SECURE does not exist\n" unless -d $SECURE;
- X chdir($SECURE) || die "can't cd to $SECURE: $!";
- X exec './cops';
- }
- X
- # internal cops stuff needed
- require "$LIBCOPS/pathconf.pl";
- require "$LIBCOPS/is_able.pl";
- X
- chmod 0700, $SECURE;
- chdir ($SECURE) || die "Error -- Security directory $SECURE doesn't exist";
- X
- # Read stuff to do from the config file
- die "$0: Can't trust $CONFIG to reconfig!" if &'is_writable($CONFIG);
- open CONFIG || die "can't open $CONFIG: $!";
- X
- &argh unless -s $CONFIG;
- X
- &init_result;
- X
- while (<CONFIG>) {
- X next if /^\s*#/;
- X next if /^\s*$/;
- X
- X if (/^\s*[\$&\@\%]/) { # reset a config variable
- X s/#.*//;
- X eval;
- X warn "Bad config variable at line $. of $CONFIG:\n\t$_\t$@\n" if $@;
- X next;
- X }
- X
- X # must be a program to run
- X chop;
- X s/#.*//;
- X s/;$//;
- X @ARGV=split;
- X $program = shift;
- X if ($verbose) { print "\n******* $program *******\n\n"; }
- X &flush;
- X &run("$LIBCOPS/$program");
- X &flush;
- X
- }
- X
- &save_result;
- X
- &argh unless $ran_something;
- X
- Xexit 0;
- X
- ######################################################################
- sub run {
- X local($module) = @_;
- X local($status);
- X local($0) = $module; # so it shows up in ps
- X local($!);
- X
- X
- X $ran_something++;
- X
- X open(STDERR, $COPS_ERRORS ? ">&STDOUT" : ">/dev/null");
- X
- X unless ($status = do $module) {
- X if ($@) {
- X warn "cops: unexpected exit from $module:\n\t-> $@\n";
- X } elsif ($! != 0) {
- X warn "cops: couldn't run $module: $!\n";
- X } else {
- X warn "cops: $module returned $status\n";
- X }
- X }
- X
- X # hack for kuang, who doesn't write to STDOUT (yet!)
- X $SUCCESS = "$SECURE/Success";
- X if ($module =~ /^kuang/ && -e $SUCCESS) {
- X if (open SUCCESS) {
- X print while <SUCCESS>; # STDOUT is $REPORT
- X close SUCCESS;
- X unlink $SUCCESS;
- X } else {
- X warn "can't open $SUCCESS: $!";
- X }
- X }
- }
- ######################################################################
- sub init_result {
- X $REPORT = "$SECURE/result.$$"; # global!
- X open (REPORT, ">$REPORT") || die "can't create $REPORT: $!";
- X
- X # assume dups work
- X open (STDOUT, ">&REPORT");
- X open (SAVERR, ">&STDERR");
- X open (STDERR, ">&STDOUT");
- X
- X ($sec, $min, $hour, $mday, $mon, $year,
- X $wday, $yday, $isdst) = localtime(time);
- X
- X $name = sprintf("%s_%s_%s", $year + 1900,
- X (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec)[$mon],
- X $mday);
- X
- X $host = ( -x '/bin/hostname' && `/bin/hostname` )
- X || ( -x '/bin/uname' && `/bin/uname -n` )
- X || ( -x '/usr/bin/uuname' && `/usr/bin/uuname -l`)
- X || 'Amnesiac!';
- X
- X chop $host;
- X $host =~ s/\..*//;
- X
- X print "ATTENTION:\nSecurity report for ", `date`;
- X print "\nfrom host $host, $name\n\n";
- X $report = $name;
- X
- X &flush;
- }
- ######################################################################
- sub save_result {
- X open(STDERR, ">&SAVERR");
- X
- X close REPORT || die "can't close $REPORT: $!";
- X
- X $dir = "$SECURE/$host";
- X $report = $dir . "/" . $report;
- X
- X mkdir($dir,0700) unless -d $dir;
- X
- X if ($NMAIL) {
- X system "$MAIL $SECURE_USERS < $REPORT"
- X unless $ONLY_DIFF && !&different($dir, $REPORT);
- X } else {
- # rename ($REPORT, $dir . "/" . $name) ||
- # die "can't put $REPORT into $dir/$name: $!";
- X rename ($REPORT, $report) ||
- X die "can't put $REPORT into $report: $!";
- X }
- X unlink $REPORT;
- }
- X
- ######################################################################
- sub different {
- X local($dir, $FILE1) = @_;
- X local($FILE2, $f1, $f2, $_);
- X
- X open (LS, "$LS -t $dir |");
- X chop($FILE2 = <LS>);
- X close(LS); # snuff it out
- X
- X
- X return 1 if !$FILE2 || -s $FILE1 != -s $FILE2;
- X
- X open FILE1 || die "can't open $FILE1: $!";
- X open FILE2 || die "can't open $FILE2: $!";
- X
- X for (1..5) {
- X $_ = <FILE1>;
- X $_ = <FILE2>;
- X }
- X
- X while ( ($f1 = <FILE1>), ($f2 = <FILE2>) ) {
- X last if $f1 ne $f2;
- X }
- X
- X close FILE1;
- X close FILE2;
- X
- X defined($f1) || defined($f2);
- }
- X
- ######################################################################
- sub flush {
- X local($old) = $|;
- X $| = 1;
- X print '';
- X $| = $old;
- }
- X
- sub argh {
- X die "Argh -- Can't find anything in $CONFIG\n";
- }
- SHAR_EOF
- chmod 0700 p-cops.alpha/cops ||
- echo 'restore of p-cops.alpha/cops failed'
- Wc_c="`wc -c < 'p-cops.alpha/cops'`"
- test 6390 -eq "$Wc_c" ||
- echo 'p-cops.alpha/cops: original size 6390, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/fgrep.pl ==============
- if test -f 'p-cops.alpha/fgrep.pl' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/fgrep.pl (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/fgrep.pl (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/fgrep.pl' &&
- #
- # Just a quick perl fgrep...
- #
- package fgrep;
- X
- sub main'fgrep {
- X local($file, @exprs) = @_;
- X local(@list);
- X
- X if (open file) {
- X $code = "while (<file>) {\n\tchop;\n";
- X for (@exprs) {
- X $code .= "\tpush(\@list, \$_), next if m\201${_}\201;\n";
- X }
- X $code .= "}\n";
- X warn "fgrep code is $code" if $debug;
- X eval $code;
- X warn "fgrep @exprs $file: $@\n" if $@;
- X } elsif ($debug) {
- X warn "main'fgrep: can't open $file: $!\n";
- X }
- X
- X @list;
- }
- X
- 1;
- SHAR_EOF
- chmod 0700 p-cops.alpha/fgrep.pl ||
- echo 'restore of p-cops.alpha/fgrep.pl failed'
- Wc_c="`wc -c < 'p-cops.alpha/fgrep.pl'`"
- test 463 -eq "$Wc_c" ||
- echo 'p-cops.alpha/fgrep.pl: original size 463, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/file_mode.pl ==============
- if test -f 'p-cops.alpha/file_mode.pl' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/file_mode.pl (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/file_mode.pl (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/file_mode.pl' &&
- #
- # This retrieves a possibly cached mode on file.
- # If it returns "BOGUS", it means that the stat failed.
- #
- # tchrist@convx.com
- X
- package main;
- require 'stat.pl';
- X
- package file_mode;
- X
- sub main'Mode {
- X local($file) = @_;
- X
- X if (!defined $modes{$file}) {
- X if (&'Stat($file)) {
- X $modes{$file} = $'st_mode;
- X } else {
- X $modes{$file} = 'BOGUS';
- X }
- X }
- X $modes{$file};
- }
- SHAR_EOF
- chmod 0700 p-cops.alpha/file_mode.pl ||
- echo 'restore of p-cops.alpha/file_mode.pl failed'
- Wc_c="`wc -c < 'p-cops.alpha/file_mode.pl'`"
- test 413 -eq "$Wc_c" ||
- echo 'p-cops.alpha/file_mode.pl: original size 413, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/file_owner.pl ==============
- if test -f 'p-cops.alpha/file_owner.pl' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/file_owner.pl (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/file_owner.pl (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/file_owner.pl' &&
- #
- # This retrieves possibly cached owner of a file.
- # If it returns "BOGUS", it means that the stat failed.
- X
- package main;
- require 'stat.pl';
- X
- package file_owner;
- X
- sub main'Owner {
- X local($file) = @_;
- X
- X if (!defined $owners{$file}) {
- X if (&'Stat($file)) {
- X $owners{$file} = $'st_uid;
- X } else {
- X $owners{$file} = 'BOGUS';
- X }
- X }
- X $owners{$file};
- }
- SHAR_EOF
- chmod 0700 p-cops.alpha/file_owner.pl ||
- echo 'restore of p-cops.alpha/file_owner.pl failed'
- Wc_c="`wc -c < 'p-cops.alpha/file_owner.pl'`"
- test 398 -eq "$Wc_c" ||
- echo 'p-cops.alpha/file_owner.pl: original size 398, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/dev.chk ==============
- if test -f 'p-cops.alpha/dev.chk' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/dev.chk (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/dev.chk (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/dev.chk' &&
- #!/bin/sh # need to mention perl here to avoid recursion
- #
- # dev.chk [-g]
- #
- # This shell script checks the permissions of all devs listed in the
- # file /etc/fstab (the "mount" command would be a preferable way of
- # getting the file system name, but the syntax of the output is variable
- # from machine to machine), and flags them if they are readable by using
- # the "is_readable" command. It also checks for unrestricted NFS
- # mountings. By default, dev_check will flag devs only if world readable
- # or writable. The -g option tells it to print out devs that are also
- # group readable/writable.
- # As an aside, the fact that NFS mounted dirs are world readable isn't
- # a big deal, but they shouldn't be world writable. So do two checks here,
- # instead of one.
- #
- # Two types of /etc/fstab formats I've seen so far:
- #
- # "old" --
- # spec:file:type:freq:passno:name:options
- # NFS are indicated by an "@"
- #
- # "new" --
- # fsname dir type opts freq passno
- # NFS are indicated by an ":"
- #
- # NOTE:
- #
- # if you know where perl is and your system groks #!, put its
- # pathname at the top to make this a tad faster.
- #
- # the following magic is from the perl man page
- # and should work to get us to run with perl
- # even if invoked as an sh or csh or foosh script.
- # notice we don't use full path cause we don't
- # know where the user has perl on their system.
- #
- eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
- & eval 'exec perl -S $0 $argv:q'
- X if $running_under_some_stupid_shell_instead_of_perl;
- X
- #
- # dev.chk [-g]
- #
- # tchrist@convx.com
- #
- X
- require 'is_able.pl';
- X
- $MTAB = '/etc/fstab' unless defined $MTAB;
- $EXPORTS = '/etc/exports' unless defined $EXPORTS;
- $TAB_STYLE = 'new' unless defined $TAB_STYLE; # or 'old'
- X
- &usage if @ARGV > 1;
- X
- sub usage { die "Usage: $0 [-g]\n"; }
- X
- if (@ARGV == 1) {
- X if ($ARGV[0] eq '-g') {
- X $group++;
- X } else {
- X &usage;
- X }
- }
- X
- X
- open MTAB || die "can't open $MTAB: $!";
- X
- while (<MTAB>) {
- X next if /^#/;
- X chop;
- X if ($TAB_STYLE eq 'new') {
- X ($dev, $fs) = split;
- X next unless $fs;
- X if ($dev =~ /:/) {
- X push(@nfs_devs, $fs);
- X } else {
- X push(@local_devs, $dev);
- X }
- X } else {
- X ($dev, $fs) = split(/:/);
- X next unless $fs;
- X if ($dev =~ /@/) {
- X push(@nfs_devs, $fs);
- X } else {
- X push(@local_devs, $dev);
- X }
- X }
- X
- }
- X
- if (open EXPORTS) {
- X while (<EXPORTS>) {
- X next if /^\s*#/;
- X next if /\S\s+\S/;
- X chop;
- X printf "Warning! NFS file system $_ exported with no restrictions.\n";
- X }
- }
- X
- # WARNING: we may hang if server down....
- #
- for (@nfs_devs, @local_devs) {
- X &is_able($_, 'w', 'w');
- X next unless $group;
- X &is_able($_, 'g', 'w');
- }
- X
- for (@local_devs) {
- X &is_able($_, 'w', 'r');
- X next unless $group;
- X &is_able($_, 'g', 'r');
- }
- X
- 1;
- SHAR_EOF
- chmod 0700 p-cops.alpha/dev.chk ||
- echo 'restore of p-cops.alpha/dev.chk failed'
- Wc_c="`wc -c < 'p-cops.alpha/dev.chk'`"
- test 2739 -eq "$Wc_c" ||
- echo 'p-cops.alpha/dev.chk: original size 2739, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/getopts.pl ==============
- if test -f 'p-cops.alpha/getopts.pl' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/getopts.pl (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/getopts.pl (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/getopts.pl' &&
- ;# getopts.pl - a better getopt.pl
- X
- ;# Usage:
- ;# do Getopts('a:bc'); # -a takes arg. -b & -c not. Sets opt_* as a
- ;# # side effect.
- X
- sub Getopts {
- X local($argumentative) = @_;
- X local(@args,$_,$first,$rest,$errs);
- X local($[) = 0;
- X
- X @args = split( / */, $argumentative );
- X while(($_ = $ARGV[0]) =~ /^-(.)(.*)/) {
- X ($first,$rest) = ($1,$2);
- X $pos = index($argumentative,$first);
- X if($pos >= $[) {
- X if($args[$pos+1] eq ':') {
- X shift(@ARGV);
- X if($rest eq '') {
- X $rest = shift(@ARGV);
- X }
- X eval "\$opt_$first = \$rest;";
- X }
- X else {
- X eval "\$opt_$first = 1";
- X if($rest eq '') {
- X shift(@ARGV);
- X }
- X else {
- X $ARGV[0] = "-$rest";
- X }
- X }
- X }
- X else {
- X print STDERR "Unknown option: $first\n";
- X ++$errs;
- X if($rest ne '') {
- X $ARGV[0] = "-$rest";
- X }
- X else {
- X shift(@ARGV);
- X }
- X }
- X }
- X $errs == 0;
- }
- X
- 1;
- SHAR_EOF
- chmod 0700 p-cops.alpha/getopts.pl ||
- echo 'restore of p-cops.alpha/getopts.pl failed'
- Wc_c="`wc -c < 'p-cops.alpha/getopts.pl'`"
- test 902 -eq "$Wc_c" ||
- echo 'p-cops.alpha/getopts.pl: original size 902, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/glob.pl ==============
- if test -f 'p-cops.alpha/glob.pl' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/glob.pl (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/glob.pl (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/glob.pl' &&
- #
- # This does shell or perl globbing without resorting
- # to the shell -- we were having problems with the shell blowing
- # up with extra long pathnames and lots of file names. set $glob'debug
- # for trace information.
- #
- # tom christiansen <tchrist@convex.com>
- X
- package glob;
- X
- sub main'glob {
- X local($expr) = @_;
- X local(@files);
- X
- X $? = 0;
- X open(SAVERR, ">&STDERR"); close(STDERR); # suppress args too long
- X @files = <${expr}>;
- X if ($?) {
- X print SAVERR "shell glob blew up on $expr\n" if $debug;
- X @files = &SHglob($expr);
- X }
- X open (STDERR, ">&SAVERR");
- X # if (@files == 1 && $files[0] eq $expr) { @files = ''; } # sh foo
- X @files;
- }
- X
- sub main'SHglob {
- X local($expr) = @_;
- X local(@retlist) = ();
- X local($dir);
- X
- X printf "SHglob: globbing $expr\n" if $debug;
- X
- X $expr =~ s/([.{+\\])/\\$1/g;
- X $expr =~ s/\*/.*/g;
- X $expr =~ s/\?/./g;
- X
- X for $dir (split(' ',$expr)) {
- X push(@retlist, &main'REglob($dir));
- X }
- X
- X return sort @retlist;
- }
- X
- sub main'REglob {
- X local($path) = @_;
- X local($_);
- X local(@retlist) = ();
- X local($root,$expr,$pos);
- X local($relative) = 0;
- X local(@dirs);
- X local($user);
- X
- X $haveglobbed = 0;
- X
- X @dirs = split(/\/+/, $path);
- X
- X if ($dirs[$[] =~ m!~(.*)!) {
- X $dirs[$[] = &homedir($1);
- X return @retlist unless $dirs[$[];
- X } elsif ($dirs[$[] eq '') {
- X $dirs[$[] = '/' unless $dirs[$[] =~ m!^\.{1,2}$!;
- X } else {
- X unshift(@dirs, '.');
- X $relative = 1;
- X }
- X
- X printf "REglob: globbing %s\n", join('/',@dirs) if $debug;
- X
- X @retlist = &expand(@dirs);
- X
- X for (@retlist) {
- X if ($relative) {
- X s!^\./!!o;
- X }
- X s!/{2,}!/!g;
- X }
- X
- X return sort @retlist;
- }
- X
- sub expand {
- X local($dir, $thisdir, @rest) = @_;
- X local($nextdir);
- X local($_);
- X local(@retlist) = ();
- X local(*DIR);
- X
- X unless ($haveglobbed || $thisdir =~ /([^\\]?)[?.*{[+\\]/ && $1 ne '\\') {
- X @retlist = ($thisdir);
- X } else {
- X unless (opendir(DIR,$dir)) {
- X warn "glob: can't opendir $dir: $!\n" if $debug;
- X } else {
- X @retlist = grep(/^$thisdir$/,readdir(DIR));
- X @retlist = grep(!/^\./, @retlist) unless $thisdir =~ /^\\\./;
- X $haveglobbed++;
- X }
- X closedir DIR;
- X }
- X
- X for (@retlist) {
- X $_ = $dir . '/' . $_;
- X }
- X
- X if ($nextdir = shift @rest) {
- X local(@newlist) = ();
- X for (@retlist) {
- X push(@newlist,&expand($_,$nextdir,@rest));
- X }
- X @retlist = @newlist;
- X }
- X
- X return @retlist;
- }
- X
- sub homedir {
- X local($user) = @_;
- X local(@pwent);
- X # global %homedir
- X
- X if (!$user) {
- X return $ENV{'HOME'} if $ENV{'HOME'};
- X ($user = $ENV{'USER'}) ||
- X ($user = getlogin) ||
- X (($user) = getpwnam($>));
- X warn "glob'homedir: who are you, user #$>?" unless $user;
- X return '/';
- X }
- X unless (defined $homedir{$user}) {
- X if (@pwent = getpwnam($user)) {
- X $homedir{$user} = $pwent[$#pwent - 1];
- X } else {
- X warn "glob'homedir: who are you, user #$>?" unless $user;
- X $homedir{$user} = '/';
- X }
- X }
- X return $homedir{$user};
- }
- X
- X
- 1;
- SHAR_EOF
- chmod 0700 p-cops.alpha/glob.pl ||
- echo 'restore of p-cops.alpha/glob.pl failed'
- Wc_c="`wc -c < 'p-cops.alpha/glob.pl'`"
- test 2960 -eq "$Wc_c" ||
- echo 'p-cops.alpha/glob.pl: original size 2960, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/group.chk ==============
- if test -f 'p-cops.alpha/group.chk' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/group.chk (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/group.chk (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/group.chk' &&
- #!/bin/sh # need to mention perl here to avoid recursion
- #
- # group.chk.pl
- #
- # Check group file -- /etc/group -- for incorrect number of fields,
- # duplicate groups, non-alphanumeric group names, and non-numeric group
- # id's.
- #
- # Mechanism: Group.check uses awk to ensure that each line of the group
- # has 4 fields, as well as examining each line for any duplicate groups or
- # any duplicate user id's in a given group by using "sort -u" to ferret
- # out any duplications. It also checks to make sure that the password
- # field (the second one) is a "*", meaning the group has no password (a
- # group password is usually not necessary because each member listed on
- # the line has all the privilages that the group has.) All results are
- # echoed to standard output. Finally it ensures that the group names
- # are alphanumeric, that the group id's are numeric, and that there are
- # no blank lines. For yellow pages groups, it does the same checking,
- # but in order to get a listing of all members of the groups, it does a
- # "ypcat group".
- #
- # The /etc/group file has a very specific format, making the task
- # fairly simple. Normally it has lines with 4 fields, each field
- # separated by a colon (:). The first field is the group name, 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 group id number, and the fourth field is a list of user
- # ids in the group. If a line begins with a plus sign (+), it is a yellow
- # pages entry. See group(5) for more information.
- #
- # NOTE:
- # If you know where perl is and your system groks #!, put its
- # pathname at the top to make this a tad faster.
- #
- # the following magic is from the perl man page
- # and should work to get us to run with perl
- # even if invoked as an sh or csh or foosh script.
- # notice we don't use full path cause we don't
- # know where the user has perl on their system.
- #
- eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
- & eval 'exec perl -S $0 $argv:q'
- X if $running_under_some_stupid_shell_instead_of_perl;
- X
- # should get below config stuff from cops.cf file
- package main;
- X
- die "Usage: $0\n" if @ARGV;
- X
- require 'pathconf.pl';
- X
- # Used for Sun C2 security group file. FALSE (default) will flag
- # valid C2 group syntax as an error, TRUE attempts to validate it.
- # Thanks to Pete Troxell for pointing this out.
- #
- # moved to cops.cf
- X
- $etc_group=$GROUP || '/etc/group';
- X
- package group_chk;
- X
- $yptmp = "./yptmp.$$";
- X
- # Testing $etc_group for potential problems....
- open (Group, "< $'etc_group") || warn "$0: Can't open $'etc_group: $!\n";
- &chk_group_file_format('Group');
- close Group;
- X
- # Testing ypcat group for potential problems
- $yp=0;
- if (-s $'YPCAT && -x _) {
- X system("$'YPCAT group >$yptmp 2>/dev/null");
- X if (-s $yptmp) {
- X open(YGroup, "$'YPCAT group |") || die "$0: Can't popen $'YPCAT: $!\n";
- X &chk_group_file_format('YGroup');
- X close(YGroup);
- X $yp=1;
- X }
- }
- X
- # usage: &chk_group_file_format('Filehandle-name');
- # skips over lines that begin with "+:"
- # It really should check for correct yellow pages syntax....
- #
- # this routine checks lines read from a filehandle for potential format
- # problems .. should be matching group(5)
- #
- # checks for duplicate users in a group as it reads the lines instead
- # of after (as the original shell script does)
- X
- sub chk_group_file_format {
- X local($file) = @_;
- X local($W) = "Warning! $file file,";
- X
- X while (<$file>) {
- X next if /^\+:/;
- X print "$W line $., is blank\n" if /^\s*$/;
- X split(/:/);
- X $groups{$_[0]}++; # keep track of dups
- X print "$W line $., does not have 4 fields: $_" if (@_ != 4);
- X print "$W line $., nonalphanumeric group name: $_"
- X if $_[0] !~ /^[A-Za-z0-9-]+$/;
- X if ($_[1] && $_[1] ne '*') {
- X if ( ! $C2 || $yp ) {
- X print "$W line $., group has password: $_"
- X if length($_[1]) == 13;
- X } else {
- X print "$W line $., group has invalid field for C2:\n$_"
- X if $_[1] ne "#\$$_[0]";
- X }
- X }
- X print "$W line $., nonnumeric group id: $_" if $_[2] !~ /^\d+$/;
- X
- X # look for duplicate users in a group
- X # kinda ugly, but it works .. and I have too much other work right
- X # now to clean it up. maybe later.. ;-)
- X chop($_[3]); # down here, 'cos split gets rid of final null fields
- X @users = sort split(/\s*,\s*/, $_[3]);
- X # %users = # of times user is in group, $dup_user = duplicate found
- X undef %users; $dup_user=0;
- X grep(!$users{$_}++, @users);
- X for (keys %users) {
- X (print "Warning! Group $_[0] has duplicate user(s):\n"),
- X $dup_user=1 if !$dup_user && $users{$_} > 1;
- X print "$_ " if $users{$_} > 1;
- X }
- X print "\n" if $dup_user;
- X
- X }
- X # find duplicate group names
- X # not the best way, but it works..
- X # boy, this is ugly too .. but, not as bad as above.. :)
- X $dup_warned = 0;
- X for (sort keys %groups) {
- X (print "Warning! Duplicate Group(s) found in $file:\n"), $dup_warned++
- X if !$dup_warned && $groups{$_} > 1;
- X print "$_ " if $groups{$_} > 1;
- X }
- X print "\n" if $dup_warned;
- }
- X
- unlink $yptmp;
- X
- 1;
- # end
- SHAR_EOF
- chmod 0700 p-cops.alpha/group.chk ||
- echo 'restore of p-cops.alpha/group.chk failed'
- Wc_c="`wc -c < 'p-cops.alpha/group.chk'`"
- test 5060 -eq "$Wc_c" ||
- echo 'p-cops.alpha/group.chk: original size 5060, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/hostname.pl ==============
- if test -f 'p-cops.alpha/hostname.pl' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/hostname.pl (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/hostname.pl (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/hostname.pl' &&
- #
- # file: hostname.pl
- # usage: $hostname = &'hostname;
- #
- # purpose: get hostname -- try method until we get an answer
- # or return "Amnesiac!"
- #
- X
- package hostname;
- X
- sub main'hostname {
- X if (!defined $hostname) {
- X $hostname = ( -x '/bin/hostname' && `/bin/hostname` )
- X || ( -x '/bin/uname' && `/bin/uname -n` )
- X || ( -x '/usr/bin/uuname' && `/usr/bin/uuname -l`)
- X || 'Amnesiac!';
- X chop $hostname;
- X }
- X $hostname;
- }
- X
- 1;
- SHAR_EOF
- chmod 0700 p-cops.alpha/hostname.pl ||
- echo 'restore of p-cops.alpha/hostname.pl failed'
- Wc_c="`wc -c < 'p-cops.alpha/hostname.pl'`"
- test 444 -eq "$Wc_c" ||
- echo 'p-cops.alpha/hostname.pl: original size 444, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/is_able.chk ==============
- if test -f 'p-cops.alpha/is_able.chk' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/is_able.chk (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/is_able.chk (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/is_able.chk' &&
- #!/bin/sh # need to mention perl here to avoid recursion
- #
- # is_able.chk
- #
- # This shell script checks the permissions of all files and directories
- # listed in the configuration file "is_able.lst", and prints warning messages
- # according to the status of files. You can specify world or group readability
- # or writeability. See the config file for the format of the configuration
- # file.
- #
- # Mechanism: This shell script parses each line from the configure file
- # and uses the "is_able.pl" program to check if any of
- # the directories in question are writable by world/group.
- #
- # NOTE:
- # If you know where perl is and your system groks #!, put its
- # pathname at the top to make this a tad faster.
- #
- # the following magic is from the perl man page
- # and should work to get us to run with perl
- # even if invoked as an sh or csh or foosh script.
- # notice we don't use full path cause we don't
- # know where the user has perl on their system.
- #
- eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
- & eval 'exec perl -S $0 $argv:q'
- X if $running_under_some_stupid_shell_instead_of_perl;
- require 'is_able.pl';
- require 'file_mode.pl';
- require 'glob.pl';
- X
- if ($ARGV[0] eq '-d') {
- X shift;
- X $debug = $glob'debug = 1; # maybe should turn off glob'debug afterwards
- }
- X
- unshift (@ARGV, "is_able.lst" ) unless @ARGV;
- X
- while (<>) {
- X next if /^\s*#/;
- X split;
- X next unless @_ == 3;
- X ($file, $x, $y) = @_;
- X @files = $file =~ /[\[?*]/ ? &'glob($file) : ($file);
- X for $file (@files) {
- X print STDERR "is_able $file $x $y\n" if $debug;
- X &'is_able($file, $x, $y);
- X }
- }
- X
- 1;
- SHAR_EOF
- chmod 0700 p-cops.alpha/is_able.chk ||
- echo 'restore of p-cops.alpha/is_able.chk failed'
- Wc_c="`wc -c < 'p-cops.alpha/is_able.chk'`"
- test 1591 -eq "$Wc_c" ||
- echo 'p-cops.alpha/is_able.chk: original size 1591, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/is_able.lst ==============
- if test -f 'p-cops.alpha/is_able.lst' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/is_able.lst (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/is_able.lst (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/is_able.lst' &&
- # This lists any/all sensitive files the administration wants to ensure
- # non-read/writability of. Comments are lines starting with a "#".
- #
- # USE FULL PATHNAMES!
- #
- # Lines are of the format:
- #
- # /path/to/{dir|file} World/Group Read/Write/Both
- #
- # as above {w|g} {r|w|b}
- #
- / w w
- /etc w w
- /usr w w
- /bin w w
- /dev w w
- /usr/bin w w
- /usr/etc w w
- /usr/adm w w
- /usr/lib w w
- /usr/spool w w
- /usr/spool/mail w w
- /usr/spool/news w w
- /usr/spool/uucp w w
- /usr/spool/at w w
- /usr/local w w
- /usr/local/bin w w
- /usr/local/lib w w
- /usr/users w w
- /Mail w w
- X
- # some Un*x's put shadowpass stuff here:
- /etc/security w r
- X
- # /.login /.profile /.cshrc /.rhosts
- /.* w w
- X
- # I think everything in /etc should be !world-writable, as a rule; but
- # if you're selecting individual files, do at *least* these:
- # /etc/passwd /etc/group /etc/inittab /etc/rc /etc/rc.local /etc/rc.boot
- # /etc/hosts.equiv /etc/profile /etc/syslog.conf /etc/export /etc/utmp
- # /etc/wtmp
- /etc/* w w
- X
- /bin/* w w
- /usr/bin/* w w
- /usr/etc/* w w
- /usr/adm/* w w
- /usr/lib/* w w
- /usr/local/lib/* w w
- /usr/local/bin/* w w
- /usr/etc/yp* w w
- /usr/etc/yp/* w w
- X
- # individual files:
- /usr/lib/crontab w b
- /usr/lib/aliases w w
- /usr/lib/sendmail w w
- /usr/spool/uucp/L.sys w b
- X
- # NEVER want these readable!
- /dev/kmem w b
- /dev/mem w b
- X
- # Optional List of assorted files that shouldn't be
- # write/readable (mix 'n match; add to the list as desired):
- /usr/adm/sulog w r
- /.netrc w b
- # HP-UX and others:
- /etc/btmp w b
- /etc/securetty w b
- # Sun-fun
- /dev/drum w b
- /dev/nit w b
- SHAR_EOF
- chmod 0700 p-cops.alpha/is_able.lst ||
- echo 'restore of p-cops.alpha/is_able.lst failed'
- Wc_c="`wc -c < 'p-cops.alpha/is_able.lst'`"
- test 1603 -eq "$Wc_c" ||
- echo 'p-cops.alpha/is_able.lst: original size 1603, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/is_able.pl ==============
- if test -f 'p-cops.alpha/is_able.pl' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/is_able.pl (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/is_able.pl (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/is_able.pl' &&
- #
- # (This takes the place of the C program is_able.c, BTW.)
- #
- # is_able filename {w|g|s|S} {r|w|B|b|s}
- # (world/group/SUID/SGID read/write/{read&write}/{suid&write}/s[ug]id)
- #
- # The second arg of {r|w} determines whether a file is (group or world
- # depending on the first arg of {w|g}) writable/readable, or if it is
- # SUID/SGID (first arg, either s or S, respectively), and prints out a
- # short message to that effect.
- #
- # So:
- # is_able w w # checks if world writable
- # is_able g r # checks if group readable
- # is_able s s # checks if SUID
- # is_able S b # checks if world writable and SGID
- X
- package main;
- require 'file_mode.pl';
- X
- package is_able;
- X
- # package statics
- #
- %wg = (
- X 'w', 00006,
- X 'g', 00060,
- X 's', 04000,
- X 'S', 02000,
- X );
- X
- %rwb= (
- X 'r', 00044,
- X 'w', 00022,
- X 'B', 00066,
- X 'b', 04022,
- X 's', 06000,
- X );
- X
- $silent = 0; # for suppressing diagnostic messages
- X
- X
- sub main'is_able {
- X local($file, $wg, $rwb) = @_;
- X
- X local (
- X $mode, # file mode
- X $piece, # 1 directory component
- X @pieces, # all the pieces
- X @dirs, # all the directories
- X $p, # punctuation; (*) mean writable
- X # due to writable parent
- X $retval, # true if vulnerable
- X $[ # paranoia
- X );
- X
- X &usage, return undef if @_ != 3 || $file eq '';
- X
- X &usage, return undef unless defined $wg{$wg} && defined $rwb{$rwb};
- X
- X if (&'Mode($file) eq 'BOGUS' && $noisy) {
- X warn "is_able: can't stat $file: $!\n";
- X return undef;
- X }
- X
- X $retval = 0;
- X
- X if ($rwb{$rwb} & $rwb{'w'}) {
- X @pieces = split(m#/#, $file);
- X for ($i = 1; $i <= $#pieces; $i++) {
- X push(@dirs, join('/', @pieces[0..$i]));
- X }
- X } else {
- X @dirs = ( $file );
- X }
- X
- X for $piece ( reverse @dirs ) {
- X
- X next unless $mode = &'Mode($piece);
- X next if $mode eq 'BOGUS';
- X
- X next unless $mode &= 07777 & $wg{$wg} & $rwb{$rwb};
- X
- X $retval = 1;
- X
- X $p = $piece eq $file ? '!' : '! (*)';
- X
- X $parent_is_writable = $p eq '! (*)'; # for later
- X
- X next if $silent; # for &is_writable
- X
- X print "Warning! $file is group readable$p\n" if $mode & 00040;
- X print "Warning! $file is _World_ readable$p\n" if $mode & 00004;
- X print "Warning! $file is group writable$p\n" if $mode & 00020;
- X print "Warning! $file is _World_ writable$p\n" if $mode & 00002;
- X print "Warning! $file is SUID!\n" if $mode & 04000;
- X print "Warning! $file is SGID!\n" if $mode & 02000;
- X
- X last if $piece ne $file; # only complain on first writable parent
- X }
- X $retval;
- }
- X
- sub main'is_writable {
- X local($silent) = 1;
- X &'is_able($_[0], 'w', 'w')
- X ? $parent_is_writable
- X ? "writable (*)"
- X : "writable"
- X : 0;
- }
- X
- sub main'is_readable {
- X local($silent) = 1;
- X &'is_able($_[0], 'w', 'r');
- }
- X
- sub usage {
- X warn <<EOF;
- Usage: is_able file {w|g|S|s} {r|w|B|b|s}
- X (not: is_able @_)
- EOF
- }
- X
- 1;
- SHAR_EOF
- chmod 0700 p-cops.alpha/is_able.pl ||
- echo 'restore of p-cops.alpha/is_able.pl failed'
- Wc_c="`wc -c < 'p-cops.alpha/is_able.pl'`"
- test 2835 -eq "$Wc_c" ||
- echo 'p-cops.alpha/is_able.pl: original size 2835, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= p-cops.alpha/kuang ==============
- if test -f 'p-cops.alpha/kuang' -a X"$1" != X"-c"; then
- echo 'x - skipping p-cops.alpha/kuang (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting p-cops.alpha/kuang (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'p-cops.alpha/kuang' &&
- #! /usr/local/bin/perl
- X
- #
- # kuang - rule based analysis of Unix security
- #
- # Perl version by Steve Romig of the CIS department, The Ohio State
- # University, October 1990.
- #
- # Based on the shell script version by Dan Farmer from his COPS
- # package, which in turn is based on a shell version by Robert
- # Baldwin.
- #
- #-----------------------------------------------------------------------------
- # Players:
- # romig Steve Romig, romig@cis.ohio-state.edu
- # tjt Tim Tessin, tjt@cirrus.com
- #
- # History:
- # 4/25/91 tjt, romig Various fixes to filewriters (better messages about
- # permission problems) and don't update the DBM cache
- # with local file info.
- # 11/1/90 romig Major rewrite - generic lists, nuking get_entry
- # and put_entry, moved rules to separate file.
- #
- X
- #
- # Options
- #
- # -l list uid's that can access the given target, directly
- # or indirectly
- # -d debug
- # -v verbose
- #
- # -k file load the list of known CO's
- # -f file preload file information from the named file.
- # -p file preload passwd info from the named file.
- # -P preload passwd info from ypcat + /etc/passwd
- # -g group preload group info from the named file.
- # -G preload group info from ypcat + /etc/group
- #
- X
- $options = "ldvk:p:g:f:PG";
- $usage = "usage: kuang [-l] [-d] [-v] [-k known] [-f file] [-P] [-G] [-p passwd] [-g group] [u.username|g.groupname]\n";
- X
- $add_files_to_cache = 1; # Whether to update the %files cache
- X # with local file info or not.
- X
- #
- # Terminology:
- #
- # An "op" is an operation, such as uid, gid, write, or replace.
- # 'uid' means to gain access to some uid, 'gid' means to gain access
- # to some gid. 'write' and 'replace' refer to files - replace means
- # that we can delete a file and replace it with a new one somehow
- # (for example, if we could write the directory it is in).
- #
- # An object is a uid, gid or pathname.
- #
- # A Controlling Operation (CO) is a (operation, object) pair
- # represented as "op object": "uid 216" (become uid 216) or "replace
- # /.rhosts" (replace file /.rhosts). These are represented
- # internally as "c value", where "c" is a character representing an
- SHAR_EOF
- true || echo 'restore of p-cops.alpha/kuang failed'
- fi
- echo 'End of alpha p-cops part 1'
- echo 'File p-cops.alpha/kuang is continued in part 2'
- echo 2 > _shar_seq_.tmp
- exit 0
-