xref: /csrg-svn/etc/security (revision 53264)
142328Sbostic#!/bin/sh -
242328Sbostic#
3*53264Sbostic#	@(#)security	5.23 (Berkeley) 04/24/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]*$/)
2953130Sbostic		printf("Login %s has non-numeric 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
63*53264Sbostic# Backup the master password file; a special case, the normal backup
64*53264Sbostic# mechanisms also print out file differences and we don't want to do
65*53264Sbostic# that because this file has encrypted passwords in it.
66*53264SbosticCUR=/var/backups/`basename $MP`.current
67*53264SbosticBACK=/var/backups/`basename $MP`.backup
68*53264Sbosticif [ -s $CUR ] ; then
69*53264Sbostic	if cmp -s $CUR $MP; then
70*53264Sbostic		:
71*53264Sbostic	else
72*53264Sbostic		cp -p $CUR $BACK
73*53264Sbostic		cp -p $MP $CUR
74*53264Sbostic		chown root.wheel $CUR
75*53264Sbostic	fi
76*53264Sbosticelse
77*53264Sbostic	cp -p $MP $CUR
78*53264Sbostic	chown root.wheel $CUR
79*53264Sbosticfi
80*53264Sbostic
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]*$/)
9153130Sbostic		printf("Group %s has non-numeric 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
21553184Sbostic# There should be no plus signs in /etc/hosts.equiv.
21653130Sbosticif egrep '\+|^$' /etc/hosts.equiv > /dev/null ; then
21753130Sbostic	printf "\nEmpty line or + in /etc/hosts.equiv file.\n"
21853130Sbosticfi
21953130Sbostic
22053130Sbostic# Check for special users with .rhosts files.  Only root and toor should
22153130Sbostic# have a .rhosts files.  Also, .rhosts files should not have blank lines
22253130Sbostic# or plus signs.
22353130Sbosticawk -F: '$1 != "root" && $1 != "toor" && \
22453130Sbostic	($3 < 100 || $1 == "ftp" || $1 == "uucp") \
22553130Sbostic		{ print $1 " " $6 }' /etc/passwd |
22653130Sbosticwhile read uid homedir; do
22753130Sbostic	if [ -f ${homedir}/.rhosts ] ; then
22853130Sbostic		rhost=`ls -ldgT ${homedir}/.rhosts`
22953130Sbostic		printf "$uid: $rhost\n"
23053130Sbostic	fi
23153130Sbosticdone > $OUTPUT
23253130Sbosticif [ -s $OUTPUT ] ; then
23353130Sbostic	printf "\nChecking for special users with .rhosts files.\n"
23453130Sbostic	cat $OUTPUT
23553130Sbosticfi
23653130Sbostic
23753130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \
23853130Sbosticwhile read uid homedir; do
23953130Sbostic	if [ -f ${homedir}/.rhosts ] && \
24053130Sbostic	    egrep '\+|^$' ${homedir}/.rhosts > /dev/null ; then
24153130Sbostic		printf "$uid: empty line or + in .rhosts file.\n"
24253130Sbostic	fi
24353130Sbosticdone > $OUTPUT
24453130Sbosticif [ -s $OUTPUT ] ; then
24553130Sbostic	printf "\nChecking .rhosts files syntax.\n"
24653130Sbostic	cat $OUTPUT
24753130Sbosticfi
24853130Sbostic
24953184Sbostic# Check home directories.  Directories should not be owned by someone else
25053184Sbostic# or writeable.
25153130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \
25253105Sbosticwhile read uid homedir; do
25353105Sbostic	if [ -d ${homedir}/ ] ; then
25453105Sbostic		file=`ls -ldgT ${homedir}`
25553130Sbostic		printf "$uid $file\n"
25653105Sbostic	fi
25753130Sbosticdone |
25853130Sbosticawk '$1 != $4 && $4 != "root" \
25953130Sbostic	{ print "user " $1 " home directory is owned by " $4 }
26053130Sbostic     $2 ~ /^-....w/ \
26153130Sbostic	{ print "user " $1 " home directory is group writeable" }
26253130Sbostic     $2 ~ /^-.......w/ \
26353130Sbostic	{ print "user " $1 " home directory is other writeable" }' > $OUTPUT
26453130Sbosticif [ -s $OUTPUT ] ; then
26553130Sbostic	printf "\nChecking home directories.\n"
26653130Sbostic	cat $OUTPUT
26753130Sbosticfi
26853105Sbostic
26953104Sbostic# Files that should not be owned by someone else or readable.
27053130Sbosticlist=".netrc .rhosts"
27153130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \
27253104Sbosticwhile read uid homedir; do
27353130Sbostic	for f in $list ; do
27453130Sbostic		file=${homedir}/${f}
27553130Sbostic		if [ -f $file ] ; then
27653130Sbostic			printf "$uid $f `ls -ldgT $file`\n"
27753130Sbostic		fi
27853130Sbostic	done
27953130Sbosticdone |
28053130Sbosticawk '$1 != $5 && $5 != "root" \
28153130Sbostic	{ print "user " $1 " " $2 " file is owned by " $5 }
28253130Sbostic     $3 ~ /^-...r/ \
28353130Sbostic	{ print "user " $1 " " $2 " file is group readable" }
28453130Sbostic     $3 ~ /^-......r/ \
28553130Sbostic	{ print "user " $1 " " $2 " file is other readable" }
28653130Sbostic     $3 ~ /^-....w/ \
28753130Sbostic	{ print "user " $1 " " $2 " file is group writeable" }
28853130Sbostic     $3 ~ /^-.......w/ \
28953130Sbostic	{ print "user " $1 " " $2 " file is other writeable" }' > $OUTPUT
29053104Sbostic
29153104Sbostic# Files that should not be owned by someone else or writeable.
29253130Sbosticlist=".bashrc .cshrc .emacsrc .exrc .forward .klogin .login .logout \
29353130Sbostic      .profile .tcshrc"
29453130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \
29553104Sbosticwhile read uid homedir; do
29653130Sbostic	for f in $list ; do
29753130Sbostic		file=${homedir}/${f}
29853130Sbostic		if [ -f $file ] ; then
29953130Sbostic			printf "$uid $f `ls -ldgT $file`\n"
30053130Sbostic		fi
30153130Sbostic	done
30253130Sbosticdone |
30353130Sbosticawk '$1 != $5 && $5 != "root" \
30453130Sbostic	{ print "user " $1 " " $2 " file is owned by " $5 }
30553130Sbostic     $3 ~ /^-....w/ \
30653130Sbostic	{ print "user " $1 " " $2 " file is group writeable" }
30753130Sbostic     $3 ~ /^-.......w/ \
30853130Sbostic	{ print "user " $1 " " $2 " file is other writeable" }' >> $OUTPUT
30953130Sbosticif [ -s $OUTPUT ] ; then
31053130Sbostic	printf "\nChecking dot files.\n"
31153130Sbostic	cat $OUTPUT
31253130Sbosticfi
31353104Sbostic
31453184Sbostic# Mailboxes should be owned by user and unreadable.
31553130Sbosticls -l /var/mail | sed 1d | \
31653130Sbosticawk '$3 != $9 \
31753130Sbostic	{ print "user " $9 " mailbox is owned by " $3 }
31853130Sbostic     $1 != "-rw-------" \
31953130Sbostic	{ print "user " $9 " mailbox is " $1 ", group " $4 }' > $OUTPUT
32053130Sbosticif [ -s $OUTPUT ] ; then
32153130Sbostic	printf "\nChecking mailbox ownership.\n"
32253130Sbostic	cat $OUTPUT
32353130Sbosticfi
32453104Sbostic
32553184Sbostic# File systems should not be globally exported.
32653105Sbosticawk '{
32753105Sbostic	readonly = 0;
32853105Sbostic	for (i = 2; i <= NF; ++i) {
32953105Sbostic		if ($i ~ /-ro/)
33053105Sbostic			readonly = 1;
33153105Sbostic		else if ($i !~ /^-/)
33253105Sbostic			next;
33353105Sbostic	}
33453105Sbostic	if (readonly)
33553105Sbostic		print "File system " $1 " globally exported, read-only."
33653105Sbostic	else
33753105Sbostic		print "File system " $1 " globally exported, read-write."
33853130Sbostic}' < /etc/exports > $OUTPUT
33953130Sbosticif [ -s $OUTPUT ] ; then
34053130Sbostic	printf "\nChecking for globally exported file systems.\n"
34153130Sbostic	cat $OUTPUT
34253130Sbosticfi
34353105Sbostic
34453184Sbostic# Display any changes in setuid files and devices.
34553130Sbosticprintf "\nChecking setuid files and devices:\n"
34653130Sbostic(find / ! -fstype local -a -prune -o \
34753130Sbostic    \( -perm -u+s -o -perm -g+s -o ! -type d -a ! -type f -a ! -type l -a \
34853130Sbostic       ! -type s \) | \
34953130Sbosticsort | sed -e 's/^/ls -ldgT /' | sh > $LIST) 2> $OUTPUT
35042328Sbostic
35153098Sbostic# Display any errors that occurred during system file walk.
35253130Sbosticif [ -s $OUTPUT ] ; then
35353130Sbostic	printf "Setuid/device find errors:\n"
35453130Sbostic	cat $OUTPUT
35553130Sbostic	printf "\n"
35642328Sbosticfi
35742328Sbostic
35853098Sbostic# Display any changes in the setuid file list.
35953130Sbosticegrep -v '^[bc]' $LIST > $TMP1
36053130Sbosticif [ -s $TMP1 ] ; then
36153130Sbostic	# Check to make sure uudecode isn't setuid.
36253130Sbostic	if grep -w uudecode $TMP1 > /dev/null ; then
36353130Sbostic		printf "\nUudecode is setuid.\n"
36453130Sbostic	fi
36553130Sbostic
36653130Sbostic	CUR=/var/backups/setuid.current
36753130Sbostic	BACK=/var/backups/setuid.backup
36853130Sbostic
36953098Sbostic	if [ -s $CUR ] ; then
37053130Sbostic		if cmp -s $CUR $TMP1 ; then
37152573Sbostic			:
37252573Sbostic		else
37353130Sbostic			> $TMP2
37453130Sbostic			join -110 -210 -v2 $CUR $TMP1 > $OUTPUT
37553130Sbostic			if [ -s $OUTPUT ] ; then
37653130Sbostic				printf "Setuid additions:\n"
37753130Sbostic				tee -a $TMP2 < $OUTPUT
37853130Sbostic				printf "\n"
37952573Sbostic			fi
38052573Sbostic
38153130Sbostic			join -110 -210 -v1 $CUR $TMP1 > $OUTPUT
38253130Sbostic			if [ -s $OUTPUT ] ; then
38353130Sbostic				printf "Setuid deletions:\n"
38453130Sbostic				tee -a $TMP2 < $OUTPUT
38553130Sbostic				printf "\n"
38652573Sbostic			fi
38752573Sbostic
38853130Sbostic			sort +9 $TMP2 $CUR $TMP1 | \
38953130Sbostic			    sed -e 's/[	 ][	 ]*/ /g' | uniq -u > $OUTPUT
39053130Sbostic			if [ -s $OUTPUT ] ; then
39153130Sbostic				printf "Setuid changes:\n"
39253130Sbostic				column -t $OUTPUT
39353130Sbostic				printf "\n"
39452573Sbostic			fi
39552573Sbostic
39653130Sbostic			cp $CUR $BACK
39753130Sbostic			cp $TMP1 $CUR
39852573Sbostic		fi
39952573Sbostic	else
40053130Sbostic		printf "Setuid additions:\n"
40153140Sbostic		column -t $TMP1
40253130Sbostic		printf "\n"
40353130Sbostic		cp $TMP1 $CUR
40452573Sbostic	fi
40552215Sbosticfi
40652215Sbostic
40753184Sbostic# Check for block and character disk devices that are readable or writeable
40853140Sbostic# or not owned by root.operator.
40953130Sbosticegrep '^b' $LIST > $TMP1
41053130Sbosticegrep '^c.*/rdk[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
41153130Sbosticegrep '^c.*/rfd[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
41253130Sbosticegrep '^c.*/rhd[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
41353130Sbosticegrep '^c.*/rhk[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
41453130Sbosticegrep '^c.*/rhp[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
41553130Sbosticegrep '^c.*/rjb[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
41653130Sbosticegrep '^c.*/rkra[0-9][0-9]*[a-h]$' $LIST >> $TMP1
41753130Sbosticegrep '^c.*/rra[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
41853130Sbosticegrep '^c.*/rrb[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
41953130Sbosticegrep '^c.*/rrd[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
42053130Sbosticegrep '^c.*/rrl[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
42153130Sbosticegrep '^c.*/rrx[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
42253130Sbosticegrep '^c.*/rrz[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
42353130Sbosticegrep '^c.*/rsd[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
42453130Sbosticegrep '^c.*/rup[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
42553130Sbosticegrep '^c.*/rwd[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
42653105Sbostic
42753140Sbosticawk '$3 != "root" || $4 != "operator" || $1 !~ /.rw-r-----/ \
42853140Sbostic	{ printf("Disk %s is user %s, group %s, permissions %s.\n", \
42953140Sbostic	    $11, $3, $4, $1); }' < $TMP1 > $OUTPUT
43053130Sbosticif [ -s $OUTPUT ] ; then
43153130Sbostic	printf "\nChecking disk ownership and permissions.\n"
43253130Sbostic	cat $OUTPUT
43353130Sbostic	printf "\n"
43453130Sbosticfi
43553105Sbostic
43653184Sbostic# Display any changes in the device file list.
43753140Sbosticegrep '^[bc]' $LIST | sort +10 > $TMP1
43853130Sbosticif [ -s $TMP1 ] ; then
43953130Sbostic	CUR=/var/backups/device.current
44053130Sbostic	BACK=/var/backups/device.backup
44153098Sbostic
44253098Sbostic	if [ -s $CUR ] ; then
44353130Sbostic		if cmp -s $CUR $TMP1 ; then
44453098Sbostic			:
44553098Sbostic		else
44653130Sbostic			> $TMP2
44753130Sbostic			join -111 -211 -v2 $CUR $TMP1 > $OUTPUT
44853130Sbostic			if [ -s $OUTPUT ] ; then
44953130Sbostic				printf "Device additions:\n"
45053130Sbostic				tee -a $TMP2 < $OUTPUT
45153130Sbostic				printf "\n"
45253098Sbostic			fi
45353098Sbostic
45453130Sbostic			join -111 -211 -v1 $CUR $TMP1 > $OUTPUT
45553130Sbostic			if [ -s $OUTPUT ] ; then
45653130Sbostic				printf "Device deletions:\n"
45753130Sbostic				tee -a $TMP2 < $OUTPUT
45853130Sbostic				printf "\n"
45953098Sbostic			fi
46053098Sbostic
46153140Sbostic			# Report any block device change.  Ignore character
46253140Sbostic			# devices, only the name is significant.
46353140Sbostic			cat $TMP2 $CUR $TMP1 | \
46453140Sbostic			sed -e '/^c/d' | \
46553140Sbostic			sort +10 | \
46653130Sbostic			sed -e 's/[	 ][	 ]*/ /g' | \
46753140Sbostic			uniq -u > $OUTPUT
46853130Sbostic			if [ -s $OUTPUT ] ; then
46953140Sbostic				printf "Block device changes:\n"
47053130Sbostic				column -t $OUTPUT
47153130Sbostic				printf "\n"
47253098Sbostic			fi
47353098Sbostic
47453130Sbostic			cp $CUR $BACK
47553130Sbostic			cp $TMP1 $CUR
47653098Sbostic		fi
47753098Sbostic	else
47853130Sbostic		printf "Device additions:\n"
47953140Sbostic		column -t $TMP1
48053130Sbostic		printf "\n"
48153130Sbostic		cp $TMP1 $CUR
48253098Sbostic	fi
48353098Sbosticfi
48453098Sbostic
48553142Sbostic# Check special files.
48653142Sbostic# Check system binaries.
48753142Sbostic#
48852578Sbostic# Create the mtree tree specifications using:
48952578Sbostic#
49053130Sbostic#	mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure
49153130Sbostic#	chown root.wheel DIR.SECURE
49253130Sbostic#	chmod 600 DIR.SECURE
49352578Sbostic#
49452578Sbostic# Note, this is not complete protection against Trojan horsed binaries, as
49552578Sbostic# the hacker can modify the tree specification to match the replaced binary.
49652578Sbostic# For details on really protecting yourself against modified binaries, see
49752578Sbostic# the mtree(8) manual page.
49852578Sbosticif cd /etc/mtree; then
49953130Sbostic	mtree -e -p / -f /etc/mtree/special > $OUTPUT
50053130Sbostic	if [ -s $OUTPUT ] ; then
50153130Sbostic		printf "\nChecking special files and directories.\n"
50253130Sbostic		cat $OUTPUT
50353130Sbostic	fi
50453130Sbostic
50553130Sbostic	> $OUTPUT
50652578Sbostic	for file in *.secure; do
50752578Sbostic		tree=`sed -n -e '3s/.* //p' -e 3q $file`
50853130Sbostic		mtree -f $file -p $tree > $TMP1
50953130Sbostic		if [ -s $TMP1 ]; then
51053130Sbostic			printf "\nChecking $tree:\n" >> $OUTPUT
51153130Sbostic			cat $TMP1 >> $OUTPUT
51253130Sbostic		fi
51352578Sbostic	done
51453130Sbostic	if [ -s $OUTPUT ] ; then
51553130Sbostic		printf "\nChecking system binaries:\n"
51653130Sbostic		cat $OUTPUT
51753130Sbostic	fi
51852578Sbosticfi
519*53264Sbostic
520*53264Sbostic# List of files that get backed up and checked for any modifications.  Each
521*53264Sbostic# file is expected to have two backups, /var/backups/file.{current,backup}.
522*53264Sbostic# Any changes cause the files to rotate.
523*53264Sbosticif [ -s /etc/changelist ] ; then
524*53264Sbostic	for file in `cat /etc/changelist`; do
525*53264Sbostic		CUR=/var/backups/`basename $file`.current
526*53264Sbostic		BACK=/var/backups/`basename $file`.backup
527*53264Sbostic		if [ -s $file ]; then
528*53264Sbostic			if [ -s $CUR ] ; then
529*53264Sbostic				diff $CUR $file > $OUTPUT
530*53264Sbostic				if [ -s $OUTPUT ] ; then
531*53264Sbostic		printf "\n======\n%s diffs (OLD < > NEW)\n======\n" $file
532*53264Sbostic					cat $OUTPUT
533*53264Sbostic					cp -p $CUR $BACK
534*53264Sbostic					cp -p $file $CUR
535*53264Sbostic					chown root.wheel $CUR $BACK
536*53264Sbostic				fi
537*53264Sbostic			else
538*53264Sbostic				cp -p $file $CUR
539*53264Sbostic				chown root.wheel $CUR
540*53264Sbostic			fi
541*53264Sbostic		fi
542*53264Sbostic	done
543*53264Sbosticfi
544