[BACK]Return to skeyprune.pl CVS log [TXT][DIR] Up to [local] / src / usr.bin / skey

Diff for /src/usr.bin/skey/skeyprune.pl between version 1.2 and 1.3

version 1.2, 2001/06/20 22:19:58 version 1.3, 2002/05/16 18:27:34
Line 1 
Line 1 
 #!/usr/bin/perl -w  #!/usr/bin/perl -w
 #  #
 # Copyright (c) 1996, 2001 Todd C. Miller <Todd.Miller@courtesan.com>  # Copyright (c) 1996, 2001, 2002 Todd C. Miller <Todd.Miller@courtesan.com>
 # All rights reserved.  # All rights reserved.
 #  #
 # Redistribution and use in source and binary forms, with or without  # Redistribution and use in source and binary forms, with or without
Line 31 
Line 31 
 # $OpenBSD$  # $OpenBSD$
 #  #
   
 use File::Temp qw(:mktemp);  use POSIX qw(S_ISREG);
 use Fcntl qw(:DEFAULT :flock);  use Fcntl qw(:DEFAULT :flock);
 use Time::Local;  
   
 # Keep out the stupid  # Keep out the stupid
 die "Only root may run $0.\n" if $>;  die "Only root may run $0.\n" if $>;
 die "Usage: $0 [days]\n" if $#ARGV > 0;  die "Usage: $0 [days]\n" if $#ARGV > 0;
   
 # Pathnames  # Pathnames
 $keyfile = '/etc/skeykeys';  $skeydir = '/etc/skey';
 $template = "$keyfile.XXXXXXXX";  
   
 # Quick mapping of month name -> number  
 %months = ('Jan', 0, 'Feb', 1, 'Mar', 2, 'Apr', 3, 'May', 4,  'Jun', 5,  
            'Jul', 6, 'Aug', 7, 'Sep', 8, 'Oct', 9, 'Nov', 10, 'Dec', 11);  
   
 # Remove entries that haven't been modified in this many days.  # Remove entries that haven't been modified in this many days.
 $days_old = $ARGV[0] || -1;  $days_old = $ARGV[0] || -1;
   
 # Safe umask  # Safe umask
 umask(077);  umask(077);
   
 # Open and lock the current key file  # Current time
 open(OLD, $keyfile) || die "$0: Can't open $keyfile: $!\n";  $now = time();
 flock(OLD, LOCK_EX) || die "$0: Can't lock $keyfile: $!\n";  
   
 # Safely open temp file  # Slurp mode
 ($NEW, $temp) = mkstemp($template);  undef $/;
 die "$0: Can't open tempfile $template: $!\n" unless $temp;  
   
 # Run at a high priority so we don't keep things locked for too long  chdir($skeydir) || die "$0: Can't cd to $skeydir: $!\n";
 setpriority(0, 0, -4);  opendir(SKEYDIR, ".") || die "$0: Can't open $skeydir: $!\n";
   while (defined($user = readdir(SKEYDIR))) {
           next if $user =~ /^\./;
           if (!sysopen(SKEY, $user, 0, O_RDWR | O_NONBLOCK | O_NOFOLLOW)) {
               warn "$0: Can't open $user: $!\n";
               next;
           }
           if (!flock(SKEY, LOCK_EX)) {
                   warn "$0: Can't lock $user: $!\n";
                   close(SKEY);
                   next;
           }
   
 while (<OLD>) {          if (!stat(SKEY)) {
         chomp();                  warn "$0: Can't stat $user: $!\n";
                   close(SKEY);
                   next;
           }
   
         # Valid entry: 'username hash seq seed key date"          # Sanity checks.
         if ( /^[^\s#]+\s+(\S+\s+)?[0-9]+\s+[A-z0-9]+\s+[a-f0-9]+\s+(Jan|Feb|Mar|Apr|May|Ju[nl]|Aug|Sep|Oct|Nov|Dec)\s+[0-9]+,\s*[0-9]+\s+[0-9]+:[0-9]+:[0-9]+$/ ) {          if (!S_ISREG((stat(_))[2])) {
                   warn "$0: $user is not a regular file\n";
                   close(SKEY);
                   next;
           }
           if (((stat(_))[2] & 07777) != 0600) {
                   printf STDERR ("%s: Bad mode for %s: 0%o\n", $0, $user,
                       (stat(_))[2]);
                   close(SKEY);
                   next;
           }
           if ((stat(_))[3] != 1) {
                   printf STDERR ("%s: Bad link count for %s: %d\n", $0, $user,
                       (stat(_))[3]);
                   close(SKEY);
                   next;
           }
   
                 @entry = split(/[\s,:]+/, $_);          # Remove zero size entries
                 # Prune out old entries if asked to          if (-z _) {
                 if ($days_old > 0) {                  unlink($user) || warn "$0: Can't unlink $user: $!\n";
                         # build up time based on date string                  close(SKEY);
                         $sec = $date[10];                  next;
                         $min = $date[9];          }
                         $hours = $date[8];  
                         $mday = $date[6] - 1;  
                         $mon = $months{$date[5]};  
                         $year = $date[7] - 1900;  
   
                         $now = time();          # Prune out old entries if asked to
                         $then = timelocal($sec,$min,$hours,$mday,$mon,$year);          if ($days_old > 0) {
                         if (($now - $then) / (60 * 60 * 24) - 1 > $days_old) {                  $then = (stat(_))[9];
                                 next;   # too old                  if (($now - $then) / (60 * 60 * 24) - 1 > $days_old) {
                         }                          unlink($user) || warn "$0: Can't unlink $user: $!\n";
                           close(SKEY);
                           next;
                 }                  }
           }
   
                 # Missing hash type?  Must be md4...          # Read in the entry and check its contents.
                 if ($entry[1] =~ /^\d/) {          $entry = <SKEY>;
                         splice(@entry, 1, 0, "md4");          if ($entry !~ /^\S+[\r\n]+\S+[\r\n]+\d+[\r\n]+[A-z0-9]+[\r\n]+[a-f0-9]+[\r\n]+$/) {
                 }                  warn "$0: Invalid entry for $user:\n$entry";
   
                 printf $NEW "%s %s %04d %-16s %s %4s %02d,%-4d %02d:%02d:%02d\n",  
                     $entry[0], $entry[1], $entry[2], $entry[3], $entry[4],  
                     $entry[5], $entry[6], $entry[7], $entry[8], $entry[9],  
                     $entry[10] || do {  
                         warn "Can't write to $temp: $!\n";  
                         unlink($temp);  
                         exit(1);  
                 };  
         }          }
 }  
 close(OLD);  
 close($NEW);  
   
 # Set owner/group/mode on tempfile and move to real location.          close(SKEY);
 ($mode, $nlink, $uid, $gid) = (stat($keyfile))[2..5];  
 if (!defined($mode)) {  
         unlink($temp);  
         die "$0: Unable to stat $keyfile: $!\n";  
 }  }
 if (!chmod($mode, $temp)) {  
         unlink($temp);  
         die "$0: Unable to set mode of $temp to $mode: $!\n";  
 }  
 if (!chown($uid, $gid, $temp)) {  
         unlink($temp);  
         die "$0: Unable to set owner of $temp to ($uid, $gid): $!\n";  
 }  
 if ($nlink != 1) {  
         $nlink--;  
         warn "$0: Old $keyfile had $nlink hard links, those will be broken\n";  
 }  
 # Leave temp file in place if rename fails.  Might help in debugging.  
 rename($temp, $keyfile) || die "$0: Unable to rename $temp to $keyfile: $!\n";  
   
 exit(0);  exit(0);

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3