security revision 1.43 1 1.1 cgd #!/bin/sh -
2 1.1 cgd #
3 1.43 itojun # $NetBSD: security,v 1.43 2000/05/05 18:28:53 itojun 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.43 itojun # Uudecode should not be in the /etc/mail/aliases file.
295 1.32 lukem #
296 1.31 lukem if checkyesno check_aliases; then
297 1.43 itojun for f in /etc/mail/aliases /etc/aliases; do
298 1.43 itojun if [ -f $f ] && egrep '^[^#]*(uudecode|decode).*\|' $f; then
299 1.43 itojun printf "\nEntry for uudecode in $f file.\n"
300 1.43 itojun fi
301 1.43 itojun done
302 1.9 cgd fi
303 1.9 cgd
304 1.9 cgd # Files that should not have + signs.
305 1.32 lukem #
306 1.31 lukem if checkyesno check_rhosts; then
307 1.15 mrg list="/etc/hosts.equiv /etc/hosts.lpd"
308 1.15 mrg for f in $list ; do
309 1.15 mrg if [ -f $f ] && egrep '\+' $f > /dev/null ; then
310 1.15 mrg printf "\nPlus sign in $f file.\n"
311 1.15 mrg fi
312 1.15 mrg done
313 1.15 mrg
314 1.15 mrg # Check for special users with .rhosts files. Only root and toor should
315 1.16 mikel # have .rhosts files. Also, .rhosts files should not have plus signs.
316 1.15 mrg awk -F: '$1 != "root" && $1 != "toor" && \
317 1.15 mrg ($3 < 100 || $1 == "ftp" || $1 == "uucp") \
318 1.20 mycroft { print $1 " " $9 }' $MP |
319 1.19 mycroft sort -k2 |
320 1.15 mrg while read uid homedir; do
321 1.15 mrg if [ -f ${homedir}/.rhosts ] ; then
322 1.15 mrg rhost=`ls -ldgT ${homedir}/.rhosts`
323 1.15 mrg printf "$uid: $rhost\n"
324 1.15 mrg fi
325 1.15 mrg done > $OUTPUT
326 1.15 mrg if [ -s $OUTPUT ] ; then
327 1.15 mrg printf "\nChecking for special users with .rhosts files.\n"
328 1.15 mrg cat $OUTPUT
329 1.15 mrg fi
330 1.15 mrg
331 1.15 mrg while read uid homedir; do
332 1.35 fair if [ -f ${homedir}/.rhosts -a -r ${homedir}/.rhosts ] && \
333 1.41 christos cat -f ${homedir}/.rhosts | egrep '\+' > /dev/null ; then
334 1.15 mrg printf "$uid: + in .rhosts file.\n"
335 1.15 mrg fi
336 1.29 lukem done < $MPBYPATH > $OUTPUT
337 1.15 mrg if [ -s $OUTPUT ] ; then
338 1.15 mrg printf "\nChecking .rhosts files syntax.\n"
339 1.15 mrg cat $OUTPUT
340 1.15 mrg fi
341 1.9 cgd fi
342 1.9 cgd
343 1.9 cgd # Check home directories. Directories should not be owned by someone else
344 1.9 cgd # or writeable.
345 1.32 lukem #
346 1.31 lukem if checkyesno check_homes; then
347 1.15 mrg while read uid homedir; do
348 1.15 mrg if [ -d ${homedir}/ ] ; then
349 1.15 mrg file=`ls -ldgT ${homedir}`
350 1.15 mrg printf "$uid $file\n"
351 1.9 cgd fi
352 1.29 lukem done < $MPBYPATH |
353 1.15 mrg awk '$1 != $4 && $4 != "root" \
354 1.15 mrg { print "user " $1 " home directory is owned by " $4 }
355 1.15 mrg $2 ~ /^-....w/ \
356 1.15 mrg { print "user " $1 " home directory is group writeable" }
357 1.15 mrg $2 ~ /^-.......w/ \
358 1.27 lukem { print "user " $1 " home directory is other writeable" }' \
359 1.27 lukem > $OUTPUT
360 1.15 mrg if [ -s $OUTPUT ] ; then
361 1.15 mrg printf "\nChecking home directories.\n"
362 1.15 mrg cat $OUTPUT
363 1.15 mrg fi
364 1.15 mrg
365 1.15 mrg # Files that should not be owned by someone else or readable.
366 1.27 lukem list=".Xauthority .netrc"
367 1.15 mrg while read uid homedir; do
368 1.15 mrg for f in $list ; do
369 1.15 mrg file=${homedir}/${f}
370 1.15 mrg if [ -f $file ] ; then
371 1.15 mrg printf "$uid $f `ls -ldgT $file`\n"
372 1.15 mrg fi
373 1.15 mrg done
374 1.29 lukem done < $MPBYPATH |
375 1.15 mrg awk '$1 != $5 && $5 != "root" \
376 1.15 mrg { print "user " $1 " " $2 " file is owned by " $5 }
377 1.15 mrg $3 ~ /^-...r/ \
378 1.15 mrg { print "user " $1 " " $2 " file is group readable" }
379 1.15 mrg $3 ~ /^-......r/ \
380 1.15 mrg { print "user " $1 " " $2 " file is other readable" }
381 1.15 mrg $3 ~ /^-....w/ \
382 1.15 mrg { print "user " $1 " " $2 " file is group writeable" }
383 1.15 mrg $3 ~ /^-.......w/ \
384 1.27 lukem { print "user " $1 " " $2 " file is other writeable" }' \
385 1.27 lukem > $OUTPUT
386 1.15 mrg
387 1.15 mrg # Files that should not be owned by someone else or writeable.
388 1.19 mycroft list=".bash_history .bash_login .bash_logout .bash_profile .bashrc \
389 1.19 mycroft .cshrc .emacs .exrc .forward .history .klogin .login .logout \
390 1.27 lukem .profile .qmail .rc_history .rhosts .tcshrc .twmrc .xinitrc \
391 1.27 lukem .xsession"
392 1.15 mrg while read uid homedir; do
393 1.15 mrg for f in $list ; do
394 1.15 mrg file=${homedir}/${f}
395 1.15 mrg if [ -f $file ] ; then
396 1.15 mrg printf "$uid $f `ls -ldgT $file`\n"
397 1.15 mrg fi
398 1.15 mrg done
399 1.29 lukem done < $MPBYPATH |
400 1.15 mrg awk '$1 != $5 && $5 != "root" \
401 1.15 mrg { print "user " $1 " " $2 " file is owned by " $5 }
402 1.15 mrg $3 ~ /^-....w/ \
403 1.15 mrg { print "user " $1 " " $2 " file is group writeable" }
404 1.15 mrg $3 ~ /^-.......w/ \
405 1.27 lukem { print "user " $1 " " $2 " file is other writeable" }' \
406 1.27 lukem >> $OUTPUT
407 1.15 mrg if [ -s $OUTPUT ] ; then
408 1.15 mrg printf "\nChecking dot files.\n"
409 1.15 mrg cat $OUTPUT
410 1.15 mrg fi
411 1.9 cgd fi
412 1.9 cgd
413 1.9 cgd # Mailboxes should be owned by user and unreadable.
414 1.32 lukem #
415 1.31 lukem if checkyesno check_varmail; then
416 1.15 mrg ls -l /var/mail | sed 1d | \
417 1.15 mrg awk '$3 != $9 \
418 1.15 mrg { print "user " $9 " mailbox is owned by " $3 }
419 1.15 mrg $1 != "-rw-------" \
420 1.15 mrg { print "user " $9 " mailbox is " $1 ", group " $4 }' > $OUTPUT
421 1.15 mrg if [ -s $OUTPUT ] ; then
422 1.15 mrg printf "\nChecking mailbox ownership.\n"
423 1.15 mrg cat $OUTPUT
424 1.15 mrg fi
425 1.15 mrg fi
426 1.15 mrg
427 1.32 lukem # NFS exports shouldn't be globally exported
428 1.32 lukem #
429 1.32 lukem if checkyesno check_nfs && [ -f /etc/exports ]; then
430 1.32 lukem awk '{
431 1.22 lukem # ignore comments and blank lines
432 1.39 hubertf if ($0 ~ /^\#/ || $0 ~ /^$/ )
433 1.22 lukem next;
434 1.22 lukem
435 1.15 mrg readonly = 0;
436 1.15 mrg for (i = 2; i <= NF; ++i) {
437 1.15 mrg if ($i ~ /-ro/)
438 1.15 mrg readonly = 1;
439 1.15 mrg else if ($i !~ /^-/)
440 1.15 mrg next;
441 1.15 mrg }
442 1.15 mrg if (readonly)
443 1.15 mrg print "File system " $1 " globally exported, read-only."
444 1.15 mrg else
445 1.15 mrg print "File system " $1 " globally exported, read-write."
446 1.32 lukem }' < /etc/exports > $OUTPUT
447 1.32 lukem if [ -s $OUTPUT ] ; then
448 1.15 mrg printf "\nChecking for globally exported file systems.\n"
449 1.15 mrg cat $OUTPUT
450 1.15 mrg fi
451 1.9 cgd fi
452 1.9 cgd
453 1.9 cgd # Display any changes in setuid files and devices.
454 1.32 lukem #
455 1.31 lukem if checkyesno check_devices; then
456 1.28 lukem > $ERR
457 1.15 mrg (find / \( ! -fstype local -o -fstype fdesc -o -fstype kernfs \
458 1.15 mrg -o -fstype procfs \) -a -prune -o \
459 1.21 mycroft \( \( -perm -u+s -a ! -type d \) -o \
460 1.21 mycroft \( -perm -g+s -a ! -type d \) -o \
461 1.24 lukem -type b -o -type c \) -print0 | \
462 1.24 lukem xargs -0 ls -ldgTq | sort +9 > $LIST) 2> $OUTPUT
463 1.15 mrg
464 1.15 mrg # Display any errors that occurred during system file walk.
465 1.15 mrg if [ -s $OUTPUT ] ; then
466 1.28 lukem printf "Setuid/device find errors:\n" >> $ERR
467 1.28 lukem cat $OUTPUT >> $ERR
468 1.28 lukem printf "\n" >> $ERR
469 1.15 mrg fi
470 1.15 mrg
471 1.15 mrg # Display any changes in the setuid file list.
472 1.15 mrg egrep -v '^[bc]' $LIST > $TMP1
473 1.15 mrg if [ -s $TMP1 ] ; then
474 1.15 mrg # Check to make sure uudecode isn't setuid.
475 1.15 mrg if grep -w uudecode $TMP1 > /dev/null ; then
476 1.28 lukem printf "\nUudecode is setuid.\n" >> $ERR
477 1.15 mrg fi
478 1.15 mrg
479 1.15 mrg CUR=/var/backups/setuid.current
480 1.15 mrg BACK=/var/backups/setuid.backup
481 1.9 cgd
482 1.15 mrg if [ -s $CUR ] ; then
483 1.15 mrg if cmp -s $CUR $TMP1 ; then
484 1.15 mrg :
485 1.15 mrg else
486 1.15 mrg > $TMP2
487 1.15 mrg join -110 -210 -v2 $CUR $TMP1 > $OUTPUT
488 1.15 mrg if [ -s $OUTPUT ] ; then
489 1.28 lukem printf "Setuid additions:\n" >> $ERR
490 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
491 1.28 lukem printf "\n" >> $ERR
492 1.15 mrg fi
493 1.15 mrg
494 1.15 mrg join -110 -210 -v1 $CUR $TMP1 > $OUTPUT
495 1.15 mrg if [ -s $OUTPUT ] ; then
496 1.28 lukem printf "Setuid deletions:\n" >> $ERR
497 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
498 1.28 lukem printf "\n" >> $ERR
499 1.15 mrg fi
500 1.15 mrg
501 1.20 mycroft sort -k10 $TMP2 $CUR $TMP1 | \
502 1.27 lukem sed -e 's/[ ][ ]*/ /g' | \
503 1.27 lukem uniq -u > $OUTPUT
504 1.15 mrg if [ -s $OUTPUT ] ; then
505 1.28 lukem printf "Setuid changes:\n" >> $ERR
506 1.28 lukem column -t $OUTPUT >> $ERR
507 1.28 lukem printf "\n" >> $ERR
508 1.15 mrg fi
509 1.9 cgd
510 1.15 mrg cp $CUR $BACK
511 1.15 mrg cp $TMP1 $CUR
512 1.9 cgd fi
513 1.15 mrg else
514 1.28 lukem printf "Setuid additions:\n" >> $ERR
515 1.28 lukem column -t $TMP1 >> $ERR
516 1.28 lukem printf "\n" >> $ERR
517 1.9 cgd cp $TMP1 $CUR
518 1.9 cgd fi
519 1.15 mrg fi
520 1.15 mrg
521 1.27 lukem # Check for block and character disk devices that are readable or
522 1.27 lukem # writeable or not owned by root.operator.
523 1.15 mrg >$TMP1
524 1.27 lukem DISKLIST="acd ccd cd ch fd hk hp mcd md ra rb rd rl rx rz \
525 1.27 lukem sd se ss tz uk up vnd wd xd xy"
526 1.27 lukem # DISKLIST="$DISKLIST ct mt st wt"
527 1.15 mrg for i in $DISKLIST; do
528 1.15 mrg egrep "^b.*/${i}[0-9][0-9]*[a-p]$" $LIST >> $TMP1
529 1.15 mrg egrep "^c.*/r${i}[0-9][0-9]*[a-p]$" $LIST >> $TMP1
530 1.15 mrg done
531 1.15 mrg
532 1.15 mrg awk '$3 != "root" || $4 != "operator" || $1 !~ /.rw-r-----/ \
533 1.25 lukem { printf "Disk %s is user %s, group %s, permissions %s.\n", \
534 1.25 lukem $11, $3, $4, $1; }' < $TMP1 > $OUTPUT
535 1.15 mrg if [ -s $OUTPUT ] ; then
536 1.28 lukem printf "\nChecking disk ownership and permissions.\n" >> $ERR
537 1.28 lukem cat $OUTPUT >> $ERR
538 1.28 lukem printf "\n" >> $ERR
539 1.9 cgd fi
540 1.9 cgd
541 1.15 mrg # Display any changes in the device file list.
542 1.20 mycroft egrep '^[bc]' $LIST | sort -k11 > $TMP1
543 1.15 mrg if [ -s $TMP1 ] ; then
544 1.15 mrg CUR=/var/backups/device.current
545 1.15 mrg BACK=/var/backups/device.backup
546 1.15 mrg
547 1.15 mrg if [ -s $CUR ] ; then
548 1.15 mrg if cmp -s $CUR $TMP1 ; then
549 1.15 mrg :
550 1.15 mrg else
551 1.15 mrg > $TMP2
552 1.15 mrg join -111 -211 -v2 $CUR $TMP1 > $OUTPUT
553 1.15 mrg if [ -s $OUTPUT ] ; then
554 1.28 lukem printf "Device additions:\n" >> $ERR
555 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
556 1.28 lukem printf "\n" >> $ERR
557 1.15 mrg fi
558 1.15 mrg
559 1.15 mrg join -111 -211 -v1 $CUR $TMP1 > $OUTPUT
560 1.15 mrg if [ -s $OUTPUT ] ; then
561 1.28 lukem printf "Device deletions:\n" >> $ERR
562 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
563 1.28 lukem printf "\n" >> $ERR
564 1.15 mrg fi
565 1.15 mrg
566 1.27 lukem # Report any block device change. Ignore
567 1.27 lukem # character devices, only the name is
568 1.27 lukem # significant.
569 1.15 mrg cat $TMP2 $CUR $TMP1 | \
570 1.27 lukem sed -e '/^c/d' | \
571 1.27 lukem sort -k11 | \
572 1.27 lukem sed -e 's/[ ][ ]*/ /g' | \
573 1.27 lukem uniq -u > $OUTPUT
574 1.15 mrg if [ -s $OUTPUT ] ; then
575 1.28 lukem printf "Block device changes:\n" >> $ERR
576 1.28 lukem column -t $OUTPUT >> $ERR
577 1.28 lukem printf "\n" >> $ERR
578 1.15 mrg fi
579 1.9 cgd
580 1.15 mrg cp $CUR $BACK
581 1.15 mrg cp $TMP1 $CUR
582 1.9 cgd fi
583 1.15 mrg else
584 1.28 lukem printf "Device additions:\n" >> $ERR
585 1.28 lukem column -t $TMP1 >> $ERR
586 1.28 lukem printf "\n" >> $ERR
587 1.28 lukem cp $TMP1 $CUR >> $ERR
588 1.9 cgd fi
589 1.28 lukem fi
590 1.28 lukem if [ -s $ERR ] ; then
591 1.28 lukem printf "\nChecking setuid files and devices:\n"
592 1.28 lukem cat $ERR
593 1.28 lukem printf "\n"
594 1.9 cgd fi
595 1.9 cgd fi
596 1.9 cgd
597 1.9 cgd # Check special files.
598 1.9 cgd # Check system binaries.
599 1.9 cgd #
600 1.9 cgd # Create the mtree tree specifications using:
601 1.9 cgd #
602 1.9 cgd # mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure
603 1.38 kleink # chown root:wheel DIR.secure
604 1.16 mikel # chmod 600 DIR.secure
605 1.9 cgd #
606 1.9 cgd # Note, this is not complete protection against Trojan horsed binaries, as
607 1.9 cgd # the hacker can modify the tree specification to match the replaced binary.
608 1.9 cgd # For details on really protecting yourself against modified binaries, see
609 1.9 cgd # the mtree(8) manual page.
610 1.32 lukem #
611 1.31 lukem if checkyesno check_mtree; then
612 1.9 cgd mtree -e -p / -f /etc/mtree/special > $OUTPUT
613 1.15 mrg if [ -s $OUTPUT ]; then
614 1.9 cgd printf "\nChecking special files and directories.\n"
615 1.9 cgd cat $OUTPUT
616 1.9 cgd fi
617 1.9 cgd
618 1.9 cgd > $OUTPUT
619 1.16 mikel for file in /etc/mtree/*.secure; do
620 1.16 mikel [ $file = '/etc/mtree/*.secure' ] && continue
621 1.9 cgd tree=`sed -n -e '3s/.* //p' -e 3q $file`
622 1.9 cgd mtree -f $file -p $tree > $TMP1
623 1.9 cgd if [ -s $TMP1 ]; then
624 1.9 cgd printf "\nChecking $tree:\n" >> $OUTPUT
625 1.9 cgd cat $TMP1 >> $OUTPUT
626 1.9 cgd fi
627 1.9 cgd done
628 1.15 mrg if [ -s $OUTPUT ]; then
629 1.9 cgd printf "\nChecking system binaries:\n"
630 1.9 cgd cat $OUTPUT
631 1.9 cgd fi
632 1.9 cgd fi
633 1.9 cgd
634 1.32 lukem CHANGELIST=""
635 1.32 lukem
636 1.32 lukem # Backup disklabels of available disks
637 1.32 lukem #
638 1.32 lukem if checkyesno check_disklabels; then
639 1.32 lukem # generate list of old disklabels and remove them
640 1.32 lukem ls -1d /var/backups/disklabel.* 2>/dev/null |
641 1.32 lukem egrep -v '\.(backup|current)$' > $LABELS
642 1.32 lukem xargs rm < $LABELS
643 1.32 lukem
644 1.40 perry disks=`iostat -x | sed 1d | awk '$1 !~ /^[cfm]d/ { print $1; }'`
645 1.32 lukem for i in $disks; do
646 1.32 lukem dlf="/var/backups/disklabel.$i"
647 1.32 lukem disklabel $i > $dlf 2>/dev/null
648 1.32 lukem done
649 1.32 lukem
650 1.32 lukem # append list of new disklabels, sort list
651 1.32 lukem ls -1d /var/backups/disklabel.* 2>/dev/null |
652 1.32 lukem egrep -v '\.(backup|current)$' >> $LABELS
653 1.32 lukem sort -u -o $LABELS $LABELS
654 1.32 lukem CHANGELIST=$LABELS
655 1.32 lukem fi
656 1.32 lukem
657 1.9 cgd # List of files that get backed up and checked for any modifications. Each
658 1.9 cgd # file is expected to have two backups, /var/backups/file.{current,backup}.
659 1.9 cgd # Any changes cause the files to rotate.
660 1.32 lukem #
661 1.31 lukem if checkyesno check_changelist && [ -s /etc/changelist ] ; then
662 1.32 lukem CHANGELIST="/etc/changelist $CHANGELIST"
663 1.32 lukem fi
664 1.32 lukem
665 1.32 lukem if [ -n "$CHANGELIST" ]; then
666 1.32 lukem for file in `egrep -hv "^#|$MP" $CHANGELIST`; do
667 1.9 cgd CUR=/var/backups/`basename $file`.current
668 1.9 cgd BACK=/var/backups/`basename $file`.backup
669 1.30 mycroft if [ -f $file ]; then
670 1.30 mycroft if [ -f $CUR ] ; then
671 1.9 cgd diff $CUR $file > $OUTPUT
672 1.9 cgd if [ -s $OUTPUT ] ; then
673 1.9 cgd printf "\n======\n%s diffs (OLD < > NEW)\n======\n" $file
674 1.9 cgd cat $OUTPUT
675 1.30 mycroft mv -f $CUR $BACK
676 1.9 cgd cp -p $file $CUR
677 1.38 kleink chown root:wheel $CUR
678 1.9 cgd fi
679 1.9 cgd else
680 1.30 mycroft printf "\n======\n%s added\n======\n" $file
681 1.30 mycroft diff /dev/null $file
682 1.9 cgd cp -p $file $CUR
683 1.38 kleink chown root:wheel $CUR
684 1.30 mycroft fi
685 1.30 mycroft else
686 1.30 mycroft if [ -f $CUR ]; then
687 1.30 mycroft printf "\n======\n%s removed\n======\n" $file
688 1.30 mycroft diff $CUR /dev/null
689 1.30 mycroft mv -f $CUR $BACK
690 1.9 cgd fi
691 1.9 cgd fi
692 1.9 cgd done
693 1.42 fair fi
694 1.42 fair
695 1.42 fair # run skeyaudit to inform users of ready to expire S/Keys
696 1.42 fair #
697 1.42 fair if checkyesno run_skeyaudit; then
698 1.42 fair skeyaudit
699 1.9 cgd fi
700