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 / is_able.pl < prev    next >
Perl Script  |  1992-03-10  |  3KB  |  126 lines

  1. #
  2. #  (This takes the place of the C program is_able.c, BTW.)
  3. #  is_able filename {w|g|s|S}       {r|w|B|b|s}
  4. #      (world/group/SUID/SGID   read/write/{read&write}/{suid&write}/s[ug]id)
  5. #     The second arg of {r|w} determines whether a file is (group or world
  6. #   depending on the first arg of {w|g}) writable/readable, or if it is
  7. #   SUID/SGID (first arg, either s or S, respectively), and prints out a
  8. #   short message to that effect.
  9. #  So:
  10. #     is_able w w        # checks if world writable
  11. #     is_able g r        # checks if group readable
  12. #     is_able s s        # checks if SUID
  13. #     is_able S b        # checks if world writable and SGID
  14.  
  15. package main;
  16. require 'file_mode.pl';
  17.  
  18. package is_able;
  19.  
  20. # package statics
  21. #
  22. %wg = ( 
  23.     'w', 00006,
  24.     'g', 00060,
  25.     's', 04000,
  26.     'S', 02000,
  27.        );
  28.  
  29. %rwb= (
  30.     'r', 00044,
  31.     'w', 00022,
  32.     'B', 00066,
  33.     'b', 04022,
  34.     's', 06000,
  35.       );
  36.  
  37. $silent = 0;  # for suppressing diagnostic messages
  38.  
  39.  
  40. sub main'is_able {
  41.     local($file, $wg, $rwb) = @_;
  42.  
  43.     local ( 
  44.        $mode,             # file mode
  45.            $piece,            # 1 directory component
  46.        @pieces,             # all the pieces
  47.        @dirs,             # all the directories
  48.        $p,                 # punctuation; (*) mean writable
  49.                        #       due to writable parent
  50.        $retval,            # true if vulnerable
  51.        $[                # paranoia
  52.       );
  53.  
  54.     &usage, return undef    if @_ != 3 || $file eq '';
  55.  
  56.     &usage, return undef    unless defined $wg{$wg} && defined $rwb{$rwb};
  57.  
  58.     if (&'Mode($file) eq 'BOGUS' && $noisy) {
  59.     warn "is_able: can't stat $file: $!\n";
  60.     return undef;
  61.     }
  62.  
  63.     $retval = 0;
  64.  
  65.     if ($rwb{$rwb} & $rwb{'w'}) {
  66.     @pieces = split(m#/#, $file);
  67.     for ($i = 1; $i <= $#pieces; $i++) {
  68.         push(@dirs, join('/', @pieces[0..$i]));
  69.     }
  70.     } else {
  71.     @dirs = ( $file );
  72.     } 
  73.  
  74.     for $piece ( reverse @dirs ) {
  75.  
  76.     next unless $mode = &'Mode($piece);
  77.     next if $mode eq 'BOGUS';
  78.  
  79.     next unless $mode &= 07777 & $wg{$wg} & $rwb{$rwb};
  80.  
  81.     $retval = 1;
  82.  
  83.     $p = $piece eq $file ? '!' : '! (*)';
  84.  
  85.     $parent_is_writable = $p eq '! (*)'; # for later
  86.  
  87.     next if $silent; # for &is_writable
  88.  
  89.     print "Warning!  $file is group readable$p\n"    if $mode & 00040; 
  90.     print "Warning!  $file is _World_ readable$p\n"    if $mode & 00004; 
  91.     print "Warning!  $file is group writable$p\n"    if $mode & 00020; 
  92.     print "Warning!  $file is _World_ writable$p\n"    if $mode & 00002; 
  93.     print "Warning!  $file is SUID!\n"        if $mode & 04000; 
  94.     print "Warning!  $file is SGID!\n"        if $mode & 02000; 
  95.  
  96.     last if $piece ne $file;  # only complain on first writable parent
  97.     }
  98.     $retval;
  99. }
  100.  
  101. sub main'is_writable {
  102.     local($silent) = 1;
  103.     &'is_able($_[0], 'w', 'w') 
  104.     ? $parent_is_writable 
  105.          ? "writable (*)"
  106.          : "writable" 
  107.     : 0;
  108.  
  109. sub main'is_readable {
  110.     local($silent) = 1;
  111.     &'is_able($_[0], 'w', 'r');
  112. }
  113.  
  114. sub usage { 
  115.     warn <<EOF;
  116. Usage: is_able file {w|g|S|s} {r|w|B|b|s}
  117.  (not: is_able @_)
  118. EOF
  119. }
  120.  
  121. 1;
  122.