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