xref: /csrg-svn/etc/security (revision 53130)
142328Sbostic#!/bin/sh -
242328Sbostic#
3*53130Sbostic#	@(#)security	5.16 (Berkeley) 04/06/92
442328Sbostic#
553105Sbostic
653105Sbostic# Script to check basic system security.  Checks included are:
7*53130Sbostic#	Password and group file check.
8*53130Sbostic#	Root umask, dot in root's path.
9*53130Sbostic#	Root and uucp in /etc/ftpusers.
10*53130Sbostic#	Entry for uudecode in /etc/aliases, if uudecode is setuid.
11*53130Sbostic#	Hosts.equiv syntax.
12*53130Sbostic#	Special users that have .rhosts files, .rhosts file syntax.
1353105Sbostic#	Home directory and dot-file ownership and permissions.
1453105Sbostic#	Mailbox ownership and permissions.
15*53130Sbostic#	Globally exported NFS file systems.
1653105Sbostic#	Changes in setuid and device files.
1753105Sbostic#	Block and character disk device ownership and permissions.
18*53130Sbostic#	File list from /etc/mtree/special.
1953105Sbostic#	System binaries as described by files in /etc/mtree.
2053105Sbostic
2152578SbosticPATH=/sbin:/usr/sbin:/bin:/usr/bin
2242328Sbostic
23*53130Sbosticumask 077
2452215Sbostic
2553098SbosticERR=/tmp/_secure1.$$
2653098SbosticTMP1=/tmp/_secure2.$$
2753098SbosticTMP2=/tmp/_secure3.$$
28*53130SbosticTMP3=/tmp/_secure4.$$
29*53130SbosticLIST=/tmp/_secure5.$$
30*53130SbosticOUTPUT=/tmp/_secure6.$$
3152578Sbostic
32*53130Sbostictrap 'rm -f $ERR $TMP1 $TMP2 $TMP3 $LIST $OUTPUT' 0
3352578Sbostic
34*53130Sbostic# Check the password file syntax.
35*53130SbosticMP=/etc/master.passwd
36*53130Sbosticawk -F: '{
37*53130Sbostic	if ($0 ~ /^[	 ]*$/) {
38*53130Sbostic		printf("Line %d is a blank line.\n", NR);
39*53130Sbostic		next;
40*53130Sbostic	}
41*53130Sbostic	if (NF != 10)
42*53130Sbostic		printf("Line %d has the wrong number of fields.\n", NR);
43*53130Sbostic	if ($1 !~ /[A-za-z0-9]*/)
44*53130Sbostic		printf("Login %s has non-numeric characters.\n", $1);
45*53130Sbostic	if (length($1) > 8)
46*53130Sbostic		printf("Login %s has more than 8 characters.\n", $1);
47*53130Sbostic	if ($2 == "")
48*53130Sbostic		printf("Login %s has no password.\n", $1);
49*53130Sbostic	if (length($2) != 13 && ($10 ~ /.*sh$/ || $10 == ""))
50*53130Sbostic		printf("Login %s is off but still has a valid shell.\n", $1);
51*53130Sbostic	if ($3 == 0 && $1 != "root" && $1 != "toor")
52*53130Sbostic		printf("Login %s has a user id of 0.\n", $1);
53*53130Sbostic	if ($3 < 0)
54*53130Sbostic		printf("Login %s has a negative user id.\n", $1);
55*53130Sbostic	if ($4 < 0)
56*53130Sbostic		printf("Login %s has a negative user id.\n", $1);
57*53130Sbostic}' < $MP > $OUTPUT
58*53130Sbosticif [ -s $OUTPUT ] ; then
59*53130Sbostic	printf "\nChecking the $MP file:\n"
60*53130Sbostic	cat $OUTPUT
61*53130Sbosticfi
6242328Sbostic
63*53130Sbosticawk -F: '{ print $1 }' $MP | sort | uniq -d > $OUTPUT
64*53130Sbosticif [ -s $OUTPUT ] ; then
65*53130Sbostic	printf "\n$MP has duplicate user names.\n"
66*53130Sbostic	column $OUTPUT
67*53130Sbosticfi
6852573Sbostic
69*53130Sbosticawk -F: '{ print $1 " " $3 }' $MP | sort -n +1 | tee $TMP1 |
70*53130Sbosticuniq -d -f 1 | awk '{ print $2 }' > $TMP2
71*53130Sbosticif [ -s $TMP2 ] ; then
72*53130Sbostic	printf "\n$MP has duplicate user id's.\n"
73*53130Sbostic        while read uid; do
74*53130Sbostic                grep -w $uid $TMP1
75*53130Sbostic        done < $TMP2 | column
76*53130Sbosticfi
7753104Sbostic
78*53130Sbostic# Check the group file syntax.
79*53130SbosticGRP=/etc/group
80*53130Sbosticawk -F: '{
81*53130Sbostic	if ($0 ~ /^[	 ]*$/) {
82*53130Sbostic		printf("Line %d is a blank line.\n", NR);
83*53130Sbostic		next;
84*53130Sbostic	}
85*53130Sbostic	if (NF != 4)
86*53130Sbostic		printf("Line %d has the wrong number of fields.\n", NR);
87*53130Sbostic	if ($1 !~ /[A-za-z0-9]*/)
88*53130Sbostic		printf("Group %s has non-numeric characters.\n", $1);
89*53130Sbostic	if (length($1) > 8)
90*53130Sbostic		printf("Group %s has more than 8 characters.\n", $1);
91*53130Sbostic	if ($3 !~ /[0-9]*/)
92*53130Sbostic		printf("Login %s has a negative user id.\n", $1);
93*53130Sbostic}' < $GRP > $OUTPUT
94*53130Sbosticif [ -s $OUTPUT ] ; then
95*53130Sbostic	printf "\nChecking the $GRP file:\n"
96*53130Sbostic	cat $OUTPUT
97*53130Sbosticfi
98*53130Sbostic
99*53130Sbosticawk -F: '{ print $1 }' $GRP | sort | uniq -d > $OUTPUT
100*53130Sbosticif [ -s $OUTPUT ] ; then
101*53130Sbostic	printf "\n$GRP has duplicate group names.\n"
102*53130Sbostic	column $OUTPUT
103*53130Sbosticfi
104*53130Sbostic
105*53130Sbostic# Check for root paths, umask values in startup files.
106*53130Sbostic> $OUTPUT
107*53130Sbosticrhome=/root
108*53130Sbosticumaskset=no
109*53130Sbosticlist="/etc/csh.cshrc /etc/csh.login ${rhome}/.cshrc ${rhome}/.login"
110*53130Sbosticfor i in $list ; do
111*53130Sbostic	if [ -f $i ] ; then
112*53130Sbostic		if egrep umask $i > /dev/null ; then
113*53130Sbostic			umaskset=yes
11453104Sbostic		fi
115*53130Sbostic		egrep umask $i |
116*53130Sbostic		awk '$2 % 100 < 20 \
117*53130Sbostic			{ print "Root umask is group writeable" }
118*53130Sbostic		     $2 % 10 < 2 \
119*53130Sbostic			{ print "Root umask is other writeable" }' >> $OUTPUT
120*53130Sbostic		/bin/csh -f -s << end-of-csh > /dev/null 2>&1
121*53130Sbostic			unset path
122*53130Sbostic			source $i
123*53130Sbostic			/bin/ls -ldgT \$path > $TMP1
124*53130Sbosticend-of-csh
125*53130Sbostic		awk '{
126*53130Sbostic			if ($10 ~ /\./) {
127*53130Sbostic				print "The root path includes .";
128*53130Sbostic				next;
129*53130Sbostic			}
130*53130Sbostic		     }
131*53130Sbostic		     $1 ~ /^d....w/ \
132*53130Sbostic        { print "Root path directory " $10 " is group writeable." } \
133*53130Sbostic		     $1 ~ /^d.......w/ \
134*53130Sbostic        { print "Root path directory " $10 " is other writeable." }' \
135*53130Sbostic		< $TMP1 >> $OUTPUT
136*53130Sbostic	fi
137*53130Sbosticdone
138*53130Sbosticif [ $umaskset = "no" -o -s $OUTPUT ] ; then
139*53130Sbostic	printf "\nChecking root csh paths, umask values:\n$list\n"
140*53130Sbostic	if [ -s $OUTPUT ]; then
141*53130Sbostic		cat $OUTPUT
142*53130Sbostic	fi
143*53130Sbostic	if [ $umaskset = "no" ] ; then
144*53130Sbostic		printf "\nRoot csh startup files do not set the umask.\n"
145*53130Sbostic	fi
146*53130Sbosticfi
14753104Sbostic
148*53130Sbostic> $OUTPUT
149*53130Sbosticrhome=/root
150*53130Sbosticumaskset=no
151*53130Sbosticlist="${rhome}/.profile"
152*53130Sbosticfor i in $list; do
153*53130Sbostic	if [ -f $i ] ; then
154*53130Sbostic		if egrep umask $i > /dev/null ; then
155*53130Sbostic			umaskset=yes
156*53130Sbostic		fi
157*53130Sbostic		egrep umask $i |
158*53130Sbostic		awk '$2 % 100 < 20 \
159*53130Sbostic			{ print "Root umask is group writeable" } \
160*53130Sbostic		     $2 % 10 < 2 \
161*53130Sbostic			{ print "Root umask is other writeable" }' >> $OUTPUT
162*53130Sbostic		/bin/sh << end-of-sh > /dev/null 2>&1
163*53130Sbostic			PATH=
164*53130Sbostic			. $i
165*53130Sbostic			list=\`echo \$PATH | /usr/bin/sed -e 's/:/ /g'\`
166*53130Sbostic			/bin/ls -ldgT \$list > $TMP1
167*53130Sbosticend-of-sh
168*53130Sbostic		awk '{
169*53130Sbostic			if ($10 ~ /\./) {
170*53130Sbostic				print "The root path includes .";
171*53130Sbostic				next;
172*53130Sbostic			}
173*53130Sbostic		     }
174*53130Sbostic		     $1 ~ /^d....w/ \
175*53130Sbostic        { print "Root path directory " $10 " is group writeable." } \
176*53130Sbostic		     $1 ~ /^d.......w/ \
177*53130Sbostic        { print "Root path directory " $10 " is other writeable." }' \
178*53130Sbostic		< $TMP1 >> $OUTPUT
179*53130Sbostic
180*53130Sbostic	fi
181*53130Sbosticdone
182*53130Sbosticif [ $umaskset = "no" -o -s $OUTPUT ] ; then
183*53130Sbostic	printf "\nChecking root sh paths, umask values:\n$list\n"
184*53130Sbostic	if [ -s $OUTPUT ]; then
185*53130Sbostic		cat $OUTPUT
186*53130Sbostic	fi
187*53130Sbostic	if [ $umaskset = "no" ] ; then
188*53130Sbostic		printf "\nRoot sh startup files do not set the umask.\n"
189*53130Sbostic	fi
190*53130Sbosticfi
191*53130Sbostic
192*53130Sbostic# Root and uucp should both be in /etc/ftpusers.
193*53130Sbosticif egrep root /etc/ftpusers > /dev/null ; then
194*53130Sbostic	:
195*53130Sbosticelse
196*53130Sbostic	printf "\nRoot not listed in /etc/ftpusers file.\n"
197*53130Sbosticfi
198*53130Sbosticif egrep uucp /etc/ftpusers > /dev/null ; then
199*53130Sbostic	:
200*53130Sbosticelse
201*53130Sbostic	printf "\nUucp not listed in /etc/ftpusers file.\n"
202*53130Sbosticfi
203*53130Sbostic
204*53130Sbostic# Uudecode should not be in the aliases file.
205*53130Sbosticif grep -w uudecode /etc/aliases; then
206*53130Sbostic	printf "\nThere is an entry for uudecode in the /etc/aliases file.\n"
207*53130Sbosticfi
208*53130Sbostic
209*53130Sbostic# Check for plus signs in /etc/hosts.equiv.
210*53130Sbosticif egrep '\+|^$' /etc/hosts.equiv > /dev/null ; then
211*53130Sbostic	printf "\nEmpty line or + in /etc/hosts.equiv file.\n"
212*53130Sbosticfi
213*53130Sbostic
214*53130Sbostic# Check for special users with .rhosts files.  Only root and toor should
215*53130Sbostic# have a .rhosts files.  Also, .rhosts files should not have blank lines
216*53130Sbostic# or plus signs.
217*53130Sbosticawk -F: '$1 != "root" && $1 != "toor" && \
218*53130Sbostic	($3 < 100 || $1 == "ftp" || $1 == "uucp") \
219*53130Sbostic		{ print $1 " " $6 }' /etc/passwd |
220*53130Sbosticwhile read uid homedir; do
221*53130Sbostic	if [ -f ${homedir}/.rhosts ] ; then
222*53130Sbostic		rhost=`ls -ldgT ${homedir}/.rhosts`
223*53130Sbostic		printf "$uid: $rhost\n"
224*53130Sbostic	fi
225*53130Sbosticdone > $OUTPUT
226*53130Sbosticif [ -s $OUTPUT ] ; then
227*53130Sbostic	printf "\nChecking for special users with .rhosts files.\n"
228*53130Sbostic	cat $OUTPUT
229*53130Sbosticfi
230*53130Sbostic
231*53130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \
232*53130Sbosticwhile read uid homedir; do
233*53130Sbostic	if [ -f ${homedir}/.rhosts ] && \
234*53130Sbostic	    egrep '\+|^$' ${homedir}/.rhosts > /dev/null ; then
235*53130Sbostic		printf "$uid: empty line or + in .rhosts file.\n"
236*53130Sbostic	fi
237*53130Sbosticdone > $OUTPUT
238*53130Sbosticif [ -s $OUTPUT ] ; then
239*53130Sbostic	printf "\nChecking .rhosts files syntax.\n"
240*53130Sbostic	cat $OUTPUT
241*53130Sbosticfi
242*53130Sbostic
243*53130Sbostic# Check home directories, dot files.
24453105Sbostic# Directories should not be owned by someone else or writeable.
245*53130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \
24653105Sbosticwhile read uid homedir; do
24753105Sbostic	if [ -d ${homedir}/ ] ; then
24853105Sbostic		file=`ls -ldgT ${homedir}`
249*53130Sbostic		printf "$uid $file\n"
25053105Sbostic	fi
251*53130Sbosticdone |
252*53130Sbosticawk '$1 != $4 && $4 != "root" \
253*53130Sbostic	{ print "user " $1 " home directory is owned by " $4 }
254*53130Sbostic     $2 ~ /^-....w/ \
255*53130Sbostic	{ print "user " $1 " home directory is group writeable" }
256*53130Sbostic     $2 ~ /^-.......w/ \
257*53130Sbostic	{ print "user " $1 " home directory is other writeable" }' > $OUTPUT
258*53130Sbosticif [ -s $OUTPUT ] ; then
259*53130Sbostic	printf "\nChecking home directories.\n"
260*53130Sbostic	cat $OUTPUT
261*53130Sbosticfi
26253105Sbostic
26353104Sbostic# Files that should not be owned by someone else or readable.
264*53130Sbosticlist=".netrc .rhosts"
265*53130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \
26653104Sbosticwhile read uid homedir; do
267*53130Sbostic	for f in $list ; do
268*53130Sbostic		file=${homedir}/${f}
269*53130Sbostic		if [ -f $file ] ; then
270*53130Sbostic			printf "$uid $f `ls -ldgT $file`\n"
271*53130Sbostic		fi
272*53130Sbostic	done
273*53130Sbosticdone |
274*53130Sbosticawk '$1 != $5 && $5 != "root" \
275*53130Sbostic	{ print "user " $1 " " $2 " file is owned by " $5 }
276*53130Sbostic     $3 ~ /^-...r/ \
277*53130Sbostic	{ print "user " $1 " " $2 " file is group readable" }
278*53130Sbostic     $3 ~ /^-......r/ \
279*53130Sbostic	{ print "user " $1 " " $2 " file is other readable" }
280*53130Sbostic     $3 ~ /^-....w/ \
281*53130Sbostic	{ print "user " $1 " " $2 " file is group writeable" }
282*53130Sbostic     $3 ~ /^-.......w/ \
283*53130Sbostic	{ print "user " $1 " " $2 " file is other writeable" }' > $OUTPUT
28453104Sbostic
28553104Sbostic# Files that should not be owned by someone else or writeable.
286*53130Sbosticlist=".bashrc .cshrc .emacsrc .exrc .forward .klogin .login .logout \
287*53130Sbostic      .profile .tcshrc"
288*53130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \
28953104Sbosticwhile read uid homedir; do
290*53130Sbostic	for f in $list ; do
291*53130Sbostic		file=${homedir}/${f}
292*53130Sbostic		if [ -f $file ] ; then
293*53130Sbostic			printf "$uid $f `ls -ldgT $file`\n"
294*53130Sbostic		fi
295*53130Sbostic	done
296*53130Sbosticdone |
297*53130Sbosticawk '$1 != $5 && $5 != "root" \
298*53130Sbostic	{ print "user " $1 " " $2 " file is owned by " $5 }
299*53130Sbostic     $3 ~ /^-....w/ \
300*53130Sbostic	{ print "user " $1 " " $2 " file is group writeable" }
301*53130Sbostic     $3 ~ /^-.......w/ \
302*53130Sbostic	{ print "user " $1 " " $2 " file is other writeable" }' >> $OUTPUT
303*53130Sbosticif [ -s $OUTPUT ] ; then
304*53130Sbostic	printf "\nChecking dot files.\n"
305*53130Sbostic	cat $OUTPUT
306*53130Sbosticfi
30753104Sbostic
30853104Sbostic# Check mailbox ownership and permissions.
309*53130Sbosticls -l /var/mail | sed 1d | \
310*53130Sbosticawk '$3 != $9 \
311*53130Sbostic	{ print "user " $9 " mailbox is owned by " $3 }
312*53130Sbostic     $1 != "-rw-------" \
313*53130Sbostic	{ print "user " $9 " mailbox is " $1 ", group " $4 }' > $OUTPUT
314*53130Sbosticif [ -s $OUTPUT ] ; then
315*53130Sbostic	printf "\nChecking mailbox ownership.\n"
316*53130Sbostic	cat $OUTPUT
317*53130Sbosticfi
31853104Sbostic
31953105Sbostic# Check for globally exported file systems.
32053105Sbosticawk '{
32153105Sbostic	readonly = 0;
32253105Sbostic	for (i = 2; i <= NF; ++i) {
32353105Sbostic		if ($i ~ /-ro/)
32453105Sbostic			readonly = 1;
32553105Sbostic		else if ($i !~ /^-/)
32653105Sbostic			next;
32753105Sbostic	}
32853105Sbostic	if (readonly)
32953105Sbostic		print "File system " $1 " globally exported, read-only."
33053105Sbostic	else
33153105Sbostic		print "File system " $1 " globally exported, read-write."
332*53130Sbostic}' < /etc/exports > $OUTPUT
333*53130Sbosticif [ -s $OUTPUT ] ; then
334*53130Sbostic	printf "\nChecking for globally exported file systems.\n"
335*53130Sbostic	cat $OUTPUT
336*53130Sbosticfi
33753105Sbostic
33853098Sbostic# Display setuid and device changes.
339*53130Sbosticprintf "\nChecking setuid files and devices:\n"
340*53130Sbostic(find / ! -fstype local -a -prune -o \
341*53130Sbostic    \( -perm -u+s -o -perm -g+s -o ! -type d -a ! -type f -a ! -type l -a \
342*53130Sbostic       ! -type s \) | \
343*53130Sbosticsort | sed -e 's/^/ls -ldgT /' | sh > $LIST) 2> $OUTPUT
34442328Sbostic
34553098Sbostic# Display any errors that occurred during system file walk.
346*53130Sbosticif [ -s $OUTPUT ] ; then
347*53130Sbostic	printf "Setuid/device find errors:\n"
348*53130Sbostic	cat $OUTPUT
349*53130Sbostic	printf "\n"
35042328Sbosticfi
35142328Sbostic
35253098Sbostic# Display any changes in the setuid file list.
353*53130Sbosticegrep -v '^[bc]' $LIST > $TMP1
35452215Sbostic
355*53130Sbosticif [ -s $TMP1 ] ; then
356*53130Sbostic	# Check to make sure uudecode isn't setuid.
357*53130Sbostic	if grep -w uudecode $TMP1 > /dev/null ; then
358*53130Sbostic		printf "\nUudecode is setuid.\n"
359*53130Sbostic	fi
360*53130Sbostic
361*53130Sbostic	CUR=/var/backups/setuid.current
362*53130Sbostic	BACK=/var/backups/setuid.backup
363*53130Sbostic
36453098Sbostic	if [ -s $CUR ] ; then
365*53130Sbostic		if cmp -s $CUR $TMP1 ; then
36652573Sbostic			:
36752573Sbostic		else
368*53130Sbostic			> $TMP2
369*53130Sbostic			join -110 -210 -v2 $CUR $TMP1 > $OUTPUT
370*53130Sbostic			if [ -s $OUTPUT ] ; then
371*53130Sbostic				printf "Setuid additions:\n"
372*53130Sbostic				tee -a $TMP2 < $OUTPUT
373*53130Sbostic				printf "\n"
37452573Sbostic			fi
37552573Sbostic
376*53130Sbostic			join -110 -210 -v1 $CUR $TMP1 > $OUTPUT
377*53130Sbostic			if [ -s $OUTPUT ] ; then
378*53130Sbostic				printf "Setuid deletions:\n"
379*53130Sbostic				tee -a $TMP2 < $OUTPUT
380*53130Sbostic				printf "\n"
38152573Sbostic			fi
38252573Sbostic
383*53130Sbostic			sort +9 $TMP2 $CUR $TMP1 | \
384*53130Sbostic			    sed -e 's/[	 ][	 ]*/ /g' | uniq -u > $OUTPUT
385*53130Sbostic			if [ -s $OUTPUT ] ; then
386*53130Sbostic				printf "Setuid changes:\n"
387*53130Sbostic				column -t $OUTPUT
388*53130Sbostic				printf "\n"
38952573Sbostic			fi
39052573Sbostic
391*53130Sbostic			cp $CUR $BACK
392*53130Sbostic			cp $TMP1 $CUR
39352573Sbostic		fi
39452573Sbostic	else
395*53130Sbostic		printf "Setuid additions:\n"
396*53130Sbostic		cat $TMP1
397*53130Sbostic		printf "\n"
398*53130Sbostic		cp $TMP1 $CUR
39952573Sbostic	fi
40052215Sbosticfi
40152215Sbostic
40253105Sbostic# Check for readable/writeable block and character disk devices.
403*53130Sbosticegrep '^b' $LIST > $TMP1
404*53130Sbosticegrep '^c.*/rdk[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
405*53130Sbosticegrep '^c.*/rfd[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
406*53130Sbosticegrep '^c.*/rhd[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
407*53130Sbosticegrep '^c.*/rhk[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
408*53130Sbosticegrep '^c.*/rhp[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
409*53130Sbosticegrep '^c.*/rjb[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
410*53130Sbosticegrep '^c.*/rkra[0-9][0-9]*[a-h]$' $LIST >> $TMP1
411*53130Sbosticegrep '^c.*/rra[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
412*53130Sbosticegrep '^c.*/rrb[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
413*53130Sbosticegrep '^c.*/rrd[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
414*53130Sbosticegrep '^c.*/rrl[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
415*53130Sbosticegrep '^c.*/rrx[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
416*53130Sbosticegrep '^c.*/rrz[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
417*53130Sbosticegrep '^c.*/rsd[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
418*53130Sbosticegrep '^c.*/rup[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
419*53130Sbosticegrep '^c.*/rwd[0-9][0-9]*[a-h]$'  $LIST >> $TMP1
42053105Sbostic
421*53130Sbosticawk '$4 != "operator" \
422*53130Sbostic	{ print "Disk " $11 " not owned by group operator." }
423*53130Sbostic     $1 !~ /.rw-r-----/ \
424*53130Sbostic	{ print "Disk " $11 " is " $1 ", group " $4 }' < $TMP1 > $OUTPUT
425*53130Sbosticif [ -s $OUTPUT ] ; then
426*53130Sbostic	printf "\nChecking disk ownership and permissions.\n"
427*53130Sbostic	cat $OUTPUT
428*53130Sbostic	printf "\n"
429*53130Sbosticfi
43053105Sbostic
431*53130Sbosticegrep '^[bcs]' $LIST | sort +10 > $TMP1
43253098Sbostic# Display any changes in the device file list.
433*53130Sbosticif [ -s $TMP1 ] ; then
434*53130Sbostic	CUR=/var/backups/device.current
435*53130Sbostic	BACK=/var/backups/device.backup
43653098Sbostic
43753098Sbostic	if [ -s $CUR ] ; then
438*53130Sbostic		if cmp -s $CUR $TMP1 ; then
43953098Sbostic			:
44053098Sbostic		else
441*53130Sbostic			> $TMP2
442*53130Sbostic			join -111 -211 -v2 $CUR $TMP1 > $OUTPUT
443*53130Sbostic			if [ -s $OUTPUT ] ; then
444*53130Sbostic				printf "Device additions:\n"
445*53130Sbostic				tee -a $TMP2 < $OUTPUT
446*53130Sbostic				printf "\n"
44753098Sbostic			fi
44853098Sbostic
449*53130Sbostic			join -111 -211 -v1 $CUR $TMP1 > $OUTPUT
450*53130Sbostic			if [ -s $OUTPUT ] ; then
451*53130Sbostic				printf "Device deletions:\n"
452*53130Sbostic				tee -a $TMP2 < $OUTPUT
453*53130Sbostic				printf "\n"
45453098Sbostic			fi
45553098Sbostic
456*53130Sbostic			sort +10 $TMP2 $CUR $TMP1 | \
457*53130Sbostic			sed -e 's/[	 ][	 ]*/ /g' | \
458*53130Sbostic			awk '{ \
459*53130Sbostic			    printf("%s %s %s %s %s %s %s %s %s %s %s\n", \
460*53130Sbostic			    $7, $8, $9, $10, $1, $2, $3, $4, $5, $6, $11); \
461*53130Sbostic			    }' | uniq -f 4 -u | \
462*53130Sbostic			awk '{ \
463*53130Sbostic			    printf("%s %s %s %s %s %s %s %s %s %s %s\n", \
464*53130Sbostic			    $5, $6, $7, $8, $9, $10, $1, $2, $3, $4, $11); \
465*53130Sbostic			    }' > $OUTPUT
466*53130Sbostic			if [ -s $OUTPUT ] ; then
467*53130Sbostic				printf "Device changes:\n"
468*53130Sbostic				column -t $OUTPUT
469*53130Sbostic				printf "\n"
47053098Sbostic			fi
47153098Sbostic
472*53130Sbostic			cp $CUR $BACK
473*53130Sbostic			cp $TMP1 $CUR
47453098Sbostic		fi
47553098Sbostic	else
476*53130Sbostic		printf "Device additions:\n"
477*53130Sbostic		cat $TMP1
478*53130Sbostic		printf "\n"
479*53130Sbostic		cp $TMP1 $CUR
48053098Sbostic	fi
48153098Sbosticfi
48253098Sbostic
48352578Sbostic# Check the system binaries.
48452578Sbostic# Create the mtree tree specifications using:
48552578Sbostic#
486*53130Sbostic#	mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure
487*53130Sbostic#	chown root.wheel DIR.SECURE
488*53130Sbostic#	chmod 600 DIR.SECURE
48952578Sbostic#
49052578Sbostic# Note, this is not complete protection against Trojan horsed binaries, as
49152578Sbostic# the hacker can modify the tree specification to match the replaced binary.
49252578Sbostic# For details on really protecting yourself against modified binaries, see
49352578Sbostic# the mtree(8) manual page.
494*53130Sbostic# Check for special files.
495*53130Sbostic
49652578Sbosticif cd /etc/mtree; then
497*53130Sbostic	mtree -e -p / -f /etc/mtree/special > $OUTPUT
498*53130Sbostic	if [ -s $OUTPUT ] ; then
499*53130Sbostic		printf "\nChecking special files and directories.\n"
500*53130Sbostic		cat $OUTPUT
501*53130Sbostic	fi
502*53130Sbostic
503*53130Sbostic	> $OUTPUT
50452578Sbostic	for file in *.secure; do
50552578Sbostic		tree=`sed -n -e '3s/.* //p' -e 3q $file`
506*53130Sbostic		mtree -f $file -p $tree > $TMP1
507*53130Sbostic		if [ -s $TMP1 ]; then
508*53130Sbostic			printf "\nChecking $tree:\n" >> $OUTPUT
509*53130Sbostic			cat $TMP1 >> $OUTPUT
510*53130Sbostic		fi
51152578Sbostic	done
512*53130Sbostic	if [ -s $OUTPUT ] ; then
513*53130Sbostic		printf "\nChecking system binaries:\n"
514*53130Sbostic		cat $OUTPUT
515*53130Sbostic	fi
51652578Sbosticfi
517