#!/usr/bin/perl -w
###########################################################################
# Global definitions
###########################################################################
use Getopt::Long;
$tmpdir="/usr/tmp/integrit.$$";
$usrtmp="/usr/tmp/integrit_tmp.$$";
$filedir="$tmpdir/filedir";
$integrit_conf="$tmpdir/integrit.conf";
$integrit="/usr/local/sbin/integrit";
$knowndb="/tmp/tsecdb";
$remcurrentdb="/tmp/databases/integrit.cdb.new";
$currentdb="/tmp/databases";
$remdb="/tmp/tsecdb/integrit.cdb";
$inststuff="/ccrun/etc/inststuff.pl";
###########################################################################
#command
###########################################################################
#$scp="/usr/bin/scp";
#$ssh="/usr/local/bin/ssh";
#$rsync="/usr/bin/rsync";
#$integrit="/usr/bin/integrit";
$scp="/usr/local/bin/scp";
$ssh="/usr/local/bin/ssh";
$rsync="/usr/local/bin/rsync";
$integrit="/usr/local/sbin/integrit";
$rsync_cmd="$rsync -Rapzq --partial -e $ssh";
$rsync_del="$rsync -lvrnc --delete -e $ssh";
$rsync_exist="$rsync -lvrnc --existing -e $ssh";
###########################################################################
# Check for help request. Display help page if --help/-h/-? was passed.
###########################################################################
sub help_page {
my $programname = $0;
$programname =~ s#^\./##;
print("$programname - .Usage: $programname <-r hostname>[-i Ign]Options are interpreted as follows:-r hostname remote hostname\
-i Ign Ignores default setting.For example: \
$programname -r enghp3\n");
exit 1;
}
###########################################################################
# Check and update local configuration
###########################################################################
sub LocalVarExists ($)
{
my ($name) = @_;
return $main::{$name}; # if integrit_conf declared it, we're done.
}
my $newstuff = "";
sub LocalVar ($$)
{
my ($name, $definition) = @_;
return if $main::{$name};
$newstuff .= " " . $name;
open FILE, '>>', $integrit_conf;
print FILE $definition, "\n\n";
close FILE;
}
###########################################################################
# Check data directory
###########################################################################
sub Checkdir()
{
#Check tmp directory
unless (-d $tmpdir)
{
print "Creating tmp directory ($tmpdir) ...\n";
mkdir $tmpdir, 0770;
}
unless (-d $usrtmp)
{
print "Creating tmp directory ($usrtmp) ...\n";
mkdir $usrtmp, 0770;
}
unless (-d $knowndb)
{
print "Creating knowndb directory ($knowndb) ...\n";
mkdir $knowndb, 0770;
}
#unless (-d $datadir) {
# print "Creating data directory ($datadir) ...\n";
# mkdir $datadir, 0770;
#}
###########################################################################
#create integrit.conf
###########################################################################
unless (-e $integrit_conf){
LocalVar('root_dir', <<'END');
# integrit.conf -*- fundamental -*-
#
root=/
END
LocalVar('database', <<'END');
known=/tmp/tsecdb/integrit.cdb
current=/tmp/databases/integrit.cdb.new
END
LocalVar('README', <<'END');
# from the integrit README file:
#
# Here's a table of letters and the corresponding checks / options:
#
# s checksum
# i inode
# p permissions
# l number of links
# u uid
# g gid
# z file size (redundant if checksums are on)
# a access time
# m modification time
# c ctime (time UN*X file info last changed)
# r reset access time (use with care)
#
# Upper case turus off a given check, Lower case turns it on.
#
# Files whose contents are expected to change only get checks on
# permissions, user owner and group owner of the file.
END
LocalVar('SIMC', <<'END');
#
# For /root/
#
!/root
!/dev
!/var
!/tmp
!/mnt
!/.security
!/home
!/ora_system
!/redund
!/stand
!/tcb
!/mnt
!/etc
!/opt/hpws/tomcat
!/opt/hpwebadmin
!/opt/ignite
!/usr/goldimage
!/usr/adm
!/usr/mail
!/usr/spool
!/usr/tmp
!/usr/lost+found
!/usr/preserve
!/usr/spool
!/usr/pub
!/usr/share/man
!/usr/share/doc
!/usr/share/html
!/usr/local/man
!/usr/local/info
!/usr/local/doc
!/usr/local/oracle
!/usr/local/src
!/opt/samba_src
!/opt/java1.3
!/opt/mozilla
#
# For /etc/
#
!/etc/mtab SIMC
!/etc/ssh_random_seed
!/etc/fstab
!/etc/mnttab
!/etc/utmp
!/etc/rc.config.d
!/etc/ipf/ipmon.pid
!/etc/opt/ldapux
!/etc/opt/mx
!/etc/sfd.pid
!/etc/ftpd
!/etc/MANPATH
!/etc/PATH
!/etc/skel
!/etc/pam.conf
!/etc/default
!/etc/useracct
!/etc/utmps
!/etc/utmps
!/etc/shutdownlog
!/etc/issue
!/etc/syslog.conf
#/etc CMPILUGA
#--------------nfs directories
!/mnt/secdb
!/barhost-home
!/adm/barhost-cgi
END
LocalVar('Nocheck', <<'END');
#--------this one gets over-written at boot, so only report changes
# in its contents
# No Check. The infomation is local filesystem info which depend on local host.
!/etc/lvmconf
!/etc/lvmrc
!/etc/lvmtab
!/etc/lvm*
!/etc/vxvmconf
!/etc/vx
!/dev/vx
!/var/vx
!/usr/tmp
!/dev/vg*
!/dev/vxportal
!/etc/.profile.*
!/etc/fstab
!/etc/aliases
!/etc/oratab
!/etc/passwd
!/etc/group
!/etc/opt/resmon
!/etc/hosts
!/etc/publickey
!/etc/rc.config.d/netconf
!/etc/ioconfig
!/stand
END
LocalVar('checkdir', <<'END');
#: Check dir.
/opt CMPILUGA
/bin CMPILUGA
#/etc CMPILUGA
/lib CMPILUGA
/net CMPILUGA
/sbin CMPILUGA
/usr CMPILUGA
/pcrelease CMPILUGA
END
}
unless (-d $knowndb && -d $currentdb)
{
print "Creating known db directory or current db directory ...\n";
mkdir $knowndb, 0770;
mkdir $currentdb, 0770;
}
}
sub GetParas
{
my ($argv);
$argv = join(' ',@ARGV);
$argv = join(' ',@ARGV);
my $tmp = 0;
&help_page if ( $argv eq "" || $argv =~ m!-h! );
GetOptions("r:s","i=s");
if ($opt_r eq "")
{
&help_page;
exit(1);
}
if (! $opt_i eq "")
{
$tmp = $opt_i;
}
return ($opt_r,$tmp);
}
sub Env{
if ($> != 0)
{
print ("\nThe command need root permission!\n\n");
exit(1);
}
}
sub dbsh ($$){
my ($name, $definition) = @_;
return if $main::{$name};
$newstuff .= " " . $name;
open FILE, '>>', "$tmpdir/createdb.sh";
print FILE $definition, "\n\n";
close FILE;
}
###########################################################################
#create creatdb.sh
###########################################################################
sub newdbsh{
dbsh('createdbsh', <<'END');
#!/bin/bash
#Define work direction and command
integrit_conf=`pwd`/integrit.conf
integrit=/usr/local/sbin/integrit
#scp=/usr/bin/scp
#tmpdir=/usr/tmp/integrit.$$
currentdir=/tmp/databases/
currentdb=/tmp/databases/integrit.cdb.new
#if [ ! -d $tmpdir ]; then
# echo Creating $tmpdir directory >&2
# mkdir -p $tmpdir
#fi
if [ ! -d $currentdir ]; then
echo Creating $currentdir directory >&2
mkdir -p $currentdir
fi
ls -l / |grep "^d" |awk '{print "!/"$9}' |grep -v "usr" |grep -v "opt" |grep -v "home"|grep -v "var" |grep -v "root" |grep -v "sbin"|grep -v "bin" |grep -v "net" |grep -v "^dev"| grep -v "etc" |grep -v "lib" | grep -v "pcrelease" >>$integrit_conf
$integrit -u -C $integrit_conf
END
}
###########################################################################
#Check host
###########################################################################
sub Checkhost()
{
my ($thost) = @_;
print "Warning - remote system is $thost- are you sure? (Y/N) ";
my $tmp = <STDIN>;
if ($tmp eq "Y" && $tmp eq "y")
{
print "remote system is $thost\n";
}
else
{
exit 1;
}
}
###########################################################################
#Get remote host db file
###########################################################################
sub Getdb
{
my ($rhost) = @_;
&newdbsh;
system("ssh $rhost -l root '. /etc/.profile; mkdir $tmpdir'");
system("$scp $tmpdir/createdb.sh root\@$rhost:$tmpdir");
system("$scp $integrit_conf root\@$rhost:$tmpdir");
print "Creating integrit db file on $rhost ......\n";
system("ssh $rhost -l root '. /etc/.profile;cd $tmpdir; sh createdb.sh'");
system("$scp root\@$rhost:$remcurrentdb $remdb");
system("ssh $rhost -l root '. /etc/.profile; rm -rf $tmpdir");
}
###########################################################################
#Copy file to tmpdir
###########################################################################
sub cpfile{
my ($usrdir,$filelists) = @_;
#copy file from local host to tmpdir
open(FILE,"$usrdir/$filelists") || die "can not open filelist:$!";
while($filename=<FILE>)
{
chomp($filename);
if (! $filename eq "")
{
my $bar=`dirname $filename`;
# system("mkdir -p $usrdir/filedir$bar");
system("$rsync_cmd $filename $usrdir/filedir 2>/dev/null");
}
}
}
###########################################################################
#check file list
###########################################################################
sub checkfilelist
{
my ($chfile) = @_;
foreach $exist (`cat $tmpdir/$chfile`)
{
chomp($exist);
if (! -e $exist)
{
open (FILE, ">>$usrtmp/$chfile");
print FILE "$exist\n";
}
}
}
###########################################################################
#check not exist file list
###########################################################################
sub checknotexist
{
my ($checkfile) = @_;
foreach $notexist (`cat $tmpdir/$checkfile`)
{
chomp($notexist);
if (-e $notexist)
{
open (FILE, ">>$usrtmp/$checkfile");
print FILE "$notexist\n";
}
}
}
###########################################################################
#cleanup
###########################################################################
sub cleanup
{
system("rm -rf $tmpdir");
}
###########################################################################
#Main routine
###########################################################################
sub main {
my $help = grep(/^--help$/, @ARGV) || grep (/^-h$/, @ARGV) || grep (/^-\?$/, @ARGV) || 0;
help_page() if $help;
#check user uid
&Env;
#Get hostname
my ($host,$Ignores)=&GetParas;
#check host
print ("Warning - remote system is $host- are you sure? (Y/N)");
my $tmp = <STDIN>;
chomp($tmp);
if ($tmp eq "Y" or $tmp eq "y")
{
print "remote system is $host\n";
}
else
{
exit 1;
}
#check data dir
&Checkdir;
#Get remote db file
&Getdb($host);
#no check dirs list
system("ls -1 / |grep -v \"usr\" |grep -v \"opt\"|grep -v \"home\"|grep -v \"var\" |grep -v \"root\" |grep -v \"sbin\"|grep -v \"bin\"|grep -v \"net\"|grep -v \"^dev\" |grep -v \"etc\" |grep -v \"lib\" | grep -v \"pcrelease\" > $tmpdir/rootdirs ");
foreach $dir (`cat $tmpdir/rootdirs`)
{
open (FILE, ">>$integrit_conf");
print FILE "!/$dir";
close (FILE);
}
#create integrit database on v44 and v45 hosts
system("$integrit -u -C $integrit_conf");
system("$integrit -c -C $integrit_conf |grep -v \"^integrit: \">$tmpdir/diffs");
system("cat \"$tmpdir/diffs\" |perl -pi -e 's!.*: +!!g' |perl -pi -e 's! +.*!!g'|sort |uniq |grep -v \"#\" >$tmpdir/diffs_file_list");
#Creating filelist
print "Creating filelist file from $tmpdir/diffs_file_list .....\n";
foreach my $list(`cat $tmpdir/diffs_file_list`)
{
chomp($list);
open (FILE, ">>/$usrtmp/filelist");
print FILE "$list\n" if (! -d $list );
close (FILE);
}
if ($Ignores==1)
{
print "Copy file to $tmpdir/filedir. are you sure? (Y/N) ";
my $tmp = <STDIN>;
chomp($tmp);
exit (1) if ($tmp eq "N" or $tmp eq "n");
}
#copy file from local host to tmpdir
print "Copy file from local host to tmpdir...\n";
open(FILE,"/$usrtmp/filelist") || die "can not open filelist:$!";
while($filename=<FILE>)
{
chomp($filename);
# my $bar=`dirname $filename`;
# system("mkdir -p $filedir$bar");
system("$rsync_cmd $filename $filedir");
}
#Creating addfilelist delfilelist and updatefilelist
print "Creating file list .....\n";
system("ls -1 $filedir >$tmpdir/filedirlist");
foreach $dirlist (`cat $tmpdir/filedirlist`)
{
chomp($dirlist);
system("$rsync_del $filedir/$dirlist/ root\@$host:/$dirlist/|grep \"^deleting\" |grep -v \"^deleting directory\"|perl -pi -e 's!deleting !\/$dirlist\/!'|sort |uniq >>$tmpdir/delfilelist");
system("$rsync_del root\@$host:/$dirlist/ $filedir/$dirlist/|grep \"^deleting\" |grep -v \"^deleting directory\"|perl -pi -e 's!^deleting !\/$dirlist\/!'|sort |uniq >>$tmpdir/addfilelist");
system("$rsync_exist $filedir/$dirlist/ root\@$host:/$dirlist/|grep -v \"^deleting\" |grep -v \"^skipping\"|grep -v \"^building\" |grep -v \"^sent\" |grep -v \"^total\" |grep -v \"^wrote \"|perl -pi -e 's!->.*!!'|perl -pi -e 's!^receiving *!!'|sort |uniq >>$tmpdir/up");
foreach $update (`cat $tmpdir/up`)
{
open (FILE, ">>$tmpdir/updatefilelist");
print FILE "/$dirlist/$update";
close (FILE);
}
}
#check file list
print "checking delete file list....\n";
&checkfilelist("delfilelist");
#copy new file to $usrtmp/filedir
&checknotexist("addfilelist");
if (-e "$usrtmp/addfilelist")
{
print "copy new file to $usrtmp/filedir...\n";
&cpfile($usrtmp,"addfilelist");
}
#copy update file to $usrtmp/filedir
&checknotexist("updatefilelist");
if (-e "$usrtmp/updatefilelist")
{
print "copy update file to $usrtmp/filedir...\n";
&cpfile($usrtmp,"updatefilelist");
}
#please running instsutff.pl
print "Copy file $inststuff from localhost to $tmpdir @ $host.....\n";
system("ssh $host -l root '. /etc/.profile;mkdir $tmpdir'");
system("$rsync -av $inststuff $usrtmp");
system("$rsync -apzq --partial -e $ssh $usrtmp/ root\@$host:$tmpdir");
print("******************************************************************New files ready for final installation on $host:$tmpdir****NOW login to $host and running $tmpdir/instsutff.pl**** For example: **** sudo $tmpdir/inststuff.pl -d $tmpdir**************************************************************\n");
&cleanup;
}
&main;