[BACK]Return to rc CVS log [TXT][DIR] Up to [local] / src / etc

File: [local] / src / etc / rc (download)

Revision 1.505, Tue Jun 27 03:42:00 2017 UTC (6 years, 11 months ago) by tedu
Branch: MAIN
Changes since 1.504: +2 -8 lines

remove some old cruft.

#	$OpenBSD: rc,v 1.505 2017/06/27 03:42:00 tedu Exp $

# System startup script run by init on autoboot or after single-user.
# Output and error are redirected to console by init, and the console is the
# controlling terminal.

# Turn off Strict Bourne shell.
set +o sh

# Subroutines (have to come first).

# Strip in- and whole-line comments from a file.
# Strip leading and trailing whitespace if IFS is set.
# Usage: stripcom /path/to/file
stripcom() {
	local _file=$1 _line

	[[ -s $_file ]] || return

	while read _line ; do
		_line=${_line%%#*}
		[[ -n $_line ]] && print -r -- "$_line"
	done <$_file
}

# Update resource limits based on login.conf settings.
# Usage: update_limit -flag capability
update_limit() {
	local _flag=$1		# ulimit flag
	local _cap=$2 _val	# login.conf capability and its value
	local _suffix

	for _suffix in {,-max,-cur}; do
		_val=$(getcap -f /etc/login.conf -s ${_cap}${_suffix} daemon 2>/dev/null)
		[[ -n $_val ]] || continue
		[[ $_val == infinity ]] && _val=unlimited

		case $_suffix in
		-cur)	ulimit -S $_flag $_val
			;;
		-max)	ulimit -H $_flag $_val
			;;
		*)	ulimit $_flag $_val
			return
			;;
		esac
	done
}

# Apply sysctl.conf(5) settings.
sysctl_conf() {
	stripcom /etc/sysctl.conf |
	while read _line; do
		sysctl "$_line"

		case $_line in
		kern.maxproc=*)
			update_limit -p maxproc;;
		kern.maxfiles=*)
			update_limit -n openfiles;;
		esac
	done
}

# Apply mixerctl.conf(5) settings.
mixerctl_conf() {
	stripcom /etc/mixerctl.conf |
	while read _line; do
		mixerctl -q "$_line" 2>/dev/null
	done
}

# Apply wsconsctl.conf(5) settings.
wsconsctl_conf() {
	[[ -x /sbin/wsconsctl ]] || return

	stripcom /etc/wsconsctl.conf |
	while read _line; do
		eval "wsconsctl $_line"
	done
}

# Push the old seed into the kernel, create a future seed  and create a seed
# file for the boot-loader.
random_seed() {
	dd if=/var/db/host.random of=/dev/random bs=65536 count=1 status=none
	chmod 600 /var/db/host.random
	dd if=/dev/random of=/var/db/host.random bs=65536 count=1 status=none
	dd if=/dev/random of=/etc/random.seed bs=512 count=1 status=none
	chmod 600 /etc/random.seed
}

# Populate net.inet.(tcp|udp).baddynamic with the contents of /etc/services so
# as to avoid randomly allocating source ports that correspond to well-known
# services.
# Usage: fill_baddynamic tcp|udp
fill_baddynamic() {
	local _service=$1
	local _sysctl="net.inet.${_service}.baddynamic"

	stripcom /etc/services |
	{
		_ban=
		while IFS=" 	/" read _name _port _srv _junk; do
			[[ $_srv == $_service ]] || continue

			_ban="${_ban:+$_ban,}+$_port"

			# Flush before argv gets too long
			if ((${#_ban} > 1024)); then
				sysctl -q "$_sysctl=$_ban"
				_ban=
			fi
		done
		[[ -n $_ban ]] && sysctl -q "$_sysctl=$_ban"
	}
}

# Start daemon using the rc.d daemon control scripts.
# Usage: start_daemon daemon1 daemon2 daemon3
start_daemon() {
	local _daemon

	for _daemon; do
		eval "_do=\${${_daemon}_flags}"
		[[ $_do != NO ]] && /etc/rc.d/${_daemon} start
	done
}

# Generate keys for isakmpd, iked and sshd if they don't exist yet.
make_keys() {
	local _isakmpd_key=/etc/isakmpd/private/local.key
	local _isakmpd_pub=/etc/isakmpd/local.pub
	local _iked_key=/etc/iked/private/local.key
	local _iked_pub=/etc/iked/local.pub

	if [[ ! -f $_isakmpd_key ]]; then
		echo -n "openssl: generating isakmpd/iked RSA keys... "
		if openssl genrsa -out $_isakmpd_key 2048 >/dev/null 2>&1 &&
			chmod 600 $_isakmpd_key &&
			openssl rsa -out $_isakmpd_pub -in $_isakmpd_key \
			    -pubout >/dev/null 2>&1; then
			echo done.
		else
			echo failed.
		fi
	fi

	if [[ ! -f $_iked_key ]]; then
		# Just copy the generated isakmpd key
		cp $_isakmpd_key $_iked_key
		chmod 600 $_iked_key
		cp $_isakmpd_pub $_iked_pub
	fi

	ssh-keygen -A
}

# Re-link libraries, placing the objects in a random order.
reorder_libs() {
	local _dkdev _l _liba _libas _mp _tmpdir _remount=false _error=false

	[[ $library_aslr == NO ]] && return

	_dkdev=$(df /usr/lib | sed '1d;s/ .*//')
	_mp=$(mount | grep "^$_dkdev")

	# Skip if /usr/lib is on a nfs mounted filesystem.
	[[ $_mp == *' type nfs '* ]] && return

	echo -n 'reordering libraries:'

	# Only choose the latest version of the libraries.
	for _liba in /usr/lib/libc.so.*.a /usr/lib/libcrypto.so.*.a; do
		_liba=$(ls ${_liba%%.[0-9]*}*.a | sort -V | tail -1)
		for _l in $_libas; do
			[[ $_l == $_liba ]] && continue 2
		done
		_libas="$_libas $_liba"
	done

	# Remount read-write, if /usr/lib is on a read-only ffs filesystem.
	if [[ $_mp == *' type ffs '*'read-only'* ]]; then
		if mount -u -w $_dkdev; then
			_remount=true
		else
			echo ' failed.'
			return
		fi
	fi

	for _liba in $_libas; do
		_tmpdir=$(mktemp -dq /tmp/_librebuild.XXXXXXXXXXXX) && (
			set -o errexit
			_lib=${_liba#/usr/lib/}
			_lib=${_lib%.a}
			cd $_tmpdir
			ar x ${_liba}
			cc -shared -o $_lib $(ls *.so | sort -R) $(cat .ldadd)
			[[ -s $_lib ]] && file $_lib | fgrep -q 'shared object'
			LD_BIND_NOW=1 LD_LIBRARY_PATH=$_tmpdir awk 'BEGIN {exit 0}'
			LD_BIND_NOW=1 LD_LIBRARY_PATH=$_tmpdir openssl \
			    x509 -in /etc/ssl/cert.pem -out /dev/null
			install -F -S -o root -g bin -m 0444 $_lib /usr/lib/$_lib
		) || { _error=true; break; }
	done

	rm -rf /tmp/_librebuild.*

	# Restore previous mount state if it was changed.
	if $_remount; then
		mount -u -r $_dkdev || _error=true
	fi

	if $_error; then
		echo ' failed.'
	else
		echo ' done.'
	fi
}

# Re-link the kernel, placing the objects in a random order.
# Replace current with relinked kernel and inform root about it.
reorder_kernel() {
	(
	set -e
	_compile_dir=/usr/share/compile
	_kernel=$(sysctl -n kern.osversion)
	_kernel=${_kernel%#*}
	_kernel_dir=$_compile_dir/$_kernel
	_sha256=/var/db/kernel.SHA256

	if [[ -f /usr/share/compile.tgz ]]; then
		rm -rf $_compile_dir
		mkdir -m 700 -p $_compile_dir
		tar -C $_compile_dir -xzf /usr/share/compile.tgz $_kernel
		rm -f /usr/share/compile.tgz
	fi

	sha256 -q -C $_sha256 /bsd

	cd $_kernel_dir
	make newbsd   >$_kernel_dir/log 2>&1
	make newinstall >>$_kernel_dir/log 2>&1
	(umask 077 && sha256 -h $_sha256 /bsd)

	(echo "Kernel has been relinked and is active on next reboot\n"; \
		cat $_sha256; echo "\nRelink log:\n"; cat $_kernel_dir/log ) |
		mail -Es "$(hostname) Kernel relink info" root >/dev/null

	) >/dev/null 2>&1 &
}

# Run rc.* script and email output to root.
# Usage: run_upgrade_script firsttime|sysmerge
run_upgrade_script() {
	local _suffix=$1

	[[ -n $_suffix ]] || return 1

	if [[ -f /etc/rc.$_suffix ]]; then
		mv /etc/rc.$_suffix /etc/rc.$_suffix.run
		. /etc/rc.$_suffix.run 2>&1 | tee /dev/tty |
			mail -Es "$(hostname) rc.$_suffix output" root >/dev/null
	fi
	rm -f /etc/rc.$_suffix.run
}

# Check filesystems, optionally by using a fsck(8) flag.
# Usage: do_fsck [-flag]
do_fsck() {
	fsck -p "$@"
	case $? in
	0)	;;
	2)	exit 1
		;;
	4)	echo "Rebooting..."
		reboot
		echo "Reboot failed; help!"
		exit 1
		;;
	8)	echo "Automatic file system check failed; help!"
		exit 1
		;;
	12)	echo "Boot interrupted."
		exit 1
		;;
	130)	# Interrupt before catcher installed.
		exit 1
		;;
	*)	echo "Unknown error; help!"
		exit 1
		;;
	esac
}

# End subroutines.

stty status '^T'

# Set shell to ignore SIGINT (2), but not children; shell catches SIGQUIT (3)
# and returns to single user after fsck.
trap : 2
trap : 3	# Shouldn't be needed.

export HOME=/
export INRC=1
export PATH=/sbin:/bin:/usr/sbin:/usr/bin

# Must set the domainname before rc.conf, so YP startup choices can be made.
if [[ -s /etc/defaultdomain ]]; then
	domainname "$(stripcom /etc/defaultdomain)"
fi

# Get local functions from rc.subr to load rc.conf into scope.
FUNCS_ONLY=1 . /etc/rc.d/rc.subr
_rc_parse_conf

# If executed with the 'shutdown' parameter by the halt, reboot or shutdown:
# - update seed files
# - execute the rc.d scripts specified by $pkg_scripts in reverse order
# - bring carp interfaces down gracefully
if [[ $1 == shutdown ]]; then
	if echo 2>/dev/null >>/var/db/host.random || \
	    echo 2>/dev/null >>/etc/random.seed; then
		random_seed
	else
		echo warning: cannot write random seed to disk
	fi

	# If we are in secure level 0, assume single user mode.
	if (($(sysctl -n kern.securelevel) == 0)); then
		echo 'single user: not running shutdown scripts'
	else
		pkg_scripts=${pkg_scripts%%*( )}
		if [[ -n $pkg_scripts ]]; then
			echo -n 'stopping package daemons:'
			while [[ -n $pkg_scripts ]]; do
				_d=${pkg_scripts##* }
				pkg_scripts=${pkg_scripts%%*( )$_d}
				[[ -x /etc/rc.d/$_d ]] && /etc/rc.d/$_d stop
			done
			echo '.'
		fi

		[[ -f /etc/rc.shutdown ]] && sh /etc/rc.shutdown
	fi

	ifconfig | while read _if _junk; do
		[[ $_if == carp+([0-9]): ]] && ifconfig ${_if%:} down
	done

	exit 0
fi

# Add swap block-devices.
swapctl -A -t blk

# Run filesystem check unless a /fastboot file exists.
if [[ -e /fastboot ]]; then
	echo "Fast boot: skipping disk checks."
elif [[ $1 == autoboot ]]; then
	echo "Automatic boot in progress: starting file system checks."
	do_fsck
fi

# From now on, allow user to interrupt (^C) the boot process.
trap "echo 'Boot interrupted.'; exit 1" 3

# Unmount all filesystems except root.
umount -a >/dev/null 2>&1

# Mount all filesystems except those of type NFS and VND.
mount -a -t nonfs,vnd

# Re-mount the root filesystem read/writeable. (root on nfs requires this,
# others aren't hurt.)
mount -uw /
chmod og-rwx /bsd
ln -fh /bsd /bsd.booted

rm -f /fastboot

# Set flags on ttys.
echo 'setting tty flags'
ttyflags -a

# Set keyboard encoding.
if [[ -x /sbin/kbd && -s /etc/kbdtype ]]; then
	kbd "$(cat /etc/kbdtype)"
fi

wsconsctl_conf

# Set initial temporary pf rule set.
if [[ $pf != NO ]]; then
	RULES="block all"
	RULES="$RULES\npass on lo0"
	RULES="$RULES\npass in proto tcp from any to any port ssh keep state"
	RULES="$RULES\npass out proto { tcp, udp } from any to any port domain keep state"
	RULES="$RULES\npass out inet proto icmp all icmp-type echoreq keep state"
	RULES="$RULES\npass out inet proto udp from any port bootpc to any port bootps"
	RULES="$RULES\npass in inet proto udp from any port bootps to any port bootpc"
	if ifconfig lo0 inet6 >/dev/null 2>&1; then
		RULES="$RULES\npass out inet6 proto icmp6 all icmp6-type neighbrsol"
		RULES="$RULES\npass in inet6 proto icmp6 all icmp6-type neighbradv"
		RULES="$RULES\npass out inet6 proto icmp6 all icmp6-type routersol"
		RULES="$RULES\npass in inet6 proto icmp6 all icmp6-type routeradv"
		RULES="$RULES\npass out inet6 proto udp from any port dhcpv6-client to any port dhcpv6-server"
		RULES="$RULES\npass in inet6 proto udp from any port dhcpv6-server to any port dhcpv6-client"
	fi
	RULES="$RULES\npass in proto carp keep state (no-sync)"
	RULES="$RULES\npass out proto carp !received-on any keep state (no-sync)"
	if [[ $(sysctl vfs.mounts.nfs 2>/dev/null) == *[1-9]* ]]; then
		# Don't kill NFS.
		RULES="set reassemble yes no-df\n$RULES"
		RULES="$RULES\npass in proto { tcp, udp } from any port { sunrpc, nfsd } to any"
		RULES="$RULES\npass out proto { tcp, udp } from any to any port { sunrpc, nfsd } !received-on any"
	fi
	print -- "$RULES" | pfctl -f -
	pfctl -e
fi

fill_baddynamic udp
fill_baddynamic tcp

sysctl_conf

start_daemon slaacd >/dev/null 2>&1

echo 'starting network'

# Set carp interlock by increasing the demotion counter.
# Prevents carp from preempting until the system is booted.
ifconfig -g carp carpdemote 128

sh /etc/netstart

# Any write triggers a rekey.
dmesg >/dev/random

# Load pf rules and bring up pfsync interface.
if [[ $pf != NO ]]; then
	if [[ -f /etc/pf.conf ]]; then
		pfctl -f /etc/pf.conf
	fi
	if [[ -f /etc/hostname.pfsync0 ]]; then
		sh /etc/netstart pfsync0
	fi
fi

mount -s /usr >/dev/null 2>&1
mount -s /var >/dev/null 2>&1

random_seed

reorder_libs

# Clean up left-over files.
rm -f /etc/nologin /var/spool/lock/LCK.*
(cd /var/run && { rm -rf -- *; install -c -m 664 -g utmp /dev/null utmp; })
(cd /var/authpf && rm -rf -- *)

# Save a copy of the boot messages.
dmesg >/var/run/dmesg.boot

make_keys

echo -n 'starting early daemons:'
start_daemon syslogd ldattach pflogd nsd rebound unbound ntpd
start_daemon iscsid isakmpd iked sasyncd ldapd npppd
echo '.'

# Load IPsec rules.
if [[ $ipsec != NO && -f /etc/ipsec.conf ]]; then
	ipsecctl -f /etc/ipsec.conf
fi

echo -n 'starting RPC daemons:'
start_daemon portmap ypldap
rm -f /var/run/ypbind.lock
if [[ -n $(domainname) ]]; then
	start_daemon ypserv ypbind
fi
start_daemon mountd nfsd lockd statd amd
echo '.'

# Check and mount remaining file systems and enable additional swap.
mount -a
swapctl -A -t noblk
do_fsck -N
mount -a -N

# /var/crash should be a directory or a symbolic link to the crash directory
# if core dumps are to be saved.
if [[ -d /var/crash ]]; then
	savecore $savecore_flags /var/crash
fi

# Store ACPI tables in /var/db/acpi to be used by sendbug(1).
if [[ -x /usr/sbin/acpidump ]]; then
	acpidump -o /var/db/acpi/
fi

if [[ $check_quotas == YES ]]; then
	echo -n 'checking quotas:'
	quotacheck -a
	echo ' done.'
	quotaon -a
fi

# Build kvm(3) and /dev databases.
kvm_mkdb
dev_mkdb

# Set proper permission for the tty device files.
chmod 666 /dev/tty[pqrstuvwxyzPQRST]*
chown root:wheel /dev/tty[pqrstuvwxyzPQRST]*

# Check for the password temp/lock file.
if [[ -f /etc/ptmp ]]; then
	logger -s -p auth.err \
	    'password file may be incorrect -- /etc/ptmp exists'
fi

echo clearing /tmp

# Prune quickly with one rm, then use find to clean up /tmp/[lqv]*
# (not needed with mfs /tmp, but doesn't hurt there...).
(cd /tmp && rm -rf [a-km-pr-uw-zA-Z]*)
(cd /tmp &&
    find . -maxdepth 1 ! -name . ! -name lost+found ! -name quota.user \
	! -name quota.group ! -name vi.recover -execdir rm -rf -- {} \;)

# Create Unix sockets directories for X if needed and make sure they have
# correct permissions.
[[ -d /usr/X11R6/lib ]] && mkdir -m 1777 /tmp/.{X11,ICE}-unix

[[ -f /etc/rc.securelevel ]] && sh /etc/rc.securelevel

# rc.securelevel did not specifically set -1 or 2, so select the default: 1.
(($(sysctl -n kern.securelevel) == 0)) && sysctl kern.securelevel=1


# Patch /etc/motd.
if [[ ! -f /etc/motd ]]; then
	install -c -o root -g wheel -m 664 /dev/null /etc/motd
fi
if T=$(mktemp /tmp/_motd.XXXXXXXXXX); then
	sysctl -n kern.version | sed 1q >$T
	sed -n '/^$/,$p' </etc/motd >>$T
	cmp -s $T /etc/motd || cp $T /etc/motd
	rm -f $T
fi

if [[ $accounting == YES ]]; then
	[[ ! -f /var/account/acct ]] && touch /var/account/acct
	echo 'turning on accounting'
	accton /var/account/acct
fi

if [[ -x /sbin/ldconfig ]]; then
	echo 'creating runtime link editor directory cache.'
	[[ -d /usr/local/lib ]] && shlib_dirs="/usr/local/lib $shlib_dirs"
	[[ -d /usr/X11R6/lib ]] && shlib_dirs="/usr/X11R6/lib $shlib_dirs"
	ldconfig $shlib_dirs
fi

echo 'preserving editor files.'; /usr/libexec/vi.recover

# If rc.sysmerge exists, run it just once, and make sure it is deleted.
run_upgrade_script sysmerge

echo -n 'starting network daemons:'
start_daemon ldomd sshd switchd snmpd ldpd ripd ospfd ospf6d bgpd ifstated
start_daemon relayd dhcpd dhcrelay mrouted dvmrpd radiusd eigrpd

if ifconfig lo0 inet6 >/dev/null 2>&1; then
	if (($(sysctl -n net.inet6.ip6.forwarding) == 1)); then
		start_daemon route6d rtadvd
	fi
fi

start_daemon hostapd lpd smtpd slowcgi httpd ftpd
start_daemon ftpproxy ftpproxy6 tftpd tftpproxy identd inetd rarpd bootparamd
start_daemon rbootd mopd vmd spamd spamlogd sndiod
echo '.'

# If rc.firsttime exists, run it just once, and make sure it is deleted.
run_upgrade_script firsttime

# Run rc.d(8) scripts from packages.
if [[ -n $pkg_scripts ]]; then
	echo -n 'starting package daemons:'
	for _daemon in $pkg_scripts; do
		if [[ -x /etc/rc.d/$_daemon ]]; then
			start_daemon $_daemon
		else
			echo -n " ${_daemon}(absent)"
		fi
	done
	echo '.'
fi

[[ -f /etc/rc.local ]] && sh /etc/rc.local

# Disable carp interlock.
ifconfig -g carp -carpdemote 128

mixerctl_conf

echo -n 'starting local daemons:'
start_daemon apmd sensorsd hotplugd watchdogd cron wsmoused xenodm
echo '.'

reorder_kernel

date
exit 0