Home | History | Annotate | Line # | Download | only in etc
security revision 1.21
      1   1.1      cgd #!/bin/sh -
      2   1.1      cgd #
      3  1.21  mycroft #	$NetBSD: security,v 1.21 1997/04/21 17:38:39 mycroft Exp $
      4   1.9      cgd #	from: @(#)security	8.1 (Berkeley) 6/9/93
      5   1.1      cgd #
      6   1.1      cgd 
      7   1.9      cgd PATH=/sbin:/usr/sbin:/bin:/usr/bin
      8   1.1      cgd 
      9   1.9      cgd umask 077
     10   1.1      cgd 
     11  1.15      mrg if [ -s /etc/security.conf ]; then
     12  1.15      mrg 	. /etc/security.conf
     13  1.15      mrg fi
     14  1.15      mrg 
     15  1.15      mrg SECUREDIR=/tmp/_securedir.$$
     16  1.15      mrg if ! mkdir $SECUREDIR; then
     17  1.15      mrg 	echo can not create $SECUREDIR.
     18  1.15      mrg 	exit 1
     19  1.15      mrg fi
     20  1.15      mrg 
     21  1.15      mrg if ! cd $SECUREDIR; then
     22  1.15      mrg 	echo can not chdir to $SECUREDIR.
     23  1.15      mrg 	exit 1
     24  1.15      mrg fi
     25  1.15      mrg 
     26  1.15      mrg ERR=secure1.$$
     27  1.15      mrg TMP1=secure2.$$
     28  1.15      mrg TMP2=secure3.$$
     29  1.15      mrg TMP3=secure4.$$
     30  1.15      mrg LIST=secure5.$$
     31  1.15      mrg OUTPUT=secure6.$$
     32  1.15      mrg 
     33  1.15      mrg trap 'rm -rf $SECUREDIR' 0
     34  1.15      mrg 
     35  1.15      mrg MP=/etc/master.passwd
     36   1.9      cgd 
     37  1.15      mrg # this is used several times.
     38  1.20  mycroft awk -F: '{ print $1 " " $3 }' $MP | sort -k2n > $TMP1
     39   1.9      cgd 
     40   1.9      cgd # Check the master password file syntax.
     41  1.17  mycroft if [ "$check_passwd" = YES ]; then
     42  1.15      mrg 	awk -F: '{
     43  1.15      mrg 		if ($0 ~ /^[	 ]*$/) {
     44  1.15      mrg 			printf("Line %d is a blank line.\n", NR);
     45  1.15      mrg 			next;
     46  1.15      mrg 		}
     47  1.15      mrg 		if (NF != 10)
     48  1.15      mrg 			printf("Line %d has the wrong number of fields.\n", NR);
     49  1.15      mrg 		if ($1 !~ /^[A-Za-z0-9]*$/)
     50  1.15      mrg 			printf("Login %s has non-alphanumeric characters.\n", $1);
     51  1.15      mrg 		if (length($1) > 8)
     52  1.15      mrg 			printf("Login %s has more than 8 characters.\n", $1);
     53  1.15      mrg 		if ($2 == "")
     54  1.15      mrg 			printf("Login %s has no password.\n", $1);
     55  1.15      mrg 		if (length($2) != 13 && $2 != "" && ($10 ~ /.*sh$/ || $10 == ""))
     56  1.15      mrg 			printf("Login %s is off but still has a valid shell.\n", $1);
     57  1.15      mrg 		if ($3 == 0 && $1 != "root" && $1 != "toor")
     58  1.15      mrg 			printf("Login %s has a user id of 0.\n", $1);
     59  1.15      mrg 		if ($3 < 0)
     60  1.15      mrg 			printf("Login %s has a negative user id.\n", $1);
     61  1.15      mrg 		if ($4 < 0)
     62  1.15      mrg 			printf("Login %s has a negative group id.\n", $1);
     63  1.15      mrg 	}' < $MP > $OUTPUT
     64  1.15      mrg 	if [ -s $OUTPUT ] ; then
     65  1.15      mrg 		printf "\nChecking the $MP file:\n"
     66  1.15      mrg 		cat $OUTPUT
     67  1.15      mrg 	fi
     68  1.15      mrg 
     69  1.15      mrg 	awk -F: '{ print $1 }' $MP | sort | uniq -d > $OUTPUT
     70  1.15      mrg 	if [ -s $OUTPUT ] ; then
     71  1.15      mrg 		printf "\n$MP has duplicate user names.\n"
     72  1.15      mrg 		column $OUTPUT
     73  1.15      mrg 	fi
     74  1.15      mrg 
     75  1.15      mrg 	< $TMP1 uniq -d -f 1 | awk '{ print $2 }' > $TMP2
     76  1.15      mrg 	if [ -s $TMP2 ] ; then
     77  1.15      mrg 		printf "\n$MP has duplicate user id's.\n"
     78  1.15      mrg 		while read uid; do
     79  1.15      mrg 			grep -w $uid $TMP1
     80  1.15      mrg 		done < $TMP2 | column
     81  1.15      mrg 	fi
     82   1.9      cgd fi
     83   1.9      cgd 
     84   1.9      cgd # Backup the master password file; a special case, the normal backup
     85   1.9      cgd # mechanisms also print out file differences and we don't want to do
     86   1.9      cgd # that because this file has encrypted passwords in it.
     87   1.9      cgd CUR=/var/backups/`basename $MP`.current
     88   1.9      cgd BACK=/var/backups/`basename $MP`.backup
     89   1.9      cgd if [ -s $CUR ] ; then
     90   1.9      cgd 	if cmp -s $CUR $MP; then
     91   1.9      cgd 		:
     92   1.9      cgd 	else
     93   1.9      cgd 		cp -p $CUR $BACK
     94   1.9      cgd 		cp -p $MP $CUR
     95   1.9      cgd 		chown root.wheel $CUR
     96   1.9      cgd 	fi
     97   1.9      cgd else
     98   1.9      cgd 	cp -p $MP $CUR
     99   1.9      cgd 	chown root.wheel $CUR
    100   1.9      cgd fi
    101   1.9      cgd 
    102   1.9      cgd # Check the group file syntax.
    103  1.17  mycroft if [ "$check_group" = YES ]; then
    104  1.15      mrg 	GRP=/etc/group
    105  1.15      mrg 	awk -F: '{
    106  1.15      mrg 		if ($0 ~ /^[	 ]*$/) {
    107  1.15      mrg 			printf("Line %d is a blank line.\n", NR);
    108  1.15      mrg 			next;
    109  1.15      mrg 		}
    110  1.15      mrg 		if (NF != 4)
    111  1.15      mrg 			printf("Line %d has the wrong number of fields.\n", NR);
    112  1.15      mrg 		if ($1 !~ /^[A-za-z0-9]*$/)
    113  1.15      mrg 			printf("Group %s has non-alphanumeric characters.\n", $1);
    114  1.15      mrg 		if (length($1) > 8)
    115  1.15      mrg 			printf("Group %s has more than 8 characters.\n", $1);
    116  1.15      mrg 		if ($3 !~ /[0-9]*/)
    117  1.15      mrg 			printf("Login %s has a negative group id.\n", $1);
    118  1.15      mrg 	}' < $GRP > $OUTPUT
    119  1.15      mrg 	if [ -s $OUTPUT ] ; then
    120  1.15      mrg 		printf "\nChecking the $GRP file:\n"
    121  1.15      mrg 		cat $OUTPUT
    122  1.15      mrg 	fi
    123  1.15      mrg 
    124  1.15      mrg 	awk -F: '{ print $1 }' $GRP | sort | uniq -d > $OUTPUT
    125  1.15      mrg 	if [ -s $OUTPUT ] ; then
    126  1.15      mrg 		printf "\n$GRP has duplicate group names.\n"
    127  1.15      mrg 		column $OUTPUT
    128  1.15      mrg 	fi
    129   1.9      cgd fi
    130   1.9      cgd 
    131   1.9      cgd # Check for root paths, umask values in startup files.
    132   1.9      cgd # The check for the root paths is problematical -- it's likely to fail
    133   1.9      cgd # in other environments.  Once the shells have been modified to warn
    134   1.9      cgd # of '.' in the path, the path tests should go away.
    135  1.17  mycroft if [ "$check_rootdotfiles" = YES ]; then
    136  1.15      mrg 	cp /dev/null $OUTPUT
    137  1.15      mrg 	rhome=`csh -fc "echo ~root"`
    138  1.15      mrg 	umaskset=no
    139  1.15      mrg 	list="/etc/csh.cshrc /etc/csh.login ${rhome}/.cshrc ${rhome}/.login"
    140  1.15      mrg 	for i in $list ; do
    141  1.15      mrg 		if [ -f $i ] ; then
    142  1.15      mrg 			if egrep umask $i > /dev/null ; then
    143  1.15      mrg 				umaskset=yes
    144  1.15      mrg 			fi
    145  1.15      mrg 			egrep umask $i |
    146  1.15      mrg 			awk '$2 % 100 < 20 \
    147  1.15      mrg 				{ print "Root umask is group writeable" }
    148  1.15      mrg 			     $2 % 10 < 2 \
    149  1.15      mrg 				{ print "Root umask is other writeable" }' >> $OUTPUT
    150  1.15      mrg 			/bin/csh -f -s << end-of-csh > /dev/null 2>&1
    151  1.15      mrg 				unset path
    152  1.15      mrg 				source $i
    153  1.15      mrg 				/bin/ls -ldgT \$path > $TMP1
    154   1.9      cgd end-of-csh
    155  1.15      mrg 			awk '{
    156  1.15      mrg 				if ($10 ~ /^\.$/) {
    157  1.15      mrg 					print "The root path includes .";
    158  1.15      mrg 					next;
    159  1.15      mrg 				}
    160  1.15      mrg 			     }
    161  1.15      mrg 			     $1 ~ /^d....w/ \
    162  1.15      mrg 		{ print "Root path directory " $10 " is group writeable." } \
    163  1.15      mrg 			     $1 ~ /^d.......w/ \
    164  1.15      mrg 		{ print "Root path directory " $10 " is other writeable." }' \
    165  1.15      mrg 			< $TMP1 >> $OUTPUT
    166  1.15      mrg 		fi
    167  1.15      mrg 	done
    168  1.15      mrg 	if [ $umaskset = "no" -o -s $OUTPUT ] ; then
    169  1.15      mrg 		printf "\nChecking root csh paths, umask values:\n$list\n"
    170  1.15      mrg 		if [ -s $OUTPUT ]; then
    171  1.15      mrg 			cat $OUTPUT
    172  1.15      mrg 		fi
    173  1.15      mrg 		if [ $umaskset = "no" ] ; then
    174  1.15      mrg 			printf "\nRoot csh startup files do not set the umask.\n"
    175  1.15      mrg 		fi
    176   1.9      cgd 	fi
    177   1.9      cgd 
    178  1.15      mrg 	cp /dev/null $OUTPUT
    179  1.15      mrg 	rhome=/root
    180  1.15      mrg 	umaskset=no
    181  1.15      mrg 	list="${rhome}/.profile"
    182  1.15      mrg 	for i in $list; do
    183  1.15      mrg 		if [ -f $i ] ; then
    184  1.15      mrg 			if egrep umask $i > /dev/null ; then
    185  1.15      mrg 				umaskset=yes
    186  1.15      mrg 			fi
    187  1.15      mrg 			egrep umask $i |
    188  1.15      mrg 			awk '$2 % 100 < 20 \
    189  1.15      mrg 				{ print "Root umask is group writeable" } \
    190  1.15      mrg 			     $2 % 10 < 2 \
    191  1.15      mrg 				{ print "Root umask is other writeable" }' >> $OUTPUT
    192  1.15      mrg 			/bin/sh << end-of-sh > /dev/null 2>&1
    193  1.15      mrg 				PATH=
    194  1.15      mrg 				. $i
    195  1.15      mrg 				list=\`echo \$PATH | /usr/bin/sed -e 's/:/ /g'\`
    196  1.15      mrg 				/bin/ls -ldgT \$list > $TMP1
    197   1.9      cgd end-of-sh
    198  1.15      mrg 			awk '{
    199  1.15      mrg 				if ($10 ~ /^\.$/) {
    200  1.15      mrg 					print "The root path includes .";
    201  1.15      mrg 					next;
    202  1.15      mrg 				}
    203  1.15      mrg 			     }
    204  1.15      mrg 			     $1 ~ /^d....w/ \
    205  1.15      mrg 		{ print "Root path directory " $10 " is group writeable." } \
    206  1.15      mrg 			     $1 ~ /^d.......w/ \
    207  1.15      mrg 		{ print "Root path directory " $10 " is other writeable." }' \
    208  1.15      mrg 			< $TMP1 >> $OUTPUT
    209   1.9      cgd 
    210  1.15      mrg 		fi
    211  1.15      mrg 	done
    212  1.15      mrg 	if [ $umaskset = "no" -o -s $OUTPUT ] ; then
    213  1.15      mrg 		printf "\nChecking root sh paths, umask values:\n$list\n"
    214  1.15      mrg 		if [ -s $OUTPUT ]; then
    215  1.15      mrg 			cat $OUTPUT
    216  1.15      mrg 		fi
    217  1.15      mrg 		if [ $umaskset = "no" ] ; then
    218  1.15      mrg 			printf "\nRoot sh startup files do not set the umask.\n"
    219  1.15      mrg 		fi
    220   1.9      cgd 	fi
    221   1.9      cgd fi
    222   1.9      cgd 
    223   1.9      cgd # Root and uucp should both be in /etc/ftpusers.
    224  1.17  mycroft if [ "$check_ftpusers" = YES ]; then
    225  1.15      mrg 	if egrep root /etc/ftpusers > /dev/null ; then
    226  1.15      mrg 		:
    227  1.15      mrg 	else
    228  1.15      mrg 		printf "\nRoot not listed in /etc/ftpusers file.\n"
    229  1.15      mrg 	fi
    230  1.15      mrg 	if egrep uucp /etc/ftpusers > /dev/null ; then
    231  1.15      mrg 		:
    232  1.15      mrg 	else
    233  1.15      mrg 		printf "\nUucp not listed in /etc/ftpusers file.\n"
    234  1.15      mrg 	fi
    235   1.9      cgd fi
    236   1.9      cgd 
    237   1.9      cgd # Uudecode should not be in the /etc/aliases file.
    238  1.17  mycroft if [ "$check_aliases" = YES ]; then
    239  1.18    mikel 	if egrep '^[^#]*(uudecode|decode).*\|' /etc/aliases; then
    240  1.18    mikel 		printf "\nEntry for uudecode in /etc/aliases file.\n"
    241  1.15      mrg 	fi
    242   1.9      cgd fi
    243   1.9      cgd 
    244   1.9      cgd # Files that should not have + signs.
    245  1.17  mycroft if [ "$check_rhosts" = YES ]; then
    246  1.15      mrg 	list="/etc/hosts.equiv /etc/hosts.lpd"
    247  1.15      mrg 	for f in $list ; do
    248  1.15      mrg 		if [ -f $f ] && egrep '\+' $f > /dev/null ; then
    249  1.15      mrg 			printf "\nPlus sign in $f file.\n"
    250  1.15      mrg 		fi
    251  1.15      mrg 	done
    252  1.15      mrg 
    253  1.15      mrg 	# Check for special users with .rhosts files.  Only root and toor should
    254  1.16    mikel 	# have .rhosts files.  Also, .rhosts files should not have plus signs.
    255  1.15      mrg 	awk -F: '$1 != "root" && $1 != "toor" && \
    256  1.15      mrg 		($3 < 100 || $1 == "ftp" || $1 == "uucp") \
    257  1.20  mycroft 			{ print $1 " " $9 }' $MP |
    258  1.19  mycroft 	sort -k2 |
    259  1.15      mrg 	while read uid homedir; do
    260  1.15      mrg 		if [ -f ${homedir}/.rhosts ] ; then
    261  1.15      mrg 			rhost=`ls -ldgT ${homedir}/.rhosts`
    262  1.15      mrg 			printf "$uid: $rhost\n"
    263  1.15      mrg 		fi
    264  1.15      mrg 	done > $OUTPUT
    265  1.15      mrg 	if [ -s $OUTPUT ] ; then
    266  1.15      mrg 		printf "\nChecking for special users with .rhosts files.\n"
    267  1.15      mrg 		cat $OUTPUT
    268  1.15      mrg 	fi
    269  1.15      mrg 
    270  1.20  mycroft 	awk -F: '{ print $1 " " $9 }' $MP |
    271  1.19  mycroft 	sort -k2 |
    272  1.15      mrg 	while read uid homedir; do
    273  1.15      mrg 		if [ -f ${homedir}/.rhosts ] && \
    274  1.15      mrg 		    egrep '\+' ${homedir}/.rhosts > /dev/null ; then
    275  1.15      mrg 			printf "$uid: + in .rhosts file.\n"
    276  1.15      mrg 		fi
    277  1.15      mrg 	done > $OUTPUT
    278  1.15      mrg 	if [ -s $OUTPUT ] ; then
    279  1.15      mrg 		printf "\nChecking .rhosts files syntax.\n"
    280  1.15      mrg 		cat $OUTPUT
    281  1.15      mrg 	fi
    282   1.9      cgd fi
    283   1.9      cgd 
    284   1.9      cgd # Check home directories.  Directories should not be owned by someone else
    285   1.9      cgd # or writeable.
    286  1.17  mycroft if [ "$check_homes" = YES ]; then
    287  1.20  mycroft 	awk -F: '{ print $1 " " $9 }' $MP |
    288  1.19  mycroft 	sort -k2 |
    289  1.15      mrg 	while read uid homedir; do
    290  1.15      mrg 		if [ -d ${homedir}/ ] ; then
    291  1.15      mrg 			file=`ls -ldgT ${homedir}`
    292  1.15      mrg 			printf "$uid $file\n"
    293   1.9      cgd 		fi
    294  1.15      mrg 	done |
    295  1.15      mrg 	awk '$1 != $4 && $4 != "root" \
    296  1.15      mrg 		{ print "user " $1 " home directory is owned by " $4 }
    297  1.15      mrg 	     $2 ~ /^-....w/ \
    298  1.15      mrg 		{ print "user " $1 " home directory is group writeable" }
    299  1.15      mrg 	     $2 ~ /^-.......w/ \
    300  1.15      mrg 		{ print "user " $1 " home directory is other writeable" }' > $OUTPUT
    301  1.15      mrg 	if [ -s $OUTPUT ] ; then
    302  1.15      mrg 		printf "\nChecking home directories.\n"
    303  1.15      mrg 		cat $OUTPUT
    304  1.15      mrg 	fi
    305  1.15      mrg 
    306  1.15      mrg 	# Files that should not be owned by someone else or readable.
    307  1.19  mycroft 	list=".Xauthority .netrc .rhosts"
    308  1.20  mycroft 	awk -F: '{ print $1 " " $9 }' $MP |
    309  1.19  mycroft 	sort -k2 |
    310  1.15      mrg 	while read uid homedir; do
    311  1.15      mrg 		for f in $list ; do
    312  1.15      mrg 			file=${homedir}/${f}
    313  1.15      mrg 			if [ -f $file ] ; then
    314  1.15      mrg 				printf "$uid $f `ls -ldgT $file`\n"
    315  1.15      mrg 			fi
    316  1.15      mrg 		done
    317  1.15      mrg 	done |
    318  1.15      mrg 	awk '$1 != $5 && $5 != "root" \
    319  1.15      mrg 		{ print "user " $1 " " $2 " file is owned by " $5 }
    320  1.15      mrg 	     $3 ~ /^-...r/ \
    321  1.15      mrg 		{ print "user " $1 " " $2 " file is group readable" }
    322  1.15      mrg 	     $3 ~ /^-......r/ \
    323  1.15      mrg 		{ print "user " $1 " " $2 " file is other readable" }
    324  1.15      mrg 	     $3 ~ /^-....w/ \
    325  1.15      mrg 		{ print "user " $1 " " $2 " file is group writeable" }
    326  1.15      mrg 	     $3 ~ /^-.......w/ \
    327  1.15      mrg 		{ print "user " $1 " " $2 " file is other writeable" }' > $OUTPUT
    328  1.15      mrg 
    329  1.15      mrg 	# Files that should not be owned by someone else or writeable.
    330  1.19  mycroft 	list=".bash_history .bash_login .bash_logout .bash_profile .bashrc \
    331  1.19  mycroft 	      .cshrc .emacs .exrc .forward .history .klogin .login .logout \
    332  1.19  mycroft 	      .profile .qmail .rc_history .tcshrc .twmrc .xinitrc .xsession"
    333  1.20  mycroft 	awk -F: '{ print $1 " " $9 }' $MP |
    334  1.19  mycroft 	sort -k2 |
    335  1.15      mrg 	while read uid homedir; do
    336  1.15      mrg 		for f in $list ; do
    337  1.15      mrg 			file=${homedir}/${f}
    338  1.15      mrg 			if [ -f $file ] ; then
    339  1.15      mrg 				printf "$uid $f `ls -ldgT $file`\n"
    340  1.15      mrg 			fi
    341  1.15      mrg 		done
    342  1.15      mrg 	done |
    343  1.15      mrg 	awk '$1 != $5 && $5 != "root" \
    344  1.15      mrg 		{ print "user " $1 " " $2 " file is owned by " $5 }
    345  1.15      mrg 	     $3 ~ /^-....w/ \
    346  1.15      mrg 		{ print "user " $1 " " $2 " file is group writeable" }
    347  1.15      mrg 	     $3 ~ /^-.......w/ \
    348  1.15      mrg 		{ print "user " $1 " " $2 " file is other writeable" }' >> $OUTPUT
    349  1.15      mrg 	if [ -s $OUTPUT ] ; then
    350  1.15      mrg 		printf "\nChecking dot files.\n"
    351  1.15      mrg 		cat $OUTPUT
    352  1.15      mrg 	fi
    353   1.9      cgd fi
    354   1.9      cgd 
    355   1.9      cgd # Mailboxes should be owned by user and unreadable.
    356  1.17  mycroft if [ "$check_varmail" = YES ]; then
    357  1.15      mrg 	ls -l /var/mail | sed 1d | \
    358  1.15      mrg 	awk '$3 != $9 \
    359  1.15      mrg 		{ print "user " $9 " mailbox is owned by " $3 }
    360  1.15      mrg 	     $1 != "-rw-------" \
    361  1.15      mrg 		{ print "user " $9 " mailbox is " $1 ", group " $4 }' > $OUTPUT
    362  1.15      mrg 	if [ -s $OUTPUT ] ; then
    363  1.15      mrg 		printf "\nChecking mailbox ownership.\n"
    364  1.15      mrg 		cat $OUTPUT
    365  1.15      mrg 	fi
    366  1.15      mrg fi
    367  1.15      mrg 
    368  1.17  mycroft if [ "$check_nfs" = YES ]; then
    369  1.15      mrg 	if [ -f /etc/exports ]; then
    370  1.15      mrg 	    # File systems should not be globally exported.
    371  1.15      mrg 	    awk '{
    372  1.15      mrg 		readonly = 0;
    373  1.15      mrg 		for (i = 2; i <= NF; ++i) {
    374  1.15      mrg 			if ($i ~ /-ro/)
    375  1.15      mrg 				readonly = 1;
    376  1.15      mrg 			else if ($i !~ /^-/)
    377  1.15      mrg 				next;
    378  1.15      mrg 		}
    379  1.15      mrg 		if (readonly)
    380  1.15      mrg 			print "File system " $1 " globally exported, read-only."
    381  1.15      mrg 		else
    382  1.15      mrg 			print "File system " $1 " globally exported, read-write."
    383  1.15      mrg 	    }' < /etc/exports > $OUTPUT
    384  1.15      mrg 	    if [ -s $OUTPUT ] ; then
    385  1.15      mrg 		printf "\nChecking for globally exported file systems.\n"
    386  1.15      mrg 		cat $OUTPUT
    387  1.15      mrg 	    fi
    388  1.15      mrg 	fi
    389   1.9      cgd fi
    390   1.9      cgd 
    391   1.9      cgd # Display any changes in setuid files and devices.
    392  1.17  mycroft if [ "$check_devices" = YES ]; then
    393  1.15      mrg 	printf "\nChecking setuid files and devices:\n"
    394  1.15      mrg 	(find / \( ! -fstype local -o -fstype fdesc -o -fstype kernfs \
    395  1.15      mrg 			-o -fstype procfs \) -a -prune -o \
    396  1.21  mycroft 	    \( \( -perm -u+s -a ! -type d \) -o \
    397  1.21  mycroft 	       \( -perm -g+s -a ! -type d \) -o \
    398  1.21  mycroft 	       -type b -o -type c \) -print | \
    399  1.15      mrg 	sort | sed -e 's/^/ls -ldgT /' | sh > $LIST) 2> $OUTPUT
    400  1.15      mrg 
    401  1.15      mrg 	# Display any errors that occurred during system file walk.
    402  1.15      mrg 	if [ -s $OUTPUT ] ; then
    403  1.15      mrg 		printf "Setuid/device find errors:\n"
    404  1.15      mrg 		cat $OUTPUT
    405  1.15      mrg 		printf "\n"
    406  1.15      mrg 	fi
    407  1.15      mrg 
    408  1.15      mrg 	# Display any changes in the setuid file list.
    409  1.15      mrg 	egrep -v '^[bc]' $LIST > $TMP1
    410  1.15      mrg 	if [ -s $TMP1 ] ; then
    411  1.15      mrg 		# Check to make sure uudecode isn't setuid.
    412  1.15      mrg 		if grep -w uudecode $TMP1 > /dev/null ; then
    413  1.15      mrg 			printf "\nUudecode is setuid.\n"
    414  1.15      mrg 		fi
    415  1.15      mrg 
    416  1.15      mrg 		CUR=/var/backups/setuid.current
    417  1.15      mrg 		BACK=/var/backups/setuid.backup
    418   1.9      cgd 
    419  1.15      mrg 		if [ -s $CUR ] ; then
    420  1.15      mrg 			if cmp -s $CUR $TMP1 ; then
    421  1.15      mrg 				:
    422  1.15      mrg 			else
    423  1.15      mrg 				> $TMP2
    424  1.15      mrg 				join -110 -210 -v2 $CUR $TMP1 > $OUTPUT
    425  1.15      mrg 				if [ -s $OUTPUT ] ; then
    426  1.15      mrg 					printf "Setuid additions:\n"
    427  1.15      mrg 					tee -a $TMP2 < $OUTPUT
    428  1.15      mrg 					printf "\n"
    429  1.15      mrg 				fi
    430  1.15      mrg 
    431  1.15      mrg 				join -110 -210 -v1 $CUR $TMP1 > $OUTPUT
    432  1.15      mrg 				if [ -s $OUTPUT ] ; then
    433  1.15      mrg 					printf "Setuid deletions:\n"
    434  1.15      mrg 					tee -a $TMP2 < $OUTPUT
    435  1.15      mrg 					printf "\n"
    436  1.15      mrg 				fi
    437  1.15      mrg 
    438  1.20  mycroft 				sort -k10 $TMP2 $CUR $TMP1 | \
    439  1.15      mrg 				    sed -e 's/[	 ][	 ]*/ /g' | uniq -u > $OUTPUT
    440  1.15      mrg 				if [ -s $OUTPUT ] ; then
    441  1.15      mrg 					printf "Setuid changes:\n"
    442  1.15      mrg 					column -t $OUTPUT
    443  1.15      mrg 					printf "\n"
    444  1.15      mrg 				fi
    445   1.9      cgd 
    446  1.15      mrg 				cp $CUR $BACK
    447  1.15      mrg 				cp $TMP1 $CUR
    448   1.9      cgd 			fi
    449  1.15      mrg 		else
    450  1.15      mrg 			printf "Setuid additions:\n"
    451  1.15      mrg 			column -t $TMP1
    452  1.15      mrg 			printf "\n"
    453   1.9      cgd 			cp $TMP1 $CUR
    454   1.9      cgd 		fi
    455  1.15      mrg 	fi
    456  1.15      mrg 
    457  1.15      mrg 	# Check for block and character disk devices that are readable or writeable
    458  1.15      mrg 	# or not owned by root.operator.
    459  1.15      mrg 	>$TMP1
    460  1.15      mrg 	DISKLIST="dk fd hd hk hp jb kra ra rb rd rl rx rz sd up wd xd xy"
    461  1.15      mrg 	for i in $DISKLIST; do
    462  1.15      mrg 		egrep "^b.*/${i}[0-9][0-9]*[a-p]$"  $LIST >> $TMP1
    463  1.15      mrg 		egrep "^c.*/r${i}[0-9][0-9]*[a-p]$"  $LIST >> $TMP1
    464  1.15      mrg 	done
    465  1.15      mrg 
    466  1.15      mrg 	awk '$3 != "root" || $4 != "operator" || $1 !~ /.rw-r-----/ \
    467  1.15      mrg 		{ printf("Disk %s is user %s, group %s, permissions %s.\n", \
    468  1.15      mrg 		    $11, $3, $4, $1); }' < $TMP1 > $OUTPUT
    469  1.15      mrg 	if [ -s $OUTPUT ] ; then
    470  1.15      mrg 		printf "\nChecking disk ownership and permissions.\n"
    471  1.15      mrg 		cat $OUTPUT
    472   1.9      cgd 		printf "\n"
    473   1.9      cgd 	fi
    474   1.9      cgd 
    475  1.15      mrg 	# Display any changes in the device file list.
    476  1.20  mycroft 	egrep '^[bc]' $LIST | sort -k11 > $TMP1
    477  1.15      mrg 	if [ -s $TMP1 ] ; then
    478  1.15      mrg 		CUR=/var/backups/device.current
    479  1.15      mrg 		BACK=/var/backups/device.backup
    480  1.15      mrg 
    481  1.15      mrg 		if [ -s $CUR ] ; then
    482  1.15      mrg 			if cmp -s $CUR $TMP1 ; then
    483  1.15      mrg 				:
    484  1.15      mrg 			else
    485  1.15      mrg 				> $TMP2
    486  1.15      mrg 				join -111 -211 -v2 $CUR $TMP1 > $OUTPUT
    487  1.15      mrg 				if [ -s $OUTPUT ] ; then
    488  1.15      mrg 					printf "Device additions:\n"
    489  1.15      mrg 					tee -a $TMP2 < $OUTPUT
    490  1.15      mrg 					printf "\n"
    491  1.15      mrg 				fi
    492  1.15      mrg 
    493  1.15      mrg 				join -111 -211 -v1 $CUR $TMP1 > $OUTPUT
    494  1.15      mrg 				if [ -s $OUTPUT ] ; then
    495  1.15      mrg 					printf "Device deletions:\n"
    496  1.15      mrg 					tee -a $TMP2 < $OUTPUT
    497  1.15      mrg 					printf "\n"
    498  1.15      mrg 				fi
    499  1.15      mrg 
    500  1.15      mrg 				# Report any block device change.  Ignore character
    501  1.15      mrg 				# devices, only the name is significant.
    502  1.15      mrg 				cat $TMP2 $CUR $TMP1 | \
    503  1.15      mrg 				sed -e '/^c/d' | \
    504  1.20  mycroft 				sort -k11 | \
    505  1.15      mrg 				sed -e 's/[	 ][	 ]*/ /g' | \
    506  1.15      mrg 				uniq -u > $OUTPUT
    507  1.15      mrg 				if [ -s $OUTPUT ] ; then
    508  1.15      mrg 					printf "Block device changes:\n"
    509  1.15      mrg 					column -t $OUTPUT
    510  1.15      mrg 					printf "\n"
    511  1.15      mrg 				fi
    512   1.9      cgd 
    513  1.15      mrg 				cp $CUR $BACK
    514  1.15      mrg 				cp $TMP1 $CUR
    515   1.9      cgd 			fi
    516  1.15      mrg 		else
    517  1.15      mrg 			printf "Device additions:\n"
    518  1.15      mrg 			column -t $TMP1
    519  1.15      mrg 			printf "\n"
    520   1.9      cgd 			cp $TMP1 $CUR
    521   1.9      cgd 		fi
    522   1.9      cgd 	fi
    523   1.9      cgd fi
    524   1.9      cgd 
    525   1.9      cgd # Check special files.
    526   1.9      cgd # Check system binaries.
    527   1.9      cgd #
    528   1.9      cgd # Create the mtree tree specifications using:
    529   1.9      cgd #
    530   1.9      cgd #	mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure
    531  1.16    mikel #	chown root.wheel DIR.secure
    532  1.16    mikel #	chmod 600 DIR.secure
    533   1.9      cgd #
    534   1.9      cgd # Note, this is not complete protection against Trojan horsed binaries, as
    535   1.9      cgd # the hacker can modify the tree specification to match the replaced binary.
    536   1.9      cgd # For details on really protecting yourself against modified binaries, see
    537   1.9      cgd # the mtree(8) manual page.
    538  1.17  mycroft if [ "$check_mtree" = YES ]; then
    539   1.9      cgd 	mtree -e -p / -f /etc/mtree/special > $OUTPUT
    540  1.15      mrg 	if [ -s $OUTPUT ]; then
    541   1.9      cgd 		printf "\nChecking special files and directories.\n"
    542   1.9      cgd 		cat $OUTPUT
    543   1.9      cgd 	fi
    544   1.9      cgd 
    545   1.9      cgd 	> $OUTPUT
    546  1.16    mikel 	for file in /etc/mtree/*.secure; do
    547  1.16    mikel 		[ $file = '/etc/mtree/*.secure' ] && continue
    548   1.9      cgd 		tree=`sed -n -e '3s/.* //p' -e 3q $file`
    549   1.9      cgd 		mtree -f $file -p $tree > $TMP1
    550   1.9      cgd 		if [ -s $TMP1 ]; then
    551   1.9      cgd 			printf "\nChecking $tree:\n" >> $OUTPUT
    552   1.9      cgd 			cat $TMP1 >> $OUTPUT
    553   1.9      cgd 		fi
    554   1.9      cgd 	done
    555  1.15      mrg 	if [ -s $OUTPUT ]; then
    556   1.9      cgd 		printf "\nChecking system binaries:\n"
    557   1.9      cgd 		cat $OUTPUT
    558   1.9      cgd 	fi
    559   1.9      cgd fi
    560   1.9      cgd 
    561   1.9      cgd # List of files that get backed up and checked for any modifications.  Each
    562   1.9      cgd # file is expected to have two backups, /var/backups/file.{current,backup}.
    563   1.9      cgd # Any changes cause the files to rotate.
    564  1.17  mycroft if [ "$check_changelist" = YES ] && [ -s /etc/changelist ] ; then
    565   1.9      cgd 	for file in `cat /etc/changelist`; do
    566   1.9      cgd 		CUR=/var/backups/`basename $file`.current
    567   1.9      cgd 		BACK=/var/backups/`basename $file`.backup
    568   1.9      cgd 		if [ -s $file ]; then
    569   1.9      cgd 			if [ -s $CUR ] ; then
    570   1.9      cgd 				diff $CUR $file > $OUTPUT
    571   1.9      cgd 				if [ -s $OUTPUT ] ; then
    572   1.9      cgd 		printf "\n======\n%s diffs (OLD < > NEW)\n======\n" $file
    573   1.9      cgd 					cat $OUTPUT
    574   1.9      cgd 					cp -p $CUR $BACK
    575   1.9      cgd 					cp -p $file $CUR
    576   1.9      cgd 					chown root.wheel $CUR $BACK
    577   1.9      cgd 				fi
    578   1.9      cgd 			else
    579   1.9      cgd 				cp -p $file $CUR
    580   1.9      cgd 				chown root.wheel $CUR
    581   1.9      cgd 			fi
    582   1.9      cgd 		fi
    583   1.9      cgd 	done
    584   1.9      cgd fi
    585