xref: /csrg-svn/etc/security (revision 53363)
142328Sbostic#!/bin/sh -
242328Sbostic#
3*53363Sbostic#	@(#)security	5.26 (Berkeley) 05/04/92
442328Sbostic#
553105Sbostic
652578SbosticPATH=/sbin:/usr/sbin:/bin:/usr/bin
742328Sbostic
853130Sbosticumask 077
952215Sbostic
1053098SbosticERR=/tmp/_secure1.$$
1153098SbosticTMP1=/tmp/_secure2.$$
1253098SbosticTMP2=/tmp/_secure3.$$
1353130SbosticTMP3=/tmp/_secure4.$$
1453130SbosticLIST=/tmp/_secure5.$$
1553130SbosticOUTPUT=/tmp/_secure6.$$
1652578Sbostic
1753130Sbostictrap 'rm -f $ERR $TMP1 $TMP2 $TMP3 $LIST $OUTPUT' 0
1852578Sbostic
1953184Sbostic# Check the master password file syntax.
2053130SbosticMP=/etc/master.passwd
2153130Sbosticawk -F: '{
2253130Sbostic	if ($0 ~ /^[	 ]*$/) {
2353130Sbostic		printf("Line %d is a blank line.\n", NR);
2453130Sbostic		next;
2553130Sbostic	}
2653130Sbostic	if (NF != 10)
2753130Sbostic		printf("Line %d has the wrong number of fields.\n", NR);
2853155Sbostic	if ($1 !~ /^[A-Za-z0-9]*$/)
2953308Sbostic		printf("Login %s has non-alphanumeric characters.\n", $1);
3053130Sbostic	if (length($1) > 8)
3153130Sbostic		printf("Login %s has more than 8 characters.\n", $1);
3253130Sbostic	if ($2 == "")
3353130Sbostic		printf("Login %s has no password.\n", $1);
3453130Sbostic	if (length($2) != 13 && ($10 ~ /.*sh$/ || $10 == ""))
3553130Sbostic		printf("Login %s is off but still has a valid shell.\n", $1);
3653130Sbostic	if ($3 == 0 && $1 != "root" && $1 != "toor")
3753130Sbostic		printf("Login %s has a user id of 0.\n", $1);
3853130Sbostic	if ($3 < 0)
3953130Sbostic		printf("Login %s has a negative user id.\n", $1);
4053130Sbostic	if ($4 < 0)
4153155Sbostic		printf("Login %s has a negative group id.\n", $1);
4253130Sbostic}' < $MP > $OUTPUT
4353130Sbosticif [ -s $OUTPUT ] ; then
4453130Sbostic	printf "\nChecking the $MP file:\n"
4553130Sbostic	cat $OUTPUT
4653130Sbosticfi
4742328Sbostic
4853130Sbosticawk -F: '{ print $1 }' $MP | sort | uniq -d > $OUTPUT
4953130Sbosticif [ -s $OUTPUT ] ; then
5053130Sbostic	printf "\n$MP has duplicate user names.\n"
5153130Sbostic	column $OUTPUT
5253130Sbosticfi
5352573Sbostic
5453130Sbosticawk -F: '{ print $1 " " $3 }' $MP | sort -n +1 | tee $TMP1 |
5553130Sbosticuniq -d -f 1 | awk '{ print $2 }' > $TMP2
5653130Sbosticif [ -s $TMP2 ] ; then
5753130Sbostic	printf "\n$MP has duplicate user id's.\n"
5853130Sbostic        while read uid; do
5953130Sbostic                grep -w $uid $TMP1
6053130Sbostic        done < $TMP2 | column
6153130Sbosticfi
6253104Sbostic
6353264Sbostic# Backup the master password file; a special case, the normal backup
6453264Sbostic# mechanisms also print out file differences and we don't want to do
6553264Sbostic# that because this file has encrypted passwords in it.
6653264SbosticCUR=/var/backups/`basename $MP`.current
6753264SbosticBACK=/var/backups/`basename $MP`.backup
6853264Sbosticif [ -s $CUR ] ; then
6953264Sbostic	if cmp -s $CUR $MP; then
7053264Sbostic		:
7153264Sbostic	else
7253264Sbostic		cp -p $CUR $BACK
7353264Sbostic		cp -p $MP $CUR
7453264Sbostic		chown root.wheel $CUR
7553264Sbostic	fi
7653264Sbosticelse
7753264Sbostic	cp -p $MP $CUR
7853264Sbostic	chown root.wheel $CUR
7953264Sbosticfi
8053264Sbostic
8153130Sbostic# Check the group file syntax.
8253130SbosticGRP=/etc/group
8353130Sbosticawk -F: '{
8453130Sbostic	if ($0 ~ /^[	 ]*$/) {
8553130Sbostic		printf("Line %d is a blank line.\n", NR);
8653130Sbostic		next;
8753130Sbostic	}
8853130Sbostic	if (NF != 4)
8953130Sbostic		printf("Line %d has the wrong number of fields.\n", NR);
9053159Sbostic	if ($1 !~ /^[A-za-z0-9]*$/)
9153308Sbostic		printf("Group %s has non-alphanumeric characters.\n", $1);
9253130Sbostic	if (length($1) > 8)
9353130Sbostic		printf("Group %s has more than 8 characters.\n", $1);
9453130Sbostic	if ($3 !~ /[0-9]*/)
9553155Sbostic		printf("Login %s has a negative group id.\n", $1);
9653130Sbostic}' < $GRP > $OUTPUT
9753130Sbosticif [ -s $OUTPUT ] ; then
9853130Sbostic	printf "\nChecking the $GRP file:\n"
9953130Sbostic	cat $OUTPUT
10053130Sbosticfi
10153130Sbostic
10253130Sbosticawk -F: '{ print $1 }' $GRP | sort | uniq -d > $OUTPUT
10353130Sbosticif [ -s $OUTPUT ] ; then
10453130Sbostic	printf "\n$GRP has duplicate group names.\n"
10553130Sbostic	column $OUTPUT
10653130Sbosticfi
10753130Sbostic
10853130Sbostic# Check for root paths, umask values in startup files.
10953184Sbostic# The check for the root paths is problematical -- it's likely to fail
11053184Sbostic# in other environments.  Once the shells have been modified to warn
11153184Sbostic# of '.' in the path, the path tests should go away.
11253130Sbostic> $OUTPUT
11353130Sbosticrhome=/root
11453130Sbosticumaskset=no
11553130Sbosticlist="/etc/csh.cshrc /etc/csh.login ${rhome}/.cshrc ${rhome}/.login"
11653130Sbosticfor i in $list ; do
11753130Sbostic	if [ -f $i ] ; then
11853130Sbostic		if egrep umask $i > /dev/null ; then
11953130Sbostic			umaskset=yes
12053104Sbostic		fi
12153130Sbostic		egrep umask $i |
12253130Sbostic		awk '$2 % 100 < 20 \
12353130Sbostic			{ print "Root umask is group writeable" }
12453130Sbostic		     $2 % 10 < 2 \
12553130Sbostic			{ print "Root umask is other writeable" }' >> $OUTPUT
12653130Sbostic		/bin/csh -f -s << end-of-csh > /dev/null 2>&1
12753130Sbostic			unset path
12853130Sbostic			source $i
12953130Sbostic			/bin/ls -ldgT \$path > $TMP1
13053130Sbosticend-of-csh
13153130Sbostic		awk '{
13253159Sbostic			if ($10 ~ /^\.$/) {
13353130Sbostic				print "The root path includes .";
13453130Sbostic				next;
13553130Sbostic			}
13653130Sbostic		     }
13753130Sbostic		     $1 ~ /^d....w/ \
13853130Sbostic        { print "Root path directory " $10 " is group writeable." } \
13953130Sbostic		     $1 ~ /^d.......w/ \
14053130Sbostic        { print "Root path directory " $10 " is other writeable." }' \
14153130Sbostic		< $TMP1 >> $OUTPUT
14253130Sbostic	fi
14353130Sbosticdone
14453130Sbosticif [ $umaskset = "no" -o -s $OUTPUT ] ; then
14553130Sbostic	printf "\nChecking root csh paths, umask values:\n$list\n"
14653130Sbostic	if [ -s $OUTPUT ]; then
14753130Sbostic		cat $OUTPUT
14853130Sbostic	fi
14953130Sbostic	if [ $umaskset = "no" ] ; then
15053130Sbostic		printf "\nRoot csh startup files do not set the umask.\n"
15153130Sbostic	fi
15253130Sbosticfi
15353104Sbostic
15453130Sbostic> $OUTPUT
15553130Sbosticrhome=/root
15653130Sbosticumaskset=no
15753130Sbosticlist="${rhome}/.profile"
15853130Sbosticfor i in $list; do
15953130Sbostic	if [ -f $i ] ; then
16053130Sbostic		if egrep umask $i > /dev/null ; then
16153130Sbostic			umaskset=yes
16253130Sbostic		fi
16353130Sbostic		egrep umask $i |
16453130Sbostic		awk '$2 % 100 < 20 \
16553130Sbostic			{ print "Root umask is group writeable" } \
16653130Sbostic		     $2 % 10 < 2 \
16753130Sbostic			{ print "Root umask is other writeable" }' >> $OUTPUT
16853130Sbostic		/bin/sh << end-of-sh > /dev/null 2>&1
16953130Sbostic			PATH=
17053130Sbostic			. $i
17153130Sbostic			list=\`echo \$PATH | /usr/bin/sed -e 's/:/ /g'\`
17253130Sbostic			/bin/ls -ldgT \$list > $TMP1
17353130Sbosticend-of-sh
17453130Sbostic		awk '{
17553159Sbostic			if ($10 ~ /^\.$/) {
17653130Sbostic				print "The root path includes .";
17753130Sbostic				next;
17853130Sbostic			}
17953130Sbostic		     }
18053130Sbostic		     $1 ~ /^d....w/ \
18153130Sbostic        { print "Root path directory " $10 " is group writeable." } \
18253130Sbostic		     $1 ~ /^d.......w/ \
18353130Sbostic        { print "Root path directory " $10 " is other writeable." }' \
18453130Sbostic		< $TMP1 >> $OUTPUT
18553130Sbostic
18653130Sbostic	fi
18753130Sbosticdone
18853130Sbosticif [ $umaskset = "no" -o -s $OUTPUT ] ; then
18953130Sbostic	printf "\nChecking root sh paths, umask values:\n$list\n"
19053130Sbostic	if [ -s $OUTPUT ]; then
19153130Sbostic		cat $OUTPUT
19253130Sbostic	fi
19353130Sbostic	if [ $umaskset = "no" ] ; then
19453130Sbostic		printf "\nRoot sh startup files do not set the umask.\n"
19553130Sbostic	fi
19653130Sbosticfi
19753130Sbostic
19853130Sbostic# Root and uucp should both be in /etc/ftpusers.
19953130Sbosticif egrep root /etc/ftpusers > /dev/null ; then
20053130Sbostic	:
20153130Sbosticelse
20253130Sbostic	printf "\nRoot not listed in /etc/ftpusers file.\n"
20353130Sbosticfi
20453130Sbosticif egrep uucp /etc/ftpusers > /dev/null ; then
20553130Sbostic	:
20653130Sbosticelse
20753130Sbostic	printf "\nUucp not listed in /etc/ftpusers file.\n"
20853130Sbosticfi
20953130Sbostic
21053184Sbostic# Uudecode should not be in the /etc/aliases file.
21153130Sbosticif grep -w uudecode /etc/aliases; then
21253130Sbostic	printf "\nThere is an entry for uudecode in the /etc/aliases file.\n"
21353130Sbosticfi
21453130Sbostic
215*53363Sbostic# Files that should not have + signs or empty lines.
216*53363Sbosticlist="/etc/hosts.equiv /etc/hosts.lpd"
217*53363Sbosticfor f in $list ; do
218*53363Sbostic	if egrep '\+|^$' $f > /dev/null ; then
219*53363Sbostic		printf "\nEmpty line or + in $f file.\n"
220*53363Sbostic	fi
221*53363Sbosticdone
22253130Sbostic
22353130Sbostic# Check for special users with .rhosts files.  Only root and toor should
22453130Sbostic# have a .rhosts files.  Also, .rhosts files should not have blank lines
22553130Sbostic# or plus signs.
22653130Sbosticawk -F: '$1 != "root" && $1 != "toor" && \
22753130Sbostic	($3 < 100 || $1 == "ftp" || $1 == "uucp") \
22853130Sbostic		{ print $1 " " $6 }' /etc/passwd |
22953130Sbosticwhile read uid homedir; do
23053130Sbostic	if [ -f ${homedir}/.rhosts ] ; then
23153130Sbostic		rhost=`ls -ldgT ${homedir}/.rhosts`
23253130Sbostic		printf "$uid: $rhost\n"
23353130Sbostic	fi
23453130Sbosticdone > $OUTPUT
23553130Sbosticif [ -s $OUTPUT ] ; then
23653130Sbostic	printf "\nChecking for special users with .rhosts files.\n"
23753130Sbostic	cat $OUTPUT
23853130Sbosticfi
23953130Sbostic
24053130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \
24153130Sbosticwhile read uid homedir; do
24253130Sbostic	if [ -f ${homedir}/.rhosts ] && \
24353130Sbostic	    egrep '\+|^$' ${homedir}/.rhosts > /dev/null ; then
24453130Sbostic		printf "$uid: empty line or + in .rhosts file.\n"
24553130Sbostic	fi
24653130Sbosticdone > $OUTPUT
24753130Sbosticif [ -s $OUTPUT ] ; then
24853130Sbostic	printf "\nChecking .rhosts files syntax.\n"
24953130Sbostic	cat $OUTPUT
25053130Sbosticfi
25153130Sbostic
25253184Sbostic# Check home directories.  Directories should not be owned by someone else
25353184Sbostic# or writeable.
25453130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \
25553105Sbosticwhile read uid homedir; do
25653105Sbostic	if [ -d ${homedir}/ ] ; then
25753105Sbostic		file=`ls -ldgT ${homedir}`
25853130Sbostic		printf "$uid $file\n"
25953105Sbostic	fi
26053130Sbosticdone |
26153130Sbosticawk '$1 != $4 && $4 != "root" \
26253130Sbostic	{ print "user " $1 " home directory is owned by " $4 }
26353130Sbostic     $2 ~ /^-....w/ \
26453130Sbostic	{ print "user " $1 " home directory is group writeable" }
26553130Sbostic     $2 ~ /^-.......w/ \
26653130Sbostic	{ print "user " $1 " home directory is other writeable" }' > $OUTPUT
26753130Sbosticif [ -s $OUTPUT ] ; then
26853130Sbostic	printf "\nChecking home directories.\n"
26953130Sbostic	cat $OUTPUT
27053130Sbosticfi
27153105Sbostic
27253104Sbostic# Files that should not be owned by someone else or readable.
27353130Sbosticlist=".netrc .rhosts"
27453130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \
27553104Sbosticwhile read uid homedir; do
27653130Sbostic	for f in $list ; do
27753130Sbostic		file=${homedir}/${f}
27853130Sbostic		if [ -f $file ] ; then
27953130Sbostic			printf "$uid $f `ls -ldgT $file`\n"
28053130Sbostic		fi
28153130Sbostic	done
28253130Sbosticdone |
28353130Sbosticawk '$1 != $5 && $5 != "root" \
28453130Sbostic	{ print "user " $1 " " $2 " file is owned by " $5 }
28553130Sbostic     $3 ~ /^-...r/ \
28653130Sbostic	{ print "user " $1 " " $2 " file is group readable" }
28753130Sbostic     $3 ~ /^-......r/ \
28853130Sbostic	{ print "user " $1 " " $2 " file is other readable" }
28953130Sbostic     $3 ~ /^-....w/ \
29053130Sbostic	{ print "user " $1 " " $2 " file is group writeable" }
29153130Sbostic     $3 ~ /^-.......w/ \
29253130Sbostic	{ print "user " $1 " " $2 " file is other writeable" }' > $OUTPUT
29353104Sbostic
29453104Sbostic# Files that should not be owned by someone else or writeable.
29553130Sbosticlist=".bashrc .cshrc .emacsrc .exrc .forward .klogin .login .logout \
29653130Sbostic      .profile .tcshrc"
29753130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \
29853104Sbosticwhile read uid homedir; do
29953130Sbostic	for f in $list ; do
30053130Sbostic		file=${homedir}/${f}
30153130Sbostic		if [ -f $file ] ; then
30253130Sbostic			printf "$uid $f `ls -ldgT $file`\n"
30353130Sbostic		fi
30453130Sbostic	done
30553130Sbosticdone |
30653130Sbosticawk '$1 != $5 && $5 != "root" \
30753130Sbostic	{ print "user " $1 " " $2 " file is owned by " $5 }
30853130Sbostic     $3 ~ /^-....w/ \
30953130Sbostic	{ print "user " $1 " " $2 " file is group writeable" }
31053130Sbostic     $3 ~ /^-.......w/ \
31153130Sbostic	{ print "user " $1 " " $2 " file is other writeable" }' >> $OUTPUT
31253130Sbosticif [ -s $OUTPUT ] ; then
31353130Sbostic	printf "\nChecking dot files.\n"
31453130Sbostic	cat $OUTPUT
31553130Sbosticfi
31653104Sbostic
31753184Sbostic# Mailboxes should be owned by user and unreadable.
31853130Sbosticls -l /var/mail | sed 1d | \
31953130Sbosticawk '$3 != $9 \
32053130Sbostic	{ print "user " $9 " mailbox is owned by " $3 }
32153130Sbostic     $1 != "-rw-------" \
32253130Sbostic	{ print "user " $9 " mailbox is " $1 ", group " $4 }' > $OUTPUT
32353130Sbosticif [ -s $OUTPUT ] ; then
32453130Sbostic	printf "\nChecking mailbox ownership.\n"
32553130Sbostic	cat $OUTPUT
32653130Sbosticfi
32753104Sbostic
32853184Sbostic# File systems should not be globally exported.
32953105Sbosticawk '{
33053105Sbostic	readonly = 0;
33153105Sbostic	for (i = 2; i <= NF; ++i) {
33253105Sbostic		if ($i ~ /-ro/)
33353105Sbostic			readonly = 1;
33453105Sbostic		else if ($i !~ /^-/)
33553105Sbostic			next;
33653105Sbostic	}
33753105Sbostic	if (readonly)
33853105Sbostic		print "File system " $1 " globally exported, read-only."
33953105Sbostic	else
34053105Sbostic		print "File system " $1 " globally exported, read-write."
34153130Sbostic}' < /etc/exports > $OUTPUT
34253130Sbosticif [ -s $OUTPUT ] ; then
34353130Sbostic	printf "\nChecking for globally exported file systems.\n"
34453130Sbostic	cat $OUTPUT
34553130Sbosticfi
34653105Sbostic
34753184Sbostic# Display any changes in setuid files and devices.
34853130Sbosticprintf "\nChecking setuid files and devices:\n"
34953130Sbostic(find / ! -fstype local -a -prune -o \
35053130Sbostic    \( -perm -u+s -o -perm -g+s -o ! -type d -a ! -type f -a ! -type l -a \
35153130Sbostic       ! -type s \) | \
35253130Sbosticsort | sed -e 's/^/ls -ldgT /' | sh > $LIST) 2> $OUTPUT
35342328Sbostic
35453098Sbostic# Display any errors that occurred during system file walk.
35553130Sbosticif [ -s $OUTPUT ] ; then
35653130Sbostic	printf "Setuid/device find errors:\n"
35753130Sbostic	cat $OUTPUT
35853130Sbostic	printf "\n"
35942328Sbosticfi
36042328Sbostic
36153098Sbostic# Display any changes in the setuid file list.
36253130Sbosticegrep -v '^[bc]' $LIST > $TMP1
36353130Sbosticif [ -s $TMP1 ] ; then
36453130Sbostic	# Check to make sure uudecode isn't setuid.
36553130Sbostic	if grep -w uudecode $TMP1 > /dev/null ; then
36653130Sbostic		printf "\nUudecode is setuid.\n"
36753130Sbostic	fi
36853130Sbostic
36953130Sbostic	CUR=/var/backups/setuid.current
37053130Sbostic	BACK=/var/backups/setuid.backup
37153130Sbostic
37253098Sbostic	if [ -s $CUR ] ; then
37353130Sbostic		if cmp -s $CUR $TMP1 ; then
37452573Sbostic			:
37552573Sbostic		else
37653130Sbostic			> $TMP2
37753130Sbostic			join -110 -210 -v2 $CUR $TMP1 > $OUTPUT
37853130Sbostic			if [ -s $OUTPUT ] ; then
37953130Sbostic				printf "Setuid additions:\n"
38053130Sbostic				tee -a $TMP2 < $OUTPUT
38153130Sbostic				printf "\n"
38252573Sbostic			fi
38352573Sbostic
38453130Sbostic			join -110 -210 -v1 $CUR $TMP1 > $OUTPUT
38553130Sbostic			if [ -s $OUTPUT ] ; then
38653130Sbostic				printf "Setuid deletions:\n"
38753130Sbostic				tee -a $TMP2 < $OUTPUT
38853130Sbostic				printf "\n"
38952573Sbostic			fi
39052573Sbostic
39153130Sbostic			sort +9 $TMP2 $CUR $TMP1 | \
39253130Sbostic			    sed -e 's/[	 ][	 ]*/ /g' | uniq -u > $OUTPUT
39353130Sbostic			if [ -s $OUTPUT ] ; then
39453130Sbostic				printf "Setuid changes:\n"
39553130Sbostic				column -t $OUTPUT
39653130Sbostic				printf "\n"
39752573Sbostic			fi
39852573Sbostic
39953130Sbostic			cp $CUR $BACK
40053130Sbostic			cp $TMP1 $CUR
40152573Sbostic		fi
40252573Sbostic	else
40353130Sbostic		printf "Setuid additions:\n"
40453140Sbostic		column -t $TMP1
40553130Sbostic		printf "\n"
40653130Sbostic		cp $TMP1 $CUR
40752573Sbostic	fi
40852215Sbosticfi
40952215Sbostic
41053184Sbostic# Check for block and character disk devices that are readable or writeable
41153140Sbostic# or not owned by root.operator.
41253307Sbostic>$TMP1
41353307SbosticDISKLIST="dk fd hd hk hp jb kra ra rb rd rl rx rz sd up wd"
41453307Sbosticfor i in $DISKLIST; do
41553307Sbostic	egrep "^b.*/${i}[0-9][0-9]*[a-h]$"  $LIST >> $TMP1
41653307Sbostic	egrep "^c.*/r${i}[0-9][0-9]*[a-h]$"  $LIST >> $TMP1
41753307Sbosticdone
41853105Sbostic
41953140Sbosticawk '$3 != "root" || $4 != "operator" || $1 !~ /.rw-r-----/ \
42053140Sbostic	{ printf("Disk %s is user %s, group %s, permissions %s.\n", \
42153140Sbostic	    $11, $3, $4, $1); }' < $TMP1 > $OUTPUT
42253130Sbosticif [ -s $OUTPUT ] ; then
42353130Sbostic	printf "\nChecking disk ownership and permissions.\n"
42453130Sbostic	cat $OUTPUT
42553130Sbostic	printf "\n"
42653130Sbosticfi
42753105Sbostic
42853184Sbostic# Display any changes in the device file list.
42953140Sbosticegrep '^[bc]' $LIST | sort +10 > $TMP1
43053130Sbosticif [ -s $TMP1 ] ; then
43153130Sbostic	CUR=/var/backups/device.current
43253130Sbostic	BACK=/var/backups/device.backup
43353098Sbostic
43453098Sbostic	if [ -s $CUR ] ; then
43553130Sbostic		if cmp -s $CUR $TMP1 ; then
43653098Sbostic			:
43753098Sbostic		else
43853130Sbostic			> $TMP2
43953130Sbostic			join -111 -211 -v2 $CUR $TMP1 > $OUTPUT
44053130Sbostic			if [ -s $OUTPUT ] ; then
44153130Sbostic				printf "Device additions:\n"
44253130Sbostic				tee -a $TMP2 < $OUTPUT
44353130Sbostic				printf "\n"
44453098Sbostic			fi
44553098Sbostic
44653130Sbostic			join -111 -211 -v1 $CUR $TMP1 > $OUTPUT
44753130Sbostic			if [ -s $OUTPUT ] ; then
44853130Sbostic				printf "Device deletions:\n"
44953130Sbostic				tee -a $TMP2 < $OUTPUT
45053130Sbostic				printf "\n"
45153098Sbostic			fi
45253098Sbostic
45353140Sbostic			# Report any block device change.  Ignore character
45453140Sbostic			# devices, only the name is significant.
45553140Sbostic			cat $TMP2 $CUR $TMP1 | \
45653140Sbostic			sed -e '/^c/d' | \
45753140Sbostic			sort +10 | \
45853130Sbostic			sed -e 's/[	 ][	 ]*/ /g' | \
45953140Sbostic			uniq -u > $OUTPUT
46053130Sbostic			if [ -s $OUTPUT ] ; then
46153140Sbostic				printf "Block device changes:\n"
46253130Sbostic				column -t $OUTPUT
46353130Sbostic				printf "\n"
46453098Sbostic			fi
46553098Sbostic
46653130Sbostic			cp $CUR $BACK
46753130Sbostic			cp $TMP1 $CUR
46853098Sbostic		fi
46953098Sbostic	else
47053130Sbostic		printf "Device additions:\n"
47153140Sbostic		column -t $TMP1
47253130Sbostic		printf "\n"
47353130Sbostic		cp $TMP1 $CUR
47453098Sbostic	fi
47553098Sbosticfi
47653098Sbostic
47753142Sbostic# Check special files.
47853142Sbostic# Check system binaries.
47953142Sbostic#
48052578Sbostic# Create the mtree tree specifications using:
48152578Sbostic#
48253130Sbostic#	mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure
48353130Sbostic#	chown root.wheel DIR.SECURE
48453130Sbostic#	chmod 600 DIR.SECURE
48552578Sbostic#
48652578Sbostic# Note, this is not complete protection against Trojan horsed binaries, as
48752578Sbostic# the hacker can modify the tree specification to match the replaced binary.
48852578Sbostic# For details on really protecting yourself against modified binaries, see
48952578Sbostic# the mtree(8) manual page.
49052578Sbosticif cd /etc/mtree; then
49153130Sbostic	mtree -e -p / -f /etc/mtree/special > $OUTPUT
49253130Sbostic	if [ -s $OUTPUT ] ; then
49353130Sbostic		printf "\nChecking special files and directories.\n"
49453130Sbostic		cat $OUTPUT
49553130Sbostic	fi
49653130Sbostic
49753130Sbostic	> $OUTPUT
49852578Sbostic	for file in *.secure; do
49952578Sbostic		tree=`sed -n -e '3s/.* //p' -e 3q $file`
50053130Sbostic		mtree -f $file -p $tree > $TMP1
50153130Sbostic		if [ -s $TMP1 ]; then
50253130Sbostic			printf "\nChecking $tree:\n" >> $OUTPUT
50353130Sbostic			cat $TMP1 >> $OUTPUT
50453130Sbostic		fi
50552578Sbostic	done
50653130Sbostic	if [ -s $OUTPUT ] ; then
50753130Sbostic		printf "\nChecking system binaries:\n"
50853130Sbostic		cat $OUTPUT
50953130Sbostic	fi
51052578Sbosticfi
51153264Sbostic
51253264Sbostic# List of files that get backed up and checked for any modifications.  Each
51353264Sbostic# file is expected to have two backups, /var/backups/file.{current,backup}.
51453264Sbostic# Any changes cause the files to rotate.
51553264Sbosticif [ -s /etc/changelist ] ; then
51653264Sbostic	for file in `cat /etc/changelist`; do
51753264Sbostic		CUR=/var/backups/`basename $file`.current
51853264Sbostic		BACK=/var/backups/`basename $file`.backup
51953264Sbostic		if [ -s $file ]; then
52053264Sbostic			if [ -s $CUR ] ; then
52153264Sbostic				diff $CUR $file > $OUTPUT
52253264Sbostic				if [ -s $OUTPUT ] ; then
52353264Sbostic		printf "\n======\n%s diffs (OLD < > NEW)\n======\n" $file
52453264Sbostic					cat $OUTPUT
52553264Sbostic					cp -p $CUR $BACK
52653264Sbostic					cp -p $file $CUR
52753264Sbostic					chown root.wheel $CUR $BACK
52853264Sbostic				fi
52953264Sbostic			else
53053264Sbostic				cp -p $file $CUR
53153264Sbostic				chown root.wheel $CUR
53253264Sbostic			fi
53353264Sbostic		fi
53453264Sbostic	done
53553264Sbosticfi
536