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