security revision 1.16
11.1Scgd#!/bin/sh - 21.1Scgd# 31.16Smikel# $NetBSD: security,v 1.16 1997/02/14 08:52:05 mikel 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.15Smrgawk -F: '{ print $1 " " $3 }' $MP | sort -n +1 > $TMP1 391.9Scgd 401.9Scgd# Check the master password file syntax. 411.15Smrgif [ X"$check_passwd" = XYES ]; 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.15Smrgif [ X"$check_group" = XYES ]; 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.15Smrgif [ X"$check_rootdotfiles" = XYES ]; 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.15Smrgif [ X"$check_ftpusers" = XYES ]; 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.15Smrgif [ X"$check_aliases" = XYES ]; then 2391.15Smrg if egrep 'uudecode|decode' /etc/aliases; then 2401.15Smrg printf "\nThere is an entry for uudecode in the /etc/aliases file.\n" 2411.15Smrg fi 2421.9Scgdfi 2431.9Scgd 2441.9Scgd# Files that should not have + signs. 2451.15Smrgif [ X"$check_rhosts" = XYES ]; 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.15Smrg { print $1 " " $9 }' /etc/master.passwd | 2581.15Smrg while read uid homedir; do 2591.15Smrg if [ -f ${homedir}/.rhosts ] ; then 2601.15Smrg rhost=`ls -ldgT ${homedir}/.rhosts` 2611.15Smrg printf "$uid: $rhost\n" 2621.15Smrg fi 2631.15Smrg done > $OUTPUT 2641.15Smrg if [ -s $OUTPUT ] ; then 2651.15Smrg printf "\nChecking for special users with .rhosts files.\n" 2661.15Smrg cat $OUTPUT 2671.15Smrg fi 2681.15Smrg 2691.15Smrg awk -F: '{ print $1 " " $9 }' /etc/master.passwd | \ 2701.15Smrg while read uid homedir; do 2711.15Smrg if [ -f ${homedir}/.rhosts ] && \ 2721.15Smrg egrep '\+' ${homedir}/.rhosts > /dev/null ; then 2731.15Smrg printf "$uid: + in .rhosts file.\n" 2741.15Smrg fi 2751.15Smrg done > $OUTPUT 2761.15Smrg if [ -s $OUTPUT ] ; then 2771.15Smrg printf "\nChecking .rhosts files syntax.\n" 2781.15Smrg cat $OUTPUT 2791.15Smrg fi 2801.9Scgdfi 2811.9Scgd 2821.9Scgd# Check home directories. Directories should not be owned by someone else 2831.9Scgd# or writeable. 2841.15Smrgif [ X"$check_homes" = XYES ]; then 2851.15Smrg awk -F: '{ print $1 " " $9 }' /etc/master.passwd | \ 2861.15Smrg while read uid homedir; do 2871.15Smrg if [ -d ${homedir}/ ] ; then 2881.15Smrg file=`ls -ldgT ${homedir}` 2891.15Smrg printf "$uid $file\n" 2901.9Scgd fi 2911.15Smrg done | 2921.15Smrg awk '$1 != $4 && $4 != "root" \ 2931.15Smrg { print "user " $1 " home directory is owned by " $4 } 2941.15Smrg $2 ~ /^-....w/ \ 2951.15Smrg { print "user " $1 " home directory is group writeable" } 2961.15Smrg $2 ~ /^-.......w/ \ 2971.15Smrg { print "user " $1 " home directory is other writeable" }' > $OUTPUT 2981.15Smrg if [ -s $OUTPUT ] ; then 2991.15Smrg printf "\nChecking home directories.\n" 3001.15Smrg cat $OUTPUT 3011.15Smrg fi 3021.15Smrg 3031.15Smrg # Files that should not be owned by someone else or readable. 3041.15Smrg list=".netrc .rhosts" 3051.15Smrg awk -F: '{ print $1 " " $9 }' /etc/master.passwd | \ 3061.15Smrg while read uid homedir; do 3071.15Smrg for f in $list ; do 3081.15Smrg file=${homedir}/${f} 3091.15Smrg if [ -f $file ] ; then 3101.15Smrg printf "$uid $f `ls -ldgT $file`\n" 3111.15Smrg fi 3121.15Smrg done 3131.15Smrg done | 3141.15Smrg awk '$1 != $5 && $5 != "root" \ 3151.15Smrg { print "user " $1 " " $2 " file is owned by " $5 } 3161.15Smrg $3 ~ /^-...r/ \ 3171.15Smrg { print "user " $1 " " $2 " file is group readable" } 3181.15Smrg $3 ~ /^-......r/ \ 3191.15Smrg { print "user " $1 " " $2 " file is other readable" } 3201.15Smrg $3 ~ /^-....w/ \ 3211.15Smrg { print "user " $1 " " $2 " file is group writeable" } 3221.15Smrg $3 ~ /^-.......w/ \ 3231.15Smrg { print "user " $1 " " $2 " file is other writeable" }' > $OUTPUT 3241.15Smrg 3251.15Smrg # Files that should not be owned by someone else or writeable. 3261.15Smrg list=".bashrc .cshrc .emacs .exrc .forward .klogin .login .logout \ 3271.15Smrg .profile .tcshrc .qmail" 3281.15Smrg awk -F: '{ print $1 " " $9 }' /etc/master.passwd | \ 3291.15Smrg while read uid homedir; do 3301.15Smrg for f in $list ; do 3311.15Smrg file=${homedir}/${f} 3321.15Smrg if [ -f $file ] ; then 3331.15Smrg printf "$uid $f `ls -ldgT $file`\n" 3341.15Smrg fi 3351.15Smrg done 3361.15Smrg done | 3371.15Smrg awk '$1 != $5 && $5 != "root" \ 3381.15Smrg { print "user " $1 " " $2 " file is owned by " $5 } 3391.15Smrg $3 ~ /^-....w/ \ 3401.15Smrg { print "user " $1 " " $2 " file is group writeable" } 3411.15Smrg $3 ~ /^-.......w/ \ 3421.15Smrg { print "user " $1 " " $2 " file is other writeable" }' >> $OUTPUT 3431.15Smrg if [ -s $OUTPUT ] ; then 3441.15Smrg printf "\nChecking dot files.\n" 3451.15Smrg cat $OUTPUT 3461.15Smrg fi 3471.9Scgdfi 3481.9Scgd 3491.9Scgd# Mailboxes should be owned by user and unreadable. 3501.15Smrgif [ X"$check_varmail" = XYES ]; then 3511.15Smrg ls -l /var/mail | sed 1d | \ 3521.15Smrg awk '$3 != $9 \ 3531.15Smrg { print "user " $9 " mailbox is owned by " $3 } 3541.15Smrg $1 != "-rw-------" \ 3551.15Smrg { print "user " $9 " mailbox is " $1 ", group " $4 }' > $OUTPUT 3561.15Smrg if [ -s $OUTPUT ] ; then 3571.15Smrg printf "\nChecking mailbox ownership.\n" 3581.15Smrg cat $OUTPUT 3591.15Smrg fi 3601.15Smrgfi 3611.15Smrg 3621.15Smrgif [ X"$check_nfs" = XYES ]; then 3631.15Smrg if [ -f /etc/exports ]; then 3641.15Smrg # File systems should not be globally exported. 3651.15Smrg awk '{ 3661.15Smrg readonly = 0; 3671.15Smrg for (i = 2; i <= NF; ++i) { 3681.15Smrg if ($i ~ /-ro/) 3691.15Smrg readonly = 1; 3701.15Smrg else if ($i !~ /^-/) 3711.15Smrg next; 3721.15Smrg } 3731.15Smrg if (readonly) 3741.15Smrg print "File system " $1 " globally exported, read-only." 3751.15Smrg else 3761.15Smrg print "File system " $1 " globally exported, read-write." 3771.15Smrg }' < /etc/exports > $OUTPUT 3781.15Smrg if [ -s $OUTPUT ] ; then 3791.15Smrg printf "\nChecking for globally exported file systems.\n" 3801.15Smrg cat $OUTPUT 3811.15Smrg fi 3821.15Smrg fi 3831.9Scgdfi 3841.9Scgd 3851.9Scgd# Display any changes in setuid files and devices. 3861.15Smrgif [ X"$check_devices" = XYES ]; then 3871.15Smrg printf "\nChecking setuid files and devices:\n" 3881.15Smrg (find / \( ! -fstype local -o -fstype fdesc -o -fstype kernfs \ 3891.15Smrg -o -fstype procfs \) -a -prune -o \ 3901.15Smrg \( -perm -u+s -o \( -perm -g+s -a ! -type d \) -o \ 3911.15Smrg ! -type d -a ! -type f -a ! -type l -a \ 3921.15Smrg ! -type s \) -print | \ 3931.15Smrg sort | sed -e 's/^/ls -ldgT /' | sh > $LIST) 2> $OUTPUT 3941.15Smrg 3951.15Smrg # Display any errors that occurred during system file walk. 3961.15Smrg if [ -s $OUTPUT ] ; then 3971.15Smrg printf "Setuid/device find errors:\n" 3981.15Smrg cat $OUTPUT 3991.15Smrg printf "\n" 4001.15Smrg fi 4011.15Smrg 4021.15Smrg # Display any changes in the setuid file list. 4031.15Smrg egrep -v '^[bc]' $LIST > $TMP1 4041.15Smrg if [ -s $TMP1 ] ; then 4051.15Smrg # Check to make sure uudecode isn't setuid. 4061.15Smrg if grep -w uudecode $TMP1 > /dev/null ; then 4071.15Smrg printf "\nUudecode is setuid.\n" 4081.15Smrg fi 4091.15Smrg 4101.15Smrg CUR=/var/backups/setuid.current 4111.15Smrg BACK=/var/backups/setuid.backup 4121.9Scgd 4131.15Smrg if [ -s $CUR ] ; then 4141.15Smrg if cmp -s $CUR $TMP1 ; then 4151.15Smrg : 4161.15Smrg else 4171.15Smrg > $TMP2 4181.15Smrg join -110 -210 -v2 $CUR $TMP1 > $OUTPUT 4191.15Smrg if [ -s $OUTPUT ] ; then 4201.15Smrg printf "Setuid additions:\n" 4211.15Smrg tee -a $TMP2 < $OUTPUT 4221.15Smrg printf "\n" 4231.15Smrg fi 4241.15Smrg 4251.15Smrg join -110 -210 -v1 $CUR $TMP1 > $OUTPUT 4261.15Smrg if [ -s $OUTPUT ] ; then 4271.15Smrg printf "Setuid deletions:\n" 4281.15Smrg tee -a $TMP2 < $OUTPUT 4291.15Smrg printf "\n" 4301.15Smrg fi 4311.15Smrg 4321.15Smrg sort +9 $TMP2 $CUR $TMP1 | \ 4331.15Smrg sed -e 's/[ ][ ]*/ /g' | uniq -u > $OUTPUT 4341.15Smrg if [ -s $OUTPUT ] ; then 4351.15Smrg printf "Setuid changes:\n" 4361.15Smrg column -t $OUTPUT 4371.15Smrg printf "\n" 4381.15Smrg fi 4391.9Scgd 4401.15Smrg cp $CUR $BACK 4411.15Smrg cp $TMP1 $CUR 4421.9Scgd fi 4431.15Smrg else 4441.15Smrg printf "Setuid additions:\n" 4451.15Smrg column -t $TMP1 4461.15Smrg printf "\n" 4471.9Scgd cp $TMP1 $CUR 4481.9Scgd fi 4491.15Smrg fi 4501.15Smrg 4511.15Smrg # Check for block and character disk devices that are readable or writeable 4521.15Smrg # or not owned by root.operator. 4531.15Smrg >$TMP1 4541.15Smrg DISKLIST="dk fd hd hk hp jb kra ra rb rd rl rx rz sd up wd xd xy" 4551.15Smrg for i in $DISKLIST; do 4561.15Smrg egrep "^b.*/${i}[0-9][0-9]*[a-p]$" $LIST >> $TMP1 4571.15Smrg egrep "^c.*/r${i}[0-9][0-9]*[a-p]$" $LIST >> $TMP1 4581.15Smrg done 4591.15Smrg 4601.15Smrg awk '$3 != "root" || $4 != "operator" || $1 !~ /.rw-r-----/ \ 4611.15Smrg { printf("Disk %s is user %s, group %s, permissions %s.\n", \ 4621.15Smrg $11, $3, $4, $1); }' < $TMP1 > $OUTPUT 4631.15Smrg if [ -s $OUTPUT ] ; then 4641.15Smrg printf "\nChecking disk ownership and permissions.\n" 4651.15Smrg cat $OUTPUT 4661.9Scgd printf "\n" 4671.9Scgd fi 4681.9Scgd 4691.15Smrg # Display any changes in the device file list. 4701.15Smrg egrep '^[bc]' $LIST | sort +10 > $TMP1 4711.15Smrg if [ -s $TMP1 ] ; then 4721.15Smrg CUR=/var/backups/device.current 4731.15Smrg BACK=/var/backups/device.backup 4741.15Smrg 4751.15Smrg if [ -s $CUR ] ; then 4761.15Smrg if cmp -s $CUR $TMP1 ; then 4771.15Smrg : 4781.15Smrg else 4791.15Smrg > $TMP2 4801.15Smrg join -111 -211 -v2 $CUR $TMP1 > $OUTPUT 4811.15Smrg if [ -s $OUTPUT ] ; then 4821.15Smrg printf "Device additions:\n" 4831.15Smrg tee -a $TMP2 < $OUTPUT 4841.15Smrg printf "\n" 4851.15Smrg fi 4861.15Smrg 4871.15Smrg join -111 -211 -v1 $CUR $TMP1 > $OUTPUT 4881.15Smrg if [ -s $OUTPUT ] ; then 4891.15Smrg printf "Device deletions:\n" 4901.15Smrg tee -a $TMP2 < $OUTPUT 4911.15Smrg printf "\n" 4921.15Smrg fi 4931.15Smrg 4941.15Smrg # Report any block device change. Ignore character 4951.15Smrg # devices, only the name is significant. 4961.15Smrg cat $TMP2 $CUR $TMP1 | \ 4971.15Smrg sed -e '/^c/d' | \ 4981.15Smrg sort +10 | \ 4991.15Smrg sed -e 's/[ ][ ]*/ /g' | \ 5001.15Smrg uniq -u > $OUTPUT 5011.15Smrg if [ -s $OUTPUT ] ; then 5021.15Smrg printf "Block device changes:\n" 5031.15Smrg column -t $OUTPUT 5041.15Smrg printf "\n" 5051.15Smrg fi 5061.9Scgd 5071.15Smrg cp $CUR $BACK 5081.15Smrg cp $TMP1 $CUR 5091.9Scgd fi 5101.15Smrg else 5111.15Smrg printf "Device additions:\n" 5121.15Smrg column -t $TMP1 5131.15Smrg printf "\n" 5141.9Scgd cp $TMP1 $CUR 5151.9Scgd fi 5161.9Scgd fi 5171.9Scgdfi 5181.9Scgd 5191.9Scgd# Check special files. 5201.9Scgd# Check system binaries. 5211.9Scgd# 5221.9Scgd# Create the mtree tree specifications using: 5231.9Scgd# 5241.9Scgd# mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure 5251.16Smikel# chown root.wheel DIR.secure 5261.16Smikel# chmod 600 DIR.secure 5271.9Scgd# 5281.9Scgd# Note, this is not complete protection against Trojan horsed binaries, as 5291.9Scgd# the hacker can modify the tree specification to match the replaced binary. 5301.9Scgd# For details on really protecting yourself against modified binaries, see 5311.9Scgd# the mtree(8) manual page. 5321.16Smikelif [ X"$check_mtree" = XYES ]; then 5331.9Scgd mtree -e -p / -f /etc/mtree/special > $OUTPUT 5341.15Smrg if [ -s $OUTPUT ]; then 5351.9Scgd printf "\nChecking special files and directories.\n" 5361.9Scgd cat $OUTPUT 5371.9Scgd fi 5381.9Scgd 5391.9Scgd > $OUTPUT 5401.16Smikel for file in /etc/mtree/*.secure; do 5411.16Smikel [ $file = '/etc/mtree/*.secure' ] && continue 5421.9Scgd tree=`sed -n -e '3s/.* //p' -e 3q $file` 5431.9Scgd mtree -f $file -p $tree > $TMP1 5441.9Scgd if [ -s $TMP1 ]; then 5451.9Scgd printf "\nChecking $tree:\n" >> $OUTPUT 5461.9Scgd cat $TMP1 >> $OUTPUT 5471.9Scgd fi 5481.9Scgd done 5491.15Smrg if [ -s $OUTPUT ]; then 5501.9Scgd printf "\nChecking system binaries:\n" 5511.9Scgd cat $OUTPUT 5521.9Scgd fi 5531.9Scgdfi 5541.9Scgd 5551.9Scgd# List of files that get backed up and checked for any modifications. Each 5561.9Scgd# file is expected to have two backups, /var/backups/file.{current,backup}. 5571.9Scgd# Any changes cause the files to rotate. 5581.15Smrgif [ X"$check_changelist" = XYES -a -s /etc/changelist ] ; then 5591.9Scgd for file in `cat /etc/changelist`; do 5601.9Scgd CUR=/var/backups/`basename $file`.current 5611.9Scgd BACK=/var/backups/`basename $file`.backup 5621.9Scgd if [ -s $file ]; then 5631.9Scgd if [ -s $CUR ] ; then 5641.9Scgd diff $CUR $file > $OUTPUT 5651.9Scgd if [ -s $OUTPUT ] ; then 5661.9Scgd printf "\n======\n%s diffs (OLD < > NEW)\n======\n" $file 5671.9Scgd cat $OUTPUT 5681.9Scgd cp -p $CUR $BACK 5691.9Scgd cp -p $file $CUR 5701.9Scgd chown root.wheel $CUR $BACK 5711.9Scgd fi 5721.9Scgd else 5731.9Scgd cp -p $file $CUR 5741.9Scgd chown root.wheel $CUR 5751.9Scgd fi 5761.9Scgd fi 5771.9Scgd done 5781.9Scgdfi 579