Report Password File Changes: Listings

Listing 1: Changes in the password file can be detected with diff and report generated by postprocessing the diff output.

A. Listing of the passwdchng program:

 1  #!/usr/bin/perl
 2  # @(#) passwdchng  Report changes to password file since last run
 3  # Author: Chris Wharton, December 1993
 4  # Modified by: Becca Thomas, March 1994
 5  
 6  # Configuration section:
 7  $display_passwd = "cat /etc/passwd";    # Use "ypcat passwd" for NIS
 8  $logdir = "$ENV{'HOME'}/admin/logs";    # Log file directory
 9  $old = "$logdir/passwd.old";            # File from previous run
10  $new = "$logdir/passwd.new";            # File obtained this run
11  
12  # Check logging directory:
13  die "\"$logdir\" is not a writable directory\n"
14      unless (-d $logdir && -w _);
15  
16  # Check for previous password file; if none, create it and abort:
17  unless (-f $old) {
18      system "$display_passwd > $old";
19      die "Can't run \"$display_passwd\" and save output in $old" if $?;
20      die "Run again; no previous passwd file saved for comparison!\n";
21  }
22  
23  # Get current copy of password file:
24  system "$display_passwd > $new";
25  die "Can't run \"$display_passwd\" and save output in $new" if $?;
26  
27  # Make sure both password file copies are readable:
28  die "Can't read \"$old\" file!\n" unless (-r $old);
29  die "Can't read \"$new\" file!\n" unless (-r $new);
30  
31  # Obtain differences between old and new password file:
32  open(DIFF, "diff $old $new |") || die "Can't run diff: $!: stopped";
33  
34  # Store changed lines in one of two associative arrays:
35  while (<DIFF>) {
36      next unless (/^</ || /^>/);     # ignore non-file lines
37      (/^</) ? ($entry = "old") : ($entry = "new");   # old or new entry?
38      chop;                           # remove newline from $_
39      ($line = $_) =~ s/^[<>] //;     # remove angle bracket, save result
40      ($name = $line) =~ s/:.*//;     # store user name
41      ($entry eq "old") ? ($old{$name} = $line) : ($new{$name} = $line);
42  }
43  close(DIFF);
44  
45  # Find old entries with no corresponding new entry (line removed):
46  foreach $name (keys(%old)) {
47      &show($name, "removed") unless ($new{$name});
48  }
49  
50  # Now for each new entry we show any changes from old entry:
51  foreach $name (keys(%new)) {
52      $old{$name} ? &get_changes($old{$name}, $new{$name}) :
53          &show($name, "new entry");
54  }
55  
56  # Overwrite the old copy with the new one to prepare for next run:
57  rename($new, $old) || die "Can't rename $new to $old: $!: stopped";
58  
59  # Display changes between new and old entries:
60  sub get_changes {
61      local($oline, $nline) = @_;     # store parameters as local var.
62  
63      # Split entries into fields:
64      ($oname, $opass, $ouid, $ogid, $ogcos, $ohome, $oshell)
65          = split(":", $oline);
66      ($nname, $npass, $nuid, $ngid, $ngcos, $nhome, $nshell)
67           = split(":", $nline);
68      ($oname ne $nname) && die "$oname != $nname\n"; # names must match
69  
70      # Display changes:
71      ($opass ne $npass)   && &show($name, "password", $opass, $npass);
72      ($ouid ne $nuid)     && &show($name, "user id" , $ouid, $nuid);
73      ($ogid ne $ngid)     && &show($name, "group id" , $ogid, $ngid);
74      ($ogcos ne $ngcos)   && &show($name, "gcos field", $ogcos, $ngcos);
75      ($ohome ne $nhome)   && &show($name, "home dir", $ohome, $nhome);
76      ($oshell ne $nshell) && &show($name, "shell", $oshell, $nshell);
77  }
78  
79  # Show user what happened:
80  sub show {
81      local($name, $reason, $old, $new) = @_;
82  
83      print "$name: $reason";
84      (@_ == 4) ? (print " was '$old', now '$new'\n") : (print "\n");
85  }

B. Some sample output:

dept: gcos field was 'dept. test login', now 'dept. system login'
dmv: shell was '/bin/false', now '/bin/bash'
tbaker: gcos field was 'Tony Baker 61-89-895256', now 'Tony Baker'
picasso: new entry
Print This Page


e-mail Send as e-mail

Research and Reports

Storage Virtualization Guide
May 2012

Network Computing: May 2012

TechWeb Careers