###########################################################################
# $Id: sudo,v 1.9 2005/09/26 18:11:50 mike Exp $
###########################################################################

###########################################################################
# sudo: A logwatch script to collate and format sudo log entries from
#       the secure log. Entries are broken down by the user who issued
#       the command, and further by the effective user of the command.
#
#       Detail Levels:
#        0: Just print the command
#       20: Include the current directory when the command was executed
#           (on a separate line)
#       30: Include the TTY on the directory line
###########################################################################

use strict;

my ($Debug,  $Detail,  %byUser, %byUserSum);
my $Debug = $ENV{'LOGWATCH_DEBUG'} || 0;
my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0;
# maximum number of commands user ran to display at low detail
my $CmdsThresh = $ENV{'command_run_threshold'} || 0;

while (defined(my $ThisLine = <STDIN>)) {
   if ( $ThisLine =~ m/^\s*(\w+) : TTY=(\S+) ; PWD=(.*?) ; USER=(\w+) ; COMMAND=(\S+)( ?.*)/) {
      my ($user, $tty, $dir, $euser, $cmd, $args) = ($1, $2, $3, $4, $5, $6);
      push @{$byUser{$user}{$euser}}, [$cmd,$args, $dir, $tty];
      $byUserSum{$user}{$euser}{$cmd} += 1;
   }

}

foreach my $user (sort keys %byUser) {
   print "=" x 78, "\n";
   foreach my $euser (sort keys %{$byUser{$user}}) {
      print "$user => $euser\n", "-" x 78, "\n";
      foreach my $cmd (sort keys %{$byUserSum{$user}{$euser}}) {
         if ($Detail <= 10 && $CmdsThresh <= $byUserSum{$user}{$euser}{$cmd}) {
            print "$cmd - $byUserSum{$user}{$euser}{$cmd} Times.\n";
          } # if $Detail <= 10
      } # foreach $gcmd
      foreach my $row (@{$byUser{$user}{$euser}}) {
         if ($Detail > 10 || $CmdsThresh > $byUserSum{$user}{$euser}{$$row[0]}) {
            my ($gcmd,$args, $dir, $tty) = @$row;
            my $cmd = "$gcmd$args";
            # make long commands easier to read
            $cmd =~ s/(?=.{74,})(.{1,74}) /${1} \\\n    /g if (length($cmd) > 75);
            print "$cmd\n";
            if ($Detail > 20) {
               my $ttydetail = "";
               $ttydetail = "($tty) " if $Detail >= 30;
               print "\t$ttydetail$dir\n";
            } # if $Detail > 20
         } # if $Detail > 10
      } # foreach $row
   } # foreach $euser
} # foreach $user

# vi: shiftwidth=3 tabstop=3 syntax=perl et
