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