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