aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/periodic
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/periodic')
-rw-r--r--usr.sbin/periodic/Makefile10
-rw-r--r--usr.sbin/periodic/Makefile.depend10
-rw-r--r--usr.sbin/periodic/etc/Makefile4
-rw-r--r--usr.sbin/periodic/etc/Makefile.inc4
-rwxr-xr-xusr.sbin/periodic/etc/daily/100.clean-disks54
-rwxr-xr-xusr.sbin/periodic/etc/daily/110.clean-tmps59
-rwxr-xr-xusr.sbin/periodic/etc/daily/120.clean-preserve52
-rwxr-xr-xusr.sbin/periodic/etc/daily/130.clean-msgs34
-rwxr-xr-xusr.sbin/periodic/etc/daily/140.clean-rwho52
-rwxr-xr-xusr.sbin/periodic/etc/daily/150.clean-hoststat30
-rwxr-xr-xusr.sbin/periodic/etc/daily/200.backup-passwd76
-rwxr-xr-xusr.sbin/periodic/etc/daily/210.backup-aliases46
-rwxr-xr-xusr.sbin/periodic/etc/daily/221.backup-gpart122
-rwxr-xr-xusr.sbin/periodic/etc/daily/222.backup-gmirror70
-rwxr-xr-xusr.sbin/periodic/etc/daily/223.backup-zfs78
-rwxr-xr-xusr.sbin/periodic/etc/daily/300.calendar28
-rwxr-xr-xusr.sbin/periodic/etc/daily/310.accounting69
-rwxr-xr-xusr.sbin/periodic/etc/daily/400.status-disks39
-rwxr-xr-xusr.sbin/periodic/etc/daily/401.status-graid33
-rwxr-xr-xusr.sbin/periodic/etc/daily/404.status-zfs44
-rwxr-xr-xusr.sbin/periodic/etc/daily/406.status-gmirror33
-rwxr-xr-xusr.sbin/periodic/etc/daily/407.status-graid333
-rwxr-xr-xusr.sbin/periodic/etc/daily/408.status-gstripe33
-rwxr-xr-xusr.sbin/periodic/etc/daily/409.status-gconcat33
-rw-r--r--usr.sbin/periodic/etc/daily/410.status-mfi32
-rwxr-xr-xusr.sbin/periodic/etc/daily/420.status-network30
-rwxr-xr-xusr.sbin/periodic/etc/daily/430.status-uptime37
-rwxr-xr-xusr.sbin/periodic/etc/daily/440.status-mailq65
-rwxr-xr-xusr.sbin/periodic/etc/daily/450.status-security46
-rwxr-xr-xusr.sbin/periodic/etc/daily/460.status-mail-rejects78
-rwxr-xr-xusr.sbin/periodic/etc/daily/480.leapfile-ntpd22
-rwxr-xr-xusr.sbin/periodic/etc/daily/480.status-ntpd27
-rwxr-xr-xusr.sbin/periodic/etc/daily/500.queuerun35
-rwxr-xr-xusr.sbin/periodic/etc/daily/510.status-world-kernel35
-rwxr-xr-xusr.sbin/periodic/etc/daily/800.scrub-zfs109
-rwxr-xr-xusr.sbin/periodic/etc/daily/801.trim-zfs59
-rwxr-xr-xusr.sbin/periodic/etc/daily/999.local42
-rw-r--r--usr.sbin/periodic/etc/daily/Makefile77
-rwxr-xr-xusr.sbin/periodic/etc/monthly/200.accounting64
-rwxr-xr-xusr.sbin/periodic/etc/monthly/450.status-security46
-rwxr-xr-xusr.sbin/periodic/etc/monthly/999.local39
-rw-r--r--usr.sbin/periodic/etc/monthly/Makefile20
-rwxr-xr-xusr.sbin/periodic/etc/security/100.chksetuid59
-rwxr-xr-xusr.sbin/periodic/etc/security/110.neggrpperm58
-rwxr-xr-xusr.sbin/periodic/etc/security/200.chkmounts60
-rwxr-xr-xusr.sbin/periodic/etc/security/300.chkuid051
-rwxr-xr-xusr.sbin/periodic/etc/security/400.passwdless48
-rwxr-xr-xusr.sbin/periodic/etc/security/410.logincheck52
-rwxr-xr-xusr.sbin/periodic/etc/security/500.ipfwdenied51
-rwxr-xr-xusr.sbin/periodic/etc/security/510.ipfdenied51
-rwxr-xr-xusr.sbin/periodic/etc/security/520.pfdenied56
-rwxr-xr-xusr.sbin/periodic/etc/security/550.ipfwlimit66
-rwxr-xr-xusr.sbin/periodic/etc/security/610.ipf6denied51
-rwxr-xr-xusr.sbin/periodic/etc/security/700.kernelmsg51
-rwxr-xr-xusr.sbin/periodic/etc/security/800.loginfail65
-rwxr-xr-xusr.sbin/periodic/etc/security/900.tcpwrap65
-rw-r--r--usr.sbin/periodic/etc/security/Makefile48
-rw-r--r--usr.sbin/periodic/etc/security/security.functions83
-rwxr-xr-xusr.sbin/periodic/etc/weekly/310.locate32
-rwxr-xr-xusr.sbin/periodic/etc/weekly/320.whatis50
-rwxr-xr-xusr.sbin/periodic/etc/weekly/340.noid57
-rwxr-xr-xusr.sbin/periodic/etc/weekly/450.status-security46
-rwxr-xr-xusr.sbin/periodic/etc/weekly/999.local39
-rw-r--r--usr.sbin/periodic/etc/weekly/Makefile19
-rw-r--r--usr.sbin/periodic/periodic.8265
-rw-r--r--usr.sbin/periodic/periodic.conf420
-rw-r--r--usr.sbin/periodic/periodic.sh160
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