security revision 1.125 1 1.1 cgd #!/bin/sh -
2 1.1 cgd #
3 1.125 uwe # $NetBSD: security,v 1.125 2019/09/18 22:27:55 uwe 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.112 agc if [ -s /etc/pkgpath.conf ]; then
25 1.112 agc . /etc/pkgpath.conf
26 1.112 agc fi
27 1.15 mrg
28 1.67 lukem # Set reasonable defaults (if they're not set in security.conf)
29 1.67 lukem #
30 1.67 lukem backup_dir=${backup_dir:-/var/backups}
31 1.67 lukem max_loginlen=${max_loginlen:-8}
32 1.67 lukem max_grouplen=${max_grouplen:-8}
33 1.113 prlw1 pkg_admin=${pkg_admin:-/usr/sbin/pkg_admin}
34 1.104 adrianp pkg_info=${pkg_info:-/usr/sbin/pkg_info}
35 1.67 lukem
36 1.67 lukem # Other configurable variables
37 1.67 lukem #
38 1.67 lukem special_files="/etc/mtree/special /etc/mtree/special.local"
39 1.67 lukem MP=/etc/master.passwd
40 1.67 lukem CHANGELIST=""
41 1.67 lukem work_dir=$backup_dir/work
42 1.67 lukem
43 1.67 lukem if [ ! -d "$work_dir" ]; then
44 1.67 lukem mkdir -p "$work_dir"
45 1.67 lukem fi
46 1.67 lukem
47 1.102 martti SECUREDIR=$(mktemp -d -t _securedir) || exit 1
48 1.56 lukem
49 1.67 lukem trap "/bin/rm -rf $SECUREDIR ; exit 0" EXIT INT QUIT PIPE
50 1.15 mrg
51 1.56 lukem if ! cd "$SECUREDIR"; then
52 1.56 lukem echo "Can not cd to $SECUREDIR".
53 1.15 mrg exit 1
54 1.15 mrg fi
55 1.15 mrg
56 1.91 lukem ERR=err.$$
57 1.91 lukem TMP1=tmp1.$$
58 1.91 lukem TMP2=tmp2.$$
59 1.91 lukem MPBYUID=mpbyuid.$$
60 1.91 lukem MPBYPATH=mpbypath.$$
61 1.91 lukem LIST=list.$$
62 1.91 lukem OUTPUT=output.$$
63 1.91 lukem LABELS=labels.$$
64 1.106 haad LVM_LABELS=lvm.$$
65 1.91 lukem PKGS=pkgs.$$
66 1.91 lukem CHANGEFILES=changefiles.$$
67 1.91 lukem SPECIALSPEC=specialspec.$$
68 1.67 lukem
69 1.108 jmmv if [ -n "${pkgdb_dir}" ]; then
70 1.118 uebayasi echo "WARNING: Setting pkgdb_dir in security.conf(5) is deprecated"
71 1.118 uebayasi echo "WARNING: Please define PKG_DBDIR in pkg_install.conf(5) instead"
72 1.118 uebayasi _compat_K_flag="-K ${pkgdb_dir}"
73 1.108 jmmv fi
74 1.108 jmmv
75 1.108 jmmv have_pkgs() {
76 1.108 jmmv $pkg_info ${_compat_K_flag} -q -E '*'
77 1.108 jmmv }
78 1.108 jmmv
79 1.67 lukem # migrate_file old new
80 1.67 lukem # Determine if the "${old}" path name needs to be migrated to the
81 1.67 lukem # "${new}" path. Also checks if "${old}.current" needs migrating,
82 1.67 lukem # and if so, migrate it and possibly "${old}.current,v" and
83 1.67 lukem # "${old}.backup".
84 1.67 lukem #
85 1.67 lukem migrate_file()
86 1.67 lukem {
87 1.67 lukem _old=$1
88 1.67 lukem _new=$2
89 1.123 kre if [ -z "$_old" ] || [ -z "$_new" ]; then
90 1.67 lukem err 3 "USAGE: migrate_file old new"
91 1.67 lukem fi
92 1.67 lukem if [ ! -d "${_new%/*}" ]; then
93 1.67 lukem mkdir -p "${_new%/*}"
94 1.67 lukem fi
95 1.123 kre if [ -f "${_old}" ] && ! [ -f "${_new}" ]; then
96 1.67 lukem echo "==> migrating ${_old}"
97 1.67 lukem echo " to ${_new}"
98 1.67 lukem mv "${_old}" "${_new}"
99 1.67 lukem fi
100 1.123 kre if [ -f "${_old}.current" ] && ! [ -f "${_new}.current" ]; then
101 1.67 lukem echo "==> migrating ${_old}.current"
102 1.67 lukem echo " to ${_new}.current"
103 1.67 lukem mv "${_old}.current" "${_new}.current"
104 1.123 kre if [ -f "${_old}.current,v" ] &&
105 1.123 kre ! [ -f "${_new}.current,v" ]; then
106 1.67 lukem echo "==> migrating ${_old}.current,v"
107 1.67 lukem echo " to ${_new}.current,v"
108 1.67 lukem mv "${_old}.current,v" "${_new}.current,v"
109 1.67 lukem fi
110 1.123 kre if [ -f "${_old}.backup" ] && ! [ -f "${_new}.backup" ]; then
111 1.67 lukem echo "==> migrating ${_old}.backup"
112 1.67 lukem echo " to ${_new}.backup"
113 1.67 lukem mv "${_old}.backup" "${_new}.backup"
114 1.67 lukem fi
115 1.67 lukem fi
116 1.67 lukem }
117 1.67 lukem
118 1.67 lukem
119 1.67 lukem # backup_and_diff file printdiff
120 1.67 lukem # Determine if file needs backing up, and if so, do it.
121 1.118 uebayasi # If printdiff is yes, display the diffs, otherwise
122 1.67 lukem # just print a message saying "[changes omitted]".
123 1.67 lukem #
124 1.67 lukem backup_and_diff()
125 1.67 lukem {
126 1.67 lukem _file=$1
127 1.67 lukem _printdiff=$2
128 1.123 kre if [ -z "$_file" ] || [ -z "$_printdiff" ]; then
129 1.67 lukem err 3 "USAGE: backup_and_diff file printdiff"
130 1.67 lukem fi
131 1.67 lukem ! checkyesno _printdiff
132 1.67 lukem _printdiff=$?
133 1.67 lukem
134 1.67 lukem _old=$backup_dir/${_file##*/}
135 1.67 lukem case "$_file" in
136 1.67 lukem $work_dir/*)
137 1.67 lukem _new=$_file
138 1.67 lukem migrate_file "$backup_dir/$_old" "$_new"
139 1.67 lukem migrate_file "$_old" "$_new"
140 1.67 lukem ;;
141 1.67 lukem *)
142 1.67 lukem _new=$backup_dir/$_file
143 1.67 lukem migrate_file "$_old" "$_new"
144 1.67 lukem ;;
145 1.67 lukem esac
146 1.67 lukem CUR=${_new}.current
147 1.67 lukem BACK=${_new}.backup
148 1.67 lukem if [ -f $_file ]; then
149 1.67 lukem if [ -f $CUR ] ; then
150 1.67 lukem if [ "$_printdiff" -ne 0 ]; then
151 1.83 jhawk diff ${diff_options} $CUR $_file > $OUTPUT
152 1.67 lukem else
153 1.67 lukem if ! cmp -s $CUR $_file; then
154 1.67 lukem echo "[changes omitted]"
155 1.67 lukem fi > $OUTPUT
156 1.67 lukem fi
157 1.67 lukem if [ -s $OUTPUT ] ; then
158 1.67 lukem printf \
159 1.67 lukem "\n======\n%s diffs (OLD < > NEW)\n======\n" $_file
160 1.67 lukem cat $OUTPUT
161 1.67 lukem backup_file update $_file $CUR $BACK
162 1.67 lukem fi
163 1.67 lukem else
164 1.67 lukem printf "\n======\n%s added\n======\n" $_file
165 1.67 lukem if [ "$_printdiff" -ne 0 ]; then
166 1.83 jhawk diff ${diff_options} /dev/null $_file
167 1.67 lukem else
168 1.67 lukem echo "[changes omitted]"
169 1.67 lukem fi
170 1.67 lukem backup_file add $_file $CUR $BACK
171 1.67 lukem fi
172 1.67 lukem else
173 1.67 lukem if [ -f $CUR ]; then
174 1.67 lukem printf "\n======\n%s removed\n======\n" $_file
175 1.67 lukem if [ "$_printdiff" -ne 0 ]; then
176 1.83 jhawk diff ${diff_options} $CUR /dev/null
177 1.67 lukem else
178 1.67 lukem echo "[changes omitted]"
179 1.67 lukem fi
180 1.67 lukem backup_file remove $_file $CUR $BACK
181 1.67 lukem fi
182 1.67 lukem fi
183 1.67 lukem }
184 1.48 abs
185 1.9 cgd
186 1.67 lukem # These are used several times.
187 1.67 lukem #
188 1.91 lukem awk -F: '!/^\+/ { print $1 " " $3 }' $MP | sort -k2n > $MPBYUID
189 1.29 lukem awk -F: '{ print $1 " " $9 }' $MP | sort -k2 > $MPBYPATH
190 1.91 lukem for file in $special_files; do
191 1.91 lukem [ -s $file ] && cat $file
192 1.91 lukem done | mtree -CM -k all > $SPECIALSPEC || exit 1
193 1.9 cgd
194 1.67 lukem
195 1.9 cgd # Check the master password file syntax.
196 1.32 lukem #
197 1.31 lukem if checkyesno check_passwd; then
198 1.118 uebayasi # XXX: the sense of permit_star is reversed; the code works as
199 1.118 uebayasi # implemented, but usage needs to be negated.
200 1.81 jhawk checkyesno check_passwd_permit_star && permit_star=0 || permit_star=1
201 1.94 jdolecek checkyesno check_passwd_permit_nonalpha \
202 1.94 jdolecek && permit_nonalpha=1 || permit_nonalpha=0
203 1.94 jdolecek
204 1.81 jhawk awk -v "len=$max_loginlen" \
205 1.81 jhawk -v "nowarn_shells_list=$check_passwd_nowarn_shells" \
206 1.81 jhawk -v "nowarn_users_list=$check_passwd_nowarn_users" \
207 1.94 jdolecek -v "permit_star=$permit_star" \
208 1.94 jdolecek -v "permit_nonalpha=$permit_nonalpha" \
209 1.94 jdolecek '
210 1.25 lukem BEGIN {
211 1.25 lukem while ( getline < "/etc/shells" > 0 ) {
212 1.39 hubertf if ($0 ~ /^\#/ || $0 ~ /^$/ )
213 1.25 lukem continue;
214 1.25 lukem shells[$1]++;
215 1.25 lukem }
216 1.81 jhawk split(nowarn_shells_list, a);
217 1.81 jhawk for (i in a) nowarn_shells[a[i]]++;
218 1.81 jhawk split(nowarn_users_list, a);
219 1.81 jhawk for (i in a) nowarn_users[a[i]]++;
220 1.81 jhawk uid0_users_list="root toor"
221 1.81 jhawk split(uid0_users_list, a);
222 1.81 jhawk for (i in a) uid0_users[a[i]]++;
223 1.25 lukem FS=":";
224 1.25 lukem }
225 1.25 lukem
226 1.25 lukem {
227 1.15 mrg if ($0 ~ /^[ ]*$/) {
228 1.25 lukem printf "Line %d is a blank line.\n", NR;
229 1.15 mrg next;
230 1.15 mrg }
231 1.105 dholland
232 1.105 dholland # NIS compat entry?
233 1.105 dholland compatline = $1 ~ "^[\\+-]";
234 1.105 dholland if (compatline) {
235 1.105 dholland if ($1 == "+" && NF == 1) {
236 1.105 dholland next;
237 1.105 dholland }
238 1.105 dholland sub("^.", "", $1);
239 1.105 dholland }
240 1.105 dholland if (NF != 10)
241 1.25 lukem printf "Line %d has the wrong number of fields.\n", NR;
242 1.105 dholland if (compatline) {
243 1.105 dholland if ($3 == 0)
244 1.81 jhawk printf "Line %d includes entries with uid 0.\n",
245 1.81 jhawk NR;
246 1.105 dholland if ($1 == "")
247 1.105 dholland next;
248 1.34 abs }
249 1.94 jdolecek if (!permit_nonalpha &&
250 1.95 peter $1 !~ /^[_A-Za-z0-9]([-A-Za-z0-9_.]*[A-Za-z0-9])*$/)
251 1.25 lukem printf "Login %s has non-alphanumeric characters.\n",
252 1.25 lukem $1;
253 1.34 abs if (length($1) > len)
254 1.81 jhawk printf "Login %s has more than "len" characters.\n",
255 1.81 jhawk $1;
256 1.105 dholland if ($2 == "" && !compatline && !nowarn_users[$1])
257 1.81 jhawk printf "Login %s has no password.\n", $1;
258 1.81 jhawk if (!nowarn_shells[$10] && !nowarn_users[$1]) {
259 1.81 jhawk if (length($2) != 13 &&
260 1.81 jhawk length($2) != 20 &&
261 1.81 jhawk $2 !~ /^\$1/ &&
262 1.81 jhawk $2 !~ /^\$2/ &&
263 1.99 jmcneill $2 !~ /^\$sha1/ &&
264 1.81 jhawk $2 != "" &&
265 1.81 jhawk (permit_star || $2 != "*") &&
266 1.81 jhawk $2 !~ /^\*[A-z-]+$/ &&
267 1.81 jhawk $1 != "toor") {
268 1.81 jhawk if ($10 == "" || shells[$10])
269 1.81 jhawk printf "Login %s is off but still has "\
270 1.81 jhawk "a valid shell (%s)\n", $1, $10;
271 1.105 dholland } else if (compatline && $10 == "") {
272 1.105 dholland # nothing
273 1.81 jhawk } else if (! shells[$10])
274 1.81 jhawk printf "Login %s does not have a valid "\
275 1.81 jhawk "shell (%s)\n", $1, $10;
276 1.81 jhawk }
277 1.81 jhawk if ($3 == 0 && !uid0_users[$1] && !nowarn_users[$1])
278 1.25 lukem printf "Login %s has a user id of 0.\n", $1;
279 1.105 dholland if ($3 != "" && $3 < 0)
280 1.25 lukem printf "Login %s has a negative user id.\n", $1;
281 1.105 dholland if ($4 != "" && $4 < 0)
282 1.25 lukem printf "Login %s has a negative group id.\n", $1;
283 1.15 mrg }' < $MP > $OUTPUT
284 1.15 mrg if [ -s $OUTPUT ] ; then
285 1.15 mrg printf "\nChecking the $MP file:\n"
286 1.15 mrg cat $OUTPUT
287 1.15 mrg fi
288 1.15 mrg
289 1.15 mrg awk -F: '{ print $1 }' $MP | sort | uniq -d > $OUTPUT
290 1.15 mrg if [ -s $OUTPUT ] ; then
291 1.15 mrg printf "\n$MP has duplicate user names.\n"
292 1.15 mrg column $OUTPUT
293 1.15 mrg fi
294 1.15 mrg
295 1.111 spz awk -v "permit_dups_list=$check_passwd_permit_dups" \
296 1.111 spz '
297 1.111 spz BEGIN {
298 1.111 spz split(permit_dups_list, a);
299 1.111 spz for (i in a) permit_dups[a[i]]++;
300 1.111 spz }
301 1.111 spz {
302 1.111 spz if (!permit_dups[$1])
303 1.111 spz print $2;
304 1.111 spz }' < $MPBYUID | uniq -d > $TMP2
305 1.15 mrg if [ -s $TMP2 ] ; then
306 1.111 spz printf "\n$MP has duplicate user ids.\n"
307 1.15 mrg while read uid; do
308 1.28 lukem grep -w $uid $MPBYUID
309 1.15 mrg done < $TMP2 | column
310 1.15 mrg fi
311 1.9 cgd fi
312 1.9 cgd
313 1.9 cgd # Check the group file syntax.
314 1.32 lukem #
315 1.31 lukem if checkyesno check_group; then
316 1.15 mrg GRP=/etc/group
317 1.49 jdolecek awk -F: -v "len=$max_grouplen" '{
318 1.15 mrg if ($0 ~ /^[ ]*$/) {
319 1.25 lukem printf "Line %d is a blank line.\n", NR;
320 1.15 mrg next;
321 1.15 mrg }
322 1.34 abs if (NF != 4 && ($1 != "+" || NF != 1))
323 1.25 lukem printf "Line %d has the wrong number of fields.\n", NR;
324 1.34 abs if ($1 == "+" ) {
325 1.34 abs next;
326 1.34 abs }
327 1.95 peter if ($1 !~ /^[_A-Za-z0-9]([-A-Za-z0-9_.]*[A-Za-z0-9])*$/)
328 1.25 lukem printf "Group %s has non-alphanumeric characters.\n",
329 1.25 lukem $1;
330 1.49 jdolecek if (length($1) > len)
331 1.49 jdolecek printf "Group %s has more than "len" characters.\n", $1;
332 1.15 mrg if ($3 !~ /[0-9]*/)
333 1.25 lukem printf "Login %s has a negative group id.\n", $1;
334 1.15 mrg }' < $GRP > $OUTPUT
335 1.15 mrg if [ -s $OUTPUT ] ; then
336 1.15 mrg printf "\nChecking the $GRP file:\n"
337 1.15 mrg cat $OUTPUT
338 1.15 mrg fi
339 1.15 mrg
340 1.15 mrg awk -F: '{ print $1 }' $GRP | sort | uniq -d > $OUTPUT
341 1.114 spz dupgroups=""
342 1.114 spz for group in $(cat $OUTPUT) ; do
343 1.116 apb gcount=$(awk -F: "/$group/ { print \$1,\$3 }" $GRP |
344 1.116 apb sort -u | wc -l)
345 1.114 spz if [ $gcount -gt 1 ]; then
346 1.114 spz dupgroups="$dupgroups $group"
347 1.114 spz fi
348 1.114 spz done
349 1.114 spz if [ ! -z $dupgroups ] ; then
350 1.15 mrg printf "\n$GRP has duplicate group names.\n"
351 1.114 spz printf "$dupgroups\n"
352 1.15 mrg fi
353 1.9 cgd fi
354 1.9 cgd
355 1.9 cgd # Check for root paths, umask values in startup files.
356 1.9 cgd # The check for the root paths is problematical -- it's likely to fail
357 1.9 cgd # in other environments. Once the shells have been modified to warn
358 1.9 cgd # of '.' in the path, the path tests should go away.
359 1.32 lukem #
360 1.31 lukem if checkyesno check_rootdotfiles; then
361 1.67 lukem rhome=~root
362 1.15 mrg umaskset=no
363 1.15 mrg list="/etc/csh.cshrc /etc/csh.login ${rhome}/.cshrc ${rhome}/.login"
364 1.15 mrg for i in $list ; do
365 1.15 mrg if [ -f $i ] ; then
366 1.67 lukem if egrep '^[ \t]*umask[ \t]+[0-7]+' $i > /dev/null ;
367 1.67 lukem then
368 1.15 mrg umaskset=yes
369 1.15 mrg fi
370 1.63 lukem # Double check the umask value itself; ensure that
371 1.67 lukem # both the group and other write bits are set.
372 1.67 lukem #
373 1.45 sommerfe egrep '^[ \t]*umask[ \t]+[0-7]+' $i |
374 1.63 lukem awk '{
375 1.67 lukem if ($2 ~ /^.$/ || $2 ~! /[^2367].$/) {
376 1.80 wiz print "\tRoot umask is group writable"
377 1.63 lukem }
378 1.67 lukem if ($2 ~ /[^2367]$/) {
379 1.80 wiz print "\tRoot umask is other writable"
380 1.63 lukem }
381 1.67 lukem }' | sort -u
382 1.26 lukem SAVE_PATH=$PATH
383 1.26 lukem unset PATH
384 1.15 mrg /bin/csh -f -s << end-of-csh > /dev/null 2>&1
385 1.15 mrg source $i
386 1.15 mrg /bin/ls -ldgT \$path > $TMP1
387 1.9 cgd end-of-csh
388 1.76 atatat export PATH=$SAVE_PATH
389 1.15 mrg awk '{
390 1.15 mrg if ($10 ~ /^\.$/) {
391 1.27 lukem print "\tThe root path includes .";
392 1.15 mrg next;
393 1.15 mrg }
394 1.15 mrg }
395 1.15 mrg $1 ~ /^d....w/ \
396 1.80 wiz { print "\tRoot path directory " $10 " is group writable." } \
397 1.15 mrg $1 ~ /^d.......w/ \
398 1.80 wiz { print "\tRoot path directory " $10 " is other writable." }' \
399 1.67 lukem < $TMP1
400 1.15 mrg fi
401 1.67 lukem done > $OUTPUT
402 1.124 kre if [ $umaskset = no ] || [ -s $OUTPUT ] ; then
403 1.27 lukem printf "\nChecking root csh paths, umask values:\n$list\n\n"
404 1.15 mrg if [ -s $OUTPUT ]; then
405 1.15 mrg cat $OUTPUT
406 1.15 mrg fi
407 1.123 kre if [ $umaskset = no ] ; then
408 1.27 lukem printf "\tRoot csh startup files do not set the umask.\n"
409 1.15 mrg fi
410 1.9 cgd fi
411 1.9 cgd
412 1.15 mrg umaskset=no
413 1.23 lukem list="/etc/profile ${rhome}/.profile"
414 1.15 mrg for i in $list; do
415 1.15 mrg if [ -f $i ] ; then
416 1.15 mrg if egrep umask $i > /dev/null ; then
417 1.15 mrg umaskset=yes
418 1.15 mrg fi
419 1.15 mrg egrep umask $i |
420 1.67 lukem awk '$2 ~ /^.$/ || $2 ~ /[^2367].$/ \
421 1.80 wiz { print "\tRoot umask is group writable" } \
422 1.67 lukem $2 ~ /[^2367]$/ \
423 1.80 wiz { print "\tRoot umask is other writable" }'
424 1.26 lukem SAVE_PATH=$PATH
425 1.26 lukem unset PATH
426 1.15 mrg /bin/sh << end-of-sh > /dev/null 2>&1
427 1.15 mrg . $i
428 1.110 christos list=\$(echo \$PATH | /usr/bin/sed -e \
429 1.110 christos 's/^:/.:/;s/:$/:./;s/::/:.:/g;s/:/ /g')
430 1.15 mrg /bin/ls -ldgT \$list > $TMP1
431 1.9 cgd end-of-sh
432 1.76 atatat export PATH=$SAVE_PATH
433 1.15 mrg awk '{
434 1.15 mrg if ($10 ~ /^\.$/) {
435 1.27 lukem print "\tThe root path includes .";
436 1.15 mrg next;
437 1.15 mrg }
438 1.15 mrg }
439 1.15 mrg $1 ~ /^d....w/ \
440 1.80 wiz { print "\tRoot path directory " $10 " is group writable." } \
441 1.15 mrg $1 ~ /^d.......w/ \
442 1.80 wiz { print "\tRoot path directory " $10 " is other writable." }' \
443 1.67 lukem < $TMP1
444 1.9 cgd
445 1.15 mrg fi
446 1.67 lukem done > $OUTPUT
447 1.123 kre if [ $umaskset = no ] || [ -s $OUTPUT ] ; then
448 1.15 mrg printf "\nChecking root sh paths, umask values:\n$list\n"
449 1.15 mrg if [ -s $OUTPUT ]; then
450 1.15 mrg cat $OUTPUT
451 1.15 mrg fi
452 1.123 kre if [ $umaskset = no ] ; then
453 1.27 lukem printf "\tRoot sh startup files do not set the umask.\n"
454 1.15 mrg fi
455 1.9 cgd fi
456 1.9 cgd fi
457 1.9 cgd
458 1.9 cgd # Root and uucp should both be in /etc/ftpusers.
459 1.32 lukem #
460 1.31 lukem if checkyesno check_ftpusers; then
461 1.109 christos list="uucp "$(awk '$2 == 0 { print $1 }' $MPBYUID)
462 1.27 lukem for i in $list; do
463 1.29 lukem if /usr/libexec/ftpd -C $i ; then
464 1.67 lukem printf "\t$i is not denied\n"
465 1.27 lukem fi
466 1.67 lukem done > $OUTPUT
467 1.28 lukem if [ -s $OUTPUT ]; then
468 1.28 lukem printf "\nChecking the /etc/ftpusers configuration:\n"
469 1.28 lukem cat $OUTPUT
470 1.28 lukem fi
471 1.9 cgd fi
472 1.9 cgd
473 1.43 itojun # Uudecode should not be in the /etc/mail/aliases file.
474 1.32 lukem #
475 1.31 lukem if checkyesno check_aliases; then
476 1.43 itojun for f in /etc/mail/aliases /etc/aliases; do
477 1.43 itojun if [ -f $f ] && egrep '^[^#]*(uudecode|decode).*\|' $f; then
478 1.43 itojun printf "\nEntry for uudecode in $f file.\n"
479 1.43 itojun fi
480 1.43 itojun done
481 1.9 cgd fi
482 1.9 cgd
483 1.9 cgd # Files that should not have + signs.
484 1.32 lukem #
485 1.31 lukem if checkyesno check_rhosts; then
486 1.15 mrg list="/etc/hosts.equiv /etc/hosts.lpd"
487 1.15 mrg for f in $list ; do
488 1.15 mrg if [ -f $f ] && egrep '\+' $f > /dev/null ; then
489 1.15 mrg printf "\nPlus sign in $f file.\n"
490 1.15 mrg fi
491 1.15 mrg done
492 1.15 mrg
493 1.15 mrg # Check for special users with .rhosts files. Only root and toor should
494 1.16 mikel # have .rhosts files. Also, .rhosts files should not have plus signs.
495 1.15 mrg awk -F: '$1 != "root" && $1 != "toor" && \
496 1.15 mrg ($3 < 100 || $1 == "ftp" || $1 == "uucp") \
497 1.20 mycroft { print $1 " " $9 }' $MP |
498 1.19 mycroft sort -k2 |
499 1.15 mrg while read uid homedir; do
500 1.15 mrg if [ -f ${homedir}/.rhosts ] ; then
501 1.109 christos rhost=$(ls -ldgT ${homedir}/.rhosts)
502 1.46 christos printf -- "$uid: $rhost\n"
503 1.15 mrg fi
504 1.15 mrg done > $OUTPUT
505 1.15 mrg if [ -s $OUTPUT ] ; then
506 1.15 mrg printf "\nChecking for special users with .rhosts files.\n"
507 1.15 mrg cat $OUTPUT
508 1.15 mrg fi
509 1.15 mrg
510 1.15 mrg while read uid homedir; do
511 1.123 kre if [ -f ${homedir}/.rhosts ] &&
512 1.123 kre [ -r ${homedir}/.rhosts ] &&
513 1.123 kre cat -f ${homedir}/.rhosts | egrep '\+' > /dev/null
514 1.123 kre then
515 1.46 christos printf -- "$uid: + in .rhosts file.\n"
516 1.15 mrg fi
517 1.29 lukem done < $MPBYPATH > $OUTPUT
518 1.15 mrg if [ -s $OUTPUT ] ; then
519 1.15 mrg printf "\nChecking .rhosts files syntax.\n"
520 1.15 mrg cat $OUTPUT
521 1.15 mrg fi
522 1.9 cgd fi
523 1.9 cgd
524 1.9 cgd # Check home directories. Directories should not be owned by someone else
525 1.80 wiz # or writable.
526 1.32 lukem #
527 1.31 lukem if checkyesno check_homes; then
528 1.85 jhawk checkyesno check_homes_permit_usergroups && \
529 1.85 jhawk permit_usergroups=1 || permit_usergroups=0
530 1.15 mrg while read uid homedir; do
531 1.15 mrg if [ -d ${homedir}/ ] ; then
532 1.109 christos file=$(ls -ldgT ${homedir})
533 1.46 christos printf -- "$uid $file\n"
534 1.9 cgd fi
535 1.29 lukem done < $MPBYPATH |
536 1.115 spz awk -v "usergroups=$permit_usergroups" \
537 1.118 uebayasi -v "permit_owners_list=$check_homes_permit_other_owner" '
538 1.115 spz BEGIN {
539 1.115 spz split(permit_owners_list, a);
540 1.115 spz for (i in a) permit_owners[a[i]]++;
541 1.115 spz }
542 1.115 spz $1 != $4 && $4 != "root" && !permit_owners[$1] \
543 1.15 mrg { print "user " $1 " home directory is owned by " $4 }
544 1.101 jnemeth $2 ~ /^d....w/ && (!usergroups || $5 != $1) \
545 1.80 wiz { print "user " $1 " home directory is group writable" }
546 1.101 jnemeth $2 ~ /^d.......w/ \
547 1.80 wiz { print "user " $1 " home directory is other writable" }' \
548 1.27 lukem > $OUTPUT
549 1.15 mrg if [ -s $OUTPUT ] ; then
550 1.15 mrg printf "\nChecking home directories.\n"
551 1.15 mrg cat $OUTPUT
552 1.15 mrg fi
553 1.15 mrg
554 1.15 mrg # Files that should not be owned by someone else or readable.
555 1.67 lukem list=".Xauthority .netrc .ssh/id_dsa .ssh/id_rsa .ssh/identity"
556 1.15 mrg while read uid homedir; do
557 1.15 mrg for f in $list ; do
558 1.15 mrg file=${homedir}/${f}
559 1.15 mrg if [ -f $file ] ; then
560 1.109 christos printf -- "$uid $f $(ls -ldgT $file)\n"
561 1.15 mrg fi
562 1.15 mrg done
563 1.29 lukem done < $MPBYPATH |
564 1.115 spz awk -v "usergroups=$permit_usergroups" \
565 1.118 uebayasi -v "permit_owners_list=$check_homes_permit_other_owner" '
566 1.115 spz BEGIN {
567 1.115 spz split(permit_owners_list, a);
568 1.115 spz for (i in a) permit_owners[a[i]]++;
569 1.115 spz }
570 1.115 spz $1 != $5 && $5 != "root" && !permit_owners[$1] \
571 1.15 mrg { print "user " $1 " " $2 " file is owned by " $5 }
572 1.85 jhawk $3 ~ /^-...r/ && (!usergroups || $6 != $1) \
573 1.15 mrg { print "user " $1 " " $2 " file is group readable" }
574 1.15 mrg $3 ~ /^-......r/ \
575 1.15 mrg { print "user " $1 " " $2 " file is other readable" }
576 1.85 jhawk $3 ~ /^-....w/ && (!usergroups || $6 != $1) \
577 1.80 wiz { print "user " $1 " " $2 " file is group writable" }
578 1.15 mrg $3 ~ /^-.......w/ \
579 1.80 wiz { print "user " $1 " " $2 " file is other writable" }' \
580 1.27 lukem > $OUTPUT
581 1.15 mrg
582 1.80 wiz # Files that should not be owned by someone else or writable.
583 1.19 mycroft list=".bash_history .bash_login .bash_logout .bash_profile .bashrc \
584 1.79 elric .cshrc .emacs .exrc .forward .history .k5login .klogin .login \
585 1.79 elric .logout .profile .qmail .rc_history .rhosts .shosts ssh .tcshrc \
586 1.79 elric .twmrc .xinitrc .xsession .ssh/authorized_keys \
587 1.79 elric .ssh/authorized_keys2 .ssh/config .ssh/id_dsa.pub \
588 1.79 elric .ssh/id_rsa.pub .ssh/identity.pub .ssh/known_hosts \
589 1.79 elric .ssh/known_hosts2"
590 1.15 mrg while read uid homedir; do
591 1.15 mrg for f in $list ; do
592 1.15 mrg file=${homedir}/${f}
593 1.15 mrg if [ -f $file ] ; then
594 1.109 christos printf -- "$uid $f $(ls -ldgT $file)\n"
595 1.15 mrg fi
596 1.15 mrg done
597 1.29 lukem done < $MPBYPATH |
598 1.115 spz awk -v "usergroups=$permit_usergroups" \
599 1.118 uebayasi -v "permit_owners_list=$check_homes_permit_other_owner" '
600 1.115 spz BEGIN {
601 1.115 spz split(permit_owners_list, a);
602 1.115 spz for (i in a) permit_owners[a[i]]++;
603 1.115 spz }
604 1.115 spz $1 != $5 && $5 != "root" && !permit_owners[$1] \
605 1.15 mrg { print "user " $1 " " $2 " file is owned by " $5 }
606 1.85 jhawk $3 ~ /^-....w/ && (!usergroups || $6 != $1) \
607 1.80 wiz { print "user " $1 " " $2 " file is group writable" }
608 1.15 mrg $3 ~ /^-.......w/ \
609 1.80 wiz { print "user " $1 " " $2 " file is other writable" }' \
610 1.27 lukem >> $OUTPUT
611 1.15 mrg if [ -s $OUTPUT ] ; then
612 1.15 mrg printf "\nChecking dot files.\n"
613 1.15 mrg cat $OUTPUT
614 1.15 mrg fi
615 1.9 cgd fi
616 1.9 cgd
617 1.9 cgd # Mailboxes should be owned by user and unreadable.
618 1.32 lukem #
619 1.31 lukem if checkyesno check_varmail; then
620 1.86 jhawk ls -lA /var/mail | \
621 1.63 lukem awk ' NR == 1 { next; }
622 1.86 jhawk $9 ~ /^\./ {next; }
623 1.63 lukem $3 != $9 {
624 1.63 lukem print "user " $9 " mailbox is owned by " $3
625 1.63 lukem }
626 1.63 lukem $1 != "-rw-------" {
627 1.63 lukem print "user " $9 " mailbox is " $1 ", group " $4
628 1.63 lukem }' > $OUTPUT
629 1.15 mrg if [ -s $OUTPUT ] ; then
630 1.15 mrg printf "\nChecking mailbox ownership.\n"
631 1.15 mrg cat $OUTPUT
632 1.15 mrg fi
633 1.15 mrg fi
634 1.15 mrg
635 1.32 lukem # NFS exports shouldn't be globally exported
636 1.32 lukem #
637 1.32 lukem if checkyesno check_nfs && [ -f /etc/exports ]; then
638 1.32 lukem awk '{
639 1.22 lukem # ignore comments and blank lines
640 1.39 hubertf if ($0 ~ /^\#/ || $0 ~ /^$/ )
641 1.22 lukem next;
642 1.100 tron # manage line continuation
643 1.100 tron while ($NF ~ /^\\$/) {
644 1.100 tron $NF = "";
645 1.100 tron line = $0 "";
646 1.100 tron getline;
647 1.100 tron $0 = line $0 "";
648 1.100 tron }
649 1.22 lukem
650 1.100 tron delete dir;
651 1.100 tron readonly = ndir = 0;
652 1.100 tron for (i = 1; i <= NF; ++i) {
653 1.100 tron if ($i ~ /^\//) dir[ndir++] = $i;
654 1.100 tron else if ($i ~ /^-/) {
655 1.100 tron if ($i ~ /^-(ro|o)$/) readonly = 1;
656 1.100 tron if ($i ~ /^-network/) next;
657 1.100 tron }
658 1.100 tron else next;
659 1.15 mrg }
660 1.15 mrg if (readonly)
661 1.100 tron for (item in dir)
662 1.100 tron rodir[nrodir++] = dir[item];
663 1.15 mrg else
664 1.100 tron for (item in dir)
665 1.100 tron rwdir[nrwdir++] = dir[item];
666 1.100 tron
667 1.100 tron }
668 1.100 tron
669 1.100 tron END {
670 1.100 tron if (nrodir) {
671 1.100 tron printf("Globally exported file system%s, read-only:\n",
672 1.100 tron nrodir > 1 ? "s" : "");
673 1.100 tron for (item in rodir)
674 1.100 tron printf("\t%s\n", rodir[item]);
675 1.100 tron }
676 1.100 tron if (nrwdir) {
677 1.100 tron printf("Globally exported file system%s, read-write:\n",
678 1.100 tron nrwdir > 1 ? "s" : "");
679 1.100 tron for (item in rwdir)
680 1.100 tron printf("\t%s\n", rwdir[item]);
681 1.100 tron }
682 1.32 lukem }' < /etc/exports > $OUTPUT
683 1.32 lukem if [ -s $OUTPUT ] ; then
684 1.15 mrg printf "\nChecking for globally exported file systems.\n"
685 1.15 mrg cat $OUTPUT
686 1.15 mrg fi
687 1.9 cgd fi
688 1.9 cgd
689 1.9 cgd # Display any changes in setuid files and devices.
690 1.32 lukem #
691 1.31 lukem if checkyesno check_devices; then
692 1.28 lukem > $ERR
693 1.92 erh (
694 1.98 lukem
695 1.98 lukem # Convert check_devices_ignore_fstypes="foo !bar bax"
696 1.98 lukem # into "-fstype foo -o ! -fstype bar -o -fstype bax"
697 1.98 lukem # and check_devices_ignore_paths="/foo !/bar /bax"
698 1.98 lukem # into " -path /foo -o ! -path /bar -o -path /bax"
699 1.98 lukem #
700 1.98 lukem ignexpr=$(\
701 1.98 lukem echo $check_devices_ignore_fstypes | \
702 1.98 lukem sed -e's/\(!*\)\([^[:space:]]\{1,\}\)/-o \1 -fstype \2/g' ; \
703 1.98 lukem echo $check_devices_ignore_paths | \
704 1.98 lukem sed -e's/\(!*\)\([^[:space:]]\{1,\}\)/-o \1 -path \2/g' \
705 1.98 lukem )
706 1.98 lukem
707 1.98 lukem # Massage the expression into ( $ignexpr ) -a -prune -o
708 1.98 lukem if [ -n "${ignexpr}" ]; then
709 1.98 lukem ignexpr=$(\
710 1.98 lukem echo $ignexpr | \
711 1.98 lukem sed -e 's/^-o /( /' \
712 1.98 lukem -e 's/$/ ) -a -prune -o/' \
713 1.98 lukem )
714 1.98 lukem fi
715 1.98 lukem
716 1.98 lukem find / $ignexpr \
717 1.21 mycroft \( \( -perm -u+s -a ! -type d \) -o \
718 1.21 mycroft \( -perm -g+s -a ! -type d \) -o \
719 1.24 lukem -type b -o -type c \) -print0 | \
720 1.98 lukem xargs -0 ls -ldgTq | sort +9 > $LIST
721 1.98 lukem
722 1.98 lukem ) 2> $OUTPUT
723 1.15 mrg
724 1.15 mrg # Display any errors that occurred during system file walk.
725 1.15 mrg if [ -s $OUTPUT ] ; then
726 1.28 lukem printf "Setuid/device find errors:\n" >> $ERR
727 1.28 lukem cat $OUTPUT >> $ERR
728 1.28 lukem printf "\n" >> $ERR
729 1.15 mrg fi
730 1.15 mrg
731 1.15 mrg # Display any changes in the setuid file list.
732 1.15 mrg egrep -v '^[bc]' $LIST > $TMP1
733 1.15 mrg if [ -s $TMP1 ] ; then
734 1.15 mrg # Check to make sure uudecode isn't setuid.
735 1.15 mrg if grep -w uudecode $TMP1 > /dev/null ; then
736 1.28 lukem printf "\nUudecode is setuid.\n" >> $ERR
737 1.15 mrg fi
738 1.15 mrg
739 1.67 lukem file=$work_dir/setuid
740 1.67 lukem migrate_file "$backup_dir/setuid" "$file"
741 1.67 lukem CUR=${file}.current
742 1.67 lukem BACK=${file}.backup
743 1.15 mrg if [ -s $CUR ] ; then
744 1.15 mrg if cmp -s $CUR $TMP1 ; then
745 1.15 mrg :
746 1.15 mrg else
747 1.15 mrg > $TMP2
748 1.15 mrg join -110 -210 -v2 $CUR $TMP1 > $OUTPUT
749 1.15 mrg if [ -s $OUTPUT ] ; then
750 1.28 lukem printf "Setuid additions:\n" >> $ERR
751 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
752 1.28 lukem printf "\n" >> $ERR
753 1.15 mrg fi
754 1.15 mrg
755 1.15 mrg join -110 -210 -v1 $CUR $TMP1 > $OUTPUT
756 1.15 mrg if [ -s $OUTPUT ] ; then
757 1.28 lukem printf "Setuid deletions:\n" >> $ERR
758 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
759 1.28 lukem printf "\n" >> $ERR
760 1.15 mrg fi
761 1.15 mrg
762 1.20 mycroft sort -k10 $TMP2 $CUR $TMP1 | \
763 1.27 lukem sed -e 's/[ ][ ]*/ /g' | \
764 1.27 lukem uniq -u > $OUTPUT
765 1.15 mrg if [ -s $OUTPUT ] ; then
766 1.28 lukem printf "Setuid changes:\n" >> $ERR
767 1.28 lukem column -t $OUTPUT >> $ERR
768 1.28 lukem printf "\n" >> $ERR
769 1.15 mrg fi
770 1.9 cgd
771 1.52 atatat backup_file update $TMP1 $CUR $BACK
772 1.9 cgd fi
773 1.15 mrg else
774 1.28 lukem printf "Setuid additions:\n" >> $ERR
775 1.28 lukem column -t $TMP1 >> $ERR
776 1.28 lukem printf "\n" >> $ERR
777 1.52 atatat backup_file add $TMP1 $CUR $BACK
778 1.9 cgd fi
779 1.15 mrg fi
780 1.15 mrg
781 1.27 lukem # Check for block and character disk devices that are readable or
782 1.80 wiz # writable or not owned by root.operator.
783 1.15 mrg >$TMP1
784 1.61 lukem DISKLIST="ccd ch hk hp ld md ra raid rb rd rl rx \
785 1.57 simonb sd se ss uk up vnd wd xd xy"
786 1.27 lukem # DISKLIST="$DISKLIST ct mt st wt"
787 1.15 mrg for i in $DISKLIST; do
788 1.15 mrg egrep "^b.*/${i}[0-9][0-9]*[a-p]$" $LIST >> $TMP1
789 1.15 mrg egrep "^c.*/r${i}[0-9][0-9]*[a-p]$" $LIST >> $TMP1
790 1.15 mrg done
791 1.15 mrg
792 1.15 mrg awk '$3 != "root" || $4 != "operator" || $1 !~ /.rw-r-----/ \
793 1.25 lukem { printf "Disk %s is user %s, group %s, permissions %s.\n", \
794 1.25 lukem $11, $3, $4, $1; }' < $TMP1 > $OUTPUT
795 1.15 mrg if [ -s $OUTPUT ] ; then
796 1.28 lukem printf "\nChecking disk ownership and permissions.\n" >> $ERR
797 1.28 lukem cat $OUTPUT >> $ERR
798 1.28 lukem printf "\n" >> $ERR
799 1.9 cgd fi
800 1.9 cgd
801 1.15 mrg # Display any changes in the device file list.
802 1.20 mycroft egrep '^[bc]' $LIST | sort -k11 > $TMP1
803 1.15 mrg if [ -s $TMP1 ] ; then
804 1.67 lukem file=$work_dir/device
805 1.67 lukem migrate_file "$backup_dir/device" "$file"
806 1.67 lukem CUR=${file}.current
807 1.67 lukem BACK=${file}.backup
808 1.15 mrg
809 1.15 mrg if [ -s $CUR ] ; then
810 1.15 mrg if cmp -s $CUR $TMP1 ; then
811 1.15 mrg :
812 1.15 mrg else
813 1.15 mrg > $TMP2
814 1.15 mrg join -111 -211 -v2 $CUR $TMP1 > $OUTPUT
815 1.15 mrg if [ -s $OUTPUT ] ; then
816 1.28 lukem printf "Device additions:\n" >> $ERR
817 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
818 1.28 lukem printf "\n" >> $ERR
819 1.15 mrg fi
820 1.15 mrg
821 1.15 mrg join -111 -211 -v1 $CUR $TMP1 > $OUTPUT
822 1.15 mrg if [ -s $OUTPUT ] ; then
823 1.28 lukem printf "Device deletions:\n" >> $ERR
824 1.28 lukem tee -a $TMP2 < $OUTPUT >> $ERR
825 1.28 lukem printf "\n" >> $ERR
826 1.15 mrg fi
827 1.15 mrg
828 1.27 lukem # Report any block device change. Ignore
829 1.27 lukem # character devices, only the name is
830 1.27 lukem # significant.
831 1.15 mrg cat $TMP2 $CUR $TMP1 | \
832 1.27 lukem sed -e '/^c/d' | \
833 1.27 lukem sort -k11 | \
834 1.27 lukem sed -e 's/[ ][ ]*/ /g' | \
835 1.27 lukem uniq -u > $OUTPUT
836 1.15 mrg if [ -s $OUTPUT ] ; then
837 1.28 lukem printf "Block device changes:\n" >> $ERR
838 1.28 lukem column -t $OUTPUT >> $ERR
839 1.28 lukem printf "\n" >> $ERR
840 1.15 mrg fi
841 1.9 cgd
842 1.52 atatat backup_file update $TMP1 $CUR $BACK
843 1.9 cgd fi
844 1.15 mrg else
845 1.28 lukem printf "Device additions:\n" >> $ERR
846 1.28 lukem column -t $TMP1 >> $ERR
847 1.28 lukem printf "\n" >> $ERR
848 1.52 atatat backup_file add $TMP1 $CUR $BACK >> $ERR
849 1.9 cgd fi
850 1.28 lukem fi
851 1.28 lukem if [ -s $ERR ] ; then
852 1.28 lukem printf "\nChecking setuid files and devices:\n"
853 1.28 lukem cat $ERR
854 1.28 lukem printf "\n"
855 1.9 cgd fi
856 1.9 cgd fi
857 1.9 cgd
858 1.9 cgd # Check special files.
859 1.9 cgd # Check system binaries.
860 1.9 cgd #
861 1.9 cgd # Create the mtree tree specifications using:
862 1.67 lukem # mtree -cx -pDIR -kmd5,uid,gid,mode,nlink,size,link,time > DIR.secure
863 1.38 kleink # chown root:wheel DIR.secure
864 1.67 lukem # chmod u+r,go= DIR.secure
865 1.9 cgd #
866 1.9 cgd # Note, this is not complete protection against Trojan horsed binaries, as
867 1.9 cgd # the hacker can modify the tree specification to match the replaced binary.
868 1.9 cgd # For details on really protecting yourself against modified binaries, see
869 1.9 cgd # the mtree(8) manual page.
870 1.32 lukem #
871 1.31 lukem if checkyesno check_mtree; then
872 1.82 jhawk if checkyesno check_mtree_follow_symlinks; then
873 1.82 jhawk check_mtree_flags="-L"
874 1.82 jhawk else
875 1.82 jhawk check_mtree_flags=""
876 1.82 jhawk fi
877 1.91 lukem mtree -e -l -p / $check_mtree_flags -f $SPECIALSPEC 3>&1 >$OUTPUT 2>&3 |
878 1.87 jhawk grep -v '^mtree: dev/tty: Device not configured$' >&2
879 1.15 mrg if [ -s $OUTPUT ]; then
880 1.9 cgd printf "\nChecking special files and directories.\n"
881 1.9 cgd cat $OUTPUT
882 1.9 cgd fi
883 1.9 cgd
884 1.16 mikel for file in /etc/mtree/*.secure; do
885 1.16 mikel [ $file = '/etc/mtree/*.secure' ] && continue
886 1.109 christos tree=$(sed -n -e '3s/.* //p' -e 3q $file)
887 1.82 jhawk mtree $check_mtree_flags -f $file -p $tree > $TMP1
888 1.9 cgd if [ -s $TMP1 ]; then
889 1.67 lukem printf "\nChecking $tree:\n"
890 1.67 lukem cat $TMP1
891 1.9 cgd fi
892 1.67 lukem done > $OUTPUT
893 1.15 mrg if [ -s $OUTPUT ]; then
894 1.9 cgd printf "\nChecking system binaries:\n"
895 1.9 cgd cat $OUTPUT
896 1.9 cgd fi
897 1.9 cgd fi
898 1.9 cgd
899 1.32 lukem # Backup disklabels of available disks
900 1.32 lukem #
901 1.32 lukem if checkyesno check_disklabels; then
902 1.67 lukem # migrate old disklabels
903 1.109 christos for file in $(ls -1d $backup_dir/$backup_dir/disklabel.* \
904 1.109 christos $backup_dir/disklabel.* 2>/dev/null); do
905 1.67 lukem migrate_file "$file" "$work_dir/${file##*/}"
906 1.67 lukem done
907 1.67 lukem
908 1.116 apb # generate list of old disklabels, fdisks & wedges,
909 1.116 apb # and remove them
910 1.116 apb ls -1d $work_dir/disklabel.* $work_dir/fdisk.* $work_dir/wedges.* \
911 1.116 apb 2>/dev/null |
912 1.52 atatat egrep -v '\.(backup|current)(,v)?$' > $LABELS
913 1.32 lukem xargs rm < $LABELS
914 1.32 lukem
915 1.122 mlelstv disks="$(/sbin/sysctl -n hw.iostatnames)"
916 1.117 christos
917 1.117 christos # generate disklabels of all disks excluding: cd fd md dk st
918 1.117 christos # nfs and "device" (the header of iostat)
919 1.32 lukem for i in $disks; do
920 1.117 christos case $i in
921 1.122 mlelstv [cfm]d[0-9]*|dk[0-9]*|st[0-9]*|nfs[0-9]*)
922 1.117 christos ;;
923 1.117 christos *)
924 1.120 pgoyette if disklabel $i > /dev/null 2>&1; then
925 1.117 christos disklabel $i > "$work_dir/disklabel.$i"
926 1.117 christos fi
927 1.117 christos ;;
928 1.117 christos esac
929 1.32 lukem done
930 1.32 lukem
931 1.67 lukem # if fdisk is available, generate fdisks for: ed ld sd wd
932 1.67 lukem if [ -x /sbin/fdisk ]; then
933 1.67 lukem for i in $disks; do
934 1.117 christos case $i in
935 1.117 christos [elsw]d[0-9]*)
936 1.117 christos /sbin/fdisk $i > "$work_dir/fdisk.$i" \
937 1.117 christos 2>/dev/null
938 1.117 christos ;;
939 1.117 christos esac
940 1.67 lukem done
941 1.67 lukem fi
942 1.67 lukem
943 1.116 apb # if dkctl is available, generate dkctl listwedges
944 1.116 apb # for: ed ld sd wd cgd ofdisk ra rl raid
945 1.103 tron if [ -x /sbin/dkctl ]; then
946 1.103 tron for i in $disks; do
947 1.117 christos case $i in
948 1.117 christos [elsw]d[0-9]*|cgd[0-9]*|ofdisk[0-9]*|r[al][0-9]*|raid[0-9]*)
949 1.122 mlelstv if /sbin/dkctl $i listwedges |
950 1.122 mlelstv grep -qe '[0-9] wedges:'; then
951 1.117 christos /sbin/dkctl $i listwedges \
952 1.117 christos > "$work_dir/wedges.$i" 2>/dev/null
953 1.117 christos fi
954 1.117 christos ;;
955 1.117 christos esac
956 1.103 tron done
957 1.103 tron fi
958 1.103 tron
959 1.121 riastrad # if raidctl is available, generate raidctls for: raid
960 1.121 riastrad if [ -x /sbin/raidctl ]; then
961 1.121 riastrad disks=$(iostat -x | awk 'NR > 1 && $1 ~ /^raid/ { print $1; }')
962 1.121 riastrad for i in $disks; do
963 1.121 riastrad /sbin/raidctl -G $i > "$work_dir/raidconf.$i" \
964 1.121 riastrad 2>/dev/null
965 1.121 riastrad done
966 1.121 riastrad fi
967 1.121 riastrad
968 1.103 tron # append list of new disklabels, fdisks and wedges
969 1.116 apb ls -1d $work_dir/disklabel.* $work_dir/fdisk.* $work_dir/wedges.* \
970 1.121 riastrad $work_dir/raidconf.* 2>/dev/null |
971 1.52 atatat egrep -v '\.(backup|current)(,v)?$' >> $LABELS
972 1.62 atatat CHANGELIST="$LABELS $CHANGELIST"
973 1.62 atatat fi
974 1.62 atatat
975 1.106 haad if checkyesno check_lvm; then
976 1.118 uebayasi # generate list of existing LVM elements Physical Volumes,
977 1.118 uebayasi # Volume Groups and Logical Volumes.
978 1.118 uebayasi if [ -x /sbin/lvm ]; then
979 1.118 uebayasi lvm pvdisplay -m >"$work_dir/lvm.pv" 2>/dev/null
980 1.118 uebayasi lvm vgdisplay -m >"$work_dir/lvm.vg" 2>/dev/null
981 1.118 uebayasi lvm lvdisplay -m >"$work_dir/lvm.lv" 2>/dev/null
982 1.118 uebayasi fi
983 1.118 uebayasi ls -1d $work_dir/lvm.* 2>/dev/null |
984 1.118 uebayasi egrep -v '\.(backup|current)(,v)?$'>> $LVM_LABELS
985 1.118 uebayasi CHANGELIST="$CHANGELIST $LVM_LABELS"
986 1.106 haad fi
987 1.106 haad
988 1.62 atatat # Check for changes in the list of installed pkgs
989 1.62 atatat #
990 1.108 jmmv if checkyesno check_pkgs && have_pkgs; then
991 1.67 lukem pkgs=$work_dir/pkgs
992 1.67 lukem migrate_file "$backup_dir/pkgs" "$pkgs"
993 1.112 agc pkg_dbdir=$(${pkg_admin} config-var PKG_DBDIR)
994 1.108 jmmv : ${pkg_dbdir:=/var/db/pkg}
995 1.108 jmmv ( cd $pkg_dbdir
996 1.104 adrianp $pkg_info | sort
997 1.62 atatat echo ""
998 1.62 atatat find . \( -name +REQUIRED_BY -o -name +CONTENTS \) -print0 |
999 1.72 lukem xargs -0 ls -ldgTq | sort -t. +1 | sed -e 's, \./, ,'
1000 1.62 atatat ) > $pkgs
1001 1.67 lukem echo "$pkgs" > $PKGS
1002 1.62 atatat CHANGELIST="$PKGS $CHANGELIST"
1003 1.32 lukem fi
1004 1.32 lukem
1005 1.67 lukem # List of files that get backed up and checked for any modifications.
1006 1.9 cgd # Any changes cause the files to rotate.
1007 1.32 lukem #
1008 1.67 lukem if checkyesno check_changelist ; then
1009 1.91 lukem mtree -D -k type -f $SPECIALSPEC -E exclude |
1010 1.91 lukem sed '/^type=file/!d ; s/type=file \.//' | unvis > $CHANGEFILES
1011 1.67 lukem
1012 1.75 lukem (
1013 1.68 lukem # Add other files which might dynamically exist:
1014 1.67 lukem # /etc/ifconfig.*
1015 1.67 lukem # /etc/raid*.conf
1016 1.68 lukem # /etc/rc.d/*
1017 1.67 lukem # /etc/rc.conf.d/*
1018 1.68 lukem #
1019 1.75 lukem echo "/etc/ifconfig.*"
1020 1.75 lukem echo "/etc/raid*.conf"
1021 1.75 lukem echo "/etc/rc.d/*"
1022 1.75 lukem echo "/etc/rc.conf.d/*"
1023 1.106 haad echo "/etc/lvm/backup/*"
1024 1.106 haad echo "/etc/lvm/archive/*"
1025 1.67 lukem
1026 1.68 lukem # Add /etc/changelist
1027 1.68 lukem #
1028 1.75 lukem if [ -s /etc/changelist ]; then
1029 1.75 lukem grep -v '^#' /etc/changelist
1030 1.75 lukem fi
1031 1.75 lukem ) | while read file; do
1032 1.75 lukem case "$file" in
1033 1.75 lukem *[\*\?\[]*) # If changelist line is a glob ...
1034 1.75 lukem # ... expand possible backup files
1035 1.75 lukem #
1036 1.125 uwe ls -1d $backup_dir/${file}.current 2>/dev/null \
1037 1.75 lukem | sed "s,^$backup_dir/,, ; s,\.current$,,"
1038 1.118 uebayasi
1039 1.75 lukem # ... expand possible files
1040 1.75 lukem #
1041 1.125 uwe ls -1d $file 2>/dev/null
1042 1.75 lukem ;;
1043 1.75 lukem *)
1044 1.75 lukem # Otherwise, just print the filename
1045 1.75 lukem echo $file
1046 1.75 lukem ;;
1047 1.75 lukem esac
1048 1.75 lukem done >> $CHANGEFILES
1049 1.67 lukem CHANGELIST="$CHANGEFILES $CHANGELIST"
1050 1.67 lukem fi
1051 1.67 lukem
1052 1.67 lukem # Special case backups, including the master password file and
1053 1.67 lukem # ssh private host keys. The normal backup mechanisms for
1054 1.67 lukem # $check_changelist (see below) also print out the actual file
1055 1.67 lukem # differences and we don't want to do that for these files
1056 1.67 lukem #
1057 1.67 lukem echo $MP > $TMP1 # always add /etc/master.passwd
1058 1.91 lukem mtree -D -k type -f $SPECIALSPEC -I nodiff |
1059 1.91 lukem sed '/^type=file/!d ; s/type=file \.//' | unvis >> $TMP1
1060 1.73 lukem grep -v '^$' $TMP1 | sort -u > $TMP2
1061 1.68 lukem
1062 1.69 lukem while read file; do
1063 1.67 lukem backup_and_diff "$file" no
1064 1.69 lukem done < $TMP2
1065 1.67 lukem
1066 1.32 lukem
1067 1.32 lukem if [ -n "$CHANGELIST" ]; then
1068 1.73 lukem grep -h -v '^$' $CHANGELIST | sort -u > $TMP1
1069 1.68 lukem comm -23 $TMP1 $TMP2 | while read file; do
1070 1.67 lukem backup_and_diff "$file" yes
1071 1.9 cgd done
1072 1.44 ad fi
1073 1.44 ad
1074 1.108 jmmv if have_pkgs; then
1075 1.107 jmmv if checkyesno check_pkg_vulnerabilities; then
1076 1.112 agc ${pkg_admin} ${_compat_K_flag} audit >${OUTPUT} 2>&1
1077 1.107 jmmv if [ -s ${OUTPUT} ]; then
1078 1.107 jmmv printf "\nInstalled vulnerable packages:\n"
1079 1.107 jmmv cat ${OUTPUT}
1080 1.107 jmmv fi
1081 1.107 jmmv fi
1082 1.107 jmmv
1083 1.107 jmmv if checkyesno check_pkg_signatures; then
1084 1.112 agc ${pkg_admin} ${_compat_K_flag} check >${OUTPUT} 2>&1
1085 1.107 jmmv if [ $? -ne 0 ]; then
1086 1.107 jmmv printf "\nFiles with invalid signatures:\n"
1087 1.107 jmmv cat ${OUTPUT}
1088 1.107 jmmv fi
1089 1.107 jmmv fi
1090 1.107 jmmv fi
1091 1.107 jmmv
1092 1.44 ad if [ -f /etc/security.local ]; then
1093 1.90 kim . /etc/security.local > $OUTPUT 2>&1
1094 1.84 jhawk if [ -s $OUTPUT ] ; then
1095 1.84 jhawk printf "\nRunning /etc/security.local:\n"
1096 1.84 jhawk cat $OUTPUT
1097 1.84 jhawk fi
1098 1.9 cgd fi
1099