Home | History | Annotate | Line # | Download | only in etc
security revision 1.17
      1   1.1      cgd #!/bin/sh -
      2   1.1      cgd #
      3  1.17  mycroft #	$NetBSD: security,v 1.17 1997/03/10 09:45:58 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.15      mrg awk -F: '{ print $1 " " $3 }' $MP | sort -n +1 > $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.15      mrg 	if egrep 'uudecode|decode' /etc/aliases; then
    240  1.15      mrg 		printf "\nThere is an entry for uudecode in the /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.15      mrg 			{ print $1 " " $9 }' /etc/master.passwd |
    258  1.15      mrg 	while read uid homedir; do
    259  1.15      mrg 		if [ -f ${homedir}/.rhosts ] ; then
    260  1.15      mrg 			rhost=`ls -ldgT ${homedir}/.rhosts`
    261  1.15      mrg 			printf "$uid: $rhost\n"
    262  1.15      mrg 		fi
    263  1.15      mrg 	done > $OUTPUT
    264  1.15      mrg 	if [ -s $OUTPUT ] ; then
    265  1.15      mrg 		printf "\nChecking for special users with .rhosts files.\n"
    266  1.15      mrg 		cat $OUTPUT
    267  1.15      mrg 	fi
    268  1.15      mrg 
    269  1.15      mrg 	awk -F: '{ print $1 " " $9 }' /etc/master.passwd | \
    270  1.15      mrg 	while read uid homedir; do
    271  1.15      mrg 		if [ -f ${homedir}/.rhosts ] && \
    272  1.15      mrg 		    egrep '\+' ${homedir}/.rhosts > /dev/null ; then
    273  1.15      mrg 			printf "$uid: + in .rhosts file.\n"
    274  1.15      mrg 		fi
    275  1.15      mrg 	done > $OUTPUT
    276  1.15      mrg 	if [ -s $OUTPUT ] ; then
    277  1.15      mrg 		printf "\nChecking .rhosts files syntax.\n"
    278  1.15      mrg 		cat $OUTPUT
    279  1.15      mrg 	fi
    280   1.9      cgd fi
    281   1.9      cgd 
    282   1.9      cgd # Check home directories.  Directories should not be owned by someone else
    283   1.9      cgd # or writeable.
    284  1.17  mycroft if [ "$check_homes" = YES ]; then
    285  1.15      mrg 	awk -F: '{ print $1 " " $9 }' /etc/master.passwd | \
    286  1.15      mrg 	while read uid homedir; do
    287  1.15      mrg 		if [ -d ${homedir}/ ] ; then
    288  1.15      mrg 			file=`ls -ldgT ${homedir}`
    289  1.15      mrg 			printf "$uid $file\n"
    290   1.9      cgd 		fi
    291  1.15      mrg 	done |
    292  1.15      mrg 	awk '$1 != $4 && $4 != "root" \
    293  1.15      mrg 		{ print "user " $1 " home directory is owned by " $4 }
    294  1.15      mrg 	     $2 ~ /^-....w/ \
    295  1.15      mrg 		{ print "user " $1 " home directory is group writeable" }
    296  1.15      mrg 	     $2 ~ /^-.......w/ \
    297  1.15      mrg 		{ print "user " $1 " home directory is other writeable" }' > $OUTPUT
    298  1.15      mrg 	if [ -s $OUTPUT ] ; then
    299  1.15      mrg 		printf "\nChecking home directories.\n"
    300  1.15      mrg 		cat $OUTPUT
    301  1.15      mrg 	fi
    302  1.15      mrg 
    303  1.15      mrg 	# Files that should not be owned by someone else or readable.
    304  1.15      mrg 	list=".netrc .rhosts"
    305  1.15      mrg 	awk -F: '{ print $1 " " $9 }' /etc/master.passwd | \
    306  1.15      mrg 	while read uid homedir; do
    307  1.15      mrg 		for f in $list ; do
    308  1.15      mrg 			file=${homedir}/${f}
    309  1.15      mrg 			if [ -f $file ] ; then
    310  1.15      mrg 				printf "$uid $f `ls -ldgT $file`\n"
    311  1.15      mrg 			fi
    312  1.15      mrg 		done
    313  1.15      mrg 	done |
    314  1.15      mrg 	awk '$1 != $5 && $5 != "root" \
    315  1.15      mrg 		{ print "user " $1 " " $2 " file is owned by " $5 }
    316  1.15      mrg 	     $3 ~ /^-...r/ \
    317  1.15      mrg 		{ print "user " $1 " " $2 " file is group readable" }
    318  1.15      mrg 	     $3 ~ /^-......r/ \
    319  1.15      mrg 		{ print "user " $1 " " $2 " file is other readable" }
    320  1.15      mrg 	     $3 ~ /^-....w/ \
    321  1.15      mrg 		{ print "user " $1 " " $2 " file is group writeable" }
    322  1.15      mrg 	     $3 ~ /^-.......w/ \
    323  1.15      mrg 		{ print "user " $1 " " $2 " file is other writeable" }' > $OUTPUT
    324  1.15      mrg 
    325  1.15      mrg 	# Files that should not be owned by someone else or writeable.
    326  1.15      mrg 	list=".bashrc .cshrc .emacs .exrc .forward .klogin .login .logout \
    327  1.15      mrg 	      .profile .tcshrc .qmail"
    328  1.15      mrg 	awk -F: '{ print $1 " " $9 }' /etc/master.passwd | \
    329  1.15      mrg 	while read uid homedir; do
    330  1.15      mrg 		for f in $list ; do
    331  1.15      mrg 			file=${homedir}/${f}
    332  1.15      mrg 			if [ -f $file ] ; then
    333  1.15      mrg 				printf "$uid $f `ls -ldgT $file`\n"
    334  1.15      mrg 			fi
    335  1.15      mrg 		done
    336  1.15      mrg 	done |
    337  1.15      mrg 	awk '$1 != $5 && $5 != "root" \
    338  1.15      mrg 		{ print "user " $1 " " $2 " file is owned by " $5 }
    339  1.15      mrg 	     $3 ~ /^-....w/ \
    340  1.15      mrg 		{ print "user " $1 " " $2 " file is group writeable" }
    341  1.15      mrg 	     $3 ~ /^-.......w/ \
    342  1.15      mrg 		{ print "user " $1 " " $2 " file is other writeable" }' >> $OUTPUT
    343  1.15      mrg 	if [ -s $OUTPUT ] ; then
    344  1.15      mrg 		printf "\nChecking dot files.\n"
    345  1.15      mrg 		cat $OUTPUT
    346  1.15      mrg 	fi
    347   1.9      cgd fi
    348   1.9      cgd 
    349   1.9      cgd # Mailboxes should be owned by user and unreadable.
    350  1.17  mycroft if [ "$check_varmail" = YES ]; then
    351  1.15      mrg 	ls -l /var/mail | sed 1d | \
    352  1.15      mrg 	awk '$3 != $9 \
    353  1.15      mrg 		{ print "user " $9 " mailbox is owned by " $3 }
    354  1.15      mrg 	     $1 != "-rw-------" \
    355  1.15      mrg 		{ print "user " $9 " mailbox is " $1 ", group " $4 }' > $OUTPUT
    356  1.15      mrg 	if [ -s $OUTPUT ] ; then
    357  1.15      mrg 		printf "\nChecking mailbox ownership.\n"
    358  1.15      mrg 		cat $OUTPUT
    359  1.15      mrg 	fi
    360  1.15      mrg fi
    361  1.15      mrg 
    362  1.17  mycroft if [ "$check_nfs" = YES ]; then
    363  1.15      mrg 	if [ -f /etc/exports ]; then
    364  1.15      mrg 	    # File systems should not be globally exported.
    365  1.15      mrg 	    awk '{
    366  1.15      mrg 		readonly = 0;
    367  1.15      mrg 		for (i = 2; i <= NF; ++i) {
    368  1.15      mrg 			if ($i ~ /-ro/)
    369  1.15      mrg 				readonly = 1;
    370  1.15      mrg 			else if ($i !~ /^-/)
    371  1.15      mrg 				next;
    372  1.15      mrg 		}
    373  1.15      mrg 		if (readonly)
    374  1.15      mrg 			print "File system " $1 " globally exported, read-only."
    375  1.15      mrg 		else
    376  1.15      mrg 			print "File system " $1 " globally exported, read-write."
    377  1.15      mrg 	    }' < /etc/exports > $OUTPUT
    378  1.15      mrg 	    if [ -s $OUTPUT ] ; then
    379  1.15      mrg 		printf "\nChecking for globally exported file systems.\n"
    380  1.15      mrg 		cat $OUTPUT
    381  1.15      mrg 	    fi
    382  1.15      mrg 	fi
    383   1.9      cgd fi
    384   1.9      cgd 
    385   1.9      cgd # Display any changes in setuid files and devices.
    386  1.17  mycroft if [ "$check_devices" = YES ]; then
    387  1.15      mrg 	printf "\nChecking setuid files and devices:\n"
    388  1.15      mrg 	(find / \( ! -fstype local -o -fstype fdesc -o -fstype kernfs \
    389  1.15      mrg 			-o -fstype procfs \) -a -prune -o \
    390  1.15      mrg 	    \( -perm -u+s -o \( -perm -g+s -a ! -type d \) -o \
    391  1.15      mrg 	       ! -type d -a ! -type f -a ! -type l -a \
    392  1.15      mrg 	       ! -type s \) -print | \
    393  1.15      mrg 	sort | sed -e 's/^/ls -ldgT /' | sh > $LIST) 2> $OUTPUT
    394  1.15      mrg 
    395  1.15      mrg 	# Display any errors that occurred during system file walk.
    396  1.15      mrg 	if [ -s $OUTPUT ] ; then
    397  1.15      mrg 		printf "Setuid/device find errors:\n"
    398  1.15      mrg 		cat $OUTPUT
    399  1.15      mrg 		printf "\n"
    400  1.15      mrg 	fi
    401  1.15      mrg 
    402  1.15      mrg 	# Display any changes in the setuid file list.
    403  1.15      mrg 	egrep -v '^[bc]' $LIST > $TMP1
    404  1.15      mrg 	if [ -s $TMP1 ] ; then
    405  1.15      mrg 		# Check to make sure uudecode isn't setuid.
    406  1.15      mrg 		if grep -w uudecode $TMP1 > /dev/null ; then
    407  1.15      mrg 			printf "\nUudecode is setuid.\n"
    408  1.15      mrg 		fi
    409  1.15      mrg 
    410  1.15      mrg 		CUR=/var/backups/setuid.current
    411  1.15      mrg 		BACK=/var/backups/setuid.backup
    412   1.9      cgd 
    413  1.15      mrg 		if [ -s $CUR ] ; then
    414  1.15      mrg 			if cmp -s $CUR $TMP1 ; then
    415  1.15      mrg 				:
    416  1.15      mrg 			else
    417  1.15      mrg 				> $TMP2
    418  1.15      mrg 				join -110 -210 -v2 $CUR $TMP1 > $OUTPUT
    419  1.15      mrg 				if [ -s $OUTPUT ] ; then
    420  1.15      mrg 					printf "Setuid additions:\n"
    421  1.15      mrg 					tee -a $TMP2 < $OUTPUT
    422  1.15      mrg 					printf "\n"
    423  1.15      mrg 				fi
    424  1.15      mrg 
    425  1.15      mrg 				join -110 -210 -v1 $CUR $TMP1 > $OUTPUT
    426  1.15      mrg 				if [ -s $OUTPUT ] ; then
    427  1.15      mrg 					printf "Setuid deletions:\n"
    428  1.15      mrg 					tee -a $TMP2 < $OUTPUT
    429  1.15      mrg 					printf "\n"
    430  1.15      mrg 				fi
    431  1.15      mrg 
    432  1.15      mrg 				sort +9 $TMP2 $CUR $TMP1 | \
    433  1.15      mrg 				    sed -e 's/[	 ][	 ]*/ /g' | uniq -u > $OUTPUT
    434  1.15      mrg 				if [ -s $OUTPUT ] ; then
    435  1.15      mrg 					printf "Setuid changes:\n"
    436  1.15      mrg 					column -t $OUTPUT
    437  1.15      mrg 					printf "\n"
    438  1.15      mrg 				fi
    439   1.9      cgd 
    440  1.15      mrg 				cp $CUR $BACK
    441  1.15      mrg 				cp $TMP1 $CUR
    442   1.9      cgd 			fi
    443  1.15      mrg 		else
    444  1.15      mrg 			printf "Setuid additions:\n"
    445  1.15      mrg 			column -t $TMP1
    446  1.15      mrg 			printf "\n"
    447   1.9      cgd 			cp $TMP1 $CUR
    448   1.9      cgd 		fi
    449  1.15      mrg 	fi
    450  1.15      mrg 
    451  1.15      mrg 	# Check for block and character disk devices that are readable or writeable
    452  1.15      mrg 	# or not owned by root.operator.
    453  1.15      mrg 	>$TMP1
    454  1.15      mrg 	DISKLIST="dk fd hd hk hp jb kra ra rb rd rl rx rz sd up wd xd xy"
    455  1.15      mrg 	for i in $DISKLIST; do
    456  1.15      mrg 		egrep "^b.*/${i}[0-9][0-9]*[a-p]$"  $LIST >> $TMP1
    457  1.15      mrg 		egrep "^c.*/r${i}[0-9][0-9]*[a-p]$"  $LIST >> $TMP1
    458  1.15      mrg 	done
    459  1.15      mrg 
    460  1.15      mrg 	awk '$3 != "root" || $4 != "operator" || $1 !~ /.rw-r-----/ \
    461  1.15      mrg 		{ printf("Disk %s is user %s, group %s, permissions %s.\n", \
    462  1.15      mrg 		    $11, $3, $4, $1); }' < $TMP1 > $OUTPUT
    463  1.15      mrg 	if [ -s $OUTPUT ] ; then
    464  1.15      mrg 		printf "\nChecking disk ownership and permissions.\n"
    465  1.15      mrg 		cat $OUTPUT
    466   1.9      cgd 		printf "\n"
    467   1.9      cgd 	fi
    468   1.9      cgd 
    469  1.15      mrg 	# Display any changes in the device file list.
    470  1.15      mrg 	egrep '^[bc]' $LIST | sort +10 > $TMP1
    471  1.15      mrg 	if [ -s $TMP1 ] ; then
    472  1.15      mrg 		CUR=/var/backups/device.current
    473  1.15      mrg 		BACK=/var/backups/device.backup
    474  1.15      mrg 
    475  1.15      mrg 		if [ -s $CUR ] ; then
    476  1.15      mrg 			if cmp -s $CUR $TMP1 ; then
    477  1.15      mrg 				:
    478  1.15      mrg 			else
    479  1.15      mrg 				> $TMP2
    480  1.15      mrg 				join -111 -211 -v2 $CUR $TMP1 > $OUTPUT
    481  1.15      mrg 				if [ -s $OUTPUT ] ; then
    482  1.15      mrg 					printf "Device additions:\n"
    483  1.15      mrg 					tee -a $TMP2 < $OUTPUT
    484  1.15      mrg 					printf "\n"
    485  1.15      mrg 				fi
    486  1.15      mrg 
    487  1.15      mrg 				join -111 -211 -v1 $CUR $TMP1 > $OUTPUT
    488  1.15      mrg 				if [ -s $OUTPUT ] ; then
    489  1.15      mrg 					printf "Device deletions:\n"
    490  1.15      mrg 					tee -a $TMP2 < $OUTPUT
    491  1.15      mrg 					printf "\n"
    492  1.15      mrg 				fi
    493  1.15      mrg 
    494  1.15      mrg 				# Report any block device change.  Ignore character
    495  1.15      mrg 				# devices, only the name is significant.
    496  1.15      mrg 				cat $TMP2 $CUR $TMP1 | \
    497  1.15      mrg 				sed -e '/^c/d' | \
    498  1.15      mrg 				sort +10 | \
    499  1.15      mrg 				sed -e 's/[	 ][	 ]*/ /g' | \
    500  1.15      mrg 				uniq -u > $OUTPUT
    501  1.15      mrg 				if [ -s $OUTPUT ] ; then
    502  1.15      mrg 					printf "Block device changes:\n"
    503  1.15      mrg 					column -t $OUTPUT
    504  1.15      mrg 					printf "\n"
    505  1.15      mrg 				fi
    506   1.9      cgd 
    507  1.15      mrg 				cp $CUR $BACK
    508  1.15      mrg 				cp $TMP1 $CUR
    509   1.9      cgd 			fi
    510  1.15      mrg 		else
    511  1.15      mrg 			printf "Device additions:\n"
    512  1.15      mrg 			column -t $TMP1
    513  1.15      mrg 			printf "\n"
    514   1.9      cgd 			cp $TMP1 $CUR
    515   1.9      cgd 		fi
    516   1.9      cgd 	fi
    517   1.9      cgd fi
    518   1.9      cgd 
    519   1.9      cgd # Check special files.
    520   1.9      cgd # Check system binaries.
    521   1.9      cgd #
    522   1.9      cgd # Create the mtree tree specifications using:
    523   1.9      cgd #
    524   1.9      cgd #	mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure
    525  1.16    mikel #	chown root.wheel DIR.secure
    526  1.16    mikel #	chmod 600 DIR.secure
    527   1.9      cgd #
    528   1.9      cgd # Note, this is not complete protection against Trojan horsed binaries, as
    529   1.9      cgd # the hacker can modify the tree specification to match the replaced binary.
    530   1.9      cgd # For details on really protecting yourself against modified binaries, see
    531   1.9      cgd # the mtree(8) manual page.
    532  1.17  mycroft if [ "$check_mtree" = YES ]; then
    533   1.9      cgd 	mtree -e -p / -f /etc/mtree/special > $OUTPUT
    534  1.15      mrg 	if [ -s $OUTPUT ]; then
    535   1.9      cgd 		printf "\nChecking special files and directories.\n"
    536   1.9      cgd 		cat $OUTPUT
    537   1.9      cgd 	fi
    538   1.9      cgd 
    539   1.9      cgd 	> $OUTPUT
    540  1.16    mikel 	for file in /etc/mtree/*.secure; do
    541  1.16    mikel 		[ $file = '/etc/mtree/*.secure' ] && continue
    542   1.9      cgd 		tree=`sed -n -e '3s/.* //p' -e 3q $file`
    543   1.9      cgd 		mtree -f $file -p $tree > $TMP1
    544   1.9      cgd 		if [ -s $TMP1 ]; then
    545   1.9      cgd 			printf "\nChecking $tree:\n" >> $OUTPUT
    546   1.9      cgd 			cat $TMP1 >> $OUTPUT
    547   1.9      cgd 		fi
    548   1.9      cgd 	done
    549  1.15      mrg 	if [ -s $OUTPUT ]; then
    550   1.9      cgd 		printf "\nChecking system binaries:\n"
    551   1.9      cgd 		cat $OUTPUT
    552   1.9      cgd 	fi
    553   1.9      cgd fi
    554   1.9      cgd 
    555   1.9      cgd # List of files that get backed up and checked for any modifications.  Each
    556   1.9      cgd # file is expected to have two backups, /var/backups/file.{current,backup}.
    557   1.9      cgd # Any changes cause the files to rotate.
    558  1.17  mycroft if [ "$check_changelist" = YES ] && [ -s /etc/changelist ] ; then
    559   1.9      cgd 	for file in `cat /etc/changelist`; do
    560   1.9      cgd 		CUR=/var/backups/`basename $file`.current
    561   1.9      cgd 		BACK=/var/backups/`basename $file`.backup
    562   1.9      cgd 		if [ -s $file ]; then
    563   1.9      cgd 			if [ -s $CUR ] ; then
    564   1.9      cgd 				diff $CUR $file > $OUTPUT
    565   1.9      cgd 				if [ -s $OUTPUT ] ; then
    566   1.9      cgd 		printf "\n======\n%s diffs (OLD < > NEW)\n======\n" $file
    567   1.9      cgd 					cat $OUTPUT
    568   1.9      cgd 					cp -p $CUR $BACK
    569   1.9      cgd 					cp -p $file $CUR
    570   1.9      cgd 					chown root.wheel $CUR $BACK
    571   1.9      cgd 				fi
    572   1.9      cgd 			else
    573   1.9      cgd 				cp -p $file $CUR
    574   1.9      cgd 				chown root.wheel $CUR
    575   1.9      cgd 			fi
    576   1.9      cgd 		fi
    577   1.9      cgd 	done
    578   1.9      cgd fi
    579