security revision 1.90 1 1.1 cgd #!/bin/sh -
2 1.1 cgd #
3 1.90 kim # $NetBSD: security,v 1.90 2004/04/09 17:33:35 kim 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.89 jmmv rcvar_manpage='security.conf(5)'
10 1.89 jmmv
11 1.31 lukem if [ -f /etc/rc.subr ]; then
12 1.31 lukem . /etc/rc.subr
13 1.31 lukem else
14 1.31 lukem echo "Can't read /etc/rc.subr; aborting."
15 1.31 lukem exit 1;
16 1.31 lukem fi
17 1.31 lukem
18 1.9 cgd umask 077
19 1.64 cjs TZ=UTC; export TZ
20 1.1 cgd
21 1.15 mrg if [ -s /etc/security.conf ]; then
22 1.15 mrg . /etc/security.conf
23 1.15 mrg fi
24 1.15 mrg
25 1.67 lukem # Set reasonable defaults (if they're not set in security.conf)
26 1.67 lukem #
27 1.67 lukem backup_dir=${backup_dir:-/var/backups}
28 1.67 lukem pkgdb_dir=${pkgdb_dir:-/var/db/pkg}
29 1.67 lukem max_loginlen=${max_loginlen:-8}
30 1.67 lukem max_grouplen=${max_grouplen:-8}
31 1.67 lukem
32 1.67 lukem # Other configurable variables
33 1.67 lukem #
34 1.67 lukem special_files="/etc/mtree/special /etc/mtree/special.local"
35 1.67 lukem MP=/etc/master.passwd
36 1.67 lukem CHANGELIST=""
37 1.67 lukem work_dir=$backup_dir/work
38 1.67 lukem
39 1.67 lukem if [ ! -d "$work_dir" ]; then
40 1.67 lukem mkdir -p "$work_dir"
41 1.67 lukem fi
42 1.67 lukem
43 1.56 lukem SECUREDIR=`mktemp -d /tmp/_securedir.XXXXXX` || exit 1
44 1.56 lukem
45 1.67 lukem trap "/bin/rm -rf $SECUREDIR ; exit 0" EXIT INT QUIT PIPE
46 1.15 mrg
47 1.56 lukem if ! cd "$SECUREDIR"; then
48 1.56 lukem echo "Can not cd to $SECUREDIR".
49 1.15 mrg exit 1
50 1.15 mrg fi
51 1.15 mrg
52 1.15 mrg ERR=secure1.$$
53 1.15 mrg TMP1=secure2.$$
54 1.15 mrg TMP2=secure3.$$
55 1.28 lukem MPBYUID=secure4.$$
56 1.29 lukem MPBYPATH=secure5.$$
57 1.27 lukem LIST=secure6.$$
58 1.27 lukem OUTPUT=secure7.$$
59 1.32 lukem LABELS=secure8.$$
60 1.62 atatat PKGS=secure9.$$
61 1.67 lukem CHANGEFILES=secure10.$$
62 1.67 lukem
63 1.15 mrg
64 1.67 lukem # migrate_file old new
65 1.67 lukem # Determine if the "${old}" path name needs to be migrated to the
66 1.67 lukem # "${new}" path. Also checks if "${old}.current" needs migrating,
67 1.67 lukem # and if so, migrate it and possibly "${old}.current,v" and
68 1.67 lukem # "${old}.backup".
69 1.67 lukem #
70 1.67 lukem migrate_file()
71 1.67 lukem {
72 1.67 lukem _old=$1
73 1.67 lukem _new=$2
74 1.67 lukem if [ -z "$_old" -o -z "$_new" ]; then
75 1.67 lukem err 3 "USAGE: migrate_file old new"
76 1.67 lukem fi
77 1.67 lukem if [ ! -d "${_new%/*}" ]; then
78 1.67 lukem mkdir -p "${_new%/*}"
79 1.67 lukem fi
80 1.67 lukem if [ -f "${_old}" -a ! -f "${_new}" ]; then
81 1.67 lukem echo "==> migrating ${_old}"
82 1.67 lukem echo " to ${_new}"
83 1.67 lukem mv "${_old}" "${_new}"
84 1.67 lukem fi
85 1.67 lukem if [ -f "${_old}.current" -a ! -f "${_new}.current" ]; then
86 1.67 lukem echo "==> migrating ${_old}.current"
87 1.67 lukem echo " to ${_new}.current"
88 1.67 lukem mv "${_old}.current" "${_new}.current"
89 1.67 lukem if [ -f "${_old}.current,v" -a ! -f "${_new}.current,v" ]; then
90 1.67 lukem echo "==> migrating ${_old}.current,v"
91 1.67 lukem echo " to ${_new}.current,v"
92 1.67 lukem mv "${_old}.current,v" "${_new}.current,v"
93 1.67 lukem fi
94 1.67 lukem if [ -f "${_old}.backup" -a ! -f "${_new}.backup" ]; then
95 1.67 lukem echo "==> migrating ${_old}.backup"
96 1.67 lukem echo " to ${_new}.backup"
97 1.67 lukem mv "${_old}.backup" "${_new}.backup"
98 1.67 lukem fi
99 1.67 lukem fi
100 1.67 lukem }
101 1.67 lukem
102 1.67 lukem
103 1.67 lukem # backup_and_diff file printdiff
104 1.67 lukem # Determine if file needs backing up, and if so, do it.
105 1.67 lukem # If printdiff is yes, display the diffs, otherwise
106 1.67 lukem # just print a message saying "[changes omitted]".
107 1.67 lukem #
108 1.67 lukem backup_and_diff()
109 1.67 lukem {
110 1.67 lukem _file=$1
111 1.67 lukem _printdiff=$2
112 1.67 lukem if [ -z "$_file" -o -z "$_printdiff" ]; then
113 1.67 lukem err 3 "USAGE: backup_and_diff file printdiff"
114 1.67 lukem fi
115 1.67 lukem ! checkyesno _printdiff
116 1.67 lukem _printdiff=$?
117 1.67 lukem
118 1.67 lukem _old=$backup_dir/${_file##*/}
119 1.67 lukem case "$_file" in
120 1.67 lukem $work_dir/*)
121 1.67 lukem _new=$_file
122 1.67 lukem migrate_file "$backup_dir/$_old" "$_new"
123 1.67 lukem migrate_file "$_old" "$_new"
124 1.67 lukem ;;
125 1.67 lukem *)
126 1.67 lukem _new=$backup_dir/$_file
127 1.67 lukem migrate_file "$_old" "$_new"
128 1.67 lukem ;;
129 1.67 lukem esac
130 1.67 lukem CUR=${_new}.current
131 1.67 lukem BACK=${_new}.backup
132 1.67 lukem if [ -f $_file ]; then
133 1.67 lukem if [ -f $CUR ] ; then
134 1.67 lukem if [ "$_printdiff" -ne 0 ]; then
135 1.83 jhawk diff ${diff_options} $CUR $_file > $OUTPUT
136 1.67 lukem else
137 1.67 lukem if ! cmp -s $CUR $_file; then
138 1.67 lukem echo "[changes omitted]"
139 1.67 lukem fi > $OUTPUT
140 1.67 lukem fi
141 1.67 lukem if [ -s $OUTPUT ] ; then
142 1.67 lukem printf \
143 1.67 lukem "\n======\n%s diffs (OLD < > NEW)\n======\n" $_file
144 1.67 lukem cat $OUTPUT
145 1.67 lukem backup_file update $_file $CUR $BACK
146 1.67 lukem fi
147 1.67 lukem else
148 1.67 lukem printf "\n======\n%s added\n======\n" $_file
149 1.67 lukem if [ "$_printdiff" -ne 0 ]; then
150 1.83 jhawk diff ${diff_options} /dev/null $_file
151 1.67 lukem else
152 1.67 lukem echo "[changes omitted]"
153 1.67 lukem fi
154 1.67 lukem backup_file add $_file $CUR $BACK
155 1.67 lukem fi
156 1.67 lukem else
157 1.67 lukem if [ -f $CUR ]; then
158 1.67 lukem printf "\n======\n%s removed\n======\n" $_file
159 1.67 lukem if [ "$_printdiff" -ne 0 ]; then
160 1.83 jhawk diff ${diff_options} $CUR /dev/null
161 1.67 lukem else
162 1.67 lukem echo "[changes omitted]"
163 1.67 lukem fi
164 1.67 lukem backup_file remove $_file $CUR $BACK
165 1.67 lukem fi
166 1.67 lukem fi
167 1.67 lukem }
168 1.48 abs
169 1.9 cgd
170 1.67 lukem # These are used several times.
171 1.67 lukem #
172 1.34 abs awk -F: '!/^+/ { print $1 " " $3 }' $MP | sort -k2n > $MPBYUID
173 1.29 lukem awk -F: '{ print $1 " " $9 }' $MP | sort -k2 > $MPBYPATH
174 1.9 cgd
175 1.67 lukem
176 1.9 cgd # Check the master password file syntax.
177 1.32 lukem #
178 1.31 lukem if checkyesno check_passwd; then
179 1.85 jhawk # XXX: the sense of permit_star is reversed; the code works as
180 1.85 jhawk # implemented, but usage needs to be negated.
181 1.81 jhawk checkyesno check_passwd_permit_star && permit_star=0 || permit_star=1
182 1.81 jhawk awk -v "len=$max_loginlen" \
183 1.81 jhawk -v "nowarn_shells_list=$check_passwd_nowarn_shells" \
184 1.81 jhawk -v "nowarn_users_list=$check_passwd_nowarn_users" \
185 1.81 jhawk -v "permit_star=$permit_star" '
186 1.25 lukem BEGIN {
187 1.25 lukem while ( getline < "/etc/shells" > 0 ) {
188 1.39 hubertf if ($0 ~ /^\#/ || $0 ~ /^$/ )
189 1.25 lukem continue;
190 1.25 lukem shells[$1]++;
191 1.25 lukem }
192 1.81 jhawk split(nowarn_shells_list, a);
193 1.81 jhawk for (i in a) nowarn_shells[a[i]]++;
194 1.81 jhawk split(nowarn_users_list, a);
195 1.81 jhawk for (i in a) nowarn_users[a[i]]++;
196 1.81 jhawk uid0_users_list="root toor"
197 1.81 jhawk split(uid0_users_list, a);
198 1.81 jhawk for (i in a) uid0_users[a[i]]++;
199 1.25 lukem FS=":";
200 1.25 lukem }
201 1.25 lukem
202 1.25 lukem {
203 1.15 mrg if ($0 ~ /^[ ]*$/) {
204 1.25 lukem printf "Line %d is a blank line.\n", NR;
205 1.15 mrg next;
206 1.15 mrg }
207 1.34 abs if (NF != 10 && ($1 != "+" || NF != 1))
208 1.25 lukem printf "Line %d has the wrong number of fields.\n", NR;
209 1.34 abs if ($1 == "+" ) {
210 1.34 abs if (NF != 1 && $3 == 0)
211 1.81 jhawk printf "Line %d includes entries with uid 0.\n",
212 1.81 jhawk NR;
213 1.34 abs next;
214 1.34 abs }
215 1.53 atatat if ($1 !~ /^[A-Za-z0-9]([-A-Za-z0-9]*[A-Za-z0-9])*$/)
216 1.25 lukem printf "Login %s has non-alphanumeric characters.\n",
217 1.25 lukem $1;
218 1.34 abs if (length($1) > len)
219 1.81 jhawk printf "Login %s has more than "len" characters.\n",
220 1.81 jhawk $1;
221 1.81 jhawk if ($2 == "" && !nowarn_users[$1])
222 1.81 jhawk printf "Login %s has no password.\n", $1;
223 1.81 jhawk if (!nowarn_shells[$10] && !nowarn_users[$1]) {
224 1.81 jhawk if (length($2) != 13 &&
225 1.81 jhawk length($2) != 20 &&
226 1.81 jhawk $2 !~ /^\$1/ &&
227 1.81 jhawk $2 !~ /^\$2/ &&
228 1.81 jhawk $2 != "" &&
229 1.81 jhawk (permit_star || $2 != "*") &&
230 1.81 jhawk $2 !~ /^\*[A-z-]+$/ &&
231 1.81 jhawk $1 != "toor") {
232 1.81 jhawk if ($10 == "" || shells[$10])
233 1.81 jhawk printf "Login %s is off but still has "\
234 1.81 jhawk "a valid shell (%s)\n", $1, $10;
235 1.81 jhawk } else if (! shells[$10])
236 1.81 jhawk printf "Login %s does not have a valid "\
237 1.81 jhawk "shell (%s)\n", $1, $10;
238 1.81 jhawk }
239 1.81 jhawk if ($3 == 0 && !uid0_users[$1] && !nowarn_users[$1])
240 1.25 lukem printf "Login %s has a user id of 0.\n", $1;
241 1.15 mrg if ($3 < 0)
242 1.25 lukem printf "Login %s has a negative user id.\n", $1;
243 1.15 mrg if ($4 < 0)
244 1.25 lukem printf "Login %s has a negative group id.\n", $1;
245 1.15 mrg }' < $MP > $OUTPUT
246 1.15 mrg if [ -s $OUTPUT ] ; then
247 1.15 mrg printf "\nChecking the $MP file:\n"
248 1.15 mrg cat $OUTPUT
249 1.15 mrg fi
250 1.15 mrg
251 1.15 mrg awk -F: '{ print $1 }' $MP | sort | uniq -d > $OUTPUT
252 1.15 mrg if [ -s $OUTPUT ] ; then
253 1.15 mrg printf "\n$MP has duplicate user names.\n"
254 1.15 mrg column $OUTPUT
255 1.15 mrg fi
256 1.15 mrg
257 1.37 wrstuden # To not exclude 'toor', a standard duplicate root account, from the duplicate
258 1.37 wrstuden # account test, uncomment the line below (without egrep in it)and comment
259 1.37 wrstuden # out the line (with egrep in it) below it.
260 1.37 wrstuden #
261 1.37 wrstuden # < $MPBYUID uniq -d -f 1 | awk '{ print $2 }' > $TMP2
262 1.36 wrstuden < $MPBYUID egrep -v '^toor ' | uniq -d -f 1 | awk '{ print $2 }' > $TMP2
263 1.15 mrg if [ -s $TMP2 ] ; then
264 1.15 mrg printf "\n$MP has duplicate user id's.\n"
265 1.15 mrg while read uid; do
266 1.28 lukem grep -w $uid $MPBYUID
267 1.15 mrg done < $TMP2 | column
268 1.15 mrg fi
269 1.9 cgd fi
270 1.9 cgd
271 1.9 cgd # Check the group file syntax.
272 1.32 lukem #
273 1.31 lukem if checkyesno check_group; then
274 1.15 mrg GRP=/etc/group
275 1.49 jdolecek awk -F: -v "len=$max_grouplen" '{
276 1.15 mrg if ($0 ~ /^[ ]*$/) {
277 1.25 lukem printf "Line %d is a blank line.\n", NR;
278 1.15 mrg next;
279 1.15 mrg }
280 1.34 abs if (NF != 4 && ($1 != "+" || NF != 1))
281 1.25 lukem printf "Line %d has the wrong number of fields.\n", NR;
282 1.34 abs if ($1 == "+" ) {
283 1.34 abs next;
284 1.34 abs }
285 1.53 atatat if ($1 !~ /^[A-Za-z0-9]([-A-Za-z0-9]*[A-Za-z0-9])*$/)
286 1.25 lukem printf "Group %s has non-alphanumeric characters.\n",
287 1.25 lukem $1;
288 1.49 jdolecek if (length($1) > len)
289 1.49 jdolecek printf "Group %s has more than "len" characters.\n", $1;
290 1.15 mrg if ($3 !~ /[0-9]*/)
291 1.25 lukem printf "Login %s has a negative group id.\n", $1;
292 1.15 mrg }' < $GRP > $OUTPUT
293 1.15 mrg if [ -s $OUTPUT ] ; then
294 1.15 mrg printf "\nChecking the $GRP file:\n"
295 1.15 mrg cat $OUTPUT
296 1.15 mrg fi
297 1.15 mrg
298 1.15 mrg awk -F: '{ print $1 }' $GRP | sort | uniq -d > $OUTPUT
299 1.15 mrg if [ -s $OUTPUT ] ; then
300 1.15 mrg printf "\n$GRP has duplicate group names.\n"
301 1.15 mrg column $OUTPUT
302 1.15 mrg fi
303 1.9 cgd fi
304 1.9 cgd
305 1.9 cgd # Check for root paths, umask values in startup files.
306 1.9 cgd # The check for the root paths is problematical -- it's likely to fail
307 1.9 cgd # in other environments. Once the shells have been modified to warn
308 1.9 cgd # of '.' in the path, the path tests should go away.
309 1.32 lukem #
310 1.31 lukem if checkyesno check_rootdotfiles; then
311 1.67 lukem rhome=~root
312 1.15 mrg umaskset=no
313 1.15 mrg list="/etc/csh.cshrc /etc/csh.login ${rhome}/.cshrc ${rhome}/.login"
314 1.15 mrg for i in $list ; do
315 1.15 mrg if [ -f $i ] ; then
316 1.67 lukem if egrep '^[ \t]*umask[ \t]+[0-7]+' $i > /dev/null ;
317 1.67 lukem then
318 1.15 mrg umaskset=yes
319 1.15 mrg fi
320 1.63 lukem # Double check the umask value itself; ensure that
321 1.67 lukem # both the group and other write bits are set.
322 1.67 lukem #
323 1.45 sommerfe egrep '^[ \t]*umask[ \t]+[0-7]+' $i |
324 1.63 lukem awk '{
325 1.67 lukem if ($2 ~ /^.$/ || $2 ~! /[^2367].$/) {
326 1.80 wiz print "\tRoot umask is group writable"
327 1.63 lukem }
328 1.67 lukem if ($2 ~ /[^2367]$/) {
329 1.80 wiz print "\tRoot umask is other writable"
330 1.63 lukem }
331 1.67 lukem }' | sort -u
332 1.26 lukem SAVE_PATH=$PATH
333 1.26 lukem unset PATH
334 1.15 mrg /bin/csh -f -s << end-of-csh > /dev/null 2>&1
335 1.15 mrg source $i
336 1.15 mrg /bin/ls -ldgT \$path > $TMP1
337 1.9 cgd end-of-csh
338 1.76 atatat export PATH=$SAVE_PATH
339 1.15 mrg awk '{
340 1.15 mrg if ($10 ~ /^\.$/) {
341 1.27 lukem print "\tThe root path includes .";
342 1.15 mrg next;
343 1.15 mrg }
344 1.15 mrg }
345 1.15 mrg $1 ~ /^d....w/ \
346 1.80 wiz { print "\tRoot path directory " $10 " is group writable." } \
347 1.15 mrg $1 ~ /^d.......w/ \
348 1.80 wiz { print "\tRoot path directory " $10 " is other writable." }' \
349 1.67 lukem < $TMP1
350 1.15 mrg fi
351 1.67 lukem done > $OUTPUT
352 1.15 mrg if [ $umaskset = "no" -o -s $OUTPUT ] ; then
353 1.27 lukem printf "\nChecking root csh paths, umask values:\n$list\n\n"
354 1.15 mrg if [ -s $OUTPUT ]; then
355 1.15 mrg cat $OUTPUT
356 1.15 mrg fi
357 1.15 mrg if [ $umaskset = "no" ] ; then
358 1.27 lukem printf "\tRoot csh startup files do not set the umask.\n"
359 1.15 mrg fi
360 1.9 cgd fi
361 1.9 cgd
362 1.15 mrg umaskset=no
363 1.23 lukem list="/etc/profile ${rhome}/.profile"
364 1.15 mrg for i in $list; do
365 1.15 mrg if [ -f $i ] ; then
366 1.15 mrg if egrep umask $i > /dev/null ; then
367 1.15 mrg umaskset=yes
368 1.15 mrg fi
369 1.15 mrg egrep umask $i |
370 1.67 lukem awk '$2 ~ /^.$/ || $2 ~ /[^2367].$/ \
371 1.80 wiz { print "\tRoot umask is group writable" } \
372 1.67 lukem $2 ~ /[^2367]$/ \
373 1.80 wiz { print "\tRoot umask is other writable" }'
374 1.26 lukem SAVE_PATH=$PATH
375 1.26 lukem unset PATH
376 1.15 mrg /bin/sh << end-of-sh > /dev/null 2>&1
377 1.15 mrg . $i
378 1.26 lukem list=\`echo \$PATH | /usr/bin/sed -e \
379 1.26 lukem 's/^:/.:/;s/:$/:./;s/::/:.:/g;s/:/ /g'\`
380 1.15 mrg /bin/ls -ldgT \$list > $TMP1
381 1.9 cgd end-of-sh
382 1.76 atatat export PATH=$SAVE_PATH
383 1.15 mrg awk '{
384 1.15 mrg if ($10 ~ /^\.$/) {
385 1.27 lukem print "\tThe root path includes .";
386 1.15 mrg next;
387 1.15 mrg }
388 1.15 mrg }
389 1.15 mrg $1 ~ /^d....w/ \
390 1.80 wiz { print "\tRoot path directory " $10 " is group writable." } \
391 1.15 mrg $1 ~ /^d.......w/ \
392 1.80 wiz { print "\tRoot path directory " $10 " is other writable." }' \
393 1.67 lukem < $TMP1
394 1.9 cgd
395 1.15 mrg fi
396 1.67 lukem done > $OUTPUT
397 1.15 mrg if [ $umaskset = "no" -o -s $OUTPUT ] ; then
398 1.15 mrg printf "\nChecking root sh paths, umask values:\n$list\n"
399 1.15 mrg if [ -s $OUTPUT ]; then
400 1.15 mrg cat $OUTPUT
401 1.15 mrg fi
402 1.15 mrg if [ $umaskset = "no" ] ; then
403 1.27 lukem printf "\tRoot sh startup files do not set the umask.\n"
404 1.15 mrg fi
405 1.9 cgd fi
406 1.9 cgd fi
407 1.9 cgd
408 1.9 cgd # Root and uucp should both be in /etc/ftpusers.
409 1.32 lukem #
410 1.31 lukem if checkyesno check_ftpusers; then
411 1.28 lukem list="uucp "`awk '$2 == 0 { print $1 }' $MPBYUID`
412 1.27 lukem for i in $list; do
413 1.29 lukem if /usr/libexec/ftpd -C $i ; then
414 1.67 lukem printf "\t$i is not denied\n"
415 1.27 lukem fi
416 1.67 lukem done > $OUTPUT
417 1.28 lukem if [ -s $OUTPUT ]; then
418 1.28 lukem printf "\nChecking the /etc/ftpusers configuration:\n"
419 1.28 lukem cat $OUTPUT
420 1.28 lukem fi
421 1.9 cgd fi
422 1.9 cgd
423 1.43 itojun # Uudecode should not be in the /etc/mail/aliases file.
424 1.32 lukem #
425 1.31 lukem if checkyesno check_aliases; then
426 1.43 itojun for f in /etc/mail/aliases /etc/aliases; do
427 1.43 itojun if [ -f $f ] && egrep '^[^#]*(uudecode|decode).*\|' $f; then
428 1.43 itojun printf "\nEntry for uudecode in $f file.\n"
429 1.43 itojun fi
430 1.43 itojun done
431 1.9 cgd fi
432 1.9 cgd
433 1.9 cgd # Files that should not have + signs.
434 1.32 lukem #
435 1.31 lukem if checkyesno check_rhosts; then
436 1.15 mrg list="/etc/hosts.equiv /etc/hosts.lpd"
437 1.15 mrg for f in $list ; do
438 1.15 mrg if [ -f $f ] && egrep '\+' $f > /dev/null ; then
439 1.15 mrg printf "\nPlus sign in $f file.\n"
440 1.15 mrg fi
441 1.15 mrg done
442 1.15 mrg
443 1.15 mrg # Check for special users with .rhosts files. Only root and toor should
444 1.16 mikel # have .rhosts files. Also, .rhosts files should not have plus signs.
445 1.15 mrg awk -F: '$1 != "root" && $1 != "toor" && \
446 1.15 mrg ($3 < 100 || $1 == "ftp" || $1 == "uucp") \
447 1.20 mycroft { print $1 " " $9 }' $MP |
448 1.19 mycroft sort -k2 |
449 1.15 mrg while read uid homedir; do
450 1.15 mrg if [ -f ${homedir}/.rhosts ] ; then
451 1.15 mrg rhost=`ls -ldgT ${homedir}/.rhosts`
452 1.46 christos printf -- "$uid: $rhost\n"
453 1.15 mrg fi
454 1.15 mrg done > $OUTPUT
455 1.15 mrg if [ -s $OUTPUT ] ; then
456 1.15 mrg printf "\nChecking for special users with .rhosts files.\n"
457 1.15 mrg cat $OUTPUT
458 1.15 mrg fi
459 1.15 mrg
460 1.15 mrg while read uid homedir; do
461 1.35 fair if [ -f ${homedir}/.rhosts -a -r ${homedir}/.rhosts ] && \
462 1.41 christos cat -f ${homedir}/.rhosts | egrep '\+' > /dev/null ; then
463 1.46 christos printf -- "$uid: + in .rhosts file.\n"
464 1.15 mrg fi
465 1.29 lukem done < $MPBYPATH > $OUTPUT
466 1.15 mrg if [ -s $OUTPUT ] ; then
467 1.15 mrg printf "\nChecking .rhosts files syntax.\n"
468 1.15 mrg cat $OUTPUT
469 1.15 mrg fi
470 1.9 cgd fi
471 1.9 cgd
472 1.9 cgd # Check home directories. Directories should not be owned by someone else
473 1.80 wiz # or writable.
474 1.32 lukem #
475 1.31 lukem if checkyesno check_homes; then
476 1.85 jhawk checkyesno check_homes_permit_usergroups && \
477 1.85 jhawk permit_usergroups=1 || permit_usergroups=0
478 1.15 mrg while read uid homedir; do
479 1.15 mrg if [ -d ${homedir}/ ] ; then
480 1.15 mrg file=`ls -ldgT ${homedir}`
481 1.46 christos printf -- "$uid $file\n"
482 1.9 cgd fi
483 1.29 lukem done < $MPBYPATH |
484 1.85 jhawk awk -v "usergroups=$permit_usergroups" '
485 1.85 jhawk $1 != $4 && $4 != "root" \
486 1.15 mrg { print "user " $1 " home directory is owned by " $4 }
487 1.88 jdolecek $2 ~ /^-....w/ && (!usergroups || $5 != $1) \
488 1.80 wiz { print "user " $1 " home directory is group writable" }
489 1.15 mrg $2 ~ /^-.......w/ \
490 1.80 wiz { print "user " $1 " home directory is other writable" }' \
491 1.27 lukem > $OUTPUT
492 1.15 mrg if [ -s $OUTPUT ] ; then
493 1.15 mrg printf "\nChecking home directories.\n"
494 1.15 mrg cat $OUTPUT
495 1.15 mrg fi
496 1.15 mrg
497 1.15 mrg # Files that should not be owned by someone else or readable.
498 1.67 lukem list=".Xauthority .netrc .ssh/id_dsa .ssh/id_rsa .ssh/identity"
499 1.15 mrg while read uid homedir; do
500 1.15 mrg for f in $list ; do
501 1.15 mrg file=${homedir}/${f}
502 1.15 mrg if [ -f $file ] ; then
503 1.46 christos printf -- "$uid $f `ls -ldgT $file`\n"
504 1.15 mrg fi
505 1.15 mrg done
506 1.29 lukem done < $MPBYPATH |
507 1.85 jhawk awk -v "usergroups=$permit_usergroups" '
508 1.85 jhawk $1 != $5 && $5 != "root" \
509 1.15 mrg { print "user " $1 " " $2 " file is owned by " $5 }
510 1.85 jhawk $3 ~ /^-...r/ && (!usergroups || $6 != $1) \
511 1.15 mrg { print "user " $1 " " $2 " file is group readable" }
512 1.15 mrg $3 ~ /^-......r/ \
513 1.15 mrg { print "user " $1 " " $2 " file is other readable" }
514 1.85 jhawk $3 ~ /^-....w/ && (!usergroups || $6 != $1) \
515 1.80 wiz { print "user " $1 " " $2 " file is group writable" }
516 1.15 mrg $3 ~ /^-.......w/ \
517 1.80 wiz { print "user " $1 " " $2 " file is other writable" }' \
518 1.27 lukem > $OUTPUT
519 1.15 mrg
520 1.80 wiz # Files that should not be owned by someone else or writable.
521 1.19 mycroft list=".bash_history .bash_login .bash_logout .bash_profile .bashrc \
522 1.79 elric .cshrc .emacs .exrc .forward .history .k5login .klogin .login \
523 1.79 elric .logout .profile .qmail .rc_history .rhosts .shosts ssh .tcshrc \
524 1.79 elric .twmrc .xinitrc .xsession .ssh/authorized_keys \
525 1.79 elric .ssh/authorized_keys2 .ssh/config .ssh/id_dsa.pub \
526 1.79 elric .ssh/id_rsa.pub .ssh/identity.pub .ssh/known_hosts \
527 1.79 elric .ssh/known_hosts2"
528 1.15 mrg while read uid homedir; do
529 1.15 mrg for f in $list ; do
530 1.15 mrg file=${homedir}/${f}
531 1.15 mrg if [ -f $file ] ; then
532 1.46 christos printf -- "$uid $f `ls -ldgT $file`\n"
533 1.15 mrg fi
534 1.15 mrg done
535 1.29 lukem done < $MPBYPATH |
536 1.85 jhawk awk -v "usergroups=$permit_usergroups" '
537 1.85 jhawk $1 != $5 && $5 != "root" \
538 1.15 mrg { print "user " $1 " " $2 " file is owned by " $5 }
539 1.85 jhawk $3 ~ /^-....w/ && (!usergroups || $6 != $1) \
540 1.80 wiz { print "user " $1 " " $2 " file is group writable" }
541 1.15 mrg $3 ~ /^-.......w/ \
542 1.80 wiz { print "user " $1 " " $2 " file is other writable" }' \
543 1.27 lukem >> $OUTPUT
544 1.15 mrg if [ -s $OUTPUT ] ; then
545 1.15 mrg printf "\nChecking dot files.\n"
546 1.15 mrg cat $OUTPUT
547 1.15 mrg fi
548 1.9 cgd fi
549 1.9 cgd
550 1.9 cgd # Mailboxes should be owned by user and unreadable.
551 1.32 lukem #
552 1.31 lukem if checkyesno check_varmail; then
553 1.86 jhawk ls -lA /var/mail | \
554 1.63 lukem awk ' NR == 1 { next; }
555 1.86 jhawk $9 ~ /^\./ {next; }
556 1.63 lukem $3 != $9 {
557 1.63 lukem print "user " $9 " mailbox is owned by " $3
558 1.63 lukem }
559 1.63 lukem $1 != "-rw-------" {
560 1.63 lukem print "user " $9 " mailbox is " $1 ", group " $4
561 1.63 lukem }' > $OUTPUT
562 1.15 mrg if [ -s $OUTPUT ] ; then
563 1.15 mrg printf "\nChecking mailbox ownership.\n"
564 1.15 mrg cat $OUTPUT
565 1.15 mrg fi
566 1.15 mrg fi
567 1.15 mrg
568 1.32 lukem # NFS exports shouldn't be globally exported
569 1.32 lukem #
570 1.32 lukem if checkyesno check_nfs && [ -f /etc/exports ]; then
571 1.32 lukem awk '{
572 1.22 lukem # ignore comments and blank lines
573 1.39 hubertf if ($0 ~ /^\#/ || $0 ~ /^$/ )
574 1.22 lukem next;
575 1.22 lukem
576 1.15 mrg readonly = 0;
577 1.15 mrg for (i = 2; i <= NF; ++i) {
578 1.15 mrg if ($i ~ /-ro/)
579 1.15 mrg readonly = 1;
580 1.15 mrg else if ($i !~ /^-/)
581 1.15 mrg next;
582 1.15 mrg }
583 1.15 mrg if (readonly)
584 1.15 mrg print "File system " $1 " globally exported, read-only."
585 1.15 mrg else
586 1.15 mrg print "File system " $1 " globally exported, read-write."
587 1.32 lukem }' < /etc/exports > $OUTPUT
588 1.32 lukem if [ -s $OUTPUT ] ; then
589 1.15 mrg printf "\nChecking for globally exported file systems.\n"
590 1.15 mrg cat $OUTPUT
591 1.15 mrg fi
592 1.9 cgd fi
593 1.9 cgd
594 1.9 cgd # Display any changes in setuid files and devices.
595 1.32 lukem #
596 1.31 lukem if checkyesno check_devices; then
597 1.28 lukem > $ERR
598 1.15 mrg (find / \( ! -fstype local -o -fstype fdesc -o -fstype kernfs \
599 1.74 lukem -o -fstype null \
600 1.15 mrg -o -fstype procfs \) -a -prune -o \
601 1.21 mycroft \( \( -perm -u+s -a ! -type d \) -o \
602 1.21 mycroft \( -perm -g+s -a ! -type d \) -o \
603 1.24 lukem -type b -o -type c \) -print0 | \
604 1.24 lukem xargs -0 ls -ldgTq | sort +9 > $LIST) 2> $OUTPUT
605 1.15 mrg
606 1.15 mrg # Display any errors that occurred during system file walk.
607 1.15 mrg if [ -s $OUTPUT ] ; then
608 1.28 lukem printf "Setuid/device find errors:\n" >> $ERR
609 1.28 lukem cat $OUTPUT >> $ERR
610 1.28 lukem printf "\n" >> $ERR
611 1.15 mrg fi
612 1.15 mrg
613 1.15 mrg # Display any changes in the setuid file list.
614 1.15 mrg egrep -v '^[bc]' $LIST > $TMP1
615 1.15 mrg if [ -s $TMP1 ] ; then
616 1.15 mrg # Check to make sure uudecode isn't setuid.
617 1.15 mrg if grep -w uudecode $TMP1 > /dev/null ; then
618 1.28 lukem printf "\nUudecode is setuid.\n" >> $ERR
619 1.15 mrg fi
620 1.15 mrg
621 1.67 lukem file=$work_dir/setuid
622 1.67 lukem migrate_file "$backup_dir/setuid" "$file"
623 1.67 lukem CUR=${file}.current
624 1.67 lukem BACK=${file}.backup
625 1.15 mrg if [ -s $CUR ] ; then
626 1.15 mrg if cmp -s $CUR $TMP1 ; then
627 1.15 mrg :
628 1.15 mrg else
629 1.15 mrg > $TMP2
630 1.15 mrg join -110 -210 -v2 $CUR $TMP1 > $OUTPUT
631 1.15 mrg if [ -s $OUTPUT ] ; then
632 1.28 lukem printf "Setuid additions:\n" >> $ERR
633 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
634 1.28 lukem printf "\n" >> $ERR
635 1.15 mrg fi
636 1.15 mrg
637 1.15 mrg join -110 -210 -v1 $CUR $TMP1 > $OUTPUT
638 1.15 mrg if [ -s $OUTPUT ] ; then
639 1.28 lukem printf "Setuid deletions:\n" >> $ERR
640 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
641 1.28 lukem printf "\n" >> $ERR
642 1.15 mrg fi
643 1.15 mrg
644 1.20 mycroft sort -k10 $TMP2 $CUR $TMP1 | \
645 1.27 lukem sed -e 's/[ ][ ]*/ /g' | \
646 1.27 lukem uniq -u > $OUTPUT
647 1.15 mrg if [ -s $OUTPUT ] ; then
648 1.28 lukem printf "Setuid changes:\n" >> $ERR
649 1.28 lukem column -t $OUTPUT >> $ERR
650 1.28 lukem printf "\n" >> $ERR
651 1.15 mrg fi
652 1.9 cgd
653 1.52 atatat backup_file update $TMP1 $CUR $BACK
654 1.9 cgd fi
655 1.15 mrg else
656 1.28 lukem printf "Setuid additions:\n" >> $ERR
657 1.28 lukem column -t $TMP1 >> $ERR
658 1.28 lukem printf "\n" >> $ERR
659 1.52 atatat backup_file add $TMP1 $CUR $BACK
660 1.9 cgd fi
661 1.15 mrg fi
662 1.15 mrg
663 1.27 lukem # Check for block and character disk devices that are readable or
664 1.80 wiz # writable or not owned by root.operator.
665 1.15 mrg >$TMP1
666 1.61 lukem DISKLIST="ccd ch hk hp ld md ra raid rb rd rl rx \
667 1.57 simonb sd se ss uk up vnd wd xd xy"
668 1.27 lukem # DISKLIST="$DISKLIST ct mt st wt"
669 1.15 mrg for i in $DISKLIST; do
670 1.15 mrg egrep "^b.*/${i}[0-9][0-9]*[a-p]$" $LIST >> $TMP1
671 1.15 mrg egrep "^c.*/r${i}[0-9][0-9]*[a-p]$" $LIST >> $TMP1
672 1.15 mrg done
673 1.15 mrg
674 1.15 mrg awk '$3 != "root" || $4 != "operator" || $1 !~ /.rw-r-----/ \
675 1.25 lukem { printf "Disk %s is user %s, group %s, permissions %s.\n", \
676 1.25 lukem $11, $3, $4, $1; }' < $TMP1 > $OUTPUT
677 1.15 mrg if [ -s $OUTPUT ] ; then
678 1.28 lukem printf "\nChecking disk ownership and permissions.\n" >> $ERR
679 1.28 lukem cat $OUTPUT >> $ERR
680 1.28 lukem printf "\n" >> $ERR
681 1.9 cgd fi
682 1.9 cgd
683 1.15 mrg # Display any changes in the device file list.
684 1.20 mycroft egrep '^[bc]' $LIST | sort -k11 > $TMP1
685 1.15 mrg if [ -s $TMP1 ] ; then
686 1.67 lukem file=$work_dir/device
687 1.67 lukem migrate_file "$backup_dir/device" "$file"
688 1.67 lukem CUR=${file}.current
689 1.67 lukem BACK=${file}.backup
690 1.15 mrg
691 1.15 mrg if [ -s $CUR ] ; then
692 1.15 mrg if cmp -s $CUR $TMP1 ; then
693 1.15 mrg :
694 1.15 mrg else
695 1.15 mrg > $TMP2
696 1.15 mrg join -111 -211 -v2 $CUR $TMP1 > $OUTPUT
697 1.15 mrg if [ -s $OUTPUT ] ; then
698 1.28 lukem printf "Device additions:\n" >> $ERR
699 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
700 1.28 lukem printf "\n" >> $ERR
701 1.15 mrg fi
702 1.15 mrg
703 1.15 mrg join -111 -211 -v1 $CUR $TMP1 > $OUTPUT
704 1.15 mrg if [ -s $OUTPUT ] ; then
705 1.28 lukem printf "Device deletions:\n" >> $ERR
706 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
707 1.28 lukem printf "\n" >> $ERR
708 1.15 mrg fi
709 1.15 mrg
710 1.27 lukem # Report any block device change. Ignore
711 1.27 lukem # character devices, only the name is
712 1.27 lukem # significant.
713 1.15 mrg cat $TMP2 $CUR $TMP1 | \
714 1.27 lukem sed -e '/^c/d' | \
715 1.27 lukem sort -k11 | \
716 1.27 lukem sed -e 's/[ ][ ]*/ /g' | \
717 1.27 lukem uniq -u > $OUTPUT
718 1.15 mrg if [ -s $OUTPUT ] ; then
719 1.28 lukem printf "Block device changes:\n" >> $ERR
720 1.28 lukem column -t $OUTPUT >> $ERR
721 1.28 lukem printf "\n" >> $ERR
722 1.15 mrg fi
723 1.9 cgd
724 1.52 atatat backup_file update $TMP1 $CUR $BACK
725 1.9 cgd fi
726 1.15 mrg else
727 1.28 lukem printf "Device additions:\n" >> $ERR
728 1.28 lukem column -t $TMP1 >> $ERR
729 1.28 lukem printf "\n" >> $ERR
730 1.52 atatat backup_file add $TMP1 $CUR $BACK >> $ERR
731 1.9 cgd fi
732 1.28 lukem fi
733 1.28 lukem if [ -s $ERR ] ; then
734 1.28 lukem printf "\nChecking setuid files and devices:\n"
735 1.28 lukem cat $ERR
736 1.28 lukem printf "\n"
737 1.9 cgd fi
738 1.9 cgd fi
739 1.9 cgd
740 1.9 cgd # Check special files.
741 1.9 cgd # Check system binaries.
742 1.9 cgd #
743 1.9 cgd # Create the mtree tree specifications using:
744 1.67 lukem # mtree -cx -pDIR -kmd5,uid,gid,mode,nlink,size,link,time > DIR.secure
745 1.38 kleink # chown root:wheel DIR.secure
746 1.67 lukem # chmod u+r,go= DIR.secure
747 1.9 cgd #
748 1.9 cgd # Note, this is not complete protection against Trojan horsed binaries, as
749 1.9 cgd # the hacker can modify the tree specification to match the replaced binary.
750 1.9 cgd # For details on really protecting yourself against modified binaries, see
751 1.9 cgd # the mtree(8) manual page.
752 1.32 lukem #
753 1.31 lukem if checkyesno check_mtree; then
754 1.82 jhawk if checkyesno check_mtree_follow_symlinks; then
755 1.82 jhawk check_mtree_flags="-L"
756 1.82 jhawk else
757 1.82 jhawk check_mtree_flags=""
758 1.82 jhawk fi
759 1.67 lukem for file in $special_files; do
760 1.67 lukem [ ! -s $file ] && continue
761 1.82 jhawk mtree -e -l -p / $check_mtree_flags -f $file
762 1.87 jhawk done 3>&1 >$OUTPUT 2>&3 |
763 1.87 jhawk grep -v '^mtree: dev/tty: Device not configured$' >&2
764 1.15 mrg if [ -s $OUTPUT ]; then
765 1.9 cgd printf "\nChecking special files and directories.\n"
766 1.9 cgd cat $OUTPUT
767 1.9 cgd fi
768 1.9 cgd
769 1.16 mikel for file in /etc/mtree/*.secure; do
770 1.16 mikel [ $file = '/etc/mtree/*.secure' ] && continue
771 1.9 cgd tree=`sed -n -e '3s/.* //p' -e 3q $file`
772 1.82 jhawk mtree $check_mtree_flags -f $file -p $tree > $TMP1
773 1.9 cgd if [ -s $TMP1 ]; then
774 1.67 lukem printf "\nChecking $tree:\n"
775 1.67 lukem cat $TMP1
776 1.9 cgd fi
777 1.67 lukem done > $OUTPUT
778 1.15 mrg if [ -s $OUTPUT ]; then
779 1.9 cgd printf "\nChecking system binaries:\n"
780 1.9 cgd cat $OUTPUT
781 1.9 cgd fi
782 1.9 cgd fi
783 1.9 cgd
784 1.32 lukem # Backup disklabels of available disks
785 1.32 lukem #
786 1.32 lukem if checkyesno check_disklabels; then
787 1.67 lukem # migrate old disklabels
788 1.67 lukem for file in `ls -1d $backup_dir/$backup_dir/disklabel.* \
789 1.67 lukem $backup_dir/disklabel.* 2>/dev/null`; do
790 1.67 lukem migrate_file "$file" "$work_dir/${file##*/}"
791 1.67 lukem done
792 1.67 lukem
793 1.67 lukem # generate list of old disklabels & fdisks and remove them
794 1.67 lukem ls -1d $work_dir/disklabel.* $work_dir/fdisk.* 2>/dev/null |
795 1.52 atatat egrep -v '\.(backup|current)(,v)?$' > $LABELS
796 1.32 lukem xargs rm < $LABELS
797 1.32 lukem
798 1.67 lukem # generate disklabels of all disks excluding: cd fd md
799 1.63 lukem disks=`iostat -x | awk 'NR > 1 && $1 !~ /^[cfm]d/ { print $1; }'`
800 1.32 lukem for i in $disks; do
801 1.67 lukem disklabel $i > "$work_dir/disklabel.$i" 2>/dev/null
802 1.32 lukem done
803 1.32 lukem
804 1.67 lukem # if fdisk is available, generate fdisks for: ed ld sd wd
805 1.67 lukem if [ -x /sbin/fdisk ]; then
806 1.67 lukem disks=`iostat -x| awk 'NR > 1 && $1 ~ /^[elsw]d/ { print $1; }'`
807 1.67 lukem for i in $disks; do
808 1.67 lukem /sbin/fdisk $i > "$work_dir/fdisk.$i" 2>/dev/null
809 1.67 lukem done
810 1.67 lukem fi
811 1.67 lukem
812 1.67 lukem # append list of new disklabels and fdisks
813 1.67 lukem ls -1d $work_dir/disklabel.* $work_dir/fdisk.* 2>/dev/null |
814 1.52 atatat egrep -v '\.(backup|current)(,v)?$' >> $LABELS
815 1.62 atatat CHANGELIST="$LABELS $CHANGELIST"
816 1.62 atatat fi
817 1.62 atatat
818 1.62 atatat # Check for changes in the list of installed pkgs
819 1.62 atatat #
820 1.65 lukem if checkyesno check_pkgs && [ -d $pkgdb_dir ]; then
821 1.67 lukem pkgs=$work_dir/pkgs
822 1.67 lukem migrate_file "$backup_dir/pkgs" "$pkgs"
823 1.65 lukem ( cd $pkgdb_dir
824 1.62 atatat pkg_info | sort
825 1.62 atatat echo ""
826 1.62 atatat find . \( -name +REQUIRED_BY -o -name +CONTENTS \) -print0 |
827 1.72 lukem xargs -0 ls -ldgTq | sort -t. +1 | sed -e 's, \./, ,'
828 1.62 atatat ) > $pkgs
829 1.67 lukem echo "$pkgs" > $PKGS
830 1.62 atatat CHANGELIST="$PKGS $CHANGELIST"
831 1.32 lukem fi
832 1.32 lukem
833 1.67 lukem # List of files that get backed up and checked for any modifications.
834 1.9 cgd # Any changes cause the files to rotate.
835 1.32 lukem #
836 1.67 lukem if checkyesno check_changelist ; then
837 1.67 lukem for file in $special_files; do
838 1.67 lukem [ ! -s $file ] && continue
839 1.67 lukem mtree -D -k type -f $file -E exclude |
840 1.67 lukem sed '/^type=file/!d ; s/type=file \.//'
841 1.67 lukem done > $CHANGEFILES
842 1.67 lukem
843 1.75 lukem (
844 1.68 lukem # Add other files which might dynamically exist:
845 1.67 lukem # /etc/ifconfig.*
846 1.67 lukem # /etc/raid*.conf
847 1.68 lukem # /etc/rc.d/*
848 1.67 lukem # /etc/rc.conf.d/*
849 1.68 lukem #
850 1.75 lukem echo "/etc/ifconfig.*"
851 1.75 lukem echo "/etc/raid*.conf"
852 1.75 lukem echo "/etc/rc.d/*"
853 1.75 lukem echo "/etc/rc.conf.d/*"
854 1.67 lukem
855 1.68 lukem # Add /etc/changelist
856 1.68 lukem #
857 1.75 lukem if [ -s /etc/changelist ]; then
858 1.75 lukem grep -v '^#' /etc/changelist
859 1.75 lukem fi
860 1.75 lukem ) | while read file; do
861 1.75 lukem case "$file" in
862 1.75 lukem *[\*\?\[]*) # If changelist line is a glob ...
863 1.75 lukem # ... expand possible backup files
864 1.75 lukem #
865 1.75 lukem ls -1d $(echo $backup_dir/${file}.current) 2>/dev/null \
866 1.75 lukem | sed "s,^$backup_dir/,, ; s,\.current$,,"
867 1.75 lukem
868 1.75 lukem # ... expand possible files
869 1.75 lukem #
870 1.75 lukem ls -1d $(echo $file) 2>/dev/null
871 1.75 lukem ;;
872 1.75 lukem *)
873 1.75 lukem # Otherwise, just print the filename
874 1.75 lukem echo $file
875 1.75 lukem ;;
876 1.75 lukem esac
877 1.75 lukem done >> $CHANGEFILES
878 1.67 lukem CHANGELIST="$CHANGEFILES $CHANGELIST"
879 1.67 lukem fi
880 1.67 lukem
881 1.67 lukem # Special case backups, including the master password file and
882 1.67 lukem # ssh private host keys. The normal backup mechanisms for
883 1.67 lukem # $check_changelist (see below) also print out the actual file
884 1.67 lukem # differences and we don't want to do that for these files
885 1.67 lukem #
886 1.67 lukem echo $MP > $TMP1 # always add /etc/master.passwd
887 1.67 lukem for file in $special_files; do
888 1.67 lukem [ ! -s $file ] && continue
889 1.70 lukem mtree -D -k type -f $file -I nodiff |
890 1.67 lukem sed '/^type=file/!d ; s/type=file \.//'
891 1.67 lukem done >> $TMP1
892 1.73 lukem grep -v '^$' $TMP1 | sort -u > $TMP2
893 1.68 lukem
894 1.69 lukem while read file; do
895 1.67 lukem backup_and_diff "$file" no
896 1.69 lukem done < $TMP2
897 1.67 lukem
898 1.32 lukem
899 1.32 lukem if [ -n "$CHANGELIST" ]; then
900 1.73 lukem grep -h -v '^$' $CHANGELIST | sort -u > $TMP1
901 1.68 lukem comm -23 $TMP1 $TMP2 | while read file; do
902 1.67 lukem backup_and_diff "$file" yes
903 1.9 cgd done
904 1.44 ad fi
905 1.44 ad
906 1.44 ad if [ -f /etc/security.local ]; then
907 1.90 kim . /etc/security.local > $OUTPUT 2>&1
908 1.84 jhawk if [ -s $OUTPUT ] ; then
909 1.84 jhawk printf "\nRunning /etc/security.local:\n"
910 1.84 jhawk cat $OUTPUT
911 1.84 jhawk fi
912 1.9 cgd fi
913