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