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 / root.chk < prev    next >
Text File  |  1992-03-10  |  6KB  |  216 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: root.chk
  9. #
  10. #  This script checks pathnames inside root's startup files for 
  11. # writability, improper umask settings (world writable), non-root
  12. # entries in /.rhosts, writable binaries in root's path,
  13. # and to ensure that root is in /etc/ftpuser.
  14. #
  15. # Also check for a single "+" in /etc/hosts.equiv (world is trusted),
  16. # and that /bin, /etc and certain key files are root owned, so that you
  17. # can't, say, rcp from a host.equived machine and blow over the password
  18. # file... this may or may not be bad, decide for yourself.
  19. # Startup files are /.login /.cshrc /.profile
  20. #
  21. #  Mechanism:  These files contain paths and filenames that are stripped
  22. # out using "grep".  These strings are then processed by the "is_able"
  23. # program to see if they are world writable.  Strings of the form:
  24. #
  25. #    path=(/bin /usr/bin .)
  26. #        and
  27. #    PATH=/bin:/usr/bin:.:
  28. #
  29. # are checked  to ensure that "." is not in the path.  All
  30. # results are echoed to standard output.  In addition, some effort was
  31. # put into parsing out paths with multiple lines; e.g. ending in "\",
  32. # and continuing on the next line.  Also, all executable files and 
  33. # directories in there are checked for writability as well.
  34. #
  35. #  For umask stuff, simply grep for umask in startup files, and check
  36. # umask value.  For /etc/ftpuser, simple grep to check if root is in
  37. # the file.  For /etc/hosts.equiv, just check to see if "+" is alone
  38. # on a line by awking it.
  39. #
  40.  
  41. # rewritten in perl by tchrist@convex.com
  42.  
  43. # root startup/important files
  44.  
  45. require 'file_owner.pl';
  46. require 'fgrep.pl';
  47. require 'suckline.pl';
  48. require 'is_able.pl';
  49. require 'chk_strings.pl';
  50. require 'glob.pl';
  51.  
  52. package root_chk;
  53.  
  54. # use -a true if you care about non-executables
  55. # in root's path
  56.  
  57. $ARGV[0] eq '-a' && ($all_files++, shift);
  58.  
  59. die "usage: root.chk [-a]\n" if @ARGV;
  60.  
  61. $W = 'Warning! ';
  62.  
  63. $cshrc    = '/.cshrc';
  64. $profile= '/.profile';
  65. $rhosts = '/.rhosts';
  66.  
  67. $| = 1;
  68.  
  69. @big_files= ('/.login', '/.cshrc', '/.profile', '/.logout' );
  70.  
  71. # root should own *at least* these, + $big_files; you can check for all files
  72. # in /bin & /etc, or just the directories (the default.)
  73. # root_files="/bin /bin/* /etc /etc/* $big_files $rhosts"
  74. @root_files= ('/bin','/etc',@big_files,$rhosts,'/etc/passwd','/etc/group');
  75.  
  76. # misc important stuff
  77. $ftp='/etc/ftpusers';
  78. $equiv='/etc/hosts.equiv';
  79.  
  80. #   should't have anyone but root owning /bin or /etc files/directories
  81. # In case some of the critical files don't exist (/.rhost), toss away error
  82. # messages
  83.  
  84. if (@bad_files = grep (-e && &'Owner($_), @root_files)) {
  85.     print "$W  Root does not own the following file(s):\n";
  86.     print "\t@bad_files\n";
  87.  
  88. local($chk_strings'recurse) = 1 unless defined $chk_strings'recurse;
  89.  
  90. for $file (@big_files) {
  91.     open file || next;
  92.  
  93.     &'chk_strings($file);
  94.  
  95.     # check for group or other writable umask
  96.     while (<file>) {
  97.     next if /^\s*#/;
  98.     next unless /umask\s*(\d+)/;
  99.     next unless ~oct($1) & 022;
  100.     print "$W root's umask set to $1 in $file\n";
  101.     } 
  102.  
  103. print "$W $ftp exists and root is not in it\n" 
  104.     if -e $ftp && !&'fgrep($ftp,'root');
  105.  
  106. print "$W A \"+\" entry exists in $equiv!\n" if &'fgrep($equiv, '^\+$');
  107.  
  108. if (open rhosts) {
  109.     while (<rhosts>) {
  110.     next unless /\S+\s+(\S+)/ && $1 ne 'root';
  111.     print "$W Non-root entry in $rhosts! $1\n";
  112.     }
  113. close(rhosts);
  114.  
  115. undef @rootpath;
  116.  
  117. # checking paths...
  118. #
  119. # Get the root paths from $csh.
  120.  
  121. if (open(CSHRC, $cshrc)) {
  122.     $path = '';
  123.     while (<CSHRC>) {
  124.     next if /^\s*#/;
  125.     chop unless /\\$/;
  126.     if (/set\s+path\s*=/) {
  127.         $_ = &'suckline($cshrc, $_);
  128.         s/.*set\s+path\s*=\s*//;
  129.         s/\((.*)\)/$1/;
  130.         s/#.*/./;
  131.         @tmppath = grep($_ ne '', split(' '));
  132.         for (@tmppath) { $whence{$_} .= " " . $cshrc; } 
  133.         push(@rootpath, @tmppath);
  134.     } 
  135.     } 
  136.     close(CSHRC);
  137.  
  138. if (open login) {
  139.     $path = '';
  140.     while (<cshrc>) {
  141.     next if /^\s*#/;
  142.     chop unless /\\$/;
  143.     if (/set\s+path\s*=/) {
  144.         $_ = &'suckline('login', $_);
  145.         s/.*set\s+path\s*=\s*//;
  146.         s/\((.*)\)/$1/;
  147.         s/#.*/./;
  148.         @tmppath = grep($_ ne '', split(' '));
  149.         for (@tmppath) { $whence{$_} .= " " . $login; } 
  150.         push(@rootpath, @tmppath);
  151.     } 
  152.     } 
  153.     close(login);
  154. }
  155.  
  156. if (open profile) {
  157.     $path = '';
  158.     while (<profile>) {
  159.     next if /^\s*#/;
  160.     chop unless /\\$/;
  161.     if (/PATH=/) {
  162.         $_ = &'suckline('profile', $_);
  163.         s/.*PATH=//;
  164.         s/#.*//;
  165.         s/;.*//;
  166.         @tmppath = split(/:/);
  167.         for (@tmppath) { $whence{$_} .= " " . $profile; } 
  168.         push(@rootpath, @tmppath);
  169.     } 
  170.     } 
  171.     close(profile);
  172.  
  173. for (keys %whence) {
  174.     $whence{$_} =~ s/^ //;
  175.     $whence{$_} =~ s/ / and /g;
  176.  
  177. undef %seen;
  178. grep($seen{$_}++, @rootpath);
  179.  
  180. $is_able'silent = 1;
  181. for (keys %seen) {
  182.     if (!-e && $_ ne ".") {
  183.     print "$W path component $_ in $whence{$_} doesn't exist!\n";
  184.     next;
  185.     } 
  186.  
  187.     if (/^\.?$/) {  # null -> dot
  188.     print "$W \".\" (or current directory) is in root's path in $whence{$_}!\n";
  189.     } elsif (&'is_writable($_)) {
  190.     print "$W Directory $_ is _World_ writable and in root's path in $whence{$_}!\n";
  191.     next;
  192.     }
  193.  
  194.     foreach $file (&'glob("$_/*")) {
  195.     # can't just check -x here, as that depends on current user
  196.     $is_executable = -f $file && (&'Mode($file) & 0111);
  197.     if (($all_files || $is_executable) && 
  198.             ($how = &'is_writable($file, 'w', 'w'))) {
  199.         print "$W _World_ $how ",
  200.             $is_executable ? 'executable' : 'file',
  201.         " $file in root path component $_ from $whence{$_}!\n";
  202.     } 
  203.     }
  204.  
  205. $is_able'silent = 0;
  206.  
  207. 1;
  208.