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