#!/usr/bin/perl

use strict;
use Getopt::Long;

my ($lock, $unlock, $update, $verbose, %pathdb);

GetOptions('lock'	=> \$lock,
           'unlock'	=> \$unlock,
           'update'	=> \$update);

my $commands = 'basename biff chattr chfn chsh crond date dirname du echo env find in.fingerd grep in.identd ifconfig inetd killall login ls lsattr lsof mail netstat passwd pidof in.pop2d in.pop3d ps pstree realpath rpcinfo in.rshd sendmail ssh ssh-keygen sshd su syslogd tar tcpd in.telnetd in.timed top traceroute who write';
my $pathdbfile = '/root/syspaths';
my $realpath = `which realpath`;
chomp ($realpath);

unless ($lock || $unlock || $update || (!-e $pathdbfile))
{
    &usage;
    exit (0);
}

if ($lock && $unlock)
{
    &usage;
    exit (0);
}


die "WARNING!!!  $pathdbfile is a symbolic link!  Aborting.\n" if (-l $pathdbfile);

&chattr('-i') if ($unlock && -f $pathdbfile);
unlink ($pathdbfile) if ($update && -f $pathdbfile);
&update if ($update || (! -f $pathdbfile));
&chattr('+i') if ($lock);

exit (0);


sub update
{
    dbmopen (%pathdb, $pathdbfile, 0600) || die "Cannot open $pathdbfile.\n";
    print "\nSearching for key system commands:\n";
    foreach my $cmd (split (/ /, $commands))
    {
        my $path = `which $cmd`;
        chomp ($path);
        unless ($path =~ /^which:/)
        {
            $path = `$realpath $path`;
            chomp ($path);
            $pathdb{$cmd} = $path;
            my $attr = `lsattr $path`;
            chomp ($attr);
            printf ("\t%-12s:   %s\n", $cmd, $attr);
        }
    }
    print "\n";
    dbmclose (%pathdb);
}


sub chattr
{
    my ($mode) = @_;
    dbmopen (%pathdb, $pathdbfile, 0600) || die "Cannot open $pathdbfile.\n";
    my $chattr = $pathdb{'chattr'};
    my $lsattr = $pathdb{'lsattr'};
    foreach my $cmd (sort(keys(%pathdb)))
    {
        my $path = $pathdb{$cmd};
        system(split(/ /, "$chattr $mode $path"));
        my $attr = `$lsattr $path`;
        chomp ($attr);
        printf ("\t%-12s:   %s\n", $cmd, $attr);
    }
    dbmclose (%pathdb);
}


sub usage
{
    print "Usage:\tsysfiles -update\tRebuild the path database\n";
    print "\tsysfiles -lock\t\tFlag key system files immutable\n";
    print "\tsysfiles -unlock\tClear immutable attributes\n";
}
