#!/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 (<IG>) { chomp; $self->{'u'}->{"$_"}->{'ignore'} = 1; }
close IG;
};
# Get list of users
if ($self->{'a'}) {
open PW, '/etc/passwd';
while (<PW>) { 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'}->{"$_"}->{'la
+st'};
}
# Initialize
sub _init { return bless {}, shift; }
=head1 NAME
repinactive - summarize inactive user accounts
=head1 SYNOPSIS
repinactive [ -hit ] <-a || user1 user2 ...>
=head1 DESCRIPTION
B<repinactive> 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 <file> from the report.
=item -t
Specify an inactivity period. Defaults to '90days'. Note that this m
+ust be in
valid L<Date::Manip> 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<Date::Manip>
=head1 AUTHOR
Scott Schneider, scott@loserfish.org
=cut
1;
|