[comp.lang.perl] dbm example and password aging

ling@nosun.west.sun.com (Ling Kan) (03/28/90)

A couple weeks ago someone asked for an example of using dbm, now another
person asked for a password aging program in perl. May be a piece of code I
wrote last year can satisfy both requests. 

This is a perl script that was developed as a toy program, so make sure you
understand it and modify it properly before you use it. (The location of
password database obviously need to be changed.) Also, I am sure perl guru will
correct me of any mistake. 

ps. I remember I wrote the code in least than an hour (and this was the first
time I use dbm) while a guy thinking of using C was certan that it needs
man-days to develop such a utility. I consider this is a perfect example to
illustrate the flexibility of perl. 

--------------------------------pw-aging.pl--------------------------------

#This script does password aging, it uses the associative arrary extensively
#and uses the dbm support in perl verion 3.0.

#It is run every night to check if a user's password is, say 100
#days old. It will also update the password database if any updates have
#occured.

#if the password file can not be found, then create a new one.

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);

if (! -e '/tmp/passwd.dir' || ! -e '/tmp/passwd.pag') {
  print "rebuilt password database\n";
  dbmopen(PASSD,'/tmp/passwd',0666);
  open(PASSF, 'ypcat passwd |');
  while (<PASSF>) {
    if (/CLOSED/) { next; }
    @info = split(/:/);
    $PASSD{$info[0]} = $info[1] . ':' . $yday;
  }
  close(PASSF);
  dbmclose(PASSD);
}

# Update the password database

dbmopen(PASSD,'/tmp/passwd',0666);
open(PASSF, 'ypcat passwd |');
while (<PASSF>) {
    if (/CLOSED/) { next; }
    @info = split(/:/);
    if ($PASSD{$info[0]} eq '') {
      print "Add user $info[0] into the password database\n";
      $PASSD{$info[0]} = $info[1] . ':' . $yday;
      next;
    }
    @old = split(/:/,$PASSD{$info[0]); 
    if ($info[1] ne $old[1]) {
      print "Update the password for user $info[0]\n";
      $PASSD{$info[0]} = $info[1] . ':' . $yday;     
      next;
    }
    if ($yday > ($old[1] + 100)) {    # does not handle year end 
                                      # wrap around.
      print "uesr $info[1]'s password is older than 100 days"
#     take some actions.
    }
}
dbmclose(PASSD);

-----------------------------------------------------------------------------
Name: Ling Kan                       Tel: (503) 690-1386
mail: CADRE Technologies Inc.        e-mail: nosun!microcase!ling    
      19545 N.W. Von Neumann Drive   FAX: (503) 690-1320
      Beaverton, OR 97006