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