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