security revision 1.28 1 1.1 cgd #!/bin/sh -
2 1.1 cgd #
3 1.28 lukem # $NetBSD: security,v 1.28 1997/09/18 05:16:19 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.27 lukem MPPATH=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.27 lukem awk -F: '{ print $1 " " $9 }' $MP | sort -k2 > $MPPATH
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.27 lukem # XXX This should be updated to support the new format...
251 1.17 mycroft if [ "$check_ftpusers" = YES ]; then
252 1.28 lukem > $OUTPUT
253 1.28 lukem list="uucp "`awk '$2 == 0 { print $1 }' $MPBYUID`
254 1.27 lukem for i in $list; do
255 1.27 lukem if ! egrep "^$i$" /etc/ftpusers > /dev/null ; then
256 1.28 lukem printf "\t$i is not present\n" \ >> $OUTPUT
257 1.27 lukem fi
258 1.27 lukem done
259 1.28 lukem if [ -s $OUTPUT ]; then
260 1.28 lukem printf "\nChecking the /etc/ftpusers configuration:\n"
261 1.28 lukem cat $OUTPUT
262 1.28 lukem fi
263 1.9 cgd fi
264 1.9 cgd
265 1.9 cgd # Uudecode should not be in the /etc/aliases file.
266 1.17 mycroft if [ "$check_aliases" = YES ]; then
267 1.18 mikel if egrep '^[^#]*(uudecode|decode).*\|' /etc/aliases; then
268 1.18 mikel printf "\nEntry for uudecode in /etc/aliases file.\n"
269 1.15 mrg fi
270 1.9 cgd fi
271 1.9 cgd
272 1.9 cgd # Files that should not have + signs.
273 1.17 mycroft if [ "$check_rhosts" = YES ]; then
274 1.15 mrg list="/etc/hosts.equiv /etc/hosts.lpd"
275 1.15 mrg for f in $list ; do
276 1.15 mrg if [ -f $f ] && egrep '\+' $f > /dev/null ; then
277 1.15 mrg printf "\nPlus sign in $f file.\n"
278 1.15 mrg fi
279 1.15 mrg done
280 1.15 mrg
281 1.15 mrg # Check for special users with .rhosts files. Only root and toor should
282 1.16 mikel # have .rhosts files. Also, .rhosts files should not have plus signs.
283 1.15 mrg awk -F: '$1 != "root" && $1 != "toor" && \
284 1.15 mrg ($3 < 100 || $1 == "ftp" || $1 == "uucp") \
285 1.20 mycroft { print $1 " " $9 }' $MP |
286 1.19 mycroft sort -k2 |
287 1.15 mrg while read uid homedir; do
288 1.15 mrg if [ -f ${homedir}/.rhosts ] ; then
289 1.15 mrg rhost=`ls -ldgT ${homedir}/.rhosts`
290 1.15 mrg printf "$uid: $rhost\n"
291 1.15 mrg fi
292 1.15 mrg done > $OUTPUT
293 1.15 mrg if [ -s $OUTPUT ] ; then
294 1.15 mrg printf "\nChecking for special users with .rhosts files.\n"
295 1.15 mrg cat $OUTPUT
296 1.15 mrg fi
297 1.15 mrg
298 1.15 mrg while read uid homedir; do
299 1.15 mrg if [ -f ${homedir}/.rhosts ] && \
300 1.15 mrg egrep '\+' ${homedir}/.rhosts > /dev/null ; then
301 1.15 mrg printf "$uid: + in .rhosts file.\n"
302 1.15 mrg fi
303 1.27 lukem done < $MPPATH > $OUTPUT
304 1.15 mrg if [ -s $OUTPUT ] ; then
305 1.15 mrg printf "\nChecking .rhosts files syntax.\n"
306 1.15 mrg cat $OUTPUT
307 1.15 mrg fi
308 1.9 cgd fi
309 1.9 cgd
310 1.9 cgd # Check home directories. Directories should not be owned by someone else
311 1.9 cgd # or writeable.
312 1.17 mycroft if [ "$check_homes" = YES ]; then
313 1.15 mrg while read uid homedir; do
314 1.15 mrg if [ -d ${homedir}/ ] ; then
315 1.15 mrg file=`ls -ldgT ${homedir}`
316 1.15 mrg printf "$uid $file\n"
317 1.9 cgd fi
318 1.27 lukem done < $MPPATH |
319 1.15 mrg awk '$1 != $4 && $4 != "root" \
320 1.15 mrg { print "user " $1 " home directory is owned by " $4 }
321 1.15 mrg $2 ~ /^-....w/ \
322 1.15 mrg { print "user " $1 " home directory is group writeable" }
323 1.15 mrg $2 ~ /^-.......w/ \
324 1.27 lukem { print "user " $1 " home directory is other writeable" }' \
325 1.27 lukem > $OUTPUT
326 1.15 mrg if [ -s $OUTPUT ] ; then
327 1.15 mrg printf "\nChecking home directories.\n"
328 1.15 mrg cat $OUTPUT
329 1.15 mrg fi
330 1.15 mrg
331 1.15 mrg # Files that should not be owned by someone else or readable.
332 1.27 lukem list=".Xauthority .netrc"
333 1.15 mrg while read uid homedir; do
334 1.15 mrg for f in $list ; do
335 1.15 mrg file=${homedir}/${f}
336 1.15 mrg if [ -f $file ] ; then
337 1.15 mrg printf "$uid $f `ls -ldgT $file`\n"
338 1.15 mrg fi
339 1.15 mrg done
340 1.27 lukem done < $MPPATH |
341 1.15 mrg awk '$1 != $5 && $5 != "root" \
342 1.15 mrg { print "user " $1 " " $2 " file is owned by " $5 }
343 1.15 mrg $3 ~ /^-...r/ \
344 1.15 mrg { print "user " $1 " " $2 " file is group readable" }
345 1.15 mrg $3 ~ /^-......r/ \
346 1.15 mrg { print "user " $1 " " $2 " file is other readable" }
347 1.15 mrg $3 ~ /^-....w/ \
348 1.15 mrg { print "user " $1 " " $2 " file is group writeable" }
349 1.15 mrg $3 ~ /^-.......w/ \
350 1.27 lukem { print "user " $1 " " $2 " file is other writeable" }' \
351 1.27 lukem > $OUTPUT
352 1.15 mrg
353 1.15 mrg # Files that should not be owned by someone else or writeable.
354 1.19 mycroft list=".bash_history .bash_login .bash_logout .bash_profile .bashrc \
355 1.19 mycroft .cshrc .emacs .exrc .forward .history .klogin .login .logout \
356 1.27 lukem .profile .qmail .rc_history .rhosts .tcshrc .twmrc .xinitrc \
357 1.27 lukem .xsession"
358 1.15 mrg while read uid homedir; do
359 1.15 mrg for f in $list ; do
360 1.15 mrg file=${homedir}/${f}
361 1.15 mrg if [ -f $file ] ; then
362 1.15 mrg printf "$uid $f `ls -ldgT $file`\n"
363 1.15 mrg fi
364 1.15 mrg done
365 1.27 lukem done < $MPPATH |
366 1.15 mrg awk '$1 != $5 && $5 != "root" \
367 1.15 mrg { print "user " $1 " " $2 " file is owned by " $5 }
368 1.15 mrg $3 ~ /^-....w/ \
369 1.15 mrg { print "user " $1 " " $2 " file is group writeable" }
370 1.15 mrg $3 ~ /^-.......w/ \
371 1.27 lukem { print "user " $1 " " $2 " file is other writeable" }' \
372 1.27 lukem >> $OUTPUT
373 1.15 mrg if [ -s $OUTPUT ] ; then
374 1.15 mrg printf "\nChecking dot files.\n"
375 1.15 mrg cat $OUTPUT
376 1.15 mrg fi
377 1.9 cgd fi
378 1.9 cgd
379 1.9 cgd # Mailboxes should be owned by user and unreadable.
380 1.17 mycroft if [ "$check_varmail" = YES ]; then
381 1.15 mrg ls -l /var/mail | sed 1d | \
382 1.15 mrg awk '$3 != $9 \
383 1.15 mrg { print "user " $9 " mailbox is owned by " $3 }
384 1.15 mrg $1 != "-rw-------" \
385 1.15 mrg { print "user " $9 " mailbox is " $1 ", group " $4 }' > $OUTPUT
386 1.15 mrg if [ -s $OUTPUT ] ; then
387 1.15 mrg printf "\nChecking mailbox ownership.\n"
388 1.15 mrg cat $OUTPUT
389 1.15 mrg fi
390 1.15 mrg fi
391 1.15 mrg
392 1.17 mycroft if [ "$check_nfs" = YES ]; then
393 1.15 mrg if [ -f /etc/exports ]; then
394 1.15 mrg # File systems should not be globally exported.
395 1.15 mrg awk '{
396 1.22 lukem # ignore comments and blank lines
397 1.22 lukem if ($LINE ~ /^\#/ || $LINE ~ /^$/ )
398 1.22 lukem next;
399 1.22 lukem
400 1.15 mrg readonly = 0;
401 1.15 mrg for (i = 2; i <= NF; ++i) {
402 1.15 mrg if ($i ~ /-ro/)
403 1.15 mrg readonly = 1;
404 1.15 mrg else if ($i !~ /^-/)
405 1.15 mrg next;
406 1.15 mrg }
407 1.15 mrg if (readonly)
408 1.15 mrg print "File system " $1 " globally exported, read-only."
409 1.15 mrg else
410 1.15 mrg print "File system " $1 " globally exported, read-write."
411 1.15 mrg }' < /etc/exports > $OUTPUT
412 1.15 mrg if [ -s $OUTPUT ] ; then
413 1.15 mrg printf "\nChecking for globally exported file systems.\n"
414 1.15 mrg cat $OUTPUT
415 1.15 mrg fi
416 1.15 mrg fi
417 1.9 cgd fi
418 1.9 cgd
419 1.9 cgd # Display any changes in setuid files and devices.
420 1.17 mycroft if [ "$check_devices" = YES ]; then
421 1.28 lukem > $ERR
422 1.15 mrg (find / \( ! -fstype local -o -fstype fdesc -o -fstype kernfs \
423 1.15 mrg -o -fstype procfs \) -a -prune -o \
424 1.21 mycroft \( \( -perm -u+s -a ! -type d \) -o \
425 1.21 mycroft \( -perm -g+s -a ! -type d \) -o \
426 1.24 lukem -type b -o -type c \) -print0 | \
427 1.24 lukem xargs -0 ls -ldgTq | sort +9 > $LIST) 2> $OUTPUT
428 1.15 mrg
429 1.15 mrg # Display any errors that occurred during system file walk.
430 1.15 mrg if [ -s $OUTPUT ] ; then
431 1.28 lukem printf "Setuid/device find errors:\n" >> $ERR
432 1.28 lukem cat $OUTPUT >> $ERR
433 1.28 lukem printf "\n" >> $ERR
434 1.15 mrg fi
435 1.15 mrg
436 1.15 mrg # Display any changes in the setuid file list.
437 1.15 mrg egrep -v '^[bc]' $LIST > $TMP1
438 1.15 mrg if [ -s $TMP1 ] ; then
439 1.15 mrg # Check to make sure uudecode isn't setuid.
440 1.15 mrg if grep -w uudecode $TMP1 > /dev/null ; then
441 1.28 lukem printf "\nUudecode is setuid.\n" >> $ERR
442 1.15 mrg fi
443 1.15 mrg
444 1.15 mrg CUR=/var/backups/setuid.current
445 1.15 mrg BACK=/var/backups/setuid.backup
446 1.9 cgd
447 1.15 mrg if [ -s $CUR ] ; then
448 1.15 mrg if cmp -s $CUR $TMP1 ; then
449 1.15 mrg :
450 1.15 mrg else
451 1.15 mrg > $TMP2
452 1.15 mrg join -110 -210 -v2 $CUR $TMP1 > $OUTPUT
453 1.15 mrg if [ -s $OUTPUT ] ; then
454 1.28 lukem printf "Setuid additions:\n" >> $ERR
455 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
456 1.28 lukem printf "\n" >> $ERR
457 1.15 mrg fi
458 1.15 mrg
459 1.15 mrg join -110 -210 -v1 $CUR $TMP1 > $OUTPUT
460 1.15 mrg if [ -s $OUTPUT ] ; then
461 1.28 lukem printf "Setuid deletions:\n" >> $ERR
462 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
463 1.28 lukem printf "\n" >> $ERR
464 1.15 mrg fi
465 1.15 mrg
466 1.20 mycroft sort -k10 $TMP2 $CUR $TMP1 | \
467 1.27 lukem sed -e 's/[ ][ ]*/ /g' | \
468 1.27 lukem uniq -u > $OUTPUT
469 1.15 mrg if [ -s $OUTPUT ] ; then
470 1.28 lukem printf "Setuid changes:\n" >> $ERR
471 1.28 lukem column -t $OUTPUT >> $ERR
472 1.28 lukem printf "\n" >> $ERR
473 1.15 mrg fi
474 1.9 cgd
475 1.15 mrg cp $CUR $BACK
476 1.15 mrg cp $TMP1 $CUR
477 1.9 cgd fi
478 1.15 mrg else
479 1.28 lukem printf "Setuid additions:\n" >> $ERR
480 1.28 lukem column -t $TMP1 >> $ERR
481 1.28 lukem printf "\n" >> $ERR
482 1.9 cgd cp $TMP1 $CUR
483 1.9 cgd fi
484 1.15 mrg fi
485 1.15 mrg
486 1.27 lukem # Check for block and character disk devices that are readable or
487 1.27 lukem # writeable or not owned by root.operator.
488 1.15 mrg >$TMP1
489 1.27 lukem DISKLIST="acd ccd cd ch fd hk hp mcd md ra rb rd rl rx rz \
490 1.27 lukem sd se ss tz uk up vnd wd xd xy"
491 1.27 lukem # DISKLIST="$DISKLIST ct mt st wt"
492 1.15 mrg for i in $DISKLIST; do
493 1.15 mrg egrep "^b.*/${i}[0-9][0-9]*[a-p]$" $LIST >> $TMP1
494 1.15 mrg egrep "^c.*/r${i}[0-9][0-9]*[a-p]$" $LIST >> $TMP1
495 1.15 mrg done
496 1.15 mrg
497 1.15 mrg awk '$3 != "root" || $4 != "operator" || $1 !~ /.rw-r-----/ \
498 1.25 lukem { printf "Disk %s is user %s, group %s, permissions %s.\n", \
499 1.25 lukem $11, $3, $4, $1; }' < $TMP1 > $OUTPUT
500 1.15 mrg if [ -s $OUTPUT ] ; then
501 1.28 lukem printf "\nChecking disk ownership and permissions.\n" >> $ERR
502 1.28 lukem cat $OUTPUT >> $ERR
503 1.28 lukem printf "\n" >> $ERR
504 1.9 cgd fi
505 1.9 cgd
506 1.15 mrg # Display any changes in the device file list.
507 1.20 mycroft egrep '^[bc]' $LIST | sort -k11 > $TMP1
508 1.15 mrg if [ -s $TMP1 ] ; then
509 1.15 mrg CUR=/var/backups/device.current
510 1.15 mrg BACK=/var/backups/device.backup
511 1.15 mrg
512 1.15 mrg if [ -s $CUR ] ; then
513 1.15 mrg if cmp -s $CUR $TMP1 ; then
514 1.15 mrg :
515 1.15 mrg else
516 1.15 mrg > $TMP2
517 1.15 mrg join -111 -211 -v2 $CUR $TMP1 > $OUTPUT
518 1.15 mrg if [ -s $OUTPUT ] ; then
519 1.28 lukem printf "Device additions:\n" >> $ERR
520 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
521 1.28 lukem printf "\n" >> $ERR
522 1.15 mrg fi
523 1.15 mrg
524 1.15 mrg join -111 -211 -v1 $CUR $TMP1 > $OUTPUT
525 1.15 mrg if [ -s $OUTPUT ] ; then
526 1.28 lukem printf "Device deletions:\n" >> $ERR
527 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
528 1.28 lukem printf "\n" >> $ERR
529 1.15 mrg fi
530 1.15 mrg
531 1.27 lukem # Report any block device change. Ignore
532 1.27 lukem # character devices, only the name is
533 1.27 lukem # significant.
534 1.15 mrg cat $TMP2 $CUR $TMP1 | \
535 1.27 lukem sed -e '/^c/d' | \
536 1.27 lukem sort -k11 | \
537 1.27 lukem sed -e 's/[ ][ ]*/ /g' | \
538 1.27 lukem uniq -u > $OUTPUT
539 1.15 mrg if [ -s $OUTPUT ] ; then
540 1.28 lukem printf "Block device changes:\n" >> $ERR
541 1.28 lukem column -t $OUTPUT >> $ERR
542 1.28 lukem printf "\n" >> $ERR
543 1.15 mrg fi
544 1.9 cgd
545 1.15 mrg cp $CUR $BACK
546 1.15 mrg cp $TMP1 $CUR
547 1.9 cgd fi
548 1.15 mrg else
549 1.28 lukem printf "Device additions:\n" >> $ERR
550 1.28 lukem column -t $TMP1 >> $ERR
551 1.28 lukem printf "\n" >> $ERR
552 1.28 lukem cp $TMP1 $CUR >> $ERR
553 1.9 cgd fi
554 1.28 lukem fi
555 1.28 lukem if [ -s $ERR ] ; then
556 1.28 lukem printf "\nChecking setuid files and devices:\n"
557 1.28 lukem cat $ERR
558 1.28 lukem printf "\n"
559 1.9 cgd fi
560 1.9 cgd fi
561 1.9 cgd
562 1.9 cgd # Check special files.
563 1.9 cgd # Check system binaries.
564 1.9 cgd #
565 1.9 cgd # Create the mtree tree specifications using:
566 1.9 cgd #
567 1.9 cgd # mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure
568 1.16 mikel # chown root.wheel DIR.secure
569 1.16 mikel # chmod 600 DIR.secure
570 1.9 cgd #
571 1.9 cgd # Note, this is not complete protection against Trojan horsed binaries, as
572 1.9 cgd # the hacker can modify the tree specification to match the replaced binary.
573 1.9 cgd # For details on really protecting yourself against modified binaries, see
574 1.9 cgd # the mtree(8) manual page.
575 1.17 mycroft if [ "$check_mtree" = YES ]; then
576 1.9 cgd mtree -e -p / -f /etc/mtree/special > $OUTPUT
577 1.15 mrg if [ -s $OUTPUT ]; then
578 1.9 cgd printf "\nChecking special files and directories.\n"
579 1.9 cgd cat $OUTPUT
580 1.9 cgd fi
581 1.9 cgd
582 1.9 cgd > $OUTPUT
583 1.16 mikel for file in /etc/mtree/*.secure; do
584 1.16 mikel [ $file = '/etc/mtree/*.secure' ] && continue
585 1.9 cgd tree=`sed -n -e '3s/.* //p' -e 3q $file`
586 1.9 cgd mtree -f $file -p $tree > $TMP1
587 1.9 cgd if [ -s $TMP1 ]; then
588 1.9 cgd printf "\nChecking $tree:\n" >> $OUTPUT
589 1.9 cgd cat $TMP1 >> $OUTPUT
590 1.9 cgd fi
591 1.9 cgd done
592 1.15 mrg if [ -s $OUTPUT ]; then
593 1.9 cgd printf "\nChecking system binaries:\n"
594 1.9 cgd cat $OUTPUT
595 1.9 cgd fi
596 1.9 cgd fi
597 1.9 cgd
598 1.9 cgd # List of files that get backed up and checked for any modifications. Each
599 1.9 cgd # file is expected to have two backups, /var/backups/file.{current,backup}.
600 1.9 cgd # Any changes cause the files to rotate.
601 1.17 mycroft if [ "$check_changelist" = YES ] && [ -s /etc/changelist ] ; then
602 1.27 lukem for file in `egrep -v "^#|$MP" /etc/changelist`; do
603 1.9 cgd CUR=/var/backups/`basename $file`.current
604 1.9 cgd BACK=/var/backups/`basename $file`.backup
605 1.9 cgd if [ -s $file ]; then
606 1.9 cgd if [ -s $CUR ] ; then
607 1.9 cgd diff $CUR $file > $OUTPUT
608 1.9 cgd if [ -s $OUTPUT ] ; then
609 1.9 cgd printf "\n======\n%s diffs (OLD < > NEW)\n======\n" $file
610 1.9 cgd cat $OUTPUT
611 1.9 cgd cp -p $CUR $BACK
612 1.9 cgd cp -p $file $CUR
613 1.9 cgd chown root.wheel $CUR $BACK
614 1.9 cgd fi
615 1.9 cgd else
616 1.9 cgd cp -p $file $CUR
617 1.9 cgd chown root.wheel $CUR
618 1.9 cgd fi
619 1.9 cgd fi
620 1.9 cgd done
621 1.9 cgd fi
622