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