home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / c / cops_104.zip / cops_104 / perl / cops < prev    next >
Text File  |  1992-03-10  |  7KB  |  251 lines

  1. #!/bin/sh -- need to mention perl here to avoid recursion
  2. 'true' || eval 'exec perl -S $0 $argv:q';
  3. eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
  4. & eval 'exec /usr/local/bin/perl -S $0 $argv:q'
  5.         if 0;
  6.  
  7. #
  8. #  Usage: cops [-vx] [-c config file] [-s secure_dir] [architecture]
  9. #
  10. #  This will change into the $SECURE/architecture directory, suck lots
  11. # of info and configuration stuff out of "cops.cf", and runs all of the
  12. # security programs in that file.  If any of the programs find any 
  13. # security problems, it either sends mail to everyone in the $SECURE_USERS
  14. # list (see "cops.cf"), or saves the results in a file 
  15. # $SECURE/architecture/hostname.  It then destroys all temporary files, 
  16. # and exits the program.  Programs that are run (besides this one):
  17. #
  18. #    root.chk    dev.chk        group.chk
  19. #    rc.chk        passwd.chk    is_able.chk
  20. #    pass.chk     user.chk    cron.chk
  21. #    misc.chk    ftp.chk
  22. #
  23. #  The -x and -v (verbose) flags print out the name each program to 
  24. # the results file as it is executed.  The -v flag also passes the
  25. # verbose option to other modules.  The -s and -c flags allow you
  26. # to specify the $SECURE directory and $CONFIG file, respectively.
  27. # NOTE:
  28. #   If you know where perl is and your system groks #!, put its
  29. # pathname at the top to make this a tad faster.
  30. #
  31. # the following magic is from the perl man page
  32. # and should work to get us to run with perl 
  33. # even if invoked as an sh or csh or foosh script.
  34. # notice we don't use full path cause we don't
  35. # know where the user has perl on their system.
  36. #
  37.  
  38. ######################################
  39. # perl COPS main driver.
  40. # tchrist@convex.com
  41. ######################################
  42.  
  43. # security sanity settings
  44. #
  45. $ENV{'IFS'} = '' if $ENV{'IFS'};
  46. $ENV{'PATH'} = '/bin:/usr/bin:/usr/ucb';
  47. $| = 1;
  48. umask 077;
  49.  
  50. #
  51. # Getopts stuff
  52. $usage = "Usage: $0 [-vx] [-c config_file] [-s secure_dir] architecture\n";
  53. require 'getopts.pl';
  54. # Process the command args; Either specify verbose or an alternate config file:
  55. die $usage unless &Getopts('vxc:s:');
  56.  
  57. if (defined($opt_v)) { $verbose = $opt_v;}
  58. else { $verbose = 0; }
  59.  
  60. if (defined($opt_s)) { $SECURE = $LIBCOPS = $opt_s; }
  61. else { $SECURE = $LIBCOPS = '.'; }
  62.  
  63. if (defined($opt_c)) { $CONFIG = $opt_c; }
  64. else {$CONFIG = "$SECURE/cops.cf"; }
  65.  
  66. if (@ARGV > 1) {
  67.     die $usage;
  68. } elsif (@ARGV == 1) {
  69.     $SECURE = shift;
  70.     die "Architecture directory $SECURE does not exist\n" unless -d $SECURE;
  71.     chdir($SECURE) || die "can't cd to $SECURE: $!";
  72.     exec './cops';
  73.  
  74. # internal cops stuff needed
  75. require "$LIBCOPS/pathconf.pl";
  76. require "$LIBCOPS/is_able.pl";
  77. require "$LIBCOPS/hostname.pl";
  78.  
  79. chmod 0700, $SECURE;  
  80. chdir ($SECURE) || die "Error -- Security directory $SECURE doesn't exist\n";
  81.  
  82. #  Read stuff to do from the config file
  83. die "$0: Can't trust $CONFIG to reconfig!\n"     if &'is_writable($CONFIG);
  84. open CONFIG || die "can't open $CONFIG: $!";
  85.  
  86. &argh unless -s $CONFIG;
  87.  
  88. &init_result;
  89.  
  90. while (<CONFIG>) {
  91.     next if /^\s*#/;
  92.     next if /^\s*$/;
  93.  
  94.     if (/^\s*[\$&\@\%]/) {  #  reset a config variable
  95.     s/#.*//;
  96.     eval;
  97.     warn "Bad config variable at line $. of $CONFIG:\n\t$_\t$@\n" if $@;
  98.     next;
  99.     } 
  100.  
  101.     # must be a program to run
  102.     chop;
  103.     s/#.*//;
  104.     s/;$//;
  105.     @ARGV=split;
  106.     $program = shift;
  107.     if ($verbose || $opt_x) { print "**** $program ****\n"; }
  108.     &flush;
  109.     &run("$LIBCOPS/$program");
  110.     &flush;
  111.  
  112.  
  113. &save_result;
  114.  
  115. &argh unless $ran_something;
  116.  
  117. exit 0;
  118.  
  119. ######################################################################
  120. sub run {
  121.     local($module) = @_;
  122.     local($status);
  123.     local($0) = $module; # so it shows up in ps
  124.     local($!);
  125.  
  126.  
  127.     $ran_something++;
  128.  
  129.     open(STDERR, $COPS_ERRORS ? ">&STDOUT" : ">/dev/null");
  130.  
  131.     unless ($status = do $module) {
  132.     if ($@) {
  133.         warn "cops: unexpected exit from $module:\n\t-> $@\n";
  134.     } elsif ($! != 0) {
  135.         warn "cops: couldn't run $module: $!\n";
  136.     } else {
  137.         warn "cops: $module returned $status\n";
  138.     } 
  139.     }
  140.  
  141.     # hack for kuang, who doesn't write to STDOUT (yet!)
  142.     $SUCCESS = "$SECURE/Success";
  143.     if ($module =~ /^kuang/ && -e $SUCCESS) {
  144.     if (open SUCCESS) {
  145.         print while <SUCCESS>;  # STDOUT is $REPORT
  146.         close SUCCESS;
  147.         unlink $SUCCESS;
  148.     } else {
  149.         warn "can't open $SUCCESS: $!\n";
  150.     } 
  151.     } 
  152. }
  153. ######################################################################
  154. sub init_result {
  155.     $REPORT = "$SECURE/result.$$";  # global!
  156.     open (REPORT, ">$REPORT") || die "can't create $REPORT: $!\n";
  157.  
  158.     # assume dups work
  159.     open (STDOUT, ">&REPORT");
  160.     open (SAVERR, ">&STDERR");
  161.     open (STDERR, ">&STDOUT");
  162.  
  163.     ($sec, $min, $hour, $mday, $mon, $year,
  164.     $wday, $yday, $isdst) = localtime(time);
  165.  
  166.     $name = sprintf("%s_%s_%s", $year + 1900, 
  167.     (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec)[$mon],
  168.     $mday);
  169.  
  170.     $host = &hostname;    # from hostname.pl
  171.     $host =~ s/\..*//;
  172.  
  173.     # Dan, do you want full path for `date` on next line?
  174.     print "ATTENTION:\nSecurity report for ", `date`;
  175.     print "\nfrom host $host, $name\n\n";
  176.     $report = $name;
  177.  
  178.     &flush;
  179. }
  180. ######################################################################
  181. sub save_result {
  182.     open(STDERR, ">&SAVERR");
  183.  
  184.     close REPORT || die "can't close $REPORT: $!\n";
  185.  
  186.     $dir = "$SECURE/$host";
  187.     $report = $dir . "/" . $report;
  188.  
  189.     mkdir($dir,0700) unless -d $dir;
  190.  
  191.     if ($MMAIL) {
  192.     # system "$MAIL $SECURE_USERS < $REPORT"
  193.     system "$ECHO $SECURE_USERS $REPORT"
  194.         unless $ONLY_DIFF && !&different($dir, $REPORT);
  195.     } else {
  196. #    rename ($REPORT, $dir . "/" . $name) ||
  197. #        die "can't put $REPORT into $dir/$name: $!";
  198.     rename ($REPORT, $report) ||
  199.         die "can't put $REPORT into $report: $!\n";
  200.     }
  201.     unlink $REPORT;
  202.  
  203. ######################################################################
  204. sub different {
  205.     local($dir, $FILE1) = @_;
  206.     local($FILE2, $f1, $f2, $_);
  207.  
  208.     open (LS, "$LS -t $dir |");
  209.     chop($FILE2 = <LS>);
  210.     close(LS); # snuff it out
  211.  
  212.  
  213.     if ($FILE2 eq "") {
  214.     system "$CP $REPORT $report";
  215.     }
  216.     return 1 if (($FILE2 eq "") || (-s $FILE1 != -s $report));
  217.  
  218.     open FILE1 || die "can't open $FILE1: $!\n";
  219.     open FILE2 || die "can't open $FILE2: $!\n";
  220.  
  221.     for (1..5) {
  222.     $_ = <FILE1>;
  223.     $_ = <FILE2>;
  224.     } 
  225.  
  226.     while ( ($f1 = <FILE1>), ($f2 = <FILE2>) ) {
  227.     last if $f1 ne $f2;
  228.     } 
  229.  
  230.     close FILE1;
  231.     close FILE2;
  232.  
  233.     defined($f1) || defined($f2);
  234.  
  235. ######################################################################
  236. sub flush {
  237.     local($old) = $|;
  238.     $| = 1;
  239.     print '';
  240.     $| = $old;
  241.  
  242. sub argh {
  243.     die "Argh -- Can't find anything in $CONFIG\n";
  244. }
  245.