diff options
Diffstat (limited to 'usr.sbin/periodic')
67 files changed, 3912 insertions, 0 deletions
| diff --git a/usr.sbin/periodic/Makefile b/usr.sbin/periodic/Makefile new file mode 100644 index 000000000000..c71dad51baf5 --- /dev/null +++ b/usr.sbin/periodic/Makefile @@ -0,0 +1,10 @@ +PACKAGE=	periodic + +CONFS=	periodic.conf +CONFSDIR=	/etc/defaults +SCRIPTS=periodic.sh +MAN=	periodic.8 + +SUBDIR=	etc + +.include <bsd.prog.mk> diff --git a/usr.sbin/periodic/Makefile.depend b/usr.sbin/periodic/Makefile.depend new file mode 100644 index 000000000000..11aba52f82cf --- /dev/null +++ b/usr.sbin/periodic/Makefile.depend @@ -0,0 +1,10 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.sbin/periodic/etc/Makefile b/usr.sbin/periodic/etc/Makefile new file mode 100644 index 000000000000..b93d2515ccb4 --- /dev/null +++ b/usr.sbin/periodic/etc/Makefile @@ -0,0 +1,4 @@ +SUBDIR=	daily security weekly monthly +SUBDIR_PARALLEL= + +.include <bsd.subdir.mk> diff --git a/usr.sbin/periodic/etc/Makefile.inc b/usr.sbin/periodic/etc/Makefile.inc new file mode 100644 index 000000000000..4eb9943df8d2 --- /dev/null +++ b/usr.sbin/periodic/etc/Makefile.inc @@ -0,0 +1,4 @@ +CONFMODE=	755 +CONFDIR=	ETC_PERIODIC_${.CURDIR:T:U} +ETC_PERIODIC_${.CURDIR:T:U}=	/etc/periodic/${.CURDIR:T} +NO_OBJ= diff --git a/usr.sbin/periodic/etc/daily/100.clean-disks b/usr.sbin/periodic/etc/daily/100.clean-disks new file mode 100755 index 000000000000..7eedcfce6f96 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/100.clean-disks @@ -0,0 +1,54 @@ +#!/bin/sh +# +# +# Remove garbage files more than $daily_clean_disks_days days old +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_clean_disks_enable" in +    [Yy][Ee][Ss]) +	if [ -z "$daily_clean_disks_days" ] +	then +	    echo '$daily_clean_disks_enable is set but' \ +		'$daily_clean_disks_days is not' +	    rc=2 +	elif [ -z "$daily_clean_disks_files" ] +	then +	    echo '$daily_clean_disks_enable is set but' \ +		'$daily_clean_disks_files is not' +	    rc=2 +	else +	    echo "" +	    echo "Cleaning disks:" +	    set -f noglob +	    args="-name "`echo "$daily_clean_disks_files" | +		sed -e 's/^[ 	]*//' \ +		    -e 's/[ 	]*$//' \ +		    -e 's/[ 	][ 	]*/ -o -name /g'` + +	    case "$daily_clean_disks_verbose" in +		[Yy][Ee][Ss]) +		    print=-print;; +		*) +		    print=;; +	    esac + +	    rc=$(find / \( ! -fstype local -o -fstype rdonly \) -prune -o \ +		\( $args \) -atime +$daily_clean_disks_days \ +		-execdir rm -df {} \; $print | tee /dev/stderr | wc -l) +	    [ -z "$print" ] && rc=0 +	    [ $rc -gt 1 ] && rc=1 +	    set -f glob +	fi;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/110.clean-tmps b/usr.sbin/periodic/etc/daily/110.clean-tmps new file mode 100755 index 000000000000..4780aa72aa42 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/110.clean-tmps @@ -0,0 +1,59 @@ +#!/bin/sh +# +# +# Perform temporary directory cleaning so that long-lived systems +# don't end up with excessively old files there. +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_clean_tmps_enable" in +    [Yy][Ee][Ss]) +	if [ -z "$daily_clean_tmps_days" ] +	then +	    echo '$daily_clean_tmps_enable is set but' \ +		'$daily_clean_tmps_days is not' +	    rc=2 +	else +	    echo "" +	    echo "Removing old temporary files:" + +	    set -f noglob +	    args="-atime +$daily_clean_tmps_days -mtime +$daily_clean_tmps_days" +	    args="${args} -ctime +$daily_clean_tmps_days" +	    dargs="-empty -mtime +$daily_clean_tmps_days" +	    [ -n "$daily_clean_tmps_ignore" ] && { +		args="$args "`echo " ${daily_clean_tmps_ignore% }" | +		    sed 's/[ 	][ 	]*/ ! -name /g'` +		dargs="$dargs "`echo " ${daily_clean_tmps_ignore% }" | +		    sed 's/[ 	][ 	]*/ ! -name /g'` +	    } +	    case "$daily_clean_tmps_verbose" in +		[Yy][Ee][Ss]) +		    print=-print;; +		*) +		    print=;; +	    esac + +	    rc=$(for dir in $daily_clean_tmps_dirs +		do +		    [ ."${dir#/}" != ."$dir" -a -d $dir ] && cd $dir && { +			find -x -d . -type f $args -delete $print +			find -x -d . ! -name . -type d $dargs -delete $print +		    } | sed "s,^\\.,  $dir," +		done | tee /dev/stderr | wc -l) +	    [ -z "$print" ] && rc=0 +	    [ $rc -gt 1 ] && rc=1 +	    set -f glob +	fi;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/120.clean-preserve b/usr.sbin/periodic/etc/daily/120.clean-preserve new file mode 100755 index 000000000000..9c2bc86ae48a --- /dev/null +++ b/usr.sbin/periodic/etc/daily/120.clean-preserve @@ -0,0 +1,52 @@ +#!/bin/sh +# +# +# Remove stale files in /var/preserve +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_clean_preserve_enable" in +    [Yy][Ee][Ss]) +	if [ -z "$daily_clean_preserve_days" ] +	then +	    echo '$daily_clean_preserve_enable is set but' \ +		'$daily_clean_preserve_days is not' +	    rc=2 +	elif [ ! -d /var/preserve ] +	then +	    echo '$daily_clean_preserve_enable is set but /var/preserve' \ +		"doesn't exist" +	    rc=2 +	else +	    echo "" +	    echo "Removing stale files from /var/preserve:" + +	    if cd /var/preserve +	    then +		case "$daily_clean_preserve_verbose" in +		    [Yy][Ee][Ss]) +			print=-print;; +		    *) +			print=;; +		esac + +		rc=$(find . ! -name . -mtime +$daily_clean_preserve_days \ +		    -delete $print | tee /dev/stderr | wc -l) +		[ -z "$print" ] && rc=0 +		[ $rc -gt 1 ] && rc=1 +	    else +		rc=3 +	    fi +	fi;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/130.clean-msgs b/usr.sbin/periodic/etc/daily/130.clean-msgs new file mode 100755 index 000000000000..df9f6ef2c1e1 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/130.clean-msgs @@ -0,0 +1,34 @@ +#!/bin/sh +# +# +# Remove system	messages +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_clean_msgs_enable" in +    [Yy][Ee][Ss]) +	if [ ! -d /var/msgs ] +	then +	    echo '$daily_clean_msgs_enable is set but /var/msgs' \ +		"doesn't exist" +	    rc=2 +	else +	    echo "" +	    echo "Cleaning out old system announcements:" + +	    [ -n "$daily_clean_msgs_days" ] && +		arg=-${daily_clean_msgs_days#-} || arg= +	    msgs -c $arg && rc=0 || rc=3 +	fi;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/140.clean-rwho b/usr.sbin/periodic/etc/daily/140.clean-rwho new file mode 100755 index 000000000000..b34fa80c58f7 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/140.clean-rwho @@ -0,0 +1,52 @@ +#!/bin/sh +# +# +# Remove stale files in /var/rwho +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_clean_rwho_enable" in +    [Yy][Ee][Ss]) +	if [ -z "$daily_clean_rwho_days" ] +	then +	    echo '$daily_clean_rwho_enable is enabled but' \ +		'$daily_clean_rwho_days is not set' +	    rc=2 +	elif [ ! -d /var/rwho ] +	then +	    echo '$daily_clean_rwho_enable is enabled but /var/rwho' \ +		"doesn't exist" +	    rc=2 +	else +	    echo "" +	    echo "Removing stale files from /var/rwho:" + +	    case "$daily_clean_rwho_verbose" in +		[Yy][Ee][Ss]) +		    print=-print;; +		*) +		    print=;; +	    esac + +	    if cd /var/rwho +	    then +		rc=$(find . ! -name . -mtime +$daily_clean_rwho_days \ +		    -delete $print | tee /dev/stderr | wc -l) +		[ -z "$print" ] && rc=0 +		[ $rc -gt 1 ] && rc=1 +	    else +		rc=3 +	    fi +	fi;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/150.clean-hoststat b/usr.sbin/periodic/etc/daily/150.clean-hoststat new file mode 100755 index 000000000000..5d2ba42831ee --- /dev/null +++ b/usr.sbin/periodic/etc/daily/150.clean-hoststat @@ -0,0 +1,30 @@ +#!/bin/sh +# +# +# Remove stale persistent host status files if the mailer supports it. +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ]; then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_clean_hoststat_enable" in +    [Yy][Ee][Ss]) +	if ! grep -q '^purgestat' /etc/mail/mailer.conf; then +	    rc=3 +	elif [ -z "$(hoststat 2>&1)" ]; then +	    rc=2 +	else +	    echo "" +	    echo "Removing stale entries from sendmail host status cache:" +	    rc=0 +	    purgestat || rc=1 +	fi;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/200.backup-passwd b/usr.sbin/periodic/etc/daily/200.backup-passwd new file mode 100755 index 000000000000..7cd52fc7be4b --- /dev/null +++ b/usr.sbin/periodic/etc/daily/200.backup-passwd @@ -0,0 +1,76 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_backup_passwd_enable" in +    [Yy][Ee][Ss]) +	if [ ! -f /etc/master.passwd ] +	then +	    echo '$daily_backup_passwd_enable" is set but /etc/master.passwd' \ +		"doesn't exist" +	    rc=2 +	elif [ ! -f /etc/group ] +	then +	    echo '$daily_backup_passwd_enable" is set but /etc/group' \ +		"doesn't exist" +	    rc=2 +	else +	    bak=/var/backups +	    rc=0 + +	    echo "" +	    echo "Backup passwd and group files:" + +	    if [ ! -f $bak/master.passwd.bak ] +	    then +		rc=1 +		echo "no $bak/master.passwd.bak" +		cp -p /etc/master.passwd $bak/master.passwd.bak || rc=3 +	    fi + +	    if ! cmp -s $bak/master.passwd.bak /etc/master.passwd +	    then +		[ $rc -lt 1 ] && rc=1 +		echo "$host passwd diffs:" +		diff ${daily_diff_flags} -I '^#' $bak/master.passwd.bak /etc/master.passwd |\ +			sed 's/^\([-+ ][^:]*\):[^:]*:/\1:(password):/' +		mv $bak/master.passwd.bak $bak/master.passwd.bak2 +		cp -p /etc/master.passwd $bak/master.passwd.bak || rc=3 +	    fi + +	    if [ ! -f $bak/group.bak ] +	    then +		[ $rc -lt 1 ] && rc=1 +		echo "no $bak/group.bak" +		cp -p /etc/group $bak/group.bak || rc=3 +	    fi + +	    if ! cmp -s $bak/group.bak /etc/group +	    then +		[ $rc -lt 1 ] && rc=1 +		echo "$host group diffs:" +		diff ${daily_diff_flags} $bak/group.bak /etc/group +		mv $bak/group.bak $bak/group.bak2 +		cp -p /etc/group $bak/group.bak || rc=3 +	    fi + +	    if [ -f /etc/group ] +	    then +	        echo "" +		echo "Verifying group file syntax:" +	        chkgrp /etc/group || rc=3 +	    fi +	fi;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/210.backup-aliases b/usr.sbin/periodic/etc/daily/210.backup-aliases new file mode 100755 index 000000000000..d236d9615dba --- /dev/null +++ b/usr.sbin/periodic/etc/daily/210.backup-aliases @@ -0,0 +1,46 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_backup_aliases_enable" in +    [Yy][Ee][Ss]) +	if [ ! -f /etc/mail/aliases ] +	then +	    echo '$daily_backup_aliases_enable is enabled but' \ +		"/etc/mail/aliases doesn't exist" +	    rc=2 +	else +	    bak=/var/backups +	    rc=0 + +	    echo "" +	    echo "Backing up mail aliases:" + +	    if [ ! -f $bak/aliases.bak ] +	    then +		echo "no $bak/aliases.bak" +		cp -p /etc/mail/aliases $bak/aliases.bak || rc=3 +	    fi + +	    if ! cmp -s $bak/aliases.bak /etc/mail/aliases +	    then +		[ $rc -lt 1 ] && rc=1 +		echo "$host aliases diffs:" +		diff ${daily_diff_flags} $bak/aliases.bak /etc/mail/aliases +		mv $bak/aliases.bak $bak/aliases.bak2 +		cp -p /etc/mail/aliases $bak/aliases.bak || rc=3 +	    fi +	fi;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/221.backup-gpart b/usr.sbin/periodic/etc/daily/221.backup-gpart new file mode 100755 index 000000000000..50096e38f118 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/221.backup-gpart @@ -0,0 +1,122 @@ +#!/bin/sh +## Created by: Miroslav Lachman <000.fbsd@quip.cz> + +## Backup of disk partitions layout, useful for gpart restore. +## Data are stored on local filesystem, in /var/backup. +## It is recommended to copy those files to off-site storage. + + +## If there is a global system configuration file, suck it in. +## +if [ -r /etc/defaults/periodic.conf ] +then +	. /etc/defaults/periodic.conf +	source_periodic_confs +fi + +bak_dir=/var/backups + +rotate() { +	base_name=$1 +	show_diff=$2 +	file="$bak_dir/$base_name" + +	if [ -f "${file}.bak" ] ; then +		rc=0 +		if cmp -s "${file}.bak" "${file}.tmp"; then +			rm "${file}.tmp" +		else +			rc=1 +			[ -n "$show_diff" ] && diff ${daily_diff_flags} "${file}.bak" "${file}.tmp" +			mv "${file}.bak" "${file}.bak2" || rc=3 +			mv "${file}.tmp" "${file}.bak" || rc=3 +		fi +	else +		rc=1 +		mv "${file}.tmp" "${file}.bak" || rc=3 +		[ -n "$show_diff" ] && cat "${file}.bak" +	fi +} + +case "$daily_backup_gpart_verbose" in +	[Yy][Ee][Ss]) show="YES" +esac + +case "$daily_backup_gpart_enable" in +	[Yy][Ee][Ss]) + +	echo "" +	echo "Dump of kern.geom.conftxt:"; +	sysctl -n kern.geom.conftxt > "$bak_dir/kern.geom.conftxt.tmp" +	rotate "kern.geom.conftxt" $show + +	gpart_devs=$(gpart show | awk '$1 == "=>" { print $4 }') +	if [ -n "$daily_backup_gpart_exclude" ]; then +		gpart_devs=$(echo "${gpart_devs}" | grep -E -v "${daily_backup_gpart_exclude}") +	fi + +	if [ -z "$gpart_devs"  ]; then +		echo '$daily_backup_gpart_enable is set but no disk probed by kernel.' \ +		"perhaps NFS diskless client." +		rc=2 +	else +		echo "" +		echo "Backup of partitions information for:"; + +		for d in ${gpart_devs}; do +			echo "$d" +			safe_name=$(echo "gpart.${d}" | tr -cs ".[:alnum:]\n" "_") +			gpart backup "$d" > "$bak_dir/$safe_name.tmp" +			rotate "$safe_name" $show +		done + +		gpart_show=$(gpart show -p) +		boot_part=$(echo "$gpart_show" | awk '$4 ~ /(bios|freebsd)-boot/ { print $3 }') +		if [ -n "$boot_part" ]; then +			echo "" +			echo "Backup of boot partition content:" +			for b in ${boot_part}; do +				echo "$b" +				safe_name=$(echo "boot.${b}" | tr -cs ".[:alnum:]\n" "_") +				dd if="/dev/${b}" of="$bak_dir/$safe_name.tmp" 2> /dev/null +				rotate "$safe_name" +			done +		fi + +		mbr_part=$(echo "$gpart_show" | awk '$1 == "=>" && $5 == "MBR" { print $4 }') +		if [ -n "$mbr_part" ]; then +			echo "" +			echo "Backup of MBR record:" +			for mb in ${mbr_part}; do +				echo "$mb" +				safe_name=$(echo "boot.${mb}" | tr -cs ".[:alnum:]\n" "_") +				dd if="/dev/${mb}" of="$bak_dir/$safe_name.tmp" bs=512 count=1 2> /dev/null +				rotate "$safe_name" +			done +		fi + +	fi +	;; + +	*)  rc=0 +	;; +esac + +case "$daily_backup_efi_enable" in +    [Yy][Ee][Ss]) + +    efi_part=$(gpart show -p | awk '$4 ~ /efi/ {print $3}') +    if [ -n "$efi_part" ]; then +        echo "" +        echo "Backup of EFI partition content:" +        for efi in ${efi_part}; do +            echo "$efi" +            safe_name=$(echo "efi.${efi}" | tr -cs ".[:alnum:]\n" "_") +            dd if="/dev/${efi}" of="$bak_dir/$safe_name.tmp" 2> /dev/null +            rotate "$safe_name" +        done +    fi +    ;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/222.backup-gmirror b/usr.sbin/periodic/etc/daily/222.backup-gmirror new file mode 100755 index 000000000000..45c656dc4f41 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/222.backup-gmirror @@ -0,0 +1,70 @@ +#!/bin/sh +# Created by: Miroslav Lachman <000.fbsd@quip.cz> + +# Backup output from `gmirror list`, which provides detailed information +# of all gmirrors. The backup will be stored in /var/backups/. + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +	. /etc/defaults/periodic.conf +	source_periodic_confs +fi + +bak_dir=/var/backups + +rotate() { +	base_name=$1 +	show_diff=$2 +	file="$bak_dir/$base_name" + +	if [ -f "${file}.bak" ]; then +		rc=0 +		if cmp -s "${file}.bak" "${file}.tmp"; then +			rm "${file}.tmp" +		else +			rc=1 +			[ -n "$show_diff" ] && diff ${daily_diff_flags} "${file}.bak" "${file}.tmp" +			mv "${file}.bak" "${file}.bak2" || rc=3 +			mv "${file}.tmp" "${file}.bak" || rc=3 +		fi +	else +		rc=1 +		mv "${file}.tmp" "${file}.bak" || rc=3 +		[ -n "$show_diff" ] && cat "${file}.bak" +	fi +} + +case "$daily_backup_gmirror_verbose" in +	[Yy][Ee][Ss]) show="YES" +esac + +case "$daily_backup_gmirror_enable" in +	[Yy][Ee][Ss]) + +	gmirrors=$(gmirror status 2> /dev/null | \ +		awk '$1 ~ /^mirror\// { sub(/mirror\//, ""); print $1 }') + +	if [ -z "$gmirrors"  ]; then +        echo "" +		echo "daily_backup_gmirror_enable is set to YES but no gmirrors found." +		rc=2 +	else +		echo "" +		echo "Backup of gmirror information for:"; + +		for m in ${gmirrors}; do +			echo "$m" +			safe_name=$(echo "gmirror.${m}" | tr -cs ".[:alnum:]\n" "_") +			if ! gmirror status -s "${m}" | grep -F -v "COMPLETE"; then +				gmirror list "${m}" > "$bak_dir/$safe_name.tmp" +				rotate "$safe_name" $show +			fi +		done +	fi +	;; +	*)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/223.backup-zfs b/usr.sbin/periodic/etc/daily/223.backup-zfs new file mode 100755 index 000000000000..e76421220a0b --- /dev/null +++ b/usr.sbin/periodic/etc/daily/223.backup-zfs @@ -0,0 +1,78 @@ +#!/bin/sh +# Created by: Miroslav Lachman <000.fbsd@quip.cz> + +# Backup of zpool list, zfs list, zpool properties and zfs properties +# for each filesystem. The backup will be stored in /var/backups. + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +	. /etc/defaults/periodic.conf +	source_periodic_confs +fi + +bak_dir=/var/backups +rc=0 + +rotate() { +	base_name=$1 +	show_diff=$2 +	file="$bak_dir/$base_name" + +	if [ -f "${file}.bak" ] ; then +		if cmp -s "${file}.bak" "${file}.tmp"; then +			rm "${file}.tmp" +		else +			if [ -n "$show_diff" ]; then +				rc=1 +				diff ${daily_diff_flags} "${file}.bak" "${file}.tmp" +			fi +			mv "${file}.bak" "${file}.bak2" || rc=3 +			mv "${file}.tmp" "${file}.bak" || rc=3 +		fi +	else +		rc=1 +		mv "${file}.tmp" "${file}.bak" || rc=3 +		[ -n "$show_diff" ] && cat "${file}.bak" +	fi +} + +show="" +case "$daily_backup_zfs_verbose" in +	[Yy][Ee][Ss]) show="YES" +esac + +case "$daily_backup_zfs_enable" in +	[Yy][Ee][Ss]) + +	zpools=$(zpool list $daily_backup_zpool_list_flags) + +	if [ -z "$zpools" ]; then +		echo 'daily_backup_zfs_enable is set to YES but no zpools found.' +		rc=2 +	else +		echo "" +		echo "Backup of ZFS information for all imported pools"; + +		echo "$zpools" > "$bak_dir/zpool_list.tmp" +		rotate "zpool_list" $show + +		zfs list $daily_backup_zfs_list_flags > "$bak_dir/zfs_list.tmp" +		rotate "zfs_list" $show +	fi +	;; +esac + +case "$daily_backup_zfs_props_enable" in +	[Yy][Ee][Ss]) + +	zfs get $daily_backup_zfs_get_flags > "$bak_dir/zfs_props.tmp" +	rotate "zfs_props" $show + +	zpool get $daily_backup_zpool_get_flags > "$bak_dir/zpool_props.tmp" +	rotate "zpool_props" $show +	;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/300.calendar b/usr.sbin/periodic/etc/daily/300.calendar new file mode 100755 index 000000000000..3be90a8c4754 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/300.calendar @@ -0,0 +1,28 @@ +#!/bin/sh +# +# +# `calendar -a' needs to die. Why? Because it's a bad idea, particular +# with networked home directories, but also in general.  If you want the +# output of `calendar' mailed to you, set up a cron job to do it, +# or run it from your ~/.profile or ~/.login. +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_calendar_enable" in +    [Yy][Ee][Ss]) +	echo "" +	echo "Running calendar:" + +	calendar -a && rc=0 || rc=3;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/310.accounting b/usr.sbin/periodic/etc/daily/310.accounting new file mode 100755 index 000000000000..861a22720236 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/310.accounting @@ -0,0 +1,69 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_accounting_enable" in +    [Yy][Ee][Ss]) +	if [ ! -f /var/account/acct ] +	then +	    echo '$daily_accounting_enable is set but /var/account/acct' \ +		"doesn't exist" +	    rc=2 +	elif [ $(sysctl -n kern.acct_configured) -eq 0 ] +	then +	    echo '$daily_accounting_enable is set but' \ +	    'process accounting is not active' +	    rc=2 +	elif [ -z "$daily_accounting_save" ] +	then +	    echo '$daily_accounting_enable is set but ' \ +		'$daily_accounting_save is not' +	    rc=2 +	else +	    echo "" +	    echo "Rotating accounting logs and gathering statistics:" + +	    cd /var/account +	    rc=0 + +	    n=$(( $daily_accounting_save - 1 )) +	    for f in acct.*; do +	    	case "$f" in acct.\*) continue ;; esac	# No files match +	    	m=${f%.gz} ; m=${m#acct.} +		[ $m -ge $n ] && { rm $f || rc=3; } +	    done + +	    m=$n +	    n=$(($n - 1)) +	    while [ $n -ge 0 ] +	    do +		[ -f acct.$n.gz ] && { mv -f acct.$n.gz acct.$m.gz || rc=3; } +		[ -f acct.$n ] &&    { mv -f acct.$n acct.$m || rc=3; } +		m=$n +		n=$(($n - 1)) +	    done + +	    /etc/rc.d/accounting onerotate_log || rc=3 + +	    rm -f acct.merge && cp acct.0 acct.merge || rc=3 +	    sa -s $daily_accounting_flags /var/account/acct.merge || rc=3 +	    rm acct.merge + +	    case "$daily_accounting_compress" in +		[Yy][Ee][Ss]) +		    gzip -f acct.0 || rc=3;; +	    esac +	fi;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/400.status-disks b/usr.sbin/periodic/etc/daily/400.status-disks new file mode 100755 index 000000000000..cc1fe8dc0ab3 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/400.status-disks @@ -0,0 +1,39 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_status_disks_enable" in +    [Yy][Ee][Ss]) +	echo "" +	echo "Disk status:" + +	if [ -n "${daily_status_disks_ignore}" ] ; then +		ignore="egrep -v ${daily_status_disks_ignore}" +	else +		ignore="cat" +	fi +	(df $daily_status_disks_df_flags | ${ignore}) && rc=1 || rc=3 + +	# display which filesystems need backing up +	if [ -s /etc/dumpdates ]; then +		if ! [ -f /etc/fstab ]; then +			export PATH_FSTAB=/dev/null +		fi + +		echo "" +		dump W || rc=3 +	fi +	;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/401.status-graid b/usr.sbin/periodic/etc/daily/401.status-graid new file mode 100755 index 000000000000..259722a94a0c --- /dev/null +++ b/usr.sbin/periodic/etc/daily/401.status-graid @@ -0,0 +1,33 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_status_graid_enable" in +    [Yy][Ee][Ss]) +	echo +	echo 'Checking status of graid(8) devices:' + +	if graid status; then +		components="$(graid status -s | fgrep -v OPTIMAL)" +		if [ "${components}" ]; then +			rc=3 +		else +			rc=0 +		fi +	else +		rc=2 +	fi +	;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/404.status-zfs b/usr.sbin/periodic/etc/daily/404.status-zfs new file mode 100755 index 000000000000..052f794c0bbc --- /dev/null +++ b/usr.sbin/periodic/etc/daily/404.status-zfs @@ -0,0 +1,44 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_status_zfs_enable" in +    [Yy][Ee][Ss]) +	echo +	echo 'Checking status of zfs pools:' + +	case "$daily_status_zfs_zpool_list_enable" in +	    [Yy][Ee][Ss]) +		lout=`zpool list` +		echo "$lout" +		echo +		;; +	    *) +		;; +	esac +	sout=`zpool status -x` +	echo "$sout" +	# zpool status -x always exits with 0, so we have to interpret its +	# output to see what's going on. +	if [ "$sout" = "all pools are healthy" \ +	    -o "$sout" = "no pools available" ]; then +		rc=0 +	else +		rc=1 +	fi +	;; + +    *) +	rc=0 +	;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/406.status-gmirror b/usr.sbin/periodic/etc/daily/406.status-gmirror new file mode 100755 index 000000000000..06fbb9491576 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/406.status-gmirror @@ -0,0 +1,33 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_status_gmirror_enable" in +    [Yy][Ee][Ss]) +	echo +	echo 'Checking status of gmirror(8) devices:' + +	if gmirror status; then +		components="$(gmirror status -s | fgrep -v COMPLETE)" +		if [ "${components}" ]; then +			rc=3 +		else +			rc=0 +		fi +	else +		rc=2 +	fi +	;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/407.status-graid3 b/usr.sbin/periodic/etc/daily/407.status-graid3 new file mode 100755 index 000000000000..af73ca4dd754 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/407.status-graid3 @@ -0,0 +1,33 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_status_graid3_enable" in +    [Yy][Ee][Ss]) +	echo +	echo 'Checking status of graid3(8) devices:' + +	if graid3 status; then +		components="$(graid3 status -s | fgrep -v COMPLETE)" +		if [ "${components}" ]; then +			rc=3 +		else +			rc=0 +		fi +	else +		rc=2 +	fi +	;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/408.status-gstripe b/usr.sbin/periodic/etc/daily/408.status-gstripe new file mode 100755 index 000000000000..1a4c9f053747 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/408.status-gstripe @@ -0,0 +1,33 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_status_gstripe_enable" in +    [Yy][Ee][Ss]) +	echo +	echo 'Checking status of gstripe(8) devices:' + +	if gstripe status; then +		components="$(gstripe status -s | fgrep -v UP)" +		if [ "${components}" ]; then +			rc=3 +		else +			rc=0 +		fi +	else +		rc=2 +	fi +	;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/409.status-gconcat b/usr.sbin/periodic/etc/daily/409.status-gconcat new file mode 100755 index 000000000000..2fabac1caeed --- /dev/null +++ b/usr.sbin/periodic/etc/daily/409.status-gconcat @@ -0,0 +1,33 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_status_gconcat_enable" in +    [Yy][Ee][Ss]) +	echo +	echo 'Checking status of gconcat(8) devices:' + +	if gconcat status; then +		components="$(gconcat status -s | fgrep -v UP)" +		if [ "${components}" ]; then +			rc=3 +		else +			rc=0 +		fi +	else +		rc=2 +	fi +	;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/410.status-mfi b/usr.sbin/periodic/etc/daily/410.status-mfi new file mode 100644 index 000000000000..141cd777380c --- /dev/null +++ b/usr.sbin/periodic/etc/daily/410.status-mfi @@ -0,0 +1,32 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_status_mfi_enable" in +    [Yy][Ee][Ss]) +       echo +       echo 'Checking status of mfi(4) devices:' + +       if mfiutil show volumes; then +               if mfiutil show volumes | grep -q DEGRADED; then +                       rc=3 +               else +                       rc=0 +               fi +       else +               rc=2 +       fi +       ;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/420.status-network b/usr.sbin/periodic/etc/daily/420.status-network new file mode 100755 index 000000000000..955d6b0e9146 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/420.status-network @@ -0,0 +1,30 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_status_network_enable" in +    [Yy][Ee][Ss]) +	echo "" +	echo "Network interface status:" + +	flags="${daily_status_network_netstat_flags}" +	case "$daily_status_network_usedns" in +	    [Yy][Ee][Ss]) +		;; +	    *) +		flags="${flags} -n";; +	esac +	netstat -i ${flags} && rc=0 || rc=3;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/430.status-uptime b/usr.sbin/periodic/etc/daily/430.status-uptime new file mode 100755 index 000000000000..19c4bcd0b0d0 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/430.status-uptime @@ -0,0 +1,37 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_status_uptime_enable" in +    [Yy][Ee][Ss]) +	rwho=$(echo /var/rwho/*) +        if [ -f "${rwho%% *}" ] +        then +	    echo "" +	    echo "Local network system status:" +	    prog=ruptime +	else +	    echo "" +	    echo "Local system status:" +	    prog=uptime +	fi +	rc=$($prog | tee /dev/stderr | wc -l) +	if [ $? -eq 0 ] +	then +	    [ $rc -gt 1 ] && rc=1 +	else +	    rc=3 +	fi;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/440.status-mailq b/usr.sbin/periodic/etc/daily/440.status-mailq new file mode 100755 index 000000000000..ad2c7f6af293 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/440.status-mailq @@ -0,0 +1,65 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_status_mailq_enable" in +    [Yy][Ee][Ss]) +	if [ ! -x /usr/bin/mailq ] +	then +	    echo '$daily_status_mailq_enable is set but /usr/bin/mailq' \ +		"isn't executable" +	    rc=2 +	else +	    echo "" +	    echo "Mail in local queue:" + +	    rc=$(case "$daily_status_mailq_shorten" in +		[Yy][Ee][Ss]) +		    mailq | +			egrep -e '^[[:space:]]+[^[:space:]]+@' | +			sort | +			uniq -c | +			sort -nr | +			awk '$1 >= 1 {print $1, $2}';; +		*) +		    mailq;; +	    esac | tee /dev/stderr | +	    egrep -v '((Mail |m)queue is empty|Total requests)' | wc -l) +	    [ $rc -gt 0 ] && rc=1 || rc=0 + +	    case "$daily_status_include_submit_mailq" in +	    [Yy][Ee][Ss]) +		if [ -f /etc/mail/submit.cf ] && mailq -Ac >/dev/null 2>&1 +		then +		    echo "" +		    echo "Mail in submit queue:" + +		    rc_submit=$(case "$daily_status_mailq_shorten" in +			[Yy][Ee][Ss]) +			    mailq -Ac | +				egrep -e '^[[:space:]]+[^[:space:]]+@' | +				sort | +				uniq -c | +				sort -nr | +				awk '$1 >= 1 {print $1, $2}';; +			*) +			    mailq -Ac;; +		    esac | tee /dev/stderr | +		    egrep -v '(mqueue is empty|Total requests)' | wc -l) +		    [ $rc_submit -gt 0 ] && rc=1 +		fi;; +	    esac +	fi;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/450.status-security b/usr.sbin/periodic/etc/daily/450.status-security new file mode 100755 index 000000000000..c004e0ae98ac --- /dev/null +++ b/usr.sbin/periodic/etc/daily/450.status-security @@ -0,0 +1,46 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_status_security_enable" in +    [Yy][Ee][Ss]) +	echo "" +	echo "Security check:" + +	case "$daily_status_security_inline" in +	    [Yy][Ee][Ss]) +		daily_status_security_output="";; +	esac + +	export security_output="${daily_status_security_output}" +	rc=0 +	case "${daily_status_security_output}" in +	    "") +		if tempfile=`mktemp ${TMPDIR:-/tmp}/450.status-security.XXXXXX` +		then +			periodic security > $tempfile || rc=3 +			if [ -s "$tempfile" ]; then +				cat "$tempfile" +				rc=3 +			fi +			rm -f "$tempfile" +		fi;; +	    /*) +		echo "    (output logged separately)" +		periodic security || rc=3;; +	    *) +		echo "    (output mailed separately)" +		periodic security || rc=3;; +	esac;; +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/460.status-mail-rejects b/usr.sbin/periodic/etc/daily/460.status-mail-rejects new file mode 100755 index 000000000000..b33e0062f3d7 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/460.status-mail-rejects @@ -0,0 +1,78 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_status_mail_rejects_shorten" in +[Yy][Ee][Ss])	shorten='cut -d" " -f2,3';; +*)		shorten=cat;; +esac + +case "$daily_status_mail_rejects_enable" in +    [Yy][Ee][Ss]) +	if [ ! -d /etc/mail ] +	then +	    echo '$daily_status_mail_rejects_enable is set but /etc/mail' \ +		"doesn't exist" +	    rc=2 +	elif [ ! -f /var/log/maillog ] +	then +	    echo '$daily_status_mail_rejects_enable is set but ' \ +		"/var/log/maillog doesn't exist" +	    rc=2 +	elif [ "$daily_status_mail_rejects_logs" -le 0 ] +	then +	    echo '$daily_status_mail_rejects_enable is set but ' \ +		'$daily_status_mail_rejects_logs is not greater than zero' +	    rc=2 +	else +	    echo +	    echo Checking for rejected mail hosts: + +	    yesterday=$(date -v-1d '+%b %e') +	    today=$(date '+%b %e') +	    n=$(($daily_status_mail_rejects_logs - 2)) +	    rc=$({ +		while [ $n -ge 0 ] +		do +		    if [ -f /var/log/maillog.$n ] +		    then +			cat /var/log/maillog.$n +		    elif [ -f /var/log/maillog.$n.gz ] +		    then +			zcat -fc /var/log/maillog.$n.gz +		    elif [ -f /var/log/maillog.$n.bz2 ] +		    then +			bzcat -fc /var/log/maillog.$n.bz2 +		    elif [ -f /var/log/maillog.$n.xz ] +		    then +			xzcat -f /var/log/maillog.$n.xz +		    elif [ -f /var/log/maillog.$n.zst ] +		    then +			zstdcat -fc /var/log/maillog.$n.zst +		    fi +		    n=$(($n - 1)) +		done +		cat /var/log/maillog +	    } | sed -Ene "/^$today/q" -e "/^$yesterday/{"' +		    s/.*ruleset=check_relay,.* relay=([^,]+), reject=([^ ]*).*/\2 check_relay \1/p +		    t end +                    s/.*ruleset=check_rcpt,.* arg1=<?([^>,]+).* reject=([^ ]+) .* ([^ ]+)/\2 check_rcpt \1 \3/p +		    t end +                    s/.*ruleset=check_([^,]+),.* arg1=<?([^@]+@)?([^>,]+).* reject=([^ ]+) .* ([^ ]+)/\4 check_\1 \3 \5/p +		    :end +		}' | eval $shorten | sort -f | uniq -ic | sort -fnr | tee /dev/stderr | wc -l) +	    [ $rc -gt 0 ] && rc=1 +	fi;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/480.leapfile-ntpd b/usr.sbin/periodic/etc/daily/480.leapfile-ntpd new file mode 100755 index 000000000000..c7de845ea87d --- /dev/null +++ b/usr.sbin/periodic/etc/daily/480.leapfile-ntpd @@ -0,0 +1,22 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_ntpd_leapfile_enable" in +    [Yy][Ee][Ss]) +	if service ntpd enabled && service ntpd needfetch; then +	    anticongestion +	    service ntpd fetch +	fi +	;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/480.status-ntpd b/usr.sbin/periodic/etc/daily/480.status-ntpd new file mode 100755 index 000000000000..f77910befea8 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/480.status-ntpd @@ -0,0 +1,27 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +rc=0 + +case "$daily_status_ntpd_enable" in +    [Yy][Ee][Ss]) +	echo "" +	echo "NTP status:" + +	synchronized=$(ntpq -pn | tee /dev/stderr | grep '^\*') +	if [ -z "$synchronized" ]; then +		rc=1 +	fi +	;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/500.queuerun b/usr.sbin/periodic/etc/daily/500.queuerun new file mode 100755 index 000000000000..cdc4e979b5a8 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/500.queuerun @@ -0,0 +1,35 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_queuerun_enable" in +    [Yy][Ee][Ss]) +	if [ ! -x /usr/sbin/sendmail ] +	then +	    echo '$daily_queuerun_enable is set but /usr/sbin/sendmail' \ +		"isn't executable" +	    rc=2 +	else +	    /usr/sbin/sendmail -q >/dev/null 2>&1 & +	    case "$daily_submit_queuerun" in +	    [Yy][Ee][Ss]) +		if [ -f /etc/mail/submit.cf ] +		then +		    /usr/sbin/sendmail -q -Ac >/dev/null 2>&1 & +		fi;; +	    esac +	    rc=0 +	fi;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/510.status-world-kernel b/usr.sbin/periodic/etc/daily/510.status-world-kernel new file mode 100755 index 000000000000..e9ebc0a830a9 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/510.status-world-kernel @@ -0,0 +1,35 @@ +#!/bin/sh +# +# +# Check that the running userland and kernel versions are in sync. + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_status_world_kernel" in +    [Yy][Ee][Ss]) +	rc=0 +	_U=$(/usr/bin/uname -U 2>/dev/null) +	_K=$(/usr/bin/uname -K 2>/dev/null) +	[ -z "${_U}" -o -z "${_K}" ] && exit 0 +	echo "" +	echo "Checking userland and kernel versions:" +	if [ "${_U}" != "${_K}" ]; then +	    echo "Userland and kernel are not in sync" +	    echo "Userland version: ${_U}" +	    echo "Kernel version: ${_K}" +	    rc=1 +	else +	    echo "Userland and kernel are in sync." +	fi +	;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/800.scrub-zfs b/usr.sbin/periodic/etc/daily/800.scrub-zfs new file mode 100755 index 000000000000..3a19c09b4698 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/800.scrub-zfs @@ -0,0 +1,109 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# + +newline=" +" # A single newline + +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +: ${daily_scrub_zfs_default_threshold=35} + +case "$daily_scrub_zfs_enable" in +    [Yy][Ee][Ss]) +	echo +	echo 'Scrubbing of zfs pools:' + +	if [ -z "${daily_scrub_zfs_pools}" ]; then +		daily_scrub_zfs_pools="$(zpool list -H -o name)" +	fi + +	rc=0 +	for pool in ${daily_scrub_zfs_pools}; do +		# sanity check +		_status=$(zpool list "${pool}" 2> /dev/null) +		if [ $? -ne 0 ]; then +			rc=2 +			echo "   WARNING: pool '${pool}' specified in" +			echo "            '/etc/periodic.conf:daily_scrub_zfs_pools'" +			echo "            does not exist" +			continue +		fi +		_status=${_status##*$newline} +		case ${_status} in +		*FAULTED*) +			rc=3 +			echo "Skipping faulted pool: ${pool}" +			continue ;; +		*UNAVAIL*) +			rc=4 +			echo "Skipping unavailable pool: ${pool}" +			continue ;; +		esac + +		# determine how many days shall be between scrubs +		eval _pool_threshold=\${daily_scrub_zfs_$(echo "${pool}"|tr  ".:-" "_")_threshold} +		if [ -z "${_pool_threshold}" ];then +			_pool_threshold=${daily_scrub_zfs_default_threshold} +		fi + +		_last_scrub=$(zpool history ${pool} | \ +		    egrep "^[0-9\.\:\-]{19} zpool scrub ${pool}\$" | tail -1 |\ +		    cut -d ' ' -f 1) +		if [ -z "${_last_scrub}" ]; then +			# creation time of the pool if no scrub was done +			_last_scrub=$(zpool history ${pool} | \ +			    sed -ne '2s/ .*$//p') +		fi +		if [ -z "${_last_scrub}" ]; then +			echo "   skipping scrubbing of pool '${pool}':" +			echo "      can't get last scrubbing date" +			continue +		fi + +		# Now minus last scrub (both in seconds) converted to days. +		_scrub_diff=$(expr -e \( $(date +%s) - \ +		    $(date -j -v -70M -f %F.%T ${_last_scrub} +%s) \) / 60 / 60 / 24) +		if [ ${_scrub_diff} -lt ${_pool_threshold} ]; then +			echo "   skipping scrubbing of pool '${pool}':" +			echo "      last scrubbing is ${_scrub_diff} days ago, threshold is set to ${_pool_threshold} days" +			continue +		fi + +		_status="$(zpool status ${pool} | grep scan:)" +		case "${_status}" in +			*"scrub in progress"*) +				echo "   scrubbing of pool '${pool}' already in progress, skipping:" +				;; +			*"resilver in progress"*) +				echo "   resilvering of pool '${pool}' is in progress, skipping:" +				;; +			*"none requested"*) +				echo "   starting first scrub (since reboot) of pool '${pool}':" +				zpool scrub ${pool} +				[ $rc -eq 0 ] && rc=1 +				;; +			*) +				echo "   starting scrub of pool '${pool}':" +				zpool scrub ${pool} +				[ $rc -eq 0 ] && rc=1 +				;; +		esac + +		echo "      consult 'zpool status ${pool}' for the result" +	done +	;; + +    *) +	rc=0 +	;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/801.trim-zfs b/usr.sbin/periodic/etc/daily/801.trim-zfs new file mode 100755 index 000000000000..17d2ce217c10 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/801.trim-zfs @@ -0,0 +1,59 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# + +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$daily_trim_zfs_enable" in +    [Yy][Ee][Ss]) +	echo +	echo 'Trimming of zfs pools:' + +	if [ -z "${daily_trim_zfs_pools}" ]; then +		daily_trim_zfs_pools="$(zpool list -H -o name)" +	fi + +	rc=0 +	for pool in ${daily_trim_zfs_pools}; do +		# sanity check +		_status=$(zpool list -Hohealth "${pool}" 2> /dev/null) +		if [ $? -ne 0 ]; then +			rc=2 +			echo "   WARNING: pool '${pool}' specified in" +			echo "            '/etc/periodic.conf:daily_trim_zfs_pools'" +			echo "            does not exist" +			continue +		fi +		case ${_status} in +		FAULTED) +			rc=3 +			echo "Skipping faulted pool: ${pool}" +			continue ;; +		UNAVAIL) +			rc=4 +			echo "Skipping unavailable pool: ${pool}" +			continue ;; +		esac + +		if ! zpool status "${pool}" | grep -q '(trimming)'; then +			echo "    starting trim of pool '${pool}'" +			zpool trim ${daily_zfs_trim_flags} "${pool}" +		else +			echo "    trim of pool '${pool}' already in progress, skipping" +		fi +	done +	;; + +    *) +	rc=0 +	;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/999.local b/usr.sbin/periodic/etc/daily/999.local new file mode 100755 index 000000000000..29c410f416b3 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/999.local @@ -0,0 +1,42 @@ +#!/bin/sh +# +# +# Run the old /etc/daily.local script.  This is really for backwards +# compatibility more than anything else. +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +rc=0 +for script in $daily_local +do +    echo '' +    case "$script" in +	/*) +	    if [ -x "$script" ] +	    then +		echo "Running $script:" + +		$script || rc=3 +	    elif [ -f "$script" ] +	    then +		echo "Running $script:" + +		sh $script || rc=3 +	    else +		echo "$script: No such file" +		[ $rc -lt 2 ] && rc=2 +	    fi;; +	*) +	    echo "$script: Not an absolute path" +	    [ $rc -lt 2 ] && rc=2;; +    esac +done + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/Makefile b/usr.sbin/periodic/etc/daily/Makefile new file mode 100644 index 000000000000..c92b4ed8a6ee --- /dev/null +++ b/usr.sbin/periodic/etc/daily/Makefile @@ -0,0 +1,77 @@ +.include <src.opts.mk> + +PACKAGE=	periodic + +CONFGROUPS=	CONFS + +CONFS=	100.clean-disks \ +	110.clean-tmps \ +	120.clean-preserve \ +	200.backup-passwd \ +	210.backup-aliases \ +	400.status-disks \ +	410.status-mfi \ +	420.status-network \ +	430.status-uptime \ +	450.status-security \ +	510.status-world-kernel \ +	999.local + +CONFGROUPS+=	GEOM +GEOM+=		221.backup-gpart \ +		222.backup-gmirror \ +		401.status-graid \ +		406.status-gmirror \ +		407.status-graid3 \ +		408.status-gstripe \ +		409.status-gconcat +GEOMPACKAGE=	geom + +CONFGROUPS+=	RCMDS +RCMDS+=		140.clean-rwho +RCMDSPACKAGE=	rcmds + +# NB: keep these sorted by MK_* knobs + +.if ${MK_ACCT} != "no" +CONFGROUPS+=	ACCT +ACCT+=		310.accounting +ACCTMODE=	${BINMODE} +ACCTPACKAGE=	acct +.endif + +.if ${MK_CALENDAR} != "no" +CONFS+=	300.calendar +.endif + +.if ${MK_MAIL} != "no" +CONFS+=	130.clean-msgs +.endif + +.if ${MK_NTP} != "no" +CONFGROUPS+=	NTP +NTP+=		480.status-ntpd \ +		480.leapfile-ntpd +NTPMODE=	${BINMODE} +NTPPACKAGE=	ntp +.endif + +.if ${MK_SENDMAIL} != "no" +CONFGROUPS+=		SENDMAIL +SENDMAIL+=		150.clean-hoststat \ +			440.status-mailq \ +			460.status-mail-rejects \ +			500.queuerun +SENDMAILPACKAGE=	sendmail +.endif + +.if ${MK_ZFS} != "no" +CONFGROUPS+=	ZFS +ZFS+=		223.backup-zfs \ +		404.status-zfs \ +		800.scrub-zfs  \ +		801.trim-zfs +ZFSPACKAGE=	zfs +.endif + +.include <bsd.prog.mk> diff --git a/usr.sbin/periodic/etc/monthly/200.accounting b/usr.sbin/periodic/etc/monthly/200.accounting new file mode 100755 index 000000000000..0571bebeabf0 --- /dev/null +++ b/usr.sbin/periodic/etc/monthly/200.accounting @@ -0,0 +1,64 @@ +#!/bin/sh - +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +oldmask=$(umask) +umask 066 +case "$monthly_accounting_enable" in +    [Yy][Ee][Ss]) +	W=/var/log/utx.log +	rc=0 +	remove=NO +	filetoread=$W.0 +	if [ ! -f $W.0 ] +	then +	    if [ -f $W.0.gz ] || [ -f $W.0.bz2 ] || [ -f $W.0.xz ] || [ -f $W.0.zst ] +	    then +	        TMP=`mktemp -t accounting` +		remove=YES +		filetoread=$TMP +		if [ -f $W.0.gz ] +		then +		    zcat $W.0.gz > $TMP || rc=1 +		elif [ -f $W.0.bz2 ] +		then +		    bzcat $W.0.bz2 > $TMP || rc=1 +		elif [ -f $W.0.xz ] +		then +		    xzcat $W.0.xz > $TMP || rc=1 +		elif [ -f $W.0.zst ] +		then +		    zstdcat $W.0.zst > $TMP || rc=1 +		else +		# shouldn't get here, unless something disappeared under us. +		    rc=2 +		fi +	    else +		echo '$monthly_accounting_enable is set but' \ +		    "$W.0 doesn't exist" +		rc=2 +	    fi +	fi +	if [ $rc -eq 0 ] +	then +	    echo "" +	    echo "Doing login accounting:" + +	    rc=$(ac -p -w $filetoread | sort -nr -k 2 | tee /dev/stderr | wc -l) +	    [ $rc -gt 0 ] && rc=1 +	fi +	[ $remove = YES ] && rm -f $TMP;; + +    *)  rc=0;; +esac + +umask $oldmask +exit $rc diff --git a/usr.sbin/periodic/etc/monthly/450.status-security b/usr.sbin/periodic/etc/monthly/450.status-security new file mode 100755 index 000000000000..ad6312c3cb20 --- /dev/null +++ b/usr.sbin/periodic/etc/monthly/450.status-security @@ -0,0 +1,46 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$monthly_status_security_enable" in +    [Yy][Ee][Ss]) +	echo "" +	echo "Security check:" + +	case "$monthly_status_security_inline" in +	    [Yy][Ee][Ss]) +		monthly_status_security_output="";; +	esac + +	export security_output="${monthly_status_security_output}" +	rc=0 +	case "${monthly_status_security_output}" in +	    "") +		if tempfile=`mktemp ${TMPDIR:-/tmp}/450.status-security.XXXXXX` +		then +			periodic security > $tempfile || rc=3 +			if [ -s "$tempfile" ]; then +				cat "$tempfile" +				rc=3 +			fi +			rm -f "$tempfile" +		fi;; +	    /*) +		echo "    (output logged separately)" +		periodic security || rc=3;; +	    *) +		echo "    (output mailed separately)" +		periodic security || rc=3;; +	esac;; +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/monthly/999.local b/usr.sbin/periodic/etc/monthly/999.local new file mode 100755 index 000000000000..154d8dfe090c --- /dev/null +++ b/usr.sbin/periodic/etc/monthly/999.local @@ -0,0 +1,39 @@ +#!/bin/sh - +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +rc=0 +for script in $monthly_local +do +    echo '' +    case "$script" in +	/*) +	    if [ -x "$script" ] +	    then +		echo "Running $script:" + +		$script || rc=3 +	    elif [ -f "$script" ] +	    then +		echo "Running $script:" + +		sh $script || rc=3 +	    else +		echo "$script: No such file" +		[ $rc -lt 2 ] && rc=2 +	    fi;; +	*) +	    echo "$script: Not an absolute path" +	    [ $rc -lt 2 ] && rc=2;; +    esac +done + +exit $rc diff --git a/usr.sbin/periodic/etc/monthly/Makefile b/usr.sbin/periodic/etc/monthly/Makefile new file mode 100644 index 000000000000..a158426c68b2 --- /dev/null +++ b/usr.sbin/periodic/etc/monthly/Makefile @@ -0,0 +1,20 @@ +.include <src.opts.mk> + +PACKAGE=	periodic + +CONFGROUPS=	CONFS + +CONFS=	450.status-security \ +	999.local + +# NB: keep these sorted by MK_* knobs + +.if ${MK_UTMPX} != "no" +CONFGROUPS+=	ACCT +ACCT+=		200.accounting +ACCTDIR=	/etc/periodic/monthly +ACCTMODE=	${BINMODE} +ACCTPACKAGE=	acct +.endif + +.include <bsd.prog.mk> diff --git a/usr.sbin/periodic/etc/security/100.chksetuid b/usr.sbin/periodic/etc/security/100.chksetuid new file mode 100755 index 000000000000..6ade53a180be --- /dev/null +++ b/usr.sbin/periodic/etc/security/100.chksetuid @@ -0,0 +1,59 @@ +#!/bin/sh - +# +# Copyright (c) 2001  The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +. /etc/periodic/security/security.functions + +rc=0 + +if check_yesno_period security_status_chksetuid_enable +then +	echo "" +	echo 'Checking setuid files and devices:' +	IFS=$'\n'	# Don't split mount points with spaces or tabs +	MP=`mount -t ufs,zfs | awk ' +		$0 !~ /no(suid|exec)/ { +			sub(/^.* on \//, "/"); +			sub(/ \(.*\)/, ""); +			print $0 +		}'` +	find -sx $MP /dev/null \( ! -fstype local \) -prune -o -type f \ +	    \( -perm -u+x -or -perm -g+x -or -perm -o+x \) \ +	    \( -perm -u+s -or -perm -g+s \) -exec ls -lid -D "%FT%T" \{\} \+ | +	check_diff setuid - "${host} setuid diffs:" +	rc=$? +fi + +exit $rc diff --git a/usr.sbin/periodic/etc/security/110.neggrpperm b/usr.sbin/periodic/etc/security/110.neggrpperm new file mode 100755 index 000000000000..41f2713533b0 --- /dev/null +++ b/usr.sbin/periodic/etc/security/110.neggrpperm @@ -0,0 +1,58 @@ +#!/bin/sh - +# +# Copyright (c) 2001  The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +rc=0 + +if check_yesno_period security_status_neggrpperm_enable +then +	echo "" +	echo 'Checking negative group permissions:' +	IFS=$'\n'	# Don't split mount points with spaces or tabs +	MP=`mount -t ufs,zfs | awk ' +		$0 !~ /no(suid|exec)/ { +			sub(/^.* on \//, "/"); +			sub(/ \(.*\)/, ""); +			print $0 +		}'` +	n=$(find -sx $MP /dev/null \( ! -fstype local \) -prune -o -type f \ +	    \( \( ! -perm +010 -and -perm +001 \) -or \ +	    \( ! -perm +020 -and -perm +002 \) -or \ +	    \( ! -perm +040 -and -perm +004 \) \) \ +	    -exec ls -lid -D "%FT%T" \{\} \+ | tee /dev/stderr | wc -l) +	[ $n -gt 0 ] && rc=1 || rc=0 +fi + +exit $rc diff --git a/usr.sbin/periodic/etc/security/200.chkmounts b/usr.sbin/periodic/etc/security/200.chkmounts new file mode 100755 index 000000000000..055cf256018a --- /dev/null +++ b/usr.sbin/periodic/etc/security/200.chkmounts @@ -0,0 +1,60 @@ +#!/bin/sh - +# +# Copyright (c) 2001  The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# Show changes in the way filesystems are mounted +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +. /etc/periodic/security/security.functions + +ignore="${security_status_chkmounts_ignore}" +rc=0 + +if check_yesno_period security_status_chkmounts_enable +then +	case "$security_status_noamd" in +	    [Yy][Ee][Ss]) +		ignore="${ignore}|^amd:" +	esac +	[ -n "$ignore" ] && cmd="egrep -v ${ignore#|}" || cmd=cat +	if ! [ -f /etc/fstab ]; then +		export PATH_FSTAB=/dev/null +	fi +	mount -p | sort | ${cmd} | +	  check_diff mount - "${host} changes in mounted filesystems:" +	rc=$? +fi + +exit "$rc" diff --git a/usr.sbin/periodic/etc/security/300.chkuid0 b/usr.sbin/periodic/etc/security/300.chkuid0 new file mode 100755 index 000000000000..c73980300d70 --- /dev/null +++ b/usr.sbin/periodic/etc/security/300.chkuid0 @@ -0,0 +1,51 @@ +#!/bin/sh - +# +# Copyright (c) 2001  The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +rc=0 + +if check_yesno_period security_status_chkuid0_enable +then +	echo "" +	echo 'Checking for uids of 0:' +	n=$(awk -F: '/^#/ {next} $3==0 {print $1,$3}' /etc/master.passwd | +	tee /dev/stderr | +	sed -e '/^root 0$/d' -e '/^toor 0$/d' | +	wc -l) +	[ $n -gt 0 ] && rc=1 || rc=0 +fi + +exit "$rc" diff --git a/usr.sbin/periodic/etc/security/400.passwdless b/usr.sbin/periodic/etc/security/400.passwdless new file mode 100755 index 000000000000..3e30e5e9cf5f --- /dev/null +++ b/usr.sbin/periodic/etc/security/400.passwdless @@ -0,0 +1,48 @@ +#!/bin/sh - +# +# Copyright (c) 2001  The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +rc=0 + +if check_yesno_period security_status_passwdless_enable +then +	echo "" +	echo 'Checking for passwordless accounts:' +	n=$(awk -F: 'NF > 1 && $1 !~ /^[#+-]/ && $2=="" {print $0}' /etc/master.passwd | +	    tee /dev/stderr | wc -l) +	[ $n -gt 0 ] && rc=1 || rc=0 +fi + +exit "$rc" diff --git a/usr.sbin/periodic/etc/security/410.logincheck b/usr.sbin/periodic/etc/security/410.logincheck new file mode 100755 index 000000000000..a3f3f3f1a21a --- /dev/null +++ b/usr.sbin/periodic/etc/security/410.logincheck @@ -0,0 +1,52 @@ +#!/bin/sh - +# +# Copyright (c) 2006  Tom Rhodes +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +rc=0 + +if check_yesno_period security_status_logincheck_enable +then +	echo "" +	echo 'Checking login.conf permissions:' +	if [ -G /etc/login.conf -a -O /etc/login.conf ]; then +	    n=0 +	else +	    echo "Bad ownership of /etc/login.conf" +	    n=1 +	fi +	[ $n -gt 0 ] && rc=1 || rc=0 +fi + +exit "$rc" diff --git a/usr.sbin/periodic/etc/security/500.ipfwdenied b/usr.sbin/periodic/etc/security/500.ipfwdenied new file mode 100755 index 000000000000..3ee7b3aa5cdc --- /dev/null +++ b/usr.sbin/periodic/etc/security/500.ipfwdenied @@ -0,0 +1,51 @@ +#!/bin/sh - +# +# Copyright (c) 2001  The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +. /etc/periodic/security/security.functions + +rc=0 + +if check_yesno_period security_status_ipfwdenied_enable +then +	TMP=`mktemp -t security` +	if ipfw -a list 2>/dev/null | egrep "deny|reset|unreach" > ${TMP}; then +	  check_diff new_only ipfw ${TMP} "${host} ipfw denied packets:" +	fi +	rc=$? +	rm -f ${TMP} +fi + +exit $rc diff --git a/usr.sbin/periodic/etc/security/510.ipfdenied b/usr.sbin/periodic/etc/security/510.ipfdenied new file mode 100755 index 000000000000..b9f468fb96e5 --- /dev/null +++ b/usr.sbin/periodic/etc/security/510.ipfdenied @@ -0,0 +1,51 @@ +#!/bin/sh - +# +# Copyright (c) 2001  The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +. /etc/periodic/security/security.functions + +rc=0 + +if check_yesno_period security_status_ipfdenied_enable +then +	TMP=`mktemp -t security` +	if ipfstat -nhio 2>/dev/null | grep block > ${TMP}; then +	  check_diff new_only ipf ${TMP} "${host} ipf denied packets:" +	fi +	rc=$? +	rm -f ${TMP} +fi + +exit $rc diff --git a/usr.sbin/periodic/etc/security/520.pfdenied b/usr.sbin/periodic/etc/security/520.pfdenied new file mode 100755 index 000000000000..d87dfa0ae64c --- /dev/null +++ b/usr.sbin/periodic/etc/security/520.pfdenied @@ -0,0 +1,56 @@ +#!/bin/sh - +# +# Copyright (c) 2004  The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +. /etc/periodic/security/security.functions + +rc=0 + +if check_yesno_period security_status_pfdenied_enable +then +	TMP=`mktemp -t security` +	for _a in "" $(pfctl -a "blacklistd" -sA 2>/dev/null) $(pfctl -a "blocklistd" -sA 2>/dev/null) ${security_status_pfdenied_additionalanchors} +	do +		pfctl -a "${_a}" -sr -v -z 2>/dev/null | \ +		nawk '{if (/^block/) {buf=$0; getline; gsub(" +"," ",$0); if ($5 > 0) print buf$0;} }' >> ${TMP} +	done +	if [ -s ${TMP} ]; then +		check_diff new_only pf ${TMP} "${host} pf denied packets:" +	fi +	rc=$? +	rm -f ${TMP} +fi + +exit $rc diff --git a/usr.sbin/periodic/etc/security/550.ipfwlimit b/usr.sbin/periodic/etc/security/550.ipfwlimit new file mode 100755 index 000000000000..8382c12df22f --- /dev/null +++ b/usr.sbin/periodic/etc/security/550.ipfwlimit @@ -0,0 +1,66 @@ +#!/bin/sh - +# +# Copyright (c) 2001  The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# Show ipfw rules which have reached the log limit +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +rc=0 + +if check_yesno_period security_status_ipfwlimit_enable +then +	IPFW_VERBOSE=`sysctl -n net.inet.ip.fw.verbose 2> /dev/null` +	if [ $? -ne 0 ] || [ "$IPFW_VERBOSE" -eq 0 ]; then +		exit 0 +	fi +	TMP=`mktemp -t security` +	ipfw -a list | grep " log " | \ +	grep '^[[:digit:]]\+[[:space:]]\+[[:digit:]]\+' | \ +	awk \ +		'{if ($6 == "logamount") { +			if ($2 > $7) +				{print $0}} +		}' > ${TMP} + +	if [ -s "${TMP}" ]; then +		rc=1 +		echo "" +		echo 'ipfw log limit reached:' +		cat ${TMP} +	fi +	rm -f ${TMP} +fi + +exit $rc diff --git a/usr.sbin/periodic/etc/security/610.ipf6denied b/usr.sbin/periodic/etc/security/610.ipf6denied new file mode 100755 index 000000000000..e1db7611557b --- /dev/null +++ b/usr.sbin/periodic/etc/security/610.ipf6denied @@ -0,0 +1,51 @@ +#!/bin/sh - +# +# Copyright (c) 2001  The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +. /etc/periodic/security/security.functions + +rc=0 + +if check_yesno_period security_status_ipf6denied_enable +then +	TMP=`mktemp ${TMPDIR:-/tmp}/security.XXXXXXXXXX` +	if ipfstat -nhio6 2>/dev/null | grep block > ${TMP}; then +	 check_diff new_only ipf6 ${TMP} "${host} ipf6 denied packets:" +	fi +	rc=$? +	rm -f ${TMP} +fi + +exit $rc diff --git a/usr.sbin/periodic/etc/security/700.kernelmsg b/usr.sbin/periodic/etc/security/700.kernelmsg new file mode 100755 index 000000000000..016bfbef36d0 --- /dev/null +++ b/usr.sbin/periodic/etc/security/700.kernelmsg @@ -0,0 +1,51 @@ +#!/bin/sh - +# +# Copyright (c) 2001  The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# Show kernel log messages +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +. /etc/periodic/security/security.functions + +rc=0 + +if check_yesno_period security_status_kernelmsg_enable +then +	dmesg 2>/dev/null | +	    check_diff new_only dmesg - "${host} kernel log messages:" +	rc=$? +fi + +exit $rc diff --git a/usr.sbin/periodic/etc/security/800.loginfail b/usr.sbin/periodic/etc/security/800.loginfail new file mode 100755 index 000000000000..19bf9a4b3b91 --- /dev/null +++ b/usr.sbin/periodic/etc/security/800.loginfail @@ -0,0 +1,65 @@ +#!/bin/sh - +# +# Copyright (c) 2001  The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# Show login failures +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +LOG="${security_status_logdir}" + +yesterday=`date -v-1d "+%b %e "` + +catmsgs() { +	find ${LOG} -name 'auth.log.*' -mtime -2 | +	    sort -t. -r -n -k 2,2 | +	    while read f +	    do +		zcat -f $f +	    done +	[ -f ${LOG}/auth.log ] && cat $LOG/auth.log +} + +rc=0 + +if check_yesno_period security_status_loginfail_enable +then +	echo "" +	echo "${host} login failures:" +	n=$(catmsgs | egrep -ia "^$yesterday.*: .*\b(fail(ures?|ed)?|invalid|bad|illegal|auth.*error)\b" | +	    tee /dev/stderr | wc -l) +	[ $n -gt 0 ] && rc=1 || rc=0 +fi + +exit $rc diff --git a/usr.sbin/periodic/etc/security/900.tcpwrap b/usr.sbin/periodic/etc/security/900.tcpwrap new file mode 100755 index 000000000000..bbbc04a03988 --- /dev/null +++ b/usr.sbin/periodic/etc/security/900.tcpwrap @@ -0,0 +1,65 @@ +#!/bin/sh - +# +# Copyright (c) 2001  The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# Show tcp_wrapper warning messages +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +LOG="${security_status_logdir}" + +yesterday=`date -v-1d "+%b %e "` + +catmsgs() { +	find ${LOG} -name 'messages.*' -mtime -2 | +	    sort -t. -r -n -k 2,2 | +	    while read f +	    do +		zcat -f $f +	    done +	[ -f ${LOG}/messages ] && cat $LOG/messages +} + +rc=0 + +if check_yesno_period security_status_tcpwrap_enable +then +	echo "" +	echo "${host} refused connections:" +	n=$(catmsgs | grep -i "^$yesterday.*refused connect" | +	    tee /dev/stderr | wc -l) +	[ $n -gt 0 ] && rc=1 || rc=0 +fi + +exit $rc diff --git a/usr.sbin/periodic/etc/security/Makefile b/usr.sbin/periodic/etc/security/Makefile new file mode 100644 index 000000000000..c153523d7c39 --- /dev/null +++ b/usr.sbin/periodic/etc/security/Makefile @@ -0,0 +1,48 @@ +.include <src.opts.mk> + +PACKAGE=	periodic + +CONFGROUPS=	CONFS DATA + +CONFS=	100.chksetuid \ +	110.neggrpperm \ +	200.chkmounts \ +	300.chkuid0 \ +	400.passwdless \ +	410.logincheck \ +	700.kernelmsg \ +	800.loginfail + +DATA=		security.functions +DATAMODE=	444 +DATAPACKAGE=	periodic + +# NB: keep these sorted by MK_* knobs + +.if ${MK_IPFILTER} != "no" +CONFGROUPS+=		IPFILTER +IPFILTER+=		510.ipfdenied +IPFILTER+=		610.ipf6denied +IPFILTERPACKAGE=	ipf +.endif + +.if ${MK_IPFW} != "no" +CONFGROUPS+=	IPFW +IPFW+=		500.ipfwdenied \ +		550.ipfwlimit +IPFWPACKAGE=	ipfw +.endif + +.if ${MK_PF} != "no" +CONFGROUPS+=	PF +PF+=		520.pfdenied +PFPACKAGE=	pf +.endif + +.if ${MK_INETD} != "no" && ${MK_TCP_WRAPPERS} != "no" +CONFGROUPS+=	TCPWRAP +TCPWRAP+=	900.tcpwrap +TCPWRAPPACKAGE=	tcpd +.endif + +.include <bsd.prog.mk> diff --git a/usr.sbin/periodic/etc/security/security.functions b/usr.sbin/periodic/etc/security/security.functions new file mode 100644 index 000000000000..c3ff6eb69391 --- /dev/null +++ b/usr.sbin/periodic/etc/security/security.functions @@ -0,0 +1,83 @@ +#!/bin/sh +# +# Copyright (c) 2001  The FreeBSD Project +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +#    notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +#    notice, this list of conditions and the following disclaimer in the +#    documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# This is a library file, so we only try to do something when sourced. +case "$0" in +*/security.functions) exit 0 ;; +esac + +# +# Show differences in the output of an audit command +# + +LOG="${security_status_logdir}" +rc=0 + +# Usage: COMMAND | check_diff [new_only] LABEL - MSG +#        COMMAND > TMPFILE; check_diff [new_only] LABEL TMPFILE MSG +#   if $1 is new_only, show only the 'new' part of the diff. +#   LABEL is the base name of the ${LOG}/${label}.{today,yesterday} files. + +check_diff() { +  unset IFS +  rc=0 +  if [ "$1" = "new_only" ]; then +    shift +    filter="grep '^[>+][^+]'" +  else +    filter="cat" +  fi +  label="$1"; shift +  tmpf="$1"; shift +  msg="$1"; shift + +  if [ "${tmpf}" = "-" ]; then +    tmpf=`mktemp -t security` +    cat > ${tmpf} +  fi + +  if [ ! -f ${LOG}/${label}.today ]; then +    rc=1 +    echo "" +    echo "No ${LOG}/${label}.today" +    cp ${tmpf} ${LOG}/${label}.today || rc=3 +  fi + +  if ! cmp -s ${LOG}/${label}.today ${tmpf} >/dev/null; then +    [ $rc -lt 1 ] && rc=1 +    echo "" +    echo "${msg}" +    diff ${security_status_diff_flags} ${LOG}/${label}.today \ +	${tmpf} | eval "${filter}" +    mv ${LOG}/${label}.today ${LOG}/${label}.yesterday || rc=3 +    mv ${tmpf} ${LOG}/${label}.today || rc=3 +  fi + +  rm -f ${tmpf} +  exit ${rc} +} diff --git a/usr.sbin/periodic/etc/weekly/310.locate b/usr.sbin/periodic/etc/weekly/310.locate new file mode 100755 index 000000000000..84c0d69610e1 --- /dev/null +++ b/usr.sbin/periodic/etc/weekly/310.locate @@ -0,0 +1,32 @@ +#!/bin/sh - +# +# + +# If there is a global system configuration file, read it. +# +if [ -r /etc/defaults/periodic.conf ]; then +	. /etc/defaults/periodic.conf +	source_periodic_confs +fi + +case "$weekly_locate_enable" in +	[Yy][Ee][Ss]) +	echo "" +	echo "Rebuilding locate database:" + +	. /etc/locate.rc +	: "${FCODES:=/var/db/locate.database}" +	locdb="$FCODES" + +	touch "$locdb" && rc=0 || rc=3 +	chown nobody "$locdb" || rc=3 +	chmod 644 "$locdb" || rc=3 + +	cd / +	echo /usr/libexec/locate.updatedb | nice -n 5 su -fm nobody || rc=3 +	chmod 444 "$locdb" || rc=3;; + +	*)  rc=0;; +esac + +exit "$rc" diff --git a/usr.sbin/periodic/etc/weekly/320.whatis b/usr.sbin/periodic/etc/weekly/320.whatis new file mode 100755 index 000000000000..22d9070a4dbb --- /dev/null +++ b/usr.sbin/periodic/etc/weekly/320.whatis @@ -0,0 +1,50 @@ +#!/bin/sh - +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$weekly_whatis_enable" in +    [Yy][Ee][Ss]) +	echo "" +	echo "Rebuilding whatis database:" + +	MANPATH=`/usr/bin/manpath -q` +	if [ $? = 0 ] +	then +	    if [ -z "${MANPATH}" ] +	    then +		echo "manpath failed to find any manpage directories" +		rc=3 +	    else +		man_locales=`/usr/bin/manpath -qL` +		rc=0 + +	        # Build whatis(1) database(s) for original, non-localized +		#  manpages. +		/usr/libexec/makewhatis.local "${MANPATH}" || rc=3 + +	        # Build whatis(1) database(s) for localized manpages. +		if [ X"${man_locales}" != X ] +		then +		    for i in ${man_locales} +		    do +			LC_ALL=$i /usr/libexec/makewhatis.local -a \ +			    -L "${MANPATH}" || rc=3 +		    done +		fi +	    fi +	else +	    rc=3 +	fi;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/weekly/340.noid b/usr.sbin/periodic/etc/weekly/340.noid new file mode 100755 index 000000000000..6151840ea3c2 --- /dev/null +++ b/usr.sbin/periodic/etc/weekly/340.noid @@ -0,0 +1,57 @@ +#!/bin/sh - +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$weekly_noid_enable" in +    [Yy][Ee][Ss]) +	echo "" +	echo "Check for files with an unknown user or group:" + +	# Host should not test jailed subtrees as jails have their own +	# databases of users and groups. Leave them for jailed invocations +	# of this script. + +	exclude='' +	if [ $(sysctl -n security.jail.jailed) = 0 ]; then +	    # For jail_conf +	    . /etc/rc.subr +	    load_rc_config jail + +	    sep=: +	    OIFS="$IFS" +	    IFS="$sep" +	    for param in $(jail -f "$jail_conf" -e "$sep" 2>/dev/null) +	    do +		case "$param" in +		    path=*) +			_p=${param#path=} +			if [ -z "$_p" -o "$_p" = / ]; then +				continue +			fi + +			exclude="$exclude -path $_p -prune -or" +			;; +		esac +	    done +	    IFS="$OIFS" +	fi + +	rc=$(find -H ${weekly_noid_dirs:-/} \ +	    \( $exclude ! -fstype local -prune -or -name \* \) -and \ +	    \( -nogroup -o -nouser \) -print | sed 's/^/  /' | +	    tee /dev/stderr | wc -l) +	[ $rc -gt 1 ] && rc=1 +	;; + +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/weekly/450.status-security b/usr.sbin/periodic/etc/weekly/450.status-security new file mode 100755 index 000000000000..8bb0c02859c4 --- /dev/null +++ b/usr.sbin/periodic/etc/weekly/450.status-security @@ -0,0 +1,46 @@ +#!/bin/sh +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +case "$weekly_status_security_enable" in +    [Yy][Ee][Ss]) +	echo "" +	echo "Security check:" + +	case "$weekly_status_security_inline" in +	    [Yy][Ee][Ss]) +		weekly_status_security_output="";; +	esac + +	export security_output="${weekly_status_security_output}" +	rc=0 +	case "${weekly_status_security_output}" in +	    "") +		if tempfile=`mktemp ${TMPDIR:-/tmp}/450.status-security.XXXXXX` +		then +			periodic security > $tempfile || rc=3 +			if [ -s "$tempfile" ]; then +				cat "$tempfile" +				rc=3 +			fi +			rm -f "$tempfile" +		fi;; +	    /*) +		echo "    (output logged separately)" +		periodic security || rc=3;; +	    *) +		echo "    (output mailed separately)" +		periodic security || rc=3;; +	esac;; +    *)  rc=0;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/weekly/999.local b/usr.sbin/periodic/etc/weekly/999.local new file mode 100755 index 000000000000..c53e9113cbd2 --- /dev/null +++ b/usr.sbin/periodic/etc/weekly/999.local @@ -0,0 +1,39 @@ +#!/bin/sh - +# +# + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ] +then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +rc=0 +for script in $weekly_local +do +    echo '' +    case "$script" in +	/*) +	    if [ -x "$script" ] +	    then +		echo "Running $script:" + +		$script || rc=3 +	    elif [ -f "$script" ] +	    then +		echo "Running $script:" + +		sh $script || rc=3 +	    else +		echo "$script: No such file" +		[ $rc -lt 2 ] && rc=2 +	    fi;; +	*) +	    echo "$script: Not an absolute path" +	    [ $rc -lt 2 ] && rc=2;; +    esac +done + +exit $rc diff --git a/usr.sbin/periodic/etc/weekly/Makefile b/usr.sbin/periodic/etc/weekly/Makefile new file mode 100644 index 000000000000..d194a988acf0 --- /dev/null +++ b/usr.sbin/periodic/etc/weekly/Makefile @@ -0,0 +1,19 @@ +.include <src.opts.mk> + +PACKAGE=	periodic + +CONFS=	340.noid \ +	450.status-security \ +	999.local + +# NB: keep these sorted by MK_* knobs + +.if ${MK_LOCATE} != "no" +CONFS+=	310.locate +.endif + +.if ${MK_MAN_UTILS} != "no" +CONFS+=	320.whatis +.endif + +.include <bsd.prog.mk> diff --git a/usr.sbin/periodic/periodic.8 b/usr.sbin/periodic/periodic.8 new file mode 100644 index 000000000000..0cd57bab27e2 --- /dev/null +++ b/usr.sbin/periodic/periodic.8 @@ -0,0 +1,265 @@ +.\" Copyright (c) 1997 FreeBSD, Inc. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"    notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"    notice, this list of conditions and the following disclaimer in the +.\"    documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd June 18, 2020 +.Dt PERIODIC 8 +.Os +.Sh NAME +.Nm periodic +.Nd run periodic system functions +.Sh SYNOPSIS +.Nm +.Sm off +.Cm daily | weekly | monthly | security | Ar directory +.Sm on +.Ar ... +.Sh DESCRIPTION +The +.Nm +utility is intended to be called by +.Xr cron 8 +to execute shell scripts +located in the specified directory. +.Pp +One or more of the following arguments must be specified: +.Bl -tag -width "directory" +.It Cm daily +Perform the standard daily periodic executable run. +This usually occurs early in the morning (local time). +.It Cm weekly +Perform the standard weekly periodic executable run. +This usually occurs very early on Saturday mornings. +.It Cm monthly +Perform the standard monthly periodic executable run. +This usually occurs on the first day of the month. +.It Cm security +Perform the standard daily security checks. +This is usually spawned by the +.Cm daily +run. +.It Ar directory +An arbitrary directory containing a set of executables to be run. +.El +.Pp +If an argument is an absolute directory name it is used as is, otherwise +it is searched for under +.Pa /etc/periodic +and any other directories specified by the +.Va local_periodic +setting in +.Xr periodic.conf 5 +(see below). +.Pp +The +.Nm +utility will run each executable file in the directory or directories +specified. +If a file does not have the executable bit set, it is silently ignored. +.Pp +Each script is required to exit with one of the following values: +.Bl -tag -width 4n +.It 0 +The script has produced nothing notable in its output. +The +.Ao Ar basedir Ac Ns Va _show_success +variable controls the masking of this output. +.It 1 +The script has produced some notable information in its output. +The +.Ao Ar basedir Ac Ns Va _show_info +variable controls the masking of this output. +.It 2 +The script has produced some warnings due to invalid configuration settings. +The +.Ao Ar basedir Ac Ns Va _show_badconfig +variable controls the masking of this output. +.It >2 +The script has produced output that must not be masked. +.El +.Pp +If the relevant variable (where +.Aq Ar basedir +is the base directory in which the script resides) is set to +.Dq Li NO +in +.Pa periodic.conf , +.Nm +will mask the script output. +If the variable is not set to either +.Dq Li YES +or +.Dq Li NO , +it will be given a default value as described in +.Xr periodic.conf 5 . +.Pp +All remaining script output is delivered based on the value of the +.Ao Ar basedir Ac Ns Va _output +setting. +.Pp +If this is set to a path name (beginning with a +.Ql / +character), output is simply logged to that file. +.Xr newsyslog 8 +knows about the files +.Pa /var/log/daily.log , /var/log/weekly.log +and +.Pa /var/log/monthly.log , +and if they exist, it will rotate them at the appropriate times. +These are therefore good values if you wish to log +.Nm +output. +.Pp +If the +.Ao Ar basedir Ac Ns Va _output +value does not begin with a +.Ql / +and is not empty, it is assumed to contain a list of email addresses, and +the output is mailed to them. +If +.Ao Ar basedir Ac Ns Va _show_empty_output +is set to +.Dq Li NO , +then no mail will be sent if the output was empty. +.Pp +If +.Ao Ar basedir Ac Ns Va _output +is not set or is empty, output is sent to standard output. +.Sh ENVIRONMENT +The +.Nm +utility sets the +.Ev PATH +environment to include all standard system directories, but no additional +directories, such as +.Pa /usr/local/bin . +If executables are added which depend upon other path components, each +executable must be responsible for configuring its own appropriate environment. +.Sh FILES +.Bl -tag -width ".Pa /etc/defaults/periodic.conf" +.It Pa /etc/crontab +the +.Nm +utility is typically called via entries in the system default +.Xr cron 8 +table +.It Pa /etc/periodic +the top level directory containing +.Pa daily , +.Pa weekly , +.Pa monthly , +and +.Pa security +subdirectories which contain standard system periodic executables +.It Pa /etc/defaults/periodic.conf +the +.Pa periodic.conf +system registry contains variables that control the behaviour of +.Nm +and the standard +.Pa daily , weekly , monthly , +and +.Pa security +scripts +.It Pa /etc/periodic.conf , ${LOCALBASE}/etc/periodic.conf +this file contains local overrides for the default +.Nm +configuration +.El +.Sh EXIT STATUS +Exit status is 0 on success and 1 if the command fails. +.Sh EXAMPLES +The system crontab should have entries for +.Nm +similar to the following example: +.Bd -literal -offset indent +# do daily/weekly/monthly maintenance +0      2       *       *       *       root    periodic daily +0      3       *       *       6       root    periodic weekly +0      5       1       *       *       root    periodic monthly +.Ed +.Pp +The +.Pa /etc/defaults/periodic.conf +system registry will typically have a +.Va local_periodic +variable reading: +.Pp +.Dl local_periodic="${_localbase}/etc/periodic" +.Pp +where +.Pa ${_localbase} +is being set from within +.Pa /usr/sbin/periodic . +.Pp +To log +.Nm +output instead of receiving it as email, add the following lines to +.Pa /etc/periodic.conf : +.Bd -literal -offset indent +daily_output=/var/log/daily.log +weekly_output=/var/log/weekly.log +monthly_output=/var/log/monthly.log +.Ed +.Pp +To only see important information from daily periodic jobs, add the +following lines to +.Pa /etc/periodic.conf : +.Bd -literal -offset indent +daily_show_success=NO +daily_show_info=NO +daily_show_badconfig=NO +.Ed +.Sh DIAGNOSTICS +The command may fail for one of the following reasons: +.Bl -diag +.It usage: periodic <directory of files to execute> +No directory path argument was passed to +.Nm +to specify where the script fragments reside. +.It <directory> not found +Self explanatory. +.El +.Sh SEE ALSO +.Xr sh 1 , +.Xr crontab 5 , +.Xr periodic.conf 5 , +.Xr cron 8 , +.Xr newsyslog 8 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 3.0 . +.Sh AUTHORS +.An Paul Traina Aq Mt pst@FreeBSD.org +.An Brian Somers Aq Mt brian@Awfulhak.org +.Sh BUGS +Since one specifies information about a directory using shell +variables containing the string, +.Aq Ar basedir , +.Aq Ar basedir +must only contain characters that are valid within a +.Xr sh 1 +variable name, alphanumerics and underscores, and the first character +may not be numeric. diff --git a/usr.sbin/periodic/periodic.conf b/usr.sbin/periodic/periodic.conf new file mode 100644 index 000000000000..7066c7b49fd1 --- /dev/null +++ b/usr.sbin/periodic/periodic.conf @@ -0,0 +1,420 @@ +#!/bin/sh +# +# This is defaults/periodic.conf - a file full of useful variables that +# you can set to change the default behaviour of periodic jobs on your +# system.  You should not edit this file!  Put any overrides into one of the +# $periodic_conf_files instead and you will be able to update these defaults +# later without spamming your local configuration information. +# +# The $periodic_conf_files files should only contain values which override +# values set in this file.  This eases the upgrade path when defaults +# are changed and new features are added. +# +# For a more detailed explanation of all the periodic.conf variables, please +# refer to the periodic.conf(5) manual page. +# +# + +_set_localbase() { +	_localbase=`/sbin/sysctl -n user.localbase 2> /dev/null` +	# Set default value of _localbase if not previously set +	: ${_localbase:="/usr/local"} +} + +# Set _localbase with fallback to /usr/local +_set_localbase + +# What files override these defaults ? +periodic_conf_files="/etc/periodic.conf /etc/periodic.conf.local ${_localbase}/etc/periodic.conf" + +# periodic script dirs. _localbase is being set in /usr/sbin/periodic +local_periodic="${_localbase}/etc/periodic" + +# Max time to sleep to avoid causing congestion on download servers +anticongestion_sleeptime=3600 + +# Daily options + +# These options are used by periodic(8) itself to determine what to do +# with the output of the sub-programs that are run, and where to send +# that output.  $daily_output might be set to /var/log/daily.log if you +# wish to log the daily output and have the files rotated by newsyslog(8) +# +daily_diff_flags="-b -U 0"				# flags for diff output +daily_output="root"					# user or /file +daily_show_success="YES"				# scripts returning 0 +daily_show_info="YES"					# scripts returning 1 +daily_show_badconfig="NO"				# scripts returning 2 + +# 100.clean-disks +daily_clean_disks_enable="NO"				# Delete files daily +daily_clean_disks_files="[#,]* .#* a.out *.core *.CKP .emacs_[0-9]*" +daily_clean_disks_days=3				# If older than this +daily_clean_disks_verbose="YES"				# Mention files deleted + +# 110.clean-tmps +daily_clean_tmps_enable="NO"				# Delete stuff daily +daily_clean_tmps_dirs="/tmp"				# Delete under here +daily_clean_tmps_days="3"				# If not accessed for +daily_clean_tmps_ignore=".X*-lock .X11-unix .ICE-unix .font-unix .XIM-unix" +daily_clean_tmps_ignore="$daily_clean_tmps_ignore quota.user quota.group .snap" +daily_clean_tmps_ignore="$daily_clean_tmps_ignore .sujournal" +							# Don't delete these +daily_clean_tmps_verbose="YES"				# Mention files deleted + +# 120.clean-preserve +daily_clean_preserve_enable="YES"			# Delete files daily +daily_clean_preserve_days=7				# If not modified for +daily_clean_preserve_verbose="YES"			# Mention files deleted + +# 130.clean-msgs +daily_clean_msgs_enable="YES"				# Delete msgs daily +daily_clean_msgs_days=					# If not modified for + +# 140.clean-rwho +daily_clean_rwho_enable="YES"				# Delete rwho daily +daily_clean_rwho_days=7					# If not modified for +daily_clean_rwho_verbose="YES"				# Mention files deleted + +# 150.clean-hoststat +daily_clean_hoststat_enable="YES"			# Purge sendmail host +							# status cache daily + +# 200.backup-passwd +daily_backup_passwd_enable="YES"			# Backup passwd & group + +# 210.backup-aliases +daily_backup_aliases_enable="YES"			# Backup mail aliases + +# 221.backup-gpart +if [ $(sysctl -n security.jail.jailed) = 0 ]; then +        # Backup partition table/boot partition/MBR +        daily_backup_gpart_enable="YES" +else +        daily_backup_gpart_enable="NO" +fi +daily_backup_gpart_verbose="NO"             		# Be verbose if new backup differs from the old one +daily_backup_efi_enable="NO"                		# Backup EFI system partition (ESP) + +# 222.backup-gmirror +daily_backup_gmirror_enable="NO"			# Backup of gmirror info (i.e., output of `gmirror list`) +daily_backup_gmirror_verbose="NO"			# Log diff if new backup differs from the old one + +# 223.backup-zfs +daily_backup_zfs_enable="NO"				# Backup output from zpool/zfs list +daily_backup_zfs_props_enable="NO"			# Backup zpool/zfs filesystem properties +daily_backup_zfs_get_flags="all"			# flags passed to `zfs get` +daily_backup_zfs_list_flags=""				# flags passed to `zfs list` +daily_backup_zpool_get_flags="all"			# flags passed to `zpool get` +daily_backup_zpool_list_flags="-v"			# flags passed to `zpool list` +daily_backup_zfs_verbose="NO"				# Report diff between the old and new backups. + +# 300.calendar +daily_calendar_enable="NO"				# Run calendar -a + +# 310.accounting +daily_accounting_enable="YES"				# Rotate acct files +daily_accounting_compress="NO"				# Gzip rotated files +daily_accounting_flags=-q				# Flags to /usr/sbin/sa +daily_accounting_save=3					# How many files to save + +# 400.status-disks +daily_status_disks_enable="YES"				# Check disk status +daily_status_disks_df_flags="-l -h"			# df(1) flags for check + +# 401.status-graid +daily_status_graid_enable="NO"				# Check graid(8) + +# 404.status-zfs +daily_status_zfs_enable="NO"				# Check ZFS +daily_status_zfs_zpool_list_enable="YES"		# List ZFS pools + +# 406.status-gmirror +daily_status_gmirror_enable="NO"			# Check gmirror(8) + +# 407.status-graid3 +daily_status_graid3_enable="NO" 			# Check graid3(8) + +# 408.status-gstripe +daily_status_gstripe_enable="NO"			# Check gstripe(8) + +# 409.status-gconcat +daily_status_gconcat_enable="NO"			# Check gconcat(8) + +# 410.status-mfi +daily_status_mfi_enable="NO"				# Check mfiutil(8) + +# 420.status-network +daily_status_network_enable="YES"			# Check network status +daily_status_network_usedns="YES"			# DNS lookups are ok +daily_status_network_netstat_flags="-d -W"		# netstat(1) flags + +# 430.status-uptime +daily_status_uptime_enable="YES"			# Check system uptime + +# 440.status-mailq +daily_status_mailq_enable="YES"				# Check mail status +daily_status_mailq_shorten="NO"				# Shorten output +daily_status_include_submit_mailq="YES"			# Also submit queue + +# 450.status-security +daily_status_security_enable="YES"			# Security check +# See also "Security options" below for more options +daily_status_security_inline="NO"			# Run inline ? +daily_status_security_output="root"			# user or /file + +# 460.status-mail-rejects +daily_status_mail_rejects_enable="YES"			# Check mail rejects +daily_status_mail_rejects_logs=3			# How many logs to check +daily_status_mail_rejects_shorten="NO"			# Shorten output + +# 480.leapfile-ntpd +daily_ntpd_leapfile_enable="YES"			# Fetch NTP leapfile + +# 480.status-ntpd +daily_status_ntpd_enable="NO"				# Check NTP status + +# 500.queuerun +daily_queuerun_enable="YES"				# Run mail queue +daily_submit_queuerun="YES"				# Also submit queue + +# 510.status-world-kernel +daily_status_world_kernel="YES"				# Check the running +							# userland/kernel version + +# 800.scrub-zfs +daily_scrub_zfs_enable="NO" +daily_scrub_zfs_pools=""			# empty string selects all pools +daily_scrub_zfs_default_threshold="35"		# days between scrubs +#daily_scrub_zfs_${poolname}_threshold="35"	# pool specific threshold + +# 801.trim-zfs +daily_trim_zfs_enable="NO" +daily_trim_zfs_pools=""				# empty string selects all pools +daily_trim_zfs_flags=""				# zpool-trim(8) flags + +# 999.local +daily_local="/etc/daily.local"				# Local scripts + + +# Weekly options + +# These options are used by periodic(8) itself to determine what to do +# with the output of the sub-programs that are run, and where to send +# that output.  $weekly_output might be set to /var/log/weekly.log if you +# wish to log the weekly output and have the files rotated by newsyslog(8) +# +weekly_output="root"					# user or /file +weekly_show_success="YES"				# scripts returning 0 +weekly_show_info="YES"					# scripts returning 1 +weekly_show_badconfig="NO"				# scripts returning 2 + +# 310.locate +weekly_locate_enable="YES"				# Update locate weekly + +# 320.whatis +weekly_whatis_enable="YES"				# Update whatis weekly + +# 340.noid +weekly_noid_enable="NO"					# Find unowned files +weekly_noid_dirs="/"					# Look here + +# 450.status-security +weekly_status_security_enable="YES"			# Security check +# See also "Security options" above for more options +weekly_status_security_inline="NO"			# Run inline ? +weekly_status_security_output="root"			# user or /file + +# 999.local +weekly_local="/etc/weekly.local"			# Local scripts + + +# Monthly options + +# These options are used by periodic(8) itself to determine what to do +# with the output of the sub-programs that are run, and where to send +# that output.  $monthly_output might be set to /var/log/monthly.log if you +# wish to log the monthly output and have the files rotated by newsyslog(8) +# +monthly_output="root"					# user or /file +monthly_show_success="YES"				# scripts returning 0 +monthly_show_info="YES"					# scripts returning 1 +monthly_show_badconfig="NO"				# scripts returning 2 + +# 200.accounting +monthly_accounting_enable="YES"				# Login accounting + +# 450.status-security +monthly_status_security_enable="YES"			# Security check +# See also "Security options" above for more options +monthly_status_security_inline="NO"			# Run inline ? +monthly_status_security_output="root"			# user or /file + +# 999.local +monthly_local="/etc/monthly.local"			# Local scripts + + +# Security options + +security_show_success="YES"				# scripts returning 0 +security_show_info="YES"				# scripts returning 1 +security_show_badconfig="NO"				# scripts returning 2 + +# These options are used by the security periodic(8) scripts spawned in +# daily and weekly 450.status-security. +security_status_logdir="/var/log"			# Directory for logs +security_status_diff_flags="-b -U 0"			# flags for diff output + +# Each of the security_status_*_period options below can have one of the +# following values: +# - NO: do not run at all +# - daily: only run during the daily security status +# - weekly: only run during the weekly security status +# - monthly: only run during the monthly security status +# Note that if periodic security scripts are run from crontab(5) directly, +# they will be run unless _enable or _period is set to "NO". + +# 100.chksetuid +security_status_chksetuid_enable="YES" +security_status_chksetuid_period="daily" + +# 110.neggrpperm +security_status_neggrpperm_enable="YES" +security_status_neggrpperm_period="daily" + +# 200.chkmounts +security_status_chkmounts_enable="YES" +security_status_chkmounts_period="daily" +#security_status_chkmounts_ignore="^amd:"		# Don't check matching +							# FS types +security_status_noamd="NO"				# Don't check amd mounts + +# 300.chkuid0 +security_status_chkuid0_enable="YES" +security_status_chkuid0_period="daily" + +# 400.passwdless +security_status_passwdless_enable="YES" +security_status_passwdless_period="daily" + +# 410.logincheck +security_status_logincheck_enable="YES" +security_status_logincheck_period="daily" + +# 500.ipfwdenied +security_status_ipfwdenied_enable="YES" +security_status_ipfwdenied_period="daily" + +# 510.ipfdenied +security_status_ipfdenied_enable="YES" +security_status_ipfdenied_period="daily" + +# 520.pfdenied +security_status_pfdenied_enable="YES" +security_status_pfdenied_period="daily" +security_status_pfdenied_additionalanchors="" + +# 550.ipfwlimit +security_status_ipfwlimit_enable="YES" +security_status_ipfwlimit_period="daily" + +# 610.ipf6denied +security_status_ipf6denied_enable="YES" +security_status_ipf6denied_period="daily" + +# 700.kernelmsg +security_status_kernelmsg_enable="YES" +security_status_kernelmsg_period="daily" + +# 800.loginfail +security_status_loginfail_enable="YES" +security_status_loginfail_period="daily" + +# 900.tcpwrap +security_status_tcpwrap_enable="YES" +security_status_tcpwrap_period="daily" + + + +# Define source_periodic_confs, the mechanism used by /etc/periodic/*/* +# scripts to source defaults/periodic.conf overrides safely. + +if [ -z "${source_periodic_confs_defined}" ]; then +        source_periodic_confs_defined=yes + +	# Sleep for a random amount of time in order to mitigate the thundering +	# herd problem of multiple hosts running periodic simultaneously. +	# Will not sleep when used interactively. +	# Will sleep at most once per invocation of periodic +	anticongestion() { +		[ -n "$PERIODIC_IS_INTERACTIVE" ] && return +		if [ -f "$PERIODIC_ANTICONGESTION_FILE" ]; then +			rm -f $PERIODIC_ANTICONGESTION_FILE +			sleep `jot -r 1 0 ${anticongestion_sleeptime}` +		fi +	} + +	check_yesno_period() { +		local var="$1" periodvar value period + +		eval value=\"\$$var\" +		case "$value" in +		[Yy][Ee][Ss]) ;; +		*) return 1 ;; +		esac + +		periodvar=${var%enable}period +		eval period=\"\$$periodvar\" +		case "$PERIODIC" in +		"security daily") +			case "$period" in +			[Dd][Aa][Ii][Ll][Yy]) return 0 ;; +			*) return 1 ;; +			esac +			;; +		"security weekly") +			case "$period" in +			[Ww][Ee][Ee][Kk][Ll][Yy]) return 0 ;; +			*) return 1 ;; +			esac +			;; +		"security monthly") +			case "$period" in +			[Mm][Oo][Nn][Tt][Hh][Ll][Yy]) return 0 ;; +			*) return 1 ;; +			esac +			;; +		security) +			# Run directly from crontab(5). +			case "$period" in +			[Nn][Oo]) return 1 ;; +			*) return 0 ;; +			esac +			;; +                '') +                        # Script run manually. +                        return 0 +                        ;; +		*) +			echo "ASSERTION FAILED: Unexpected value for" \ +			    "\$PERIODIC: '$PERIODIC'" >&2 +			exit 127 +			;; +		esac +	} + +        source_periodic_confs() { +                local i sourced_files + +                for i in ${periodic_conf_files}; do +                        case ${sourced_files} in +                        *:$i:*) +                                ;; +                        *) +                                sourced_files="${sourced_files}:$i:" +                                [ -r $i ] && . $i +                                ;; +                        esac +                done +        } +fi diff --git a/usr.sbin/periodic/periodic.sh b/usr.sbin/periodic/periodic.sh new file mode 100644 index 000000000000..a310f04864da --- /dev/null +++ b/usr.sbin/periodic/periodic.sh @@ -0,0 +1,160 @@ +#!/bin/sh - +# +# +# Run nightly periodic scripts +# +# usage: periodic { daily | weekly | monthly | security } - run standard scripts +#        periodic /absolute/path/to/directory  - run periodic scripts in dir +# + +usage () { +    echo "usage: $0 <directory of files to execute>" 1>&2 +    echo "or     $0 { daily | weekly | monthly | security }"    1>&2 +    exit 1 +} + +output_pipe() +{ +    # Where's our output going ? +    eval output=\$${1##*/}_output +    case "$output" in +    /*) pipe="cat >>$output";; +    "") pipe=cat;; +    *)  pipe="mail -E -s '$host ${2}${2:+ }${1##*/} run output' $output";; +    esac +    eval $pipe +} + +if [ $# -lt 1 ] ; then +    usage +fi + +# If possible, check the global system configuration file, +# to see if there are additional dirs to check +if [ -r /etc/defaults/periodic.conf ]; then +    . /etc/defaults/periodic.conf +    source_periodic_confs +fi + +# Use a deterministic path to match the preset from /etc/crontab in case +# periodic is run interactively. +export PATH=/sbin:/bin:/usr/sbin:/usr/bin:${_localbase}/sbin:${_localbase}/bin + +host=`hostname` +export host + +# If we were called normally, then create a lock file for each argument +# in turn and reinvoke ourselves with the LOCKED argument.  This prevents +# very long running jobs from being overlapped by another run as this is +# will lead the system running progressively slower and more and more jobs +# are run at once. +if [ $1 != "LOCKED" ]; then +    ret=0 +    for arg; do +        lockfile=/var/run/periodic.${arg##*/}.lock +        lockf -s -t 0 "${lockfile}" /bin/sh $0 LOCKED "$arg" +        case $? in +        0) ;; +        73) #EX_CANTCREATE +            echo "can't create ${lockfile}" | \ +                output_pipe $arg "$PERIODIC" +            ret=1 +            ;; +        75) #EX_TEMPFAIL +            echo "$host ${arg##*/} prior run still in progress" | \ +                output_pipe $arg "$PERIODIC" +            ret=1 +            ;; +        *) +            ret=1 +            ;; +        esac +    done +    exit $ret +fi + +if [ $# -ne 2 ]; then +    usage +fi +shift +arg=$1 + +if [ -z "$PERIODIC_ANTICONGESTION_FILE" ] ; then +	export PERIODIC_ANTICONGESTION_FILE=`mktemp ${TMPDIR:-/tmp}/periodic.anticongestion.XXXXXXXXXX` +	remove_periodic_anticongestion_file=yes +else +	# We might be in a recursive invocation; let the top-level invocation +	# remove the file. +	remove_periodic_anticongestion_file=no +fi +if [ -t 0 ]; then +	export PERIODIC_IS_INTERACTIVE=1 +fi +tmp_output=`mktemp ${TMPDIR:-/tmp}/periodic.XXXXXXXXXX` +context="$PERIODIC" +export PERIODIC="$arg${PERIODIC:+ }${PERIODIC}" + +# Execute each executable file in the directory list.  If the x bit is not +# set, assume the user didn't really want us to muck with it (it's a +# README file or has been disabled). + +success=YES info=YES badconfig=NO empty_output=YES	# Defaults when ${run}_* aren't YES/NO +for var in success info badconfig empty_output; do +    case $(eval echo "\$${arg##*/}_show_$var") in +    [Yy][Ee][Ss]) eval $var=YES;; +    [Nn][Oo])     eval $var=NO;; +    esac +done + +case $arg in +/*) if [ -d "$arg" ]; then +        dirlist="$arg" +    else +        echo "$0: $arg not found" >&2 +        exit 1 +    fi +    ;; +*)  dirlist= +    for top in /etc/periodic ${local_periodic}; do +        [ -d $top/$arg ] && dirlist="$dirlist $top/$arg" +    done +    ;; +esac + +{ +    empty=TRUE +    processed=0 +    for dir in $dirlist; do +        for file in $dir/*; do +            if [ -x $file -a ! -d $file ]; then +                output=TRUE +                processed=$(($processed + 1)) +                $file </dev/null >$tmp_output 2>&1 +                rc=$? +                if [ -s $tmp_output ]; then +                    case $rc in +                    0)  [ $success = NO ] && output=FALSE;; +                    1)  [ $info = NO ] && output=FALSE;; +                    2)  [ $badconfig = NO ] && output=FALSE;; +                    esac +                    [ $output = TRUE ] && { cat $tmp_output; empty=FALSE; } +                fi +                cp /dev/null $tmp_output +            fi +        done +    done +    if [ $empty = TRUE ]; then +        if [ $empty_output = TRUE ]; then +            [ $processed = 1 ] && plural= || plural=s +            echo "No output from the $processed file$plural processed" +        fi +    else +        echo "" +        echo "-- End of $arg output --" +    fi +} | output_pipe $arg "$context" + +rm -f $tmp_output +if [ $remove_periodic_anticongestion_file = "yes" ] ; then +	rm -f $PERIODIC_ANTICONGESTION_FILE +fi | 
