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