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