#! /usr/bin/perl

use warnings;
use strict;
use Sys::Syslog;

###############################################################
#
# Purpose: detect unusual commands issued by a daemon user
#          (such as the webserver, mail server, etc.)
# 
# (1) Switch on process accounting
# (2) Update the table 'table' below with expected commands 
#     for system users:
#     'username' => [ "command1", "command2", ...],
#     see examples for dovecot and postfix
# (3) always run this script just before the process accounting
#     logs are rotated
#     (e.g. on debian/ubuntu, run the script from /etc/cron.daily/acct
#     before the 'savelog' command)
# 
my %table = (
    'postfix'  => [ "anvil", "bounce", "cleanup", "flush", "scache", "smtp", "smtpd", "tlsmgr", "trivial-rewrite", "pickup", "postfix", "proxymap", "showq", "qmgr" ],
    'dovecot'  => [ "imap-login", "dovecot", "pop3-login", "scache" ],
    );

my $user;
my $exitval = 0;

openlog ("lastcomm", "pid", "LOG_DAEMON");

foreach $user (keys %table) {

    my @commands = @{$table{$user}};

    open (INFILE, "/usr/bin/lastcomm $user |") 
	or die "Cannot execute lastcomm $user: $!";

    while (<INFILE>) {

	my $test = 0;
	my @list = split;
	my $item;
	for $item (@commands) {
	    if ($list[0] eq ${item}) {
		$test = 1;
		last;
	    }
	}
	if ($test == 0) {
	    printf ("Bad command for %s: %s\n", $user, $list[0]);
	    syslog ("LOG_INFO", "Bad command for %s: %s\n", $user, $list[0]);
	    $exitval = 1;
	}
    }
    close INFILE;
}

closelog();

exit $exitval;
