######################################################## # Please file all bug reports, patches, and feature # requests under: # https://sourceforge.net/p/logwatch/_list/tickets # Help requests and discusion can be filed under: # https://sourceforge.net/p/logwatch/discussion/ ######################################################## ######################################################## ## Copyright (c) 2014 Orion Poplawski ## 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. ######################################################### use strict; my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0; my $IgnoreBackendStatus = $ENV{'ignore_backend_status'} || 0; my $IgnoreEnumerationRequested = $ENV{'ignore_enumeration_requested'} || 0; my $OfflineOkay = $ENV{'offline_okay'} || 0; my %CannotContactKDC; my $Domain; my %Errors; my $Realm; my $Service; my %Starts; my %Stops; my %OtherList; my %BackendStatus; my %BackendOffline; my $EnumerationRequested = 0; my $ignore_p11_child_error = 0; # Lines are of the form: # sssd[service]: while (defined(my $ThisLine = )) { next unless $ThisLine =~ /^sssd/; chomp($ThisLine); # Default service, domain $Service = "Daemon"; $Domain = "unknown"; # Strip off pid: $ThisLine =~ s/\[\d+\]: /: /; # Strip off and record the service if any if ($ThisLine =~ s/^sssd\[([^]]+)(?:\[\d+\])?\]: // or $ThisLine =~ s/^sssd_([^:[]+): //) { $Service = ($1 eq "be") ? "Backend[$Domain]" : $1; } # Strip off and record the backend domain if any if ($ThisLine =~ s/^sssd\[be\[([^]]+)\](?:\[\d+\])?\]: //) { $Service = "Backend[$1]"; $Domain = $1; } # Strip off leading sssd: $ThisLine =~ s/^sssd: //; # Strip off duplicate timestamp if present $ThisLine =~ s/^\(... ... .\d \d\d:\d\d:\d\d \d\d\d\d\) //; # Remove []s from debug messages if any $ThisLine =~ s/^\[(\S+)\] /$1 /; $ThisLine =~ s/^\[(\S+)\] /$1 /; # Remove pids from debug messages if any $ThisLine =~ s/\[\d+\]//; # Ignore debug messages my ($debuglevel) = ($ThisLine =~ /\s\((0x[0-9a-f]{4})\):\s/); next if defined($debuglevel) && hex($debuglevel) > 16; if ($ThisLine =~ /Starting up/) { $Starts{$Service}++; } elsif ($ThisLine =~ /^Shutting down/) { $Stops{$Service}++; } elsif ($ThisLine =~ /error/i) { $Errors{$Service}->{$ThisLine}++; } elsif (my ($status) = ($ThisLine =~ /Backend is (.*)/)) { $BackendStatus{$Domain} = $status; $BackendOffline{$Domain}++ if $BackendStatus{$Domain} eq "offline"; } elsif ($ThisLine =~ /^Enumeration requested but not enabled/) { $EnumerationRequested++ unless $IgnoreEnumerationRequested; } elsif ($Service eq "Daemon" && $ThisLine =~ /Keytab successfully retrieved and stored in:/) { # Ignore } elsif ($Service eq "krb5_child" && ( $ThisLine =~ "Preauthentication failed" or $ThisLine =~ "Client's credentials have been revoked")) { # Ignore - these will generate a pam auth failed message } elsif ($Service eq "p11_child" && $ThisLine =~ /Certificate .* not valid .*Certificate key usage inadequate for attempted operation/) { # sssd ssh does not ignore certificates of different types - ignore the errors generated by it $ignore_p11_child_error = 1; } elsif ($Service eq "p11_child" && $ThisLine =~ /do_work failed/ && $ignore_p11_child_error) { } elsif ($Service eq "p11_child" && $ThisLine =~ /p11_child failed/ && $ignore_p11_child_error) { $ignore_p11_child_error = 0; } elsif (($Realm) = ($ThisLine =~ /Cannot contact any KDC for realm '(.*)'/)) { $CannotContactKDC{$Realm}++ unless $OfflineOkay; } else { $OtherList{$Service}{$ThisLine}++; } } if (keys %Errors) { print "\nSSSD ERRORS:\n"; foreach my $Service (sort {$a cmp $b} keys %Errors) { print " $Service:\n"; foreach my $Error (sort {$a cmp $b} keys %{$Errors{$Service}}) { print " $Error: " . $Errors{$Service}->{$Error} . " Time(s)\n"; } } } # sssd will generally start in offline mode, so don't alert if we've just started up foreach $Domain (keys(%BackendOffline)) { if ($BackendOffline{$Domain} and (($Starts{"Backend[$Domain]"} < $BackendOffline{$Domain}) or ($BackendStatus{$Domain} ne "online")) and not $IgnoreBackendStatus) { print "\nSSSD Backend $Domain went offline $BackendOffline{$Domain} Time(s),"; print " and started " . $Starts{"Backend[$Domain]"} . " Time(s),"; print " last status was $BackendStatus{$Domain}\n"; } } if (keys %CannotContactKDC) { print "\nCannot contact any KDC for realm:\n"; foreach my $Realm (sort {$a cmp $b} keys %CannotContactKDC) { print " $Realm: " . $CannotContactKDC{$Realm} . " Time(s)\n"; } } if (keys %Starts and $Detail) { print "\nSSSD Services Started:\n"; foreach my $Service (sort {$a cmp $b} keys %Starts) { print " $Service: " . $Starts{$Service} . " Time(s)\n"; } } if (keys %Stops and $Detail) { print "\nSSSD Services Stopped:\n"; foreach my $Service (sort {$a cmp $b} keys %Stops) { print " $Service: " . $Stops{$Service} . " Time(s)\n"; } } if ($EnumerationRequested) { print "\nEnumeration requested but not enabled: $EnumerationRequested Time(s)\n"; } if (keys %OtherList) { print "\n\n**Unmatched Entries**\n"; foreach my $service (sort {$a cmp $b} keys %OtherList) { print " $service:\n"; foreach my $line (sort {$a cmp $b} keys %{$OtherList{$service}}) { print " $line: $OtherList{$service}{$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: