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