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