security revision 1.21
11.1Scgd#!/bin/sh - 21.1Scgd# 31.21Smycroft# $NetBSD: security,v 1.21 1997/04/21 17:38:39 mycroft Exp $ 41.9Scgd# from: @(#)security 8.1 (Berkeley) 6/9/93 51.1Scgd# 61.1Scgd 71.9ScgdPATH=/sbin:/usr/sbin:/bin:/usr/bin 81.1Scgd 91.9Scgdumask 077 101.1Scgd 111.15Smrgif [ -s /etc/security.conf ]; then 121.15Smrg . /etc/security.conf 131.15Smrgfi 141.15Smrg 151.15SmrgSECUREDIR=/tmp/_securedir.$$ 161.15Smrgif ! mkdir $SECUREDIR; then 171.15Smrg echo can not create $SECUREDIR. 181.15Smrg exit 1 191.15Smrgfi 201.15Smrg 211.15Smrgif ! cd $SECUREDIR; then 221.15Smrg echo can not chdir to $SECUREDIR. 231.15Smrg exit 1 241.15Smrgfi 251.15Smrg 261.15SmrgERR=secure1.$$ 271.15SmrgTMP1=secure2.$$ 281.15SmrgTMP2=secure3.$$ 291.15SmrgTMP3=secure4.$$ 301.15SmrgLIST=secure5.$$ 311.15SmrgOUTPUT=secure6.$$ 321.15Smrg 331.15Smrgtrap 'rm -rf $SECUREDIR' 0 341.15Smrg 351.15SmrgMP=/etc/master.passwd 361.9Scgd 371.15Smrg# this is used several times. 381.20Smycroftawk -F: '{ print $1 " " $3 }' $MP | sort -k2n > $TMP1 391.9Scgd 401.9Scgd# Check the master password file syntax. 411.17Smycroftif [ "$check_passwd" = YES ]; then 421.15Smrg awk -F: '{ 431.15Smrg if ($0 ~ /^[ ]*$/) { 441.15Smrg printf("Line %d is a blank line.\n", NR); 451.15Smrg next; 461.15Smrg } 471.15Smrg if (NF != 10) 481.15Smrg printf("Line %d has the wrong number of fields.\n", NR); 491.15Smrg if ($1 !~ /^[A-Za-z0-9]*$/) 501.15Smrg printf("Login %s has non-alphanumeric characters.\n", $1); 511.15Smrg if (length($1) > 8) 521.15Smrg printf("Login %s has more than 8 characters.\n", $1); 531.15Smrg if ($2 == "") 541.15Smrg printf("Login %s has no password.\n", $1); 551.15Smrg if (length($2) != 13 && $2 != "" && ($10 ~ /.*sh$/ || $10 == "")) 561.15Smrg printf("Login %s is off but still has a valid shell.\n", $1); 571.15Smrg if ($3 == 0 && $1 != "root" && $1 != "toor") 581.15Smrg printf("Login %s has a user id of 0.\n", $1); 591.15Smrg if ($3 < 0) 601.15Smrg printf("Login %s has a negative user id.\n", $1); 611.15Smrg if ($4 < 0) 621.15Smrg printf("Login %s has a negative group id.\n", $1); 631.15Smrg }' < $MP > $OUTPUT 641.15Smrg if [ -s $OUTPUT ] ; then 651.15Smrg printf "\nChecking the $MP file:\n" 661.15Smrg cat $OUTPUT 671.15Smrg fi 681.15Smrg 691.15Smrg awk -F: '{ print $1 }' $MP | sort | uniq -d > $OUTPUT 701.15Smrg if [ -s $OUTPUT ] ; then 711.15Smrg printf "\n$MP has duplicate user names.\n" 721.15Smrg column $OUTPUT 731.15Smrg fi 741.15Smrg 751.15Smrg < $TMP1 uniq -d -f 1 | awk '{ print $2 }' > $TMP2 761.15Smrg if [ -s $TMP2 ] ; then 771.15Smrg printf "\n$MP has duplicate user id's.\n" 781.15Smrg while read uid; do 791.15Smrg grep -w $uid $TMP1 801.15Smrg done < $TMP2 | column 811.15Smrg fi 821.9Scgdfi 831.9Scgd 841.9Scgd# Backup the master password file; a special case, the normal backup 851.9Scgd# mechanisms also print out file differences and we don't want to do 861.9Scgd# that because this file has encrypted passwords in it. 871.9ScgdCUR=/var/backups/`basename $MP`.current 881.9ScgdBACK=/var/backups/`basename $MP`.backup 891.9Scgdif [ -s $CUR ] ; then 901.9Scgd if cmp -s $CUR $MP; then 911.9Scgd : 921.9Scgd else 931.9Scgd cp -p $CUR $BACK 941.9Scgd cp -p $MP $CUR 951.9Scgd chown root.wheel $CUR 961.9Scgd fi 971.9Scgdelse 981.9Scgd cp -p $MP $CUR 991.9Scgd chown root.wheel $CUR 1001.9Scgdfi 1011.9Scgd 1021.9Scgd# Check the group file syntax. 1031.17Smycroftif [ "$check_group" = YES ]; then 1041.15Smrg GRP=/etc/group 1051.15Smrg awk -F: '{ 1061.15Smrg if ($0 ~ /^[ ]*$/) { 1071.15Smrg printf("Line %d is a blank line.\n", NR); 1081.15Smrg next; 1091.15Smrg } 1101.15Smrg if (NF != 4) 1111.15Smrg printf("Line %d has the wrong number of fields.\n", NR); 1121.15Smrg if ($1 !~ /^[A-za-z0-9]*$/) 1131.15Smrg printf("Group %s has non-alphanumeric characters.\n", $1); 1141.15Smrg if (length($1) > 8) 1151.15Smrg printf("Group %s has more than 8 characters.\n", $1); 1161.15Smrg if ($3 !~ /[0-9]*/) 1171.15Smrg printf("Login %s has a negative group id.\n", $1); 1181.15Smrg }' < $GRP > $OUTPUT 1191.15Smrg if [ -s $OUTPUT ] ; then 1201.15Smrg printf "\nChecking the $GRP file:\n" 1211.15Smrg cat $OUTPUT 1221.15Smrg fi 1231.15Smrg 1241.15Smrg awk -F: '{ print $1 }' $GRP | sort | uniq -d > $OUTPUT 1251.15Smrg if [ -s $OUTPUT ] ; then 1261.15Smrg printf "\n$GRP has duplicate group names.\n" 1271.15Smrg column $OUTPUT 1281.15Smrg fi 1291.9Scgdfi 1301.9Scgd 1311.9Scgd# Check for root paths, umask values in startup files. 1321.9Scgd# The check for the root paths is problematical -- it's likely to fail 1331.9Scgd# in other environments. Once the shells have been modified to warn 1341.9Scgd# of '.' in the path, the path tests should go away. 1351.17Smycroftif [ "$check_rootdotfiles" = YES ]; then 1361.15Smrg cp /dev/null $OUTPUT 1371.15Smrg rhome=`csh -fc "echo ~root"` 1381.15Smrg umaskset=no 1391.15Smrg list="/etc/csh.cshrc /etc/csh.login ${rhome}/.cshrc ${rhome}/.login" 1401.15Smrg for i in $list ; do 1411.15Smrg if [ -f $i ] ; then 1421.15Smrg if egrep umask $i > /dev/null ; then 1431.15Smrg umaskset=yes 1441.15Smrg fi 1451.15Smrg egrep umask $i | 1461.15Smrg awk '$2 % 100 < 20 \ 1471.15Smrg { print "Root umask is group writeable" } 1481.15Smrg $2 % 10 < 2 \ 1491.15Smrg { print "Root umask is other writeable" }' >> $OUTPUT 1501.15Smrg /bin/csh -f -s << end-of-csh > /dev/null 2>&1 1511.15Smrg unset path 1521.15Smrg source $i 1531.15Smrg /bin/ls -ldgT \$path > $TMP1 1541.9Scgdend-of-csh 1551.15Smrg awk '{ 1561.15Smrg if ($10 ~ /^\.$/) { 1571.15Smrg print "The root path includes ."; 1581.15Smrg next; 1591.15Smrg } 1601.15Smrg } 1611.15Smrg $1 ~ /^d....w/ \ 1621.15Smrg { print "Root path directory " $10 " is group writeable." } \ 1631.15Smrg $1 ~ /^d.......w/ \ 1641.15Smrg { print "Root path directory " $10 " is other writeable." }' \ 1651.15Smrg < $TMP1 >> $OUTPUT 1661.15Smrg fi 1671.15Smrg done 1681.15Smrg if [ $umaskset = "no" -o -s $OUTPUT ] ; then 1691.15Smrg printf "\nChecking root csh paths, umask values:\n$list\n" 1701.15Smrg if [ -s $OUTPUT ]; then 1711.15Smrg cat $OUTPUT 1721.15Smrg fi 1731.15Smrg if [ $umaskset = "no" ] ; then 1741.15Smrg printf "\nRoot csh startup files do not set the umask.\n" 1751.15Smrg fi 1761.9Scgd fi 1771.9Scgd 1781.15Smrg cp /dev/null $OUTPUT 1791.15Smrg rhome=/root 1801.15Smrg umaskset=no 1811.15Smrg list="${rhome}/.profile" 1821.15Smrg for i in $list; do 1831.15Smrg if [ -f $i ] ; then 1841.15Smrg if egrep umask $i > /dev/null ; then 1851.15Smrg umaskset=yes 1861.15Smrg fi 1871.15Smrg egrep umask $i | 1881.15Smrg awk '$2 % 100 < 20 \ 1891.15Smrg { print "Root umask is group writeable" } \ 1901.15Smrg $2 % 10 < 2 \ 1911.15Smrg { print "Root umask is other writeable" }' >> $OUTPUT 1921.15Smrg /bin/sh << end-of-sh > /dev/null 2>&1 1931.15Smrg PATH= 1941.15Smrg . $i 1951.15Smrg list=\`echo \$PATH | /usr/bin/sed -e 's/:/ /g'\` 1961.15Smrg /bin/ls -ldgT \$list > $TMP1 1971.9Scgdend-of-sh 1981.15Smrg awk '{ 1991.15Smrg if ($10 ~ /^\.$/) { 2001.15Smrg print "The root path includes ."; 2011.15Smrg next; 2021.15Smrg } 2031.15Smrg } 2041.15Smrg $1 ~ /^d....w/ \ 2051.15Smrg { print "Root path directory " $10 " is group writeable." } \ 2061.15Smrg $1 ~ /^d.......w/ \ 2071.15Smrg { print "Root path directory " $10 " is other writeable." }' \ 2081.15Smrg < $TMP1 >> $OUTPUT 2091.9Scgd 2101.15Smrg fi 2111.15Smrg done 2121.15Smrg if [ $umaskset = "no" -o -s $OUTPUT ] ; then 2131.15Smrg printf "\nChecking root sh paths, umask values:\n$list\n" 2141.15Smrg if [ -s $OUTPUT ]; then 2151.15Smrg cat $OUTPUT 2161.15Smrg fi 2171.15Smrg if [ $umaskset = "no" ] ; then 2181.15Smrg printf "\nRoot sh startup files do not set the umask.\n" 2191.15Smrg fi 2201.9Scgd fi 2211.9Scgdfi 2221.9Scgd 2231.9Scgd# Root and uucp should both be in /etc/ftpusers. 2241.17Smycroftif [ "$check_ftpusers" = YES ]; then 2251.15Smrg if egrep root /etc/ftpusers > /dev/null ; then 2261.15Smrg : 2271.15Smrg else 2281.15Smrg printf "\nRoot not listed in /etc/ftpusers file.\n" 2291.15Smrg fi 2301.15Smrg if egrep uucp /etc/ftpusers > /dev/null ; then 2311.15Smrg : 2321.15Smrg else 2331.15Smrg printf "\nUucp not listed in /etc/ftpusers file.\n" 2341.15Smrg fi 2351.9Scgdfi 2361.9Scgd 2371.9Scgd# Uudecode should not be in the /etc/aliases file. 2381.17Smycroftif [ "$check_aliases" = YES ]; then 2391.18Smikel if egrep '^[^#]*(uudecode|decode).*\|' /etc/aliases; then 2401.18Smikel printf "\nEntry for uudecode in /etc/aliases file.\n" 2411.15Smrg fi 2421.9Scgdfi 2431.9Scgd 2441.9Scgd# Files that should not have + signs. 2451.17Smycroftif [ "$check_rhosts" = YES ]; then 2461.15Smrg list="/etc/hosts.equiv /etc/hosts.lpd" 2471.15Smrg for f in $list ; do 2481.15Smrg if [ -f $f ] && egrep '\+' $f > /dev/null ; then 2491.15Smrg printf "\nPlus sign in $f file.\n" 2501.15Smrg fi 2511.15Smrg done 2521.15Smrg 2531.15Smrg # Check for special users with .rhosts files. Only root and toor should 2541.16Smikel # have .rhosts files. Also, .rhosts files should not have plus signs. 2551.15Smrg awk -F: '$1 != "root" && $1 != "toor" && \ 2561.15Smrg ($3 < 100 || $1 == "ftp" || $1 == "uucp") \ 2571.20Smycroft { print $1 " " $9 }' $MP | 2581.19Smycroft sort -k2 | 2591.15Smrg while read uid homedir; do 2601.15Smrg if [ -f ${homedir}/.rhosts ] ; then 2611.15Smrg rhost=`ls -ldgT ${homedir}/.rhosts` 2621.15Smrg printf "$uid: $rhost\n" 2631.15Smrg fi 2641.15Smrg done > $OUTPUT 2651.15Smrg if [ -s $OUTPUT ] ; then 2661.15Smrg printf "\nChecking for special users with .rhosts files.\n" 2671.15Smrg cat $OUTPUT 2681.15Smrg fi 2691.15Smrg 2701.20Smycroft awk -F: '{ print $1 " " $9 }' $MP | 2711.19Smycroft sort -k2 | 2721.15Smrg while read uid homedir; do 2731.15Smrg if [ -f ${homedir}/.rhosts ] && \ 2741.15Smrg egrep '\+' ${homedir}/.rhosts > /dev/null ; then 2751.15Smrg printf "$uid: + in .rhosts file.\n" 2761.15Smrg fi 2771.15Smrg done > $OUTPUT 2781.15Smrg if [ -s $OUTPUT ] ; then 2791.15Smrg printf "\nChecking .rhosts files syntax.\n" 2801.15Smrg cat $OUTPUT 2811.15Smrg fi 2821.9Scgdfi 2831.9Scgd 2841.9Scgd# Check home directories. Directories should not be owned by someone else 2851.9Scgd# or writeable. 2861.17Smycroftif [ "$check_homes" = YES ]; then 2871.20Smycroft awk -F: '{ print $1 " " $9 }' $MP | 2881.19Smycroft sort -k2 | 2891.15Smrg while read uid homedir; do 2901.15Smrg if [ -d ${homedir}/ ] ; then 2911.15Smrg file=`ls -ldgT ${homedir}` 2921.15Smrg printf "$uid $file\n" 2931.9Scgd fi 2941.15Smrg done | 2951.15Smrg awk '$1 != $4 && $4 != "root" \ 2961.15Smrg { print "user " $1 " home directory is owned by " $4 } 2971.15Smrg $2 ~ /^-....w/ \ 2981.15Smrg { print "user " $1 " home directory is group writeable" } 2991.15Smrg $2 ~ /^-.......w/ \ 3001.15Smrg { print "user " $1 " home directory is other writeable" }' > $OUTPUT 3011.15Smrg if [ -s $OUTPUT ] ; then 3021.15Smrg printf "\nChecking home directories.\n" 3031.15Smrg cat $OUTPUT 3041.15Smrg fi 3051.15Smrg 3061.15Smrg # Files that should not be owned by someone else or readable. 3071.19Smycroft list=".Xauthority .netrc .rhosts" 3081.20Smycroft awk -F: '{ print $1 " " $9 }' $MP | 3091.19Smycroft sort -k2 | 3101.15Smrg while read uid homedir; do 3111.15Smrg for f in $list ; do 3121.15Smrg file=${homedir}/${f} 3131.15Smrg if [ -f $file ] ; then 3141.15Smrg printf "$uid $f `ls -ldgT $file`\n" 3151.15Smrg fi 3161.15Smrg done 3171.15Smrg done | 3181.15Smrg awk '$1 != $5 && $5 != "root" \ 3191.15Smrg { print "user " $1 " " $2 " file is owned by " $5 } 3201.15Smrg $3 ~ /^-...r/ \ 3211.15Smrg { print "user " $1 " " $2 " file is group readable" } 3221.15Smrg $3 ~ /^-......r/ \ 3231.15Smrg { print "user " $1 " " $2 " file is other readable" } 3241.15Smrg $3 ~ /^-....w/ \ 3251.15Smrg { print "user " $1 " " $2 " file is group writeable" } 3261.15Smrg $3 ~ /^-.......w/ \ 3271.15Smrg { print "user " $1 " " $2 " file is other writeable" }' > $OUTPUT 3281.15Smrg 3291.15Smrg # Files that should not be owned by someone else or writeable. 3301.19Smycroft list=".bash_history .bash_login .bash_logout .bash_profile .bashrc \ 3311.19Smycroft .cshrc .emacs .exrc .forward .history .klogin .login .logout \ 3321.19Smycroft .profile .qmail .rc_history .tcshrc .twmrc .xinitrc .xsession" 3331.20Smycroft awk -F: '{ print $1 " " $9 }' $MP | 3341.19Smycroft sort -k2 | 3351.15Smrg while read uid homedir; do 3361.15Smrg for f in $list ; do 3371.15Smrg file=${homedir}/${f} 3381.15Smrg if [ -f $file ] ; then 3391.15Smrg printf "$uid $f `ls -ldgT $file`\n" 3401.15Smrg fi 3411.15Smrg done 3421.15Smrg done | 3431.15Smrg awk '$1 != $5 && $5 != "root" \ 3441.15Smrg { print "user " $1 " " $2 " file is owned by " $5 } 3451.15Smrg $3 ~ /^-....w/ \ 3461.15Smrg { print "user " $1 " " $2 " file is group writeable" } 3471.15Smrg $3 ~ /^-.......w/ \ 3481.15Smrg { print "user " $1 " " $2 " file is other writeable" }' >> $OUTPUT 3491.15Smrg if [ -s $OUTPUT ] ; then 3501.15Smrg printf "\nChecking dot files.\n" 3511.15Smrg cat $OUTPUT 3521.15Smrg fi 3531.9Scgdfi 3541.9Scgd 3551.9Scgd# Mailboxes should be owned by user and unreadable. 3561.17Smycroftif [ "$check_varmail" = YES ]; then 3571.15Smrg ls -l /var/mail | sed 1d | \ 3581.15Smrg awk '$3 != $9 \ 3591.15Smrg { print "user " $9 " mailbox is owned by " $3 } 3601.15Smrg $1 != "-rw-------" \ 3611.15Smrg { print "user " $9 " mailbox is " $1 ", group " $4 }' > $OUTPUT 3621.15Smrg if [ -s $OUTPUT ] ; then 3631.15Smrg printf "\nChecking mailbox ownership.\n" 3641.15Smrg cat $OUTPUT 3651.15Smrg fi 3661.15Smrgfi 3671.15Smrg 3681.17Smycroftif [ "$check_nfs" = YES ]; then 3691.15Smrg if [ -f /etc/exports ]; then 3701.15Smrg # File systems should not be globally exported. 3711.15Smrg awk '{ 3721.15Smrg readonly = 0; 3731.15Smrg for (i = 2; i <= NF; ++i) { 3741.15Smrg if ($i ~ /-ro/) 3751.15Smrg readonly = 1; 3761.15Smrg else if ($i !~ /^-/) 3771.15Smrg next; 3781.15Smrg } 3791.15Smrg if (readonly) 3801.15Smrg print "File system " $1 " globally exported, read-only." 3811.15Smrg else 3821.15Smrg print "File system " $1 " globally exported, read-write." 3831.15Smrg }' < /etc/exports > $OUTPUT 3841.15Smrg if [ -s $OUTPUT ] ; then 3851.15Smrg printf "\nChecking for globally exported file systems.\n" 3861.15Smrg cat $OUTPUT 3871.15Smrg fi 3881.15Smrg fi 3891.9Scgdfi 3901.9Scgd 3911.9Scgd# Display any changes in setuid files and devices. 3921.17Smycroftif [ "$check_devices" = YES ]; then 3931.15Smrg printf "\nChecking setuid files and devices:\n" 3941.15Smrg (find / \( ! -fstype local -o -fstype fdesc -o -fstype kernfs \ 3951.15Smrg -o -fstype procfs \) -a -prune -o \ 3961.21Smycroft \( \( -perm -u+s -a ! -type d \) -o \ 3971.21Smycroft \( -perm -g+s -a ! -type d \) -o \ 3981.21Smycroft -type b -o -type c \) -print | \ 3991.15Smrg sort | sed -e 's/^/ls -ldgT /' | sh > $LIST) 2> $OUTPUT 4001.15Smrg 4011.15Smrg # Display any errors that occurred during system file walk. 4021.15Smrg if [ -s $OUTPUT ] ; then 4031.15Smrg printf "Setuid/device find errors:\n" 4041.15Smrg cat $OUTPUT 4051.15Smrg printf "\n" 4061.15Smrg fi 4071.15Smrg 4081.15Smrg # Display any changes in the setuid file list. 4091.15Smrg egrep -v '^[bc]' $LIST > $TMP1 4101.15Smrg if [ -s $TMP1 ] ; then 4111.15Smrg # Check to make sure uudecode isn't setuid. 4121.15Smrg if grep -w uudecode $TMP1 > /dev/null ; then 4131.15Smrg printf "\nUudecode is setuid.\n" 4141.15Smrg fi 4151.15Smrg 4161.15Smrg CUR=/var/backups/setuid.current 4171.15Smrg BACK=/var/backups/setuid.backup 4181.9Scgd 4191.15Smrg if [ -s $CUR ] ; then 4201.15Smrg if cmp -s $CUR $TMP1 ; then 4211.15Smrg : 4221.15Smrg else 4231.15Smrg > $TMP2 4241.15Smrg join -110 -210 -v2 $CUR $TMP1 > $OUTPUT 4251.15Smrg if [ -s $OUTPUT ] ; then 4261.15Smrg printf "Setuid additions:\n" 4271.15Smrg tee -a $TMP2 < $OUTPUT 4281.15Smrg printf "\n" 4291.15Smrg fi 4301.15Smrg 4311.15Smrg join -110 -210 -v1 $CUR $TMP1 > $OUTPUT 4321.15Smrg if [ -s $OUTPUT ] ; then 4331.15Smrg printf "Setuid deletions:\n" 4341.15Smrg tee -a $TMP2 < $OUTPUT 4351.15Smrg printf "\n" 4361.15Smrg fi 4371.15Smrg 4381.20Smycroft sort -k10 $TMP2 $CUR $TMP1 | \ 4391.15Smrg sed -e 's/[ ][ ]*/ /g' | uniq -u > $OUTPUT 4401.15Smrg if [ -s $OUTPUT ] ; then 4411.15Smrg printf "Setuid changes:\n" 4421.15Smrg column -t $OUTPUT 4431.15Smrg printf "\n" 4441.15Smrg fi 4451.9Scgd 4461.15Smrg cp $CUR $BACK 4471.15Smrg cp $TMP1 $CUR 4481.9Scgd fi 4491.15Smrg else 4501.15Smrg printf "Setuid additions:\n" 4511.15Smrg column -t $TMP1 4521.15Smrg printf "\n" 4531.9Scgd cp $TMP1 $CUR 4541.9Scgd fi 4551.15Smrg fi 4561.15Smrg 4571.15Smrg # Check for block and character disk devices that are readable or writeable 4581.15Smrg # or not owned by root.operator. 4591.15Smrg >$TMP1 4601.15Smrg DISKLIST="dk fd hd hk hp jb kra ra rb rd rl rx rz sd up wd xd xy" 4611.15Smrg for i in $DISKLIST; do 4621.15Smrg egrep "^b.*/${i}[0-9][0-9]*[a-p]$" $LIST >> $TMP1 4631.15Smrg egrep "^c.*/r${i}[0-9][0-9]*[a-p]$" $LIST >> $TMP1 4641.15Smrg done 4651.15Smrg 4661.15Smrg awk '$3 != "root" || $4 != "operator" || $1 !~ /.rw-r-----/ \ 4671.15Smrg { printf("Disk %s is user %s, group %s, permissions %s.\n", \ 4681.15Smrg $11, $3, $4, $1); }' < $TMP1 > $OUTPUT 4691.15Smrg if [ -s $OUTPUT ] ; then 4701.15Smrg printf "\nChecking disk ownership and permissions.\n" 4711.15Smrg cat $OUTPUT 4721.9Scgd printf "\n" 4731.9Scgd fi 4741.9Scgd 4751.15Smrg # Display any changes in the device file list. 4761.20Smycroft egrep '^[bc]' $LIST | sort -k11 > $TMP1 4771.15Smrg if [ -s $TMP1 ] ; then 4781.15Smrg CUR=/var/backups/device.current 4791.15Smrg BACK=/var/backups/device.backup 4801.15Smrg 4811.15Smrg if [ -s $CUR ] ; then 4821.15Smrg if cmp -s $CUR $TMP1 ; then 4831.15Smrg : 4841.15Smrg else 4851.15Smrg > $TMP2 4861.15Smrg join -111 -211 -v2 $CUR $TMP1 > $OUTPUT 4871.15Smrg if [ -s $OUTPUT ] ; then 4881.15Smrg printf "Device additions:\n" 4891.15Smrg tee -a $TMP2 < $OUTPUT 4901.15Smrg printf "\n" 4911.15Smrg fi 4921.15Smrg 4931.15Smrg join -111 -211 -v1 $CUR $TMP1 > $OUTPUT 4941.15Smrg if [ -s $OUTPUT ] ; then 4951.15Smrg printf "Device deletions:\n" 4961.15Smrg tee -a $TMP2 < $OUTPUT 4971.15Smrg printf "\n" 4981.15Smrg fi 4991.15Smrg 5001.15Smrg # Report any block device change. Ignore character 5011.15Smrg # devices, only the name is significant. 5021.15Smrg cat $TMP2 $CUR $TMP1 | \ 5031.15Smrg sed -e '/^c/d' | \ 5041.20Smycroft sort -k11 | \ 5051.15Smrg sed -e 's/[ ][ ]*/ /g' | \ 5061.15Smrg uniq -u > $OUTPUT 5071.15Smrg if [ -s $OUTPUT ] ; then 5081.15Smrg printf "Block device changes:\n" 5091.15Smrg column -t $OUTPUT 5101.15Smrg printf "\n" 5111.15Smrg fi 5121.9Scgd 5131.15Smrg cp $CUR $BACK 5141.15Smrg cp $TMP1 $CUR 5151.9Scgd fi 5161.15Smrg else 5171.15Smrg printf "Device additions:\n" 5181.15Smrg column -t $TMP1 5191.15Smrg printf "\n" 5201.9Scgd cp $TMP1 $CUR 5211.9Scgd fi 5221.9Scgd fi 5231.9Scgdfi 5241.9Scgd 5251.9Scgd# Check special files. 5261.9Scgd# Check system binaries. 5271.9Scgd# 5281.9Scgd# Create the mtree tree specifications using: 5291.9Scgd# 5301.9Scgd# mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure 5311.16Smikel# chown root.wheel DIR.secure 5321.16Smikel# chmod 600 DIR.secure 5331.9Scgd# 5341.9Scgd# Note, this is not complete protection against Trojan horsed binaries, as 5351.9Scgd# the hacker can modify the tree specification to match the replaced binary. 5361.9Scgd# For details on really protecting yourself against modified binaries, see 5371.9Scgd# the mtree(8) manual page. 5381.17Smycroftif [ "$check_mtree" = YES ]; then 5391.9Scgd mtree -e -p / -f /etc/mtree/special > $OUTPUT 5401.15Smrg if [ -s $OUTPUT ]; then 5411.9Scgd printf "\nChecking special files and directories.\n" 5421.9Scgd cat $OUTPUT 5431.9Scgd fi 5441.9Scgd 5451.9Scgd > $OUTPUT 5461.16Smikel for file in /etc/mtree/*.secure; do 5471.16Smikel [ $file = '/etc/mtree/*.secure' ] && continue 5481.9Scgd tree=`sed -n -e '3s/.* //p' -e 3q $file` 5491.9Scgd mtree -f $file -p $tree > $TMP1 5501.9Scgd if [ -s $TMP1 ]; then 5511.9Scgd printf "\nChecking $tree:\n" >> $OUTPUT 5521.9Scgd cat $TMP1 >> $OUTPUT 5531.9Scgd fi 5541.9Scgd done 5551.15Smrg if [ -s $OUTPUT ]; then 5561.9Scgd printf "\nChecking system binaries:\n" 5571.9Scgd cat $OUTPUT 5581.9Scgd fi 5591.9Scgdfi 5601.9Scgd 5611.9Scgd# List of files that get backed up and checked for any modifications. Each 5621.9Scgd# file is expected to have two backups, /var/backups/file.{current,backup}. 5631.9Scgd# Any changes cause the files to rotate. 5641.17Smycroftif [ "$check_changelist" = YES ] && [ -s /etc/changelist ] ; then 5651.9Scgd for file in `cat /etc/changelist`; do 5661.9Scgd CUR=/var/backups/`basename $file`.current 5671.9Scgd BACK=/var/backups/`basename $file`.backup 5681.9Scgd if [ -s $file ]; then 5691.9Scgd if [ -s $CUR ] ; then 5701.9Scgd diff $CUR $file > $OUTPUT 5711.9Scgd if [ -s $OUTPUT ] ; then 5721.9Scgd printf "\n======\n%s diffs (OLD < > NEW)\n======\n" $file 5731.9Scgd cat $OUTPUT 5741.9Scgd cp -p $CUR $BACK 5751.9Scgd cp -p $file $CUR 5761.9Scgd chown root.wheel $CUR $BACK 5771.9Scgd fi 5781.9Scgd else 5791.9Scgd cp -p $file $CUR 5801.9Scgd chown root.wheel $CUR 5811.9Scgd fi 5821.9Scgd fi 5831.9Scgd done 5841.9Scgdfi 585