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