#!/bin/bash
# Title........: cmcs
# Description..: change management control system
# Author.......: Mitchell Johnston - uid 0
# Contact......: http://www.bdragon.net
# Last Modified: Mon Sep 07 2009
#----------------------------------
# This is a complete rewrite of a tool I wrote a long time ago. It is designed to run
# via cron. I have not had time to test it on a Solaris system.
# variables
#----------------------------------
BOLD=$(tput smso) # turn bold on
UBOLD=$(tput rmso) # turn bold off
LINE=$(tput smul) # turn underline on
ULINE=$(tput rmul) # turn underline off
PROG=$(basename $0) # name of script
LOG=/var/log/$PROG.log # set location
PATH=/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin:$PATH
BASEDIR=/var/cmcs # where to keep everything
LOG=$BASEDIR/cmcs.log # log of all actions
NOTICE="root" # contact to send notices to
# functions
#----------------------------------
pause(){ # simple pause routine
echo -n "Please hit ENTER: "
read x
}
log (){ # simple log entry
echo "$(date '+%D %T') $$ $*">>$LOG
}
data(){ # parses self for data elements
sed -n '/^===DATA===/,$p' <$0|grep -v '===DATA==='
}
check(){ # perform crc
if [ "$OS" = "SunOS" ]
then
/usr/bin/sum $1|cut -d' ' -f1
else
/usr/bin/sum -s $1|cut -d' ' -f1
fi
}
help(){ # display help
cat <<END-HELP
${BOLD}$PROG${UBOLD} - ${LINE}A tool to auto-version files on a system${ULINE}
${LINE}Options:${ULINE}
-h Display help
-r {file} Report on change history
-R {file} Restore file
-d {file} Display the difersance from current to the last change
-f Display listing of all the files it is configured to check for
-l Display the last run from the log: $LOG
${BOLD}NOTE:${UBOLD} {file} must be the full path to the origenal file.
Anything else and it will check all of the files it finds for changes against
the baseline. If it is a new file, it will add it.
Location of the file versions: ${LINE}$BASEDIR${ULINE}
The file list that it is configured to check is maintained in the bottom of
script.
END-HELP
}
# main
#---------------------------
## setup check
if [ ! -d $BASEDIR ]
then
mkdir -p $BASEDIR
log "Creating: $BASEDIR"
fi
case $1 in
-h) # display help
help
exit;;
-r) # report
SOURCE=$2
# check to make sure file is on system
if [ ! -f $SOURCE ]
then
echo "${BOLD}$SOURCE${UBOLD} not found"
echo " "
echo "$PROG -r {full path to file}"
echo "$PROG -r /etc/motd"
exit 2
else
NAME=$(echo $SOURCE| tr '/' '_') # this converts / to - in the name
fi
echo "${BOLD}$SOURCE${UBOLD}"
ls -l $BASEDIR/$NAME.*
exit
;;
-R) # restore file
SOURCE=$2
# check to make sure file is on system
if [ ! -f $SOURCE ]
then
echo "${BOLD}$SOURCE${UBOLD} not found"
echo " "
echo "$PROG -R {full path to file}"
echo "$PROG -R /etc/motd"
exit 2
else
NAME=$(echo $SOURCE| tr '/' '_') # this converts / to - in the name
fi
# display available versions for selection
ls -l $BASEDIR/$NAME.*
echo " "
echo -n "Which revision number do you want to restore (0-5): "
read REV
if [ ! -n $BASEDIR/$NAME.$REV ]
then
echo "$NAME.$REV does not exist"
sleep 2
else
cp $BASEDIR/$NAME.$REV $SOURCE
ES=$?
if [ $ES -gt 0 ]
then
echo "Error performing restore"
exit 1
else
log "cp $BASEDIR/$NAME.$REV $SOURCE"
exit
fi
fi
#
;;
-d) # vimdiff a file threw revisions
which vimdiff >/dev/null 2>&1
ES=$?
if [ $ES -gt 0 ]
then
echo "This feature requires ${LINE}vimdiff${ULINE} installed"
exit 1
fi
SOURCE=$2
NAME=$(echo $SOURCE| tr '/' '_') # this converts / to - in the name
if [ ! -f $BASEDIR/$NAME ]
then
echo "${BOLD}No versions of $SOURCE in $BASEDIR${UBOLD}"
exit 1
else
while :
do
clear
ls -l $BASEDIR/$NAME.*
echo "x - to exit"
echo -n "Which version number do you want to compare: "
read REV
if [ -f $BASEDIR/$NAME.$REV ]
then
vimdiff $SOURCE $BASEDIR/$NAME.$REV
else
if [ "$REV" == "x" ]
then
exit
fi
echo "$REV is an invalid version number"
sleep 2
fi
done
fi
;;
-f) # display file listing
data|more
exit;;
-l) # display log from last run
RUN=$(tail -1 $LOG|cut -d' ' -f3)
grep $RUN $LOG
exit;;
esac
## main loop
log "Starting: file check"
for FILE in $(data)
do
if [ -f $FILE ]
then
NAME=$(echo $FILE| tr '/' '_') # this converts / to - in the name
#See if file is in BASEDIR If not, back the file up to BASEDIR
if [ ! -f $BASEDIR/$NAME ]
then
cp $FILE $BASEDIR/$NAME
CRC=$(check $FILE)
log "Added: $CRC $FILE"
continue
fi
#If so, compare to system version and verify that they match
CURRENT=$(check $FILE)
LAST=$(check $BASEDIR/$NAME)
if [ $CURRENT -eq $LAST ]
then
continue
else
MTIME=$(ls -Ll $FILE | awk '{print $6, $7, $8}')
[ -f $BASEDIR/$NAME.4 ] && mv $BASEDIR/$NAME.4 $BASEDIR/$NAME.5
[ -f $BASEDIR/$NAME.3 ] && mv $BASEDIR/$NAME.3 $BASEDIR/$NAME.4
[ -f $BASEDIR/$NAME.2 ] && mv $BASEDIR/$NAME.2 $BASEDIR/$NAME.3
[ -f $BASEDIR/$NAME.1 ] && mv $BASEDIR/$NAME.1 $BASEDIR/$NAME.2
[ -f $BASEDIR/$NAME.0 ] && mv $BASEDIR/$NAME.0 $BASEDIR/$NAME.1
[ -f $BASEDIR/$NAME ] && mv $BASEDIR/$NAME $BASEDIR/$NAME.0
cp $FILE $BASEDIR/$NAME
log "Change: on [$MTIME] $CURRENT $LAST $FILE"
fi
fi
done
log "Ending: file check"
exit
===DATA===
/boot/grub/default
/boot/grub/device.map
/boot/grub/menu.lst
/etc/*.conf
/etc/TIMEZONE
/etc/default/in.ftpd
/etc/default/in.telnetd
/etc/default/login
/etc/default/su
/etc/defaultroute
/etc/dfs/dfstab
/etc/fstab
/etc/fstab
/etc/ftpchroot
/etc/ftpusers
/etc/groups
/etc/hosts
/etc/hosts.*
/etc/hosts.equiv
/etc/httpd/conf.d/*
/etc/httpd/conf/*
/etc/inet/hosts
/etc/inetd.conf
/etc/inittab
/etc/mail/aliases
/etc/mail/sendmail.cf
/etc/motd
/etc/mrtg/mrtg.cfg
/etc/my.cnf
/etc/named.boot
/etc/named.conf
/etc/netmasks
/etc/nsswitch.conf
/etc/pam.conf
/etc/pam.d/*
/etc/passwd
/etc/php.d/*
/etc/printconf
/etc/printers.conf
/etc/profile
/etc/proftpd.conf
/etc/proftpd.include
/etc/rc2.d/*
/etc/rc3.d/*
/etc/rcS.d/*
/etc/resolv.conf
/etc/services
/etc/shadow
/etc/ssh/*
/etc/ssh2/*
/etc/sysconfig/*
/etc/syslog.conf
/etc/nagios/*.cfg
/etc/system
/etc/vsftpd/*
/etc/xinetd.d/*
/opt/apache/conf/access.conf
/opt/apache/conf/httpd.conf
/opt/apache/conf/srm.conf
/root/.bash_logout
/root/.bash_profile
/root/.bashrc
/root/.rhosts
/root/.ssh/authorized_keys
/root/.ssh/authorized_keys2
/root/.ssh/id_dsa
/root/.ssh/id_dsa.pub
/root/.ssh2/*
/usr/local/etc/aide.conf
/usr/local/mysql/var/my.cnf
/usr/local/apache/conf/access.conf
/usr/local/apache/conf/httpd.conf
/usr/local/apache/conf/srm.conf
/usr/local/apache/conf/copernicus_license.txt
/usr/openv/netbackup/bp.conf
/usr/openv/netbackup/exclude_list
/var/named/*
/var/qmail/control/*
/var/spool/at/crontabs/*
/var/spool/cron/crontabs/*