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