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