security revision 1.13
11.1Scgd#!/bin/sh - 21.1Scgd# 31.13Spk# $NetBSD: security,v 1.13 1996/01/14 00:58:25 pk 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.9ScgdERR=/tmp/_secure1.$$ 121.9ScgdTMP1=/tmp/_secure2.$$ 131.9ScgdTMP2=/tmp/_secure3.$$ 141.9ScgdTMP3=/tmp/_secure4.$$ 151.9ScgdLIST=/tmp/_secure5.$$ 161.9ScgdOUTPUT=/tmp/_secure6.$$ 171.9Scgd 181.9Scgdtrap 'rm -f $ERR $TMP1 $TMP2 $TMP3 $LIST $OUTPUT' 0 191.9Scgd 201.9Scgd# Check the master password file syntax. 211.9ScgdMP=/etc/master.passwd 221.9Scgdawk -F: '{ 231.9Scgd if ($0 ~ /^[ ]*$/) { 241.9Scgd printf("Line %d is a blank line.\n", NR); 251.9Scgd next; 261.9Scgd } 271.9Scgd if (NF != 10) 281.9Scgd printf("Line %d has the wrong number of fields.\n", NR); 291.9Scgd if ($1 !~ /^[A-Za-z0-9]*$/) 301.9Scgd printf("Login %s has non-alphanumeric characters.\n", $1); 311.9Scgd if (length($1) > 8) 321.9Scgd printf("Login %s has more than 8 characters.\n", $1); 331.9Scgd if ($2 == "") 341.9Scgd printf("Login %s has no password.\n", $1); 351.13Spk if (length($2) != 13 && $2 != "" && ($10 ~ /.*sh$/ || $10 == "")) 361.9Scgd printf("Login %s is off but still has a valid shell.\n", $1); 371.9Scgd if ($3 == 0 && $1 != "root" && $1 != "toor") 381.9Scgd printf("Login %s has a user id of 0.\n", $1); 391.9Scgd if ($3 < 0) 401.9Scgd printf("Login %s has a negative user id.\n", $1); 411.9Scgd if ($4 < 0) 421.9Scgd printf("Login %s has a negative group id.\n", $1); 431.9Scgd}' < $MP > $OUTPUT 441.9Scgdif [ -s $OUTPUT ] ; then 451.9Scgd printf "\nChecking the $MP file:\n" 461.9Scgd cat $OUTPUT 471.9Scgdfi 481.9Scgd 491.9Scgdawk -F: '{ print $1 }' $MP | sort | uniq -d > $OUTPUT 501.9Scgdif [ -s $OUTPUT ] ; then 511.9Scgd printf "\n$MP has duplicate user names.\n" 521.9Scgd column $OUTPUT 531.9Scgdfi 541.9Scgd 551.9Scgdawk -F: '{ print $1 " " $3 }' $MP | sort -n +1 | tee $TMP1 | 561.9Scgduniq -d -f 1 | awk '{ print $2 }' > $TMP2 571.9Scgdif [ -s $TMP2 ] ; then 581.9Scgd printf "\n$MP has duplicate user id's.\n" 591.9Scgd while read uid; do 601.9Scgd grep -w $uid $TMP1 611.9Scgd done < $TMP2 | column 621.9Scgdfi 631.9Scgd 641.9Scgd# Backup the master password file; a special case, the normal backup 651.9Scgd# mechanisms also print out file differences and we don't want to do 661.9Scgd# that because this file has encrypted passwords in it. 671.9ScgdCUR=/var/backups/`basename $MP`.current 681.9ScgdBACK=/var/backups/`basename $MP`.backup 691.9Scgdif [ -s $CUR ] ; then 701.9Scgd if cmp -s $CUR $MP; then 711.9Scgd : 721.9Scgd else 731.9Scgd cp -p $CUR $BACK 741.9Scgd cp -p $MP $CUR 751.9Scgd chown root.wheel $CUR 761.9Scgd fi 771.9Scgdelse 781.9Scgd cp -p $MP $CUR 791.9Scgd chown root.wheel $CUR 801.9Scgdfi 811.9Scgd 821.9Scgd# Check the group file syntax. 831.9ScgdGRP=/etc/group 841.9Scgdawk -F: '{ 851.9Scgd if ($0 ~ /^[ ]*$/) { 861.9Scgd printf("Line %d is a blank line.\n", NR); 871.9Scgd next; 881.9Scgd } 891.9Scgd if (NF != 4) 901.9Scgd printf("Line %d has the wrong number of fields.\n", NR); 911.9Scgd if ($1 !~ /^[A-za-z0-9]*$/) 921.9Scgd printf("Group %s has non-alphanumeric characters.\n", $1); 931.9Scgd if (length($1) > 8) 941.9Scgd printf("Group %s has more than 8 characters.\n", $1); 951.9Scgd if ($3 !~ /[0-9]*/) 961.9Scgd printf("Login %s has a negative group id.\n", $1); 971.9Scgd}' < $GRP > $OUTPUT 981.9Scgdif [ -s $OUTPUT ] ; then 991.9Scgd printf "\nChecking the $GRP file:\n" 1001.9Scgd cat $OUTPUT 1011.9Scgdfi 1021.9Scgd 1031.9Scgdawk -F: '{ print $1 }' $GRP | sort | uniq -d > $OUTPUT 1041.9Scgdif [ -s $OUTPUT ] ; then 1051.9Scgd printf "\n$GRP has duplicate group names.\n" 1061.9Scgd column $OUTPUT 1071.9Scgdfi 1081.9Scgd 1091.9Scgd# Check for root paths, umask values in startup files. 1101.9Scgd# The check for the root paths is problematical -- it's likely to fail 1111.9Scgd# in other environments. Once the shells have been modified to warn 1121.9Scgd# of '.' in the path, the path tests should go away. 1131.9Scgd> $OUTPUT 1141.9Scgdrhome=/root 1151.9Scgdumaskset=no 1161.9Scgdlist="/etc/csh.cshrc /etc/csh.login ${rhome}/.cshrc ${rhome}/.login" 1171.9Scgdfor i in $list ; do 1181.9Scgd if [ -f $i ] ; then 1191.9Scgd if egrep umask $i > /dev/null ; then 1201.9Scgd umaskset=yes 1211.9Scgd fi 1221.9Scgd egrep umask $i | 1231.9Scgd awk '$2 % 100 < 20 \ 1241.9Scgd { print "Root umask is group writeable" } 1251.9Scgd $2 % 10 < 2 \ 1261.9Scgd { print "Root umask is other writeable" }' >> $OUTPUT 1271.9Scgd /bin/csh -f -s << end-of-csh > /dev/null 2>&1 1281.9Scgd unset path 1291.9Scgd source $i 1301.9Scgd /bin/ls -ldgT \$path > $TMP1 1311.9Scgdend-of-csh 1321.9Scgd awk '{ 1331.9Scgd if ($10 ~ /^\.$/) { 1341.9Scgd print "The root path includes ."; 1351.9Scgd next; 1361.9Scgd } 1371.9Scgd } 1381.9Scgd $1 ~ /^d....w/ \ 1391.9Scgd { print "Root path directory " $10 " is group writeable." } \ 1401.9Scgd $1 ~ /^d.......w/ \ 1411.9Scgd { print "Root path directory " $10 " is other writeable." }' \ 1421.9Scgd < $TMP1 >> $OUTPUT 1431.9Scgd fi 1441.9Scgddone 1451.9Scgdif [ $umaskset = "no" -o -s $OUTPUT ] ; then 1461.9Scgd printf "\nChecking root csh paths, umask values:\n$list\n" 1471.9Scgd if [ -s $OUTPUT ]; then 1481.9Scgd cat $OUTPUT 1491.9Scgd fi 1501.9Scgd if [ $umaskset = "no" ] ; then 1511.9Scgd printf "\nRoot csh startup files do not set the umask.\n" 1521.9Scgd fi 1531.9Scgdfi 1541.9Scgd 1551.9Scgd> $OUTPUT 1561.9Scgdrhome=/root 1571.9Scgdumaskset=no 1581.9Scgdlist="${rhome}/.profile" 1591.9Scgdfor i in $list; do 1601.9Scgd if [ -f $i ] ; then 1611.9Scgd if egrep umask $i > /dev/null ; then 1621.9Scgd umaskset=yes 1631.9Scgd fi 1641.9Scgd egrep umask $i | 1651.9Scgd awk '$2 % 100 < 20 \ 1661.9Scgd { print "Root umask is group writeable" } \ 1671.9Scgd $2 % 10 < 2 \ 1681.9Scgd { print "Root umask is other writeable" }' >> $OUTPUT 1691.9Scgd /bin/sh << end-of-sh > /dev/null 2>&1 1701.9Scgd PATH= 1711.9Scgd . $i 1721.9Scgd list=\`echo \$PATH | /usr/bin/sed -e 's/:/ /g'\` 1731.9Scgd /bin/ls -ldgT \$list > $TMP1 1741.9Scgdend-of-sh 1751.9Scgd awk '{ 1761.9Scgd if ($10 ~ /^\.$/) { 1771.9Scgd print "The root path includes ."; 1781.9Scgd next; 1791.9Scgd } 1801.9Scgd } 1811.9Scgd $1 ~ /^d....w/ \ 1821.9Scgd { print "Root path directory " $10 " is group writeable." } \ 1831.9Scgd $1 ~ /^d.......w/ \ 1841.9Scgd { print "Root path directory " $10 " is other writeable." }' \ 1851.9Scgd < $TMP1 >> $OUTPUT 1861.9Scgd 1871.9Scgd fi 1881.9Scgddone 1891.9Scgdif [ $umaskset = "no" -o -s $OUTPUT ] ; then 1901.9Scgd printf "\nChecking root sh paths, umask values:\n$list\n" 1911.9Scgd if [ -s $OUTPUT ]; then 1921.9Scgd cat $OUTPUT 1931.9Scgd fi 1941.9Scgd if [ $umaskset = "no" ] ; then 1951.9Scgd printf "\nRoot sh startup files do not set the umask.\n" 1961.9Scgd fi 1971.9Scgdfi 1981.9Scgd 1991.9Scgd# Root and uucp should both be in /etc/ftpusers. 2001.9Scgdif egrep root /etc/ftpusers > /dev/null ; then 2011.9Scgd : 2021.9Scgdelse 2031.9Scgd printf "\nRoot not listed in /etc/ftpusers file.\n" 2041.9Scgdfi 2051.9Scgdif egrep uucp /etc/ftpusers > /dev/null ; then 2061.9Scgd : 2071.9Scgdelse 2081.9Scgd printf "\nUucp not listed in /etc/ftpusers file.\n" 2091.9Scgdfi 2101.9Scgd 2111.9Scgd# Uudecode should not be in the /etc/aliases file. 2121.9Scgdif egrep 'uudecode|decode' /etc/aliases; then 2131.9Scgd printf "\nThere is an entry for uudecode in the /etc/aliases file.\n" 2141.9Scgdfi 2151.9Scgd 2161.9Scgd# Files that should not have + signs. 2171.9Scgdlist="/etc/hosts.equiv /etc/hosts.lpd" 2181.9Scgdfor f in $list ; do 2191.13Spk if [ -f $f ] && egrep '\+' $f > /dev/null ; then 2201.9Scgd printf "\nPlus sign in $f file.\n" 2211.9Scgd fi 2221.9Scgddone 2231.9Scgd 2241.9Scgd# Check for special users with .rhosts files. Only root and toor should 2251.9Scgd# have a .rhosts files. Also, .rhosts files should not plus signs. 2261.9Scgdawk -F: '$1 != "root" && $1 != "toor" && \ 2271.9Scgd ($3 < 100 || $1 == "ftp" || $1 == "uucp") \ 2281.9Scgd { print $1 " " $6 }' /etc/passwd | 2291.9Scgdwhile read uid homedir; do 2301.9Scgd if [ -f ${homedir}/.rhosts ] ; then 2311.9Scgd rhost=`ls -ldgT ${homedir}/.rhosts` 2321.9Scgd printf "$uid: $rhost\n" 2331.9Scgd fi 2341.9Scgddone > $OUTPUT 2351.9Scgdif [ -s $OUTPUT ] ; then 2361.9Scgd printf "\nChecking for special users with .rhosts files.\n" 2371.9Scgd cat $OUTPUT 2381.9Scgdfi 2391.9Scgd 2401.9Scgdawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 2411.9Scgdwhile read uid homedir; do 2421.9Scgd if [ -f ${homedir}/.rhosts ] && \ 2431.9Scgd egrep '\+' ${homedir}/.rhosts > /dev/null ; then 2441.9Scgd printf "$uid: + in .rhosts file.\n" 2451.9Scgd fi 2461.9Scgddone > $OUTPUT 2471.9Scgdif [ -s $OUTPUT ] ; then 2481.9Scgd printf "\nChecking .rhosts files syntax.\n" 2491.9Scgd cat $OUTPUT 2501.9Scgdfi 2511.9Scgd 2521.9Scgd# Check home directories. Directories should not be owned by someone else 2531.9Scgd# or writeable. 2541.9Scgdawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 2551.9Scgdwhile read uid homedir; do 2561.9Scgd if [ -d ${homedir}/ ] ; then 2571.9Scgd file=`ls -ldgT ${homedir}` 2581.9Scgd printf "$uid $file\n" 2591.9Scgd fi 2601.9Scgddone | 2611.9Scgdawk '$1 != $4 && $4 != "root" \ 2621.9Scgd { print "user " $1 " home directory is owned by " $4 } 2631.9Scgd $2 ~ /^-....w/ \ 2641.9Scgd { print "user " $1 " home directory is group writeable" } 2651.9Scgd $2 ~ /^-.......w/ \ 2661.9Scgd { print "user " $1 " home directory is other writeable" }' > $OUTPUT 2671.9Scgdif [ -s $OUTPUT ] ; then 2681.9Scgd printf "\nChecking home directories.\n" 2691.9Scgd cat $OUTPUT 2701.9Scgdfi 2711.9Scgd 2721.9Scgd# Files that should not be owned by someone else or readable. 2731.9Scgdlist=".netrc .rhosts" 2741.9Scgdawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 2751.9Scgdwhile read uid homedir; do 2761.9Scgd for f in $list ; do 2771.9Scgd file=${homedir}/${f} 2781.9Scgd if [ -f $file ] ; then 2791.9Scgd printf "$uid $f `ls -ldgT $file`\n" 2801.9Scgd fi 2811.9Scgd done 2821.9Scgddone | 2831.9Scgdawk '$1 != $5 && $5 != "root" \ 2841.9Scgd { print "user " $1 " " $2 " file is owned by " $5 } 2851.9Scgd $3 ~ /^-...r/ \ 2861.9Scgd { print "user " $1 " " $2 " file is group readable" } 2871.9Scgd $3 ~ /^-......r/ \ 2881.9Scgd { print "user " $1 " " $2 " file is other readable" } 2891.9Scgd $3 ~ /^-....w/ \ 2901.9Scgd { print "user " $1 " " $2 " file is group writeable" } 2911.9Scgd $3 ~ /^-.......w/ \ 2921.9Scgd { print "user " $1 " " $2 " file is other writeable" }' > $OUTPUT 2931.9Scgd 2941.9Scgd# Files that should not be owned by someone else or writeable. 2951.11Sjtclist=".bashrc .cshrc .emacs .exrc .forward .klogin .login .logout \ 2961.9Scgd .profile .tcshrc" 2971.9Scgdawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 2981.9Scgdwhile read uid homedir; do 2991.9Scgd for f in $list ; do 3001.9Scgd file=${homedir}/${f} 3011.9Scgd if [ -f $file ] ; then 3021.9Scgd printf "$uid $f `ls -ldgT $file`\n" 3031.9Scgd fi 3041.9Scgd done 3051.9Scgddone | 3061.9Scgdawk '$1 != $5 && $5 != "root" \ 3071.9Scgd { print "user " $1 " " $2 " file is owned by " $5 } 3081.9Scgd $3 ~ /^-....w/ \ 3091.9Scgd { print "user " $1 " " $2 " file is group writeable" } 3101.9Scgd $3 ~ /^-.......w/ \ 3111.9Scgd { print "user " $1 " " $2 " file is other writeable" }' >> $OUTPUT 3121.9Scgdif [ -s $OUTPUT ] ; then 3131.9Scgd printf "\nChecking dot files.\n" 3141.9Scgd cat $OUTPUT 3151.9Scgdfi 3161.9Scgd 3171.9Scgd# Mailboxes should be owned by user and unreadable. 3181.9Scgdls -l /var/mail | sed 1d | \ 3191.9Scgdawk '$3 != $9 \ 3201.9Scgd { print "user " $9 " mailbox is owned by " $3 } 3211.9Scgd $1 != "-rw-------" \ 3221.9Scgd { print "user " $9 " mailbox is " $1 ", group " $4 }' > $OUTPUT 3231.9Scgdif [ -s $OUTPUT ] ; then 3241.9Scgd printf "\nChecking mailbox ownership.\n" 3251.9Scgd cat $OUTPUT 3261.9Scgdfi 3271.9Scgd 3281.13Spkif [ -f /etc/exports ]; then 3291.13Spk # File systems should not be globally exported. 3301.13Spk awk '{ 3311.9Scgd readonly = 0; 3321.9Scgd for (i = 2; i <= NF; ++i) { 3331.9Scgd if ($i ~ /-ro/) 3341.9Scgd readonly = 1; 3351.9Scgd else if ($i !~ /^-/) 3361.9Scgd next; 3371.9Scgd } 3381.9Scgd if (readonly) 3391.9Scgd print "File system " $1 " globally exported, read-only." 3401.9Scgd else 3411.9Scgd print "File system " $1 " globally exported, read-write." 3421.13Spk }' < /etc/exports > $OUTPUT 3431.13Spk if [ -s $OUTPUT ] ; then 3441.9Scgd printf "\nChecking for globally exported file systems.\n" 3451.9Scgd cat $OUTPUT 3461.13Spk fi 3471.9Scgdfi 3481.9Scgd 3491.9Scgd# Display any changes in setuid files and devices. 3501.9Scgdprintf "\nChecking setuid files and devices:\n" 3511.10Smycroft(find / \( ! -fstype local -o -fstype fdesc -o -fstype kernfs \ 3521.10Smycroft -o -fstype procfs \) -a -prune -o \ 3531.9Scgd \( -perm -u+s -o -perm -g+s -o ! -type d -a ! -type f -a ! -type l -a \ 3541.13Spk ! -type s \) -print | \ 3551.9Scgdsort | sed -e 's/^/ls -ldgT /' | sh > $LIST) 2> $OUTPUT 3561.9Scgd 3571.9Scgd# Display any errors that occurred during system file walk. 3581.9Scgdif [ -s $OUTPUT ] ; then 3591.9Scgd printf "Setuid/device find errors:\n" 3601.9Scgd cat $OUTPUT 3611.9Scgd printf "\n" 3621.9Scgdfi 3631.9Scgd 3641.9Scgd# Display any changes in the setuid file list. 3651.9Scgdegrep -v '^[bc]' $LIST > $TMP1 3661.9Scgdif [ -s $TMP1 ] ; then 3671.9Scgd # Check to make sure uudecode isn't setuid. 3681.9Scgd if grep -w uudecode $TMP1 > /dev/null ; then 3691.9Scgd printf "\nUudecode is setuid.\n" 3701.9Scgd fi 3711.9Scgd 3721.9Scgd CUR=/var/backups/setuid.current 3731.9Scgd BACK=/var/backups/setuid.backup 3741.9Scgd 3751.9Scgd if [ -s $CUR ] ; then 3761.9Scgd if cmp -s $CUR $TMP1 ; then 3771.9Scgd : 3781.9Scgd else 3791.9Scgd > $TMP2 3801.9Scgd join -110 -210 -v2 $CUR $TMP1 > $OUTPUT 3811.9Scgd if [ -s $OUTPUT ] ; then 3821.9Scgd printf "Setuid additions:\n" 3831.9Scgd tee -a $TMP2 < $OUTPUT 3841.9Scgd printf "\n" 3851.9Scgd fi 3861.9Scgd 3871.9Scgd join -110 -210 -v1 $CUR $TMP1 > $OUTPUT 3881.9Scgd if [ -s $OUTPUT ] ; then 3891.9Scgd printf "Setuid deletions:\n" 3901.9Scgd tee -a $TMP2 < $OUTPUT 3911.9Scgd printf "\n" 3921.9Scgd fi 3931.9Scgd 3941.9Scgd sort +9 $TMP2 $CUR $TMP1 | \ 3951.9Scgd sed -e 's/[ ][ ]*/ /g' | uniq -u > $OUTPUT 3961.9Scgd if [ -s $OUTPUT ] ; then 3971.9Scgd printf "Setuid changes:\n" 3981.9Scgd column -t $OUTPUT 3991.9Scgd printf "\n" 4001.9Scgd fi 4011.9Scgd 4021.9Scgd cp $CUR $BACK 4031.9Scgd cp $TMP1 $CUR 4041.9Scgd fi 4051.9Scgd else 4061.9Scgd printf "Setuid additions:\n" 4071.9Scgd column -t $TMP1 4081.9Scgd printf "\n" 4091.9Scgd cp $TMP1 $CUR 4101.9Scgd fi 4111.9Scgdfi 4121.9Scgd 4131.9Scgd# Check for block and character disk devices that are readable or writeable 4141.9Scgd# or not owned by root.operator. 4151.9Scgd>$TMP1 4161.9ScgdDISKLIST="dk fd hd hk hp jb kra ra rb rd rl rx rz sd up wd" 4171.9Scgdfor i in $DISKLIST; do 4181.9Scgd egrep "^b.*/${i}[0-9][0-9]*[a-h]$" $LIST >> $TMP1 4191.9Scgd egrep "^c.*/r${i}[0-9][0-9]*[a-h]$" $LIST >> $TMP1 4201.9Scgddone 4211.9Scgd 4221.9Scgdawk '$3 != "root" || $4 != "operator" || $1 !~ /.rw-r-----/ \ 4231.9Scgd { printf("Disk %s is user %s, group %s, permissions %s.\n", \ 4241.9Scgd $11, $3, $4, $1); }' < $TMP1 > $OUTPUT 4251.9Scgdif [ -s $OUTPUT ] ; then 4261.9Scgd printf "\nChecking disk ownership and permissions.\n" 4271.9Scgd cat $OUTPUT 4281.9Scgd printf "\n" 4291.9Scgdfi 4301.9Scgd 4311.9Scgd# Display any changes in the device file list. 4321.9Scgdegrep '^[bc]' $LIST | sort +10 > $TMP1 4331.9Scgdif [ -s $TMP1 ] ; then 4341.9Scgd CUR=/var/backups/device.current 4351.9Scgd BACK=/var/backups/device.backup 4361.9Scgd 4371.9Scgd if [ -s $CUR ] ; then 4381.9Scgd if cmp -s $CUR $TMP1 ; then 4391.9Scgd : 4401.9Scgd else 4411.9Scgd > $TMP2 4421.9Scgd join -111 -211 -v2 $CUR $TMP1 > $OUTPUT 4431.9Scgd if [ -s $OUTPUT ] ; then 4441.9Scgd printf "Device additions:\n" 4451.9Scgd tee -a $TMP2 < $OUTPUT 4461.9Scgd printf "\n" 4471.9Scgd fi 4481.9Scgd 4491.9Scgd join -111 -211 -v1 $CUR $TMP1 > $OUTPUT 4501.9Scgd if [ -s $OUTPUT ] ; then 4511.9Scgd printf "Device deletions:\n" 4521.9Scgd tee -a $TMP2 < $OUTPUT 4531.9Scgd printf "\n" 4541.9Scgd fi 4551.9Scgd 4561.9Scgd # Report any block device change. Ignore character 4571.9Scgd # devices, only the name is significant. 4581.9Scgd cat $TMP2 $CUR $TMP1 | \ 4591.9Scgd sed -e '/^c/d' | \ 4601.9Scgd sort +10 | \ 4611.9Scgd sed -e 's/[ ][ ]*/ /g' | \ 4621.9Scgd uniq -u > $OUTPUT 4631.9Scgd if [ -s $OUTPUT ] ; then 4641.9Scgd printf "Block device changes:\n" 4651.9Scgd column -t $OUTPUT 4661.9Scgd printf "\n" 4671.9Scgd fi 4681.9Scgd 4691.9Scgd cp $CUR $BACK 4701.9Scgd cp $TMP1 $CUR 4711.9Scgd fi 4721.9Scgd else 4731.9Scgd printf "Device additions:\n" 4741.9Scgd column -t $TMP1 4751.9Scgd printf "\n" 4761.9Scgd cp $TMP1 $CUR 4771.9Scgd fi 4781.9Scgdfi 4791.9Scgd 4801.9Scgd# Check special files. 4811.9Scgd# Check system binaries. 4821.9Scgd# 4831.9Scgd# Create the mtree tree specifications using: 4841.9Scgd# 4851.9Scgd# mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure 4861.9Scgd# chown root.wheel DIR.SECURE 4871.9Scgd# chmod 600 DIR.SECURE 4881.9Scgd# 4891.9Scgd# Note, this is not complete protection against Trojan horsed binaries, as 4901.9Scgd# the hacker can modify the tree specification to match the replaced binary. 4911.9Scgd# For details on really protecting yourself against modified binaries, see 4921.9Scgd# the mtree(8) manual page. 4931.9Scgdif cd /etc/mtree; then 4941.9Scgd mtree -e -p / -f /etc/mtree/special > $OUTPUT 4951.9Scgd if [ -s $OUTPUT ] ; then 4961.9Scgd printf "\nChecking special files and directories.\n" 4971.9Scgd cat $OUTPUT 4981.9Scgd fi 4991.9Scgd 5001.9Scgd > $OUTPUT 5011.9Scgd for file in *.secure; do 5021.13Spk [ $file = '*.secure' ] && continue 5031.9Scgd tree=`sed -n -e '3s/.* //p' -e 3q $file` 5041.9Scgd mtree -f $file -p $tree > $TMP1 5051.9Scgd if [ -s $TMP1 ]; then 5061.9Scgd printf "\nChecking $tree:\n" >> $OUTPUT 5071.9Scgd cat $TMP1 >> $OUTPUT 5081.9Scgd fi 5091.9Scgd done 5101.9Scgd if [ -s $OUTPUT ] ; then 5111.9Scgd printf "\nChecking system binaries:\n" 5121.9Scgd cat $OUTPUT 5131.9Scgd fi 5141.9Scgdfi 5151.9Scgd 5161.9Scgd# List of files that get backed up and checked for any modifications. Each 5171.9Scgd# file is expected to have two backups, /var/backups/file.{current,backup}. 5181.9Scgd# Any changes cause the files to rotate. 5191.9Scgdif [ -s /etc/changelist ] ; then 5201.9Scgd for file in `cat /etc/changelist`; do 5211.9Scgd CUR=/var/backups/`basename $file`.current 5221.9Scgd BACK=/var/backups/`basename $file`.backup 5231.9Scgd if [ -s $file ]; then 5241.9Scgd if [ -s $CUR ] ; then 5251.9Scgd diff $CUR $file > $OUTPUT 5261.9Scgd if [ -s $OUTPUT ] ; then 5271.9Scgd printf "\n======\n%s diffs (OLD < > NEW)\n======\n" $file 5281.9Scgd cat $OUTPUT 5291.9Scgd cp -p $CUR $BACK 5301.9Scgd cp -p $file $CUR 5311.9Scgd chown root.wheel $CUR $BACK 5321.9Scgd fi 5331.9Scgd else 5341.9Scgd cp -p $file $CUR 5351.9Scgd chown root.wheel $CUR 5361.9Scgd fi 5371.9Scgd fi 5381.9Scgd done 5391.9Scgdfi 540