| |||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
||||
|
||||
|
Check your system files
#!/usr/local/bin/perl
# This script is public domain # Comments or suggestions to djl@dplace.com #This script will check for changed files in system places. #The list of places to check is in "/usr/local/etc/.checklist" #Each line in the file contains a file name or a directory name. #They must be absolute pathnames. #Lines begining with a # are comments. # #If the line contains a file name, it is followed by comma separated fields. # Field Type # 1 Checksum (computed by /bin/sum) # 2 Mode # 3 Owner # 4 Group # 5 Size #If a field is null, it will not be checked #If the file is a symbolic link, the size field will contain the link #information, an arrow and the linked to file, e.g. "-> /usr/bin" # #If the line is a directory name, following the size field may be a list #of 0 or more comma separated file names. Exactly those files must appear #in the directory. Note that this does not check the contents of the file. #To do that there must be a file line also. The line may be continued #with a '\' if necessary. If the contents of the directory is not to be #checked, e.g. /tmp, the field must be missing -- omit the comma. # # #nothing is said about the contents of /tmp # /tmp ,drwxrwxrwx,root,root, # #/lost+found must be empty # /lost+found ,drwxrwxrwx,root,root,, use Getopt::Long; sub perror($); sub oct2rwx($); sub intr { system("pkill -CONT setiathome"); exit 1; } sub usage { print "usage: checksys [-Verbose] [-File checkfile]\n"; exit } if ( $> != 0 ) { die "This needs to be run as root"; } $CHECKFILE = "/usr/local/etc/.checklist"; $ENV{'PATH'} = "/usr/local/bin:/usr/bin:/bin"; $VERBOSE = 0; $SUM = "sum"; # Remove core just in case unlink('/core'); # #Process command options # GetOptions( 'Verbose' => \$VERBOSE, 'File:s' => \$CHECKFILE, ) || &usage; $SIG{'INT'} = 'intr'; $SIG{'QUIT'} = 'intr'; system("pkill -STOP setiathome"); # # Get arrays to translate uid to owner and gid to group # while (($name, $pw, $uid) = getpwent) { $owner{$uid} = $name unless $owner{$uid}; } while (($name, $pw, $gid) = getgrent) { $group{$gid} = $name unless $group{$gid}; } # #Setup to read checkfile # open(CF, $CHECKFILE) || die "$CHECKFILE is not readable"; chdir('/'); system( "rm -f .history*" ); # #Process each line # $printed = 0; $type = "dir"; $lnum = 0; $head = 0; while(<CF>) { ++$lnum; next if /^$/; if ( /^#\s*SUM\s/ ) { ($SUM = $_) =~ s/^#\s*SUM\s+//; chomp($SUM); next; } #check for a comment next if /^#/; #options include the fields returned by ls -l chomp($_); ($file, $options) = split("\t", $_, 2); if ($printed and -d $file ) { $printed = 0; print "\n\n"; } unless ( -e $file or -l $file ) { perror("$file: Missing") unless $file eq ""; next; } #Get each argument $options =~ s/ *//; ($sum, $mode, $owner, $group, $size, $cont) = split(/, */, $options); $check_contents = /([^,]*,){5}/; #get info about the file ($dev, $ino, $cmode, $clinks, $uid, $gid, $rdev, $csize) = lstat($file); # Validate checksum if ( "$sum" ) { $csum = `$SUM '$file'`; $csum =~ s/ .*//; chomp($csum); if ( $csum ne $sum ) { perror("$file: checksum error"); } else { if ( $VERBOSE ) { print "$file: checksum OK\n"; } } } # Validate file permissions if ( "$mode" ) { $cmode = oct2rwx($cmode); if ( "$cmode" ne "$mode" ) { perror("$file: mode error, should be $mode, is $cmode"); } else { if ( $VERBOSE ) { print "$file: mode OK\n" } } } # Validate ownership if ( "$owner" ) { $cowner = $owner{$uid} || $uid; if ( $cowner ne $owner ) { perror("$file: owner error, should be $owner, is $cowner"); } else { if ( $VERBOSE ) { print "$file: owner OK\n"; } } } # Validate group ownership if ( "$group" ) { $cgroup = $group{$gid} || $gid; if ( $cgroup ne $group ) { perror("$file: group error, should be $group, is $cgroup"); } else { if ( $VERBOSE ) { print "$file: group OK\n"; } } } # Check contents of directory if ( ! -l $file and -d $file and $check_contents ) { chdir($file); $dir = $file; %files = (); while ( defined($cont) and $cont eq '\\' ) { # Read name of files in directories chomp($_ = scalar(<CF>)); ++$lnum; s/^[ ]*//; ($file, $cont) = split(/, /); if ( -e $file or -l $file ) { $files{$file} = 1; } else { perror("$file: Missing from directory $dir"); } } opendir(DIR, "."); scalar(readdir(DIR)); scalar(readdir(DIR)); $mprint = 0; while ($_ = readdir(DIR)) { chomp; next if $files{$_}; perror("In directory $dir\nThe following files were added:") unless $mprint; perror(" $_"); $mprint = 1; } close(DIR); next; } # # Check for sym_link, size field contains link info # if ( $mode =~ /^l/ ) { if ( ! -l $file ) { perror("$file: should be a sym_link"); } $clink = readlink($file); # need to re-split input since linked-to file may have a comma in the name ($sum, $mode, $owner, $group, $size) = split(/, */, $options, 5); $size =~ s/-> //; if ( "$clink" ne "$size" ) { perror("$file: Sym_link error, should point to $size, is $clink"); } else { if ( $VERBOSE ) { print "$file: sym_link OK\n"; } } next; } # # Must be plain file # if ( $size =~ /^\d+$/ ) { if ( $size != $csize ) { perror("$file: size error, should be $size, is $csize"); } else { if ( $VERBOSE ) { print "$file: size OK\n"; } } } } system("pkill -CONT setiathome"); exit($head == 0); # Translate an integer file mode to a string like "drwxr-xr-x" sub oct2rwx($) { my $mode = "----------"; my ($omode) = @_; my $type; if($omode & 01) { if($omode & 01000) { substr($mode, 9, 1) = "t"; } else { substr($mode, 9, 1) = "x"; } } else { if($omode & 01000) { substr($mode, 9, 1) = "T"; } else { substr($mode, 9, 1) = "-"; } } if($omode & 02) { substr($mode, 8, 1) = "w"; } if($omode & 04) { substr($mode, 7, 1) = "r"; } if($omode & 010) { if($omode & 02000) { substr($mode, 6, 1) = "s"; } else { substr($mode, 6, 1) = "x"; } } else { if($omode & 02000) { substr($mode, 6, 1) = "S"; } else { substr($mode, 6, 1) = "-"; } } if($omode & 020) { substr($mode, 5, 1) = "w"; } if($omode & 040) { substr($mode, 4, 1) = "r"; } if($omode & 0100) { if($omode & 04000) { substr($mode, 3, 1) = "s"; } else { substr($mode, 3, 1) = "x"; } } else { if($omode & 04000) { substr($mode, 3, 1) = "S"; } else { substr($mode, 3, 1) = "-"; } } if($omode & 0200) { substr($mode, 2, 1) = "w"; } if($omode & 0400) { substr($mode, 1, 1) = "r"; } $type = $omode & 0xF000; if( $type == 0x1000) { substr($mode, 0, 1) = "p"; # FIFO } elsif( $type == 0x2000) { substr($mode, 0, 1) = "c"; # character special } elsif( $type == 0x4000) { substr($mode, 0, 1) = "d"; # directory } elsif( $type == 0x6000) { substr($mode, 0, 1) = "b"; # block special } elsif( $type == 0x8000) { substr($mode, 0, 1) = "-"; # normal file } elsif( $type == 0xA000) { substr($mode, 0, 1) = "l"; # symbolic link } elsif( $type == 0xC000) { substr($mode, 0, 1) = "s"; # socket } elsif( $type == 0xD000) { substr($mode, 0, 1) = "D"; # door } return $mode; } sub perror($) { my $emsg; ($emsg) = @_; unless ( $head ) { print "Subject: Checking for system rot\n\n"; $head = 1; } $msg =~ s/\n/\n%lnum:\t/g; print "$lnum:\t$emsg\n"; $printed = 1; } |
![]() |
| Viewing: ASP Free Forums > Programming > Code Bank > Check your system files |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
|
|