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