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