########################################################################## # $Id: pam_pwdb,v 1.22 2008/03/24 23:31:26 kirk Exp $ ########################################################################## ##################################################### ## Copyright (c) 2008 Kirk Bauer ## Covered under the included MIT/X-Consortium License: ## http://www.opensource.org/licenses/mit-license.php ## All modifications and contributions by other persons to ## this script are assumed to have been donated to the ## Logwatch project and thus assume the above copyright ## and licensing terms. If you want to make contributions ## under your own copyright or a different license this ## must be explicitly stated in the contribution an the ## Logwatch project reserves the right to not accept such ## contributions. If you have made significant ## contributions to this script and want to claim ## copyright please contact logwatch-devel@lists.sourceforge.net. ######################################################### # NOTE: This script is for older (6.X era) Red Hat boxes $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0; while (defined($ThisLine = <STDIN>)) { if ( ( $ThisLine =~ /(.*) session closed for user .*$/ ) or ( $ThisLine =~ /^Logout user .* host .*$/ ) or ( $ThisLine =~ /^log: Password authentication/ ) or # apparently SSHD messages ( $ThisLine =~ /^log: Closing connection/ ) or # apparently SSHD messages ( $ThisLine =~ /^check pass; user unknown/ ) or ( $ThisLine =~ /^User account has expired/ ) or # This one is caught below (2-line message) ( $ThisLine =~ /^get passwd; pwdb: structure is no longer valid$/) or ( $ThisLine =~ /^fatal: Read error from remote host: Connection reset by peer$/) or ( $ThisLine =~ /^new password not acceptable$/ ) or ( $ThisLine =~ /^FTP session closed$/) or ( $ThisLine =~ /^FTP LOGIN REFUSED/) or ( $ThisLine =~ /^FAILED LOGIN SESSION FROM \S+ FOR , Error in service module/) or ( $ThisLine =~ /^FTP LOGIN FROM/ ) # I will let ftpd handle FTP messages.... ) { # We don't care about these } elsif ( $ThisLine =~ /password for \(.*\) changed by \(.*\)$/ ) { chomp($ThisLine); push @PWChanges, $ThisLine; } elsif ( ($RemoteHost,$User) = ( $ThisLine =~ /^failed login from ([^ ]+) \[.*\], ([^ ]+)$/) or ($RemoteHost,$User) = ( $ThisLine =~ /^Login failure user=(\S+) host=([^ ]+)$/) ) { chomp ($User); push @{$FailedLogins{$RemoteHost}}, $User; } elsif ( $ThisLine =~ s/auth could not identify password for \[([^ ]+)\]$/$1/ ) { chomp ($ThisLine); $CouldNotIDPW{$ThisLine}++; } elsif ( $ThisLine =~ s/^expiry check failed for \'([^ ]+)\'/$1/ ) { # user account expired? chomp($ThisLine); push @Expired, $ThisLine; } elsif ( $ThisLine =~ s/bad username \[(.*)\]$/$1/ ) { chomp($ThisLine); push @BadName, $ThisLine; } elsif ( ($StartName,$StartUID,$EndName,$ServiceName) = ( $ThisLine =~ m/authentication failure.*; ([^ ]*)\(uid=(\d+)\) -> ([^ ]+) for ([^ ]+) service$/ ) ) { $StartName = " " if (!$StartName); $ThisKey = $StartName . "(uid=" . $StartUID . ") -> " . $EndName; $AuthFailures{$ThisKey}{$ServiceName}++; } elsif ( ($Num,$StartName,$StartUID,$EndName,$ServiceName) = ( $ThisLine =~ m/^(\d+) authentication failure.*; ([^ ]*)\(uid=(\d+)\) -> ([^ ]+) for ([^ ]+) service$/ ) ) { $StartName = " " if (!$StartName); $ThisKey = $StartName . "(uid=" . $StartUID . ") -> " . $EndName; $AuthFailures{$ThisKey}{$ServiceName}+=$Num; } elsif ( ($ThisKey,$ServiceName) = ( $ThisLine =~ /([^ ]+) authentication failed for ([^ ]+)$/ ) ) { chomp($ThisKey); chomp($ServiceName); $AuthFailures{$ThisKey}{$ServiceName}++; } elsif ( ($RemoteHost, $User) = ( $ThisLine =~ m/^FAILED LOGIN .* FROM ([^ ]+) FOR (.+), .*$/ ) ) { push @{$FailedLogins{$RemoteHost}}, $User; } elsif ( $ThisLine =~ s/^ROOT LOGIN ON ([^ ]+)/$1/ ) { chomp ($ThisLine); $RootLogins{$ThisLine}++; } elsif ( ($User,$From) = ( $ThisLine =~ /^LOGIN ON [^ ]+ BY ([^ ]+) FROM ([^ ]+)$/ ) or ($User,$From) = ( $ThisLine =~ /^Login user=([^ ]+) host=([^ ]+)$/ ) ) { chomp ($From); ${$RemoteLogins{$User}}{$From}++; } elsif ( $ThisLine =~ s/^LOGIN ON [^ ]+ BY ([^ ]+$)/$1/ ) { chomp ($ThisLine); $LocalLogins{$ThisLine}++; } elsif ( ($ServiceName,$StartName,$StartUID,$EndName) = ( $ThisLine =~ m/([^ ]+)\[[0-9]+\]:\s+authentication\s+failure;\s*logname=([^ ]+)\s+uid=([^ ]+).*user=([^ ]+)/ ) ) { $StartName = " " if (!$StartName); $ThisKey = $StartName . "(uid=" . $StartUID . ") -> " . $EndName; $AuthFailures{$ThisKey}{$ServiceName}++; } elsif ( ($Service, $User, $Orig) = ( $ThisLine =~ /^\((.*)\) session opened for user ([^ ]+) by (.*\(uid=.*\))/ ) ) { if (( $Service eq "su" ) and ($Orig =~ /[^ ]+\(uid=.*\)$/)) { $Temp = " " . $Orig . " -> " . $User; $SUList{$Temp}++; } else { ${$OpenedSessions{$Service}}{$User}++; } } else { # Report any unmatched entries... chomp($ThisLine); $OtherList{$ThisLine}++; } } if (keys %SUList) { print "\nSU Sessions:\n"; foreach $SU (keys %SUList) { print " " . $SU . " - " . $SUList{$SU} . " Time(s)\n"; } } if (($Detail >= 10) and (keys %CouldNotIDPW)) { print "\nCould not identify password for:\n"; foreach $User (keys %CouldNotIDPW) { print " " . $User . " - " . $CouldNotIDPW{$User} . " Time(s)\n"; } } if (@PWChanges) { print "\nPassword Changes:\n"; foreach $Change (@PWChanges) { print " " . $Change . "\n"; } } if (($Detail >= 5) and (@BadName)) { print "\nBad Usernames Received:\n"; foreach $User (@BadName) { print " " . $User . "\n"; } } if (@Expired) { print "\nExpired User Accounts:\n"; foreach $User (@Expired) { print " " . $User . "\n"; } } if (keys %OpenedSessions) { print "\nOpened Sessions:\n"; foreach $Service (keys %OpenedSessions) { print " Service: " . $Service . "\n"; foreach $User (keys %{$OpenedSessions{$Service}}) { print " User " . $User . " - " . ${$OpenedSessions{$Service}}{$User} . " Time(s)\n"; } } } if (keys %RemoteLogins) { print "\nRemote Logins:\n"; foreach $User (keys %RemoteLogins) { print " User " . $User . ":\n"; foreach $Remote (keys %{$RemoteLogins{$User}} ) { print " Remote Host " . $Remote . " - " . ${$RemoteLogins{$User}}{$Remote} . " Time(s)\n"; } } } if (keys %LocalLogins) { print "\nLocal Logins:\n"; foreach $User (keys %LocalLogins) { print " " . $User . " - " . $LocalLogins{$User} . " Time(s)\n"; } } if (keys %RootLogins) { print "\nRoot Logins:\n"; foreach $tty (keys %RootLogins) { print " " . $tty . ": " . $RootLogins{$tty} . " time(s)\n"; } } if (($Detail >= 5) and (keys %AuthFailures)) { print "\nAuthentication Failures:\n"; foreach $Users (keys %AuthFailures) { print " " . $Users . "\n"; foreach $Service (keys %{$AuthFailures{$Users}}) { print " Service: " . $Service . ": " . ${$AuthFailures{$Users}}{$Service} . " time(s)\n"; } } } if (($Detail >= 5) and (keys %FailedLogins)) { print "\nLogin Failures:\n"; foreach $RemoteHost (keys %FailedLogins) { print " " . $RemoteHost . ": "; foreach $User ( @{$FailedLogins{$RemoteHost}} ) { print $User . ", "; } print "\n"; } } if (keys %OtherList) { print "\n**Unmatched Entries**\n"; foreach $line (sort {$a cmp $b} keys %OtherList) { print "$line: $OtherList{$line} Time(s)\n"; } } exit(0); # vi: shiftwidth=3 tabstop=3 syntax=perl et # Local Variables: # mode: perl # perl-indent-level: 3 # indent-tabs-mode: nil # End: