#!/usr/local/bin/perl -w # $Id: repinactive,v 1.6 2004/03/10 19:23:22 scott Exp $ package repinactive; use strict; use Date::Manip; use Getopt::Long; use Pod::Usage; $| = 1; # Signal-trapping $SIG{'INT'} = sub { warn "Caught INT; exiting\n"; exit; }; $SIG{'TERM'} = sub { warn "Caught TERM; exiting\n"; exit; }; my $self = repinactive->_init(); GetOptions ( 'a' => \$self->{'a'}, 'h' => \$self->{'h'}, 'i=s' => \$self->{'i'}, 't=s' => \$self->{'t'} ); # Display perldoc if -h specified $self->{'h'} and do { pod2usage('-verbose' => 2); exit; }; # Die if no options received !($ARGV[0] || $self->{'a'}) and do { pod2usage(); exit; }; $self->{'t'} ||= '90days'; # Create user hash of ignored users if -i specified $self->{'i'} and do { open IG, $self->{'i'} or die "Error opening ignore list: $!\n"; while () { chomp; $self->{'u'}->{"$_"}->{'ignore'} = 1; } close IG; }; # Get list of users if ($self->{'a'}) { open PW, '/etc/passwd'; while () { chomp; push @{$self->{'p'}}, $1 if /^(.+?):/; } close PW; } else { map { push @{$self->{'p'}}, $_; } @ARGV; } foreach my $user (@{$self->{'p'}}) { # Finger user my $last = qx(/usr/bin/finger $user); # Get real name (if avail) if ($last =~ /In real life: (.*)\/{0,}/) { $self->{'u'}->{"$user"}->{'name'} = $1; } else { $self->{'u'}->{"$user"}->{'name'} = '??'; } # Determine last login time for ($last) { # Currently online; don't disable /On since/ && do { $self->{'u'}->{"$user"}->{'last'} = 'now'; }; # Never logged in; grounds for disabling /Never logged in/ && do { $self->{'u'}->{"$user"}->{'last'} = 'never'; $self->{'u'}->{"$user"}->{'rm'} = '1'; }; # Determine if last login is within the last 90 days /Last login (.+?) on/ && do { $self->{'u'}->{"$user"}->{'last'} = $1; if (Date_Cmp( DateCalc('today', "-$self->{'t'}"), ParseDate($1) ) == 1) { $self->{'u'}->{"$user"}->{'rm'} = '1'; } }; } } # Display report chomp(my $hostname = qx(/usr/bin/hostname)); print "The following users have not logged into $hostname " . "in the last 90 days:\n\n"; printf "%-15s %-30s %-20s\n\n", 'User', 'Full name (if avail)', 'Last login'; foreach (keys %{$self->{'u'}}) { next unless $self->{'u'}->{"$_"}->{'rm'}; next if $self->{'u'}->{"$_"}->{'ignore'}; printf "%-15s %-30s %-20s\n", $_, $self->{'u'}->{"$_"}->{'name'}, $self->{'u'}->{"$_"}->{'last'}; } # Initialize sub _init { return bless {}, shift; } =head1 NAME repinactive - summarize inactive user accounts =head1 SYNOPSIS repinactive [ -hit ] <-a || user1 user2 ...> =head1 DESCRIPTION B prints a summary of accounts deemed 'inactive' (see -t option). =head1 OPTIONS =over 4 =item -h View this perldoc. =item -i Ignore (exclude) all users listed in from the report. =item -t Specify an inactivity period. Defaults to '90days'. Note that this must be in valid L format. =item -a Report on all user accounts in /etc/passwd. =back =head1 USAGE repinactive -i /etc/passwd.ignore -t 30days -a =head1 SEE ALSO L =head1 AUTHOR Scott Schneider, scott@loserfish.org =cut 1;