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