#!/usr/bin/perl -w
use strict;
##########################################################################
# $Id: pam_unix,v 1.14 2004/06/21 14:59:05 kirk Exp $
##########################################################################
# $Log: pam_unix,v $
# Revision 1.14  2004/06/21 14:59:05  kirk
# Added tons of patches from Pawe? Go?aszewski" <blues@ds.pg.gda.pl>
#
# Thanks, as always!
#
# Revision 1.13  2004/02/03 02:45:26  kirk
# Tons of patches, and new 'oidentd' and 'shaperd' filters from
# Pawe? Go?aszewski" <blues@ds.pg.gda.pl>
#
##########################################################################

########################################################
# This was written and is maintained by:
#    Kirk Bauer <kirk@kaybee.org>
#
# Please send all comments, suggestions, bug reports,
#    etc, to kirk@kaybee.org.
########################################################

use Logwatch ':sort';

my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0;

my ($service, $line, %data);

while ($line = <STDIN>) {
	chomp $line;
	$service = $line;
	if ($line =~ s/^... .. ..:..:.. .+ .+\(pam_unix\)\[\d+\]: //) {
		$service =~ s/^... .. ..:..:.. .+ (.+)\(pam_unix\)\[\d+\]: .*$/$1/;
	} else {
		next;
	}
	if (($service eq 'sshd') or ($service eq 'login') or ($service eq 'ftp')) {
		if ($line =~ s/^session opened for user (.+) by \(uid=\d+\)/$1/) {
			($Detail >= 5) && $data{$service}{'Sessions Opened'}{$line}++;
      } elsif ($line =~ s/^session opened for user ([^ ]*) by ([^ ]*)\(uid=\d+\)/$1 by $2/) {
         ($Detail >= 5) && $data{$service}{'Sessions Opened'}{$line}++;
		} elsif ($line =~ s/^session opened for user (.+) by LOGIN\(uid=\d+\)/$1/) {
			$data{$service}{'Sessions Opened'}{$line}++;
		} elsif ($line =~ /session closed for user/) {
			# ignore this line
		} elsif ($line =~ s/^authentication failure; .*rhost=([^ ]*)\s+user=([^ ]*)$/$2 ($1)/) {
			$data{$service}{'Authentication Failures'}{$line}++;
      } elsif ($line =~ s/^authentication failure; .*rhost=([^ ]*).$/unknown ($1)/) {
         $data{$service}{'Authentication Failures'}{$line}++;
      } elsif ($line =~ s/^(\d+) more authentication failure; .*rhost=(.+)\s+user=(.+)$/$2 ($1)/) {
         $data{$service}{'Authentication Failures'}{$line}++;
      } elsif ($line =~ s/^(\d+) more authentication failure; .*rhost=(.+)$/unknown ($1)/) {
         $data{$service}{'Authentication Failures'}{$line}++;
      } elsif ($line =~ /check pass; user unknown/) {
         $data{$service}{'Invalid Users'}{'Unknown Account'}++;
      } elsif ($line =~ s/^password changed for (.+)/$1(by sshd)/) {
         ($Detail >= 5) && $data{passwd}{'Password changed'}{$line}++;
      } elsif ($line =~ s/^account (.+) has expired (failed to change password)$/$1/) {
         $data{$service}{'Expired Accounts'}{$line}++;
      } elsif ($line =~ s/bad username \[(.*)\]/$1/) {
         $data{$service}{'Invalid Users'}{"Bad User: $line"}++;
      } else {
         $data{$service}{'Unknown Entries'}{$line}++;
      }
   } elsif ($service eq 'su') {
      if ($line =~ s/^authentication failure; logname=(.+) uid=(\d+) .*user=(.+)$/$1($2) -> $3/) {
         $data{$service}{'Authentication Failures'}{$line}++;
      } elsif ($line =~ /session closed for user/) {
         # ignore this line
      } elsif ($line =~ s/session opened for user (.+) by (.+)$/$2 -> $1/) {
         $data{$service}{'Sessions Opened'}{$line}++;
      } else {
         $data{$service}{'Unknown Entries'}{$line}++;
      }
   } elsif ($service eq 'passwd') {
      if ($line =~ s/^password changed for (.+)/$1/) {
         ($Detail >= 5) && $data{$service}{'Password changed'}{$line}++;
      }
   } elsif ($service eq 'poppassd') {
      if ($line =~ s/^password changed for (.+)/$1/) {
         ($Detail >= 5) && $data{$service}{'Password changed'}{$line}++;
      }
   } elsif ($service eq 'gdm') {
      if ($line =~ s/^session opened for user (.+) by \(uid=\d+\)/$1/) {
         ($Detail >= 5) && $data{$service}{'Sessions Opened'}{$line}++;
      } elsif ($line =~ /session closed for user/) {
         # ignore this line
      } else {
         $data{$service}{'Unknown Entries'}{$line}++;
      }
   } elsif ($service eq 'kdm') {
     if ($line =~ s/^session opened for user (.+) by \(uid=\d+\)/$1/) {
        ($Detail >= 5) && $data{$service}{'Sessions Opened'}{$line}++;
     } elsif ($line =~ /session closed for user/) {
        # ignore this line
     }
 } elsif ($service eq 'xdm') {
	 if ($line =~ s/^session opened for user (.+) by \(uid=\d+\)/$1/) {
		 ($Detail >= 5) && $data{$service}{'Sessions Opened'}{$line}++;
	 } elsif ($line =~ /session closed for user/) {
		 # ignore this line
	 }
   } elsif ($service eq 'imap') {
      if ($line =~ s/^authentication failure; .*user=(.+)$/$1/) {
		   $data{$service}{'Authentication Failures'}{$line}++;
	   } else {
		   $data{$service}{'Unknown Entries'}{$line}++;
	   }
   } elsif ($service eq 'spop3d') {
	   if ($line =~ s/^session opened for user (.+)/$1/) {
		   $data{$service}{'Sessions Opened'}{$line}++;
	   } elsif ($line =~ /session closed for user/) {
		   # ignore this line
      } elsif ($line =~ s/^authentication failure; .*user=(.+)$/$1/) {
		   $data{$service}{'Authentication Failures'}{$line}++;
      } elsif ($line =~ s/^account (.+) has expired (failed to change password)$/$1/) {
         $data{$service}{'Expired Accounts'}{$line}++;
	   } else {
		   $data{$service}{'Unknown Entries'}{$line}++;
	   }
   } elsif ($service eq 'pure-ftpd') {
      if ($line =~ s/^session opened for user (.+)/$1/) {
         $data{$service}{'Sessions Opened'}{$line}++;
      } elsif ($line =~ s/^check pass; (.+)/$1/) {
         $data{$service}{'Password Failures'}{$line}++;
      } else {
         $data{$service}{'Unknown Entries'}{$line}++;
      }
   } elsif ($service eq 'xscreensaver') {
      if ($line =~ s/^authentication failure; .*uid=(\d+) euid=(\d+) tty=(.+) ruser= rhost=  user=(.+)$/$4($1,$2) on display $3/) {
         $data{$service}{'Authentication Failures'}{$line}++;
      }
   } elsif ($service eq 'cron') {
	   if ($line =~ s/^session opened for user (.+) by \(uid=\d+\)/$1/) {
		   ($Detail >= 5) && $data{$service}{'Sessions Opened'}{$line}++;
	   } elsif ($line =~ /session closed for user/) {
		   # ignore this line
	   } else {
		   $data{$service}{'Unknown Entries'}{$line}++;
	   }
   } elsif ($service eq 'cyrus') {
      if ($line =~ /check pass; user unknown/) {
         $data{$service}{'Invalid Users'}{'Unknown Account'}++;
      } elsif ($line =~ /authentication failure; logname= uid=0 euid=0 tty= ruser= rhost=/) {
         # ignore this line
      } else {
         $data{$service}{'Unknown Entries'}{$line}++;
      }
   } elsif ($service eq 'samba') {
      if ($line =~ s/^session opened for user ([a-zA-Z\d]+) by (.+)/$1/) {
         ($Detail >= 5) && $data{$service}{'Sessions Opened'}{$line}++;
      } elsif ($line =~ s/^session closed for user (.+)/$1/) {
         ($Detail >= 8) && $data{$service}{'Sessions Closed'}{$line}++;
      } else {
         $data{$service}{'Unknown Entries'}{$line}++;
      }
   } else {
      $data{$service}{'Unknown Entries'}{$line}++;
   }
}

foreach my $service (sort {$a cmp $b} keys %data) {
   print "$service:\n";
   foreach my $type (sort {$a cmp $b} keys %{$data{$service}}) {
      print "   $type:\n";
      my $sort = CountOrder(%{$data{$service}{$type}});
      foreach my $entry (sort $sort keys %{$data{$service}{$type}}) {
         print "      $entry: $data{$service}{$type}{$entry} Time(s)\n";
      }
   }
   print "\n";
}

exit(0);

# vi: shiftwidth=3 tabstop=3 et

