xref: /openbsd-src/etc/rc (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1#	$OpenBSD: rc,v 1.423 2014/03/15 22:13:36 sthen Exp $
2
3# System startup script run by init on autoboot
4# or after single-user.
5# Output and error are redirected to console by init,
6# and the console is the controlling terminal.
7
8# Subroutines (have to come first).
9
10# Strip comments (and leading/trailing whitespace if IFS is set)
11# from a file and spew to stdout
12stripcom() {
13	local _file="$1"
14	local _line
15
16	{
17		while read _line ; do
18			_line=${_line%%#*}		# strip comments
19			test -z "$_line" && continue
20			echo $_line
21		done
22	} < $_file
23}
24
25# Update resource limits when sysctl changes
26# Usage: update_limit -X loginconf_name
27update_limit() {
28	local _fl="$1"	# ulimit flag
29	local _lc="$2"	# login.conf name
30	local _new _suf
31
32	for _suf in "" -cur -max; do
33		_new=`getcap -f /etc/login.conf -s ${_lc}${_suf} daemon 2>/dev/null`
34		if [ X"$_new" != X"" ]; then
35			if [ X"$_new" = X"infinity" ]; then
36				_new=unlimited
37			fi
38			case "$_suf" in
39			-cur)
40				ulimit -S $_fl $_new
41				;;
42			-max)
43				ulimit -H $_fl $_new
44				;;
45			*)
46				ulimit $_fl $_new
47				return
48				;;
49			esac
50		fi
51	done
52}
53
54sysctl_conf() {
55	test -s /etc/sysctl.conf || return
56
57	# delete comments and blank lines
58	set -- `stripcom /etc/sysctl.conf`
59	while [ $# -ge 1 ] ; do
60		sysctl $1
61		# update limits if needed
62		case $1 in
63		kern.maxproc=*)
64			update_limit -p maxproc
65			;;
66		kern.maxfiles=*)
67			update_limit -n openfiles
68			;;
69		esac
70		shift
71	done
72}
73
74mixerctl_conf()
75{
76	test -s /etc/mixerctl.conf || return
77
78	# delete comments and blank lines
79	set -- `stripcom /etc/mixerctl.conf`
80	while [ $# -ge 1 ] ; do
81		mixerctl -q $1 > /dev/null 2>&1
82		shift
83	done
84}
85
86wsconsctl_conf()
87{
88	local save_IFS="$IFS"
89
90	test -x /sbin/wsconsctl -a -s /etc/wsconsctl.conf || return
91	# delete comments and blank lines
92	IFS="
93"
94	set -- `stripcom /etc/wsconsctl.conf`
95	IFS="$save_IFS"
96	while [ $# -ge 1 ] ; do
97		eval wsconsctl $1
98		shift
99	done
100}
101
102random_seed()
103{
104	{
105		# push the old seed into the kernel
106		dd if=/var/db/host.random of=/dev/random bs=65536 count=1
107		chmod 600 /var/db/host.random
108		# ... and create a future seed
109		dd if=/dev/random of=/var/db/host.random bs=65536 count=1
110		# and create a seed file for the boot-loader
111		dd if=/dev/random of=/etc/random.seed bs=512 count=1
112		chmod 600 /etc/random.seed
113	} > /dev/null 2>&1
114}
115
116fill_baddynamic()
117{
118	local _service=$1
119	local _sysctl="net.inet.${_service}.baddynamic"
120	stripcom /etc/services |
121	{
122		# Variables are local
123		while IFS=" 	/" read _name _port _srv _junk; do
124			[ "x${_srv}" = "x${_service}" ] || continue
125			_ban="${_ban:+${_ban},}+${_port}"
126			# Flush before argv gets too long
127			if [ ${#_ban} -gt 1024 ]; then
128				sysctl -q ${_sysctl}=${_ban}
129				_ban=""
130			fi
131		done
132		[ "${_ban}" ] && sysctl -q ${_sysctl}=${_ban}
133	}
134}
135
136start_daemon()
137{
138	local _n
139	for _n; do
140		eval _do=\${${_n}_flags}
141		if [ X"${_do}" != X"NO" ]; then
142			/etc/rc.d/${_n} start
143		fi
144	done
145}
146
147make_keys()
148{
149	if [ X"${named_flags}" != X"NO" ]; then
150		if ! cmp -s /etc/rndc.key /var/named/etc/rndc.key ; then
151			echo -n "rndc-confgen: generating shared secret... "
152			if rndc-confgen -a -t /var/named >/dev/null 2>&1; then
153				chmod 0640 /var/named/etc/rndc.key \
154				    >/dev/null 2>&1
155				echo done.
156			else
157				echo failed.
158			fi
159		fi
160	fi
161
162	if [ ! -f /etc/isakmpd/private/local.key ]; then
163		echo -n "openssl: generating isakmpd/iked RSA key... "
164		if openssl genrsa -out /etc/isakmpd/private/local.key 2048 \
165		    >/dev/null 2>&1; then
166			chmod 600 /etc/isakmpd/private/local.key
167			openssl rsa -out /etc/isakmpd/local.pub -in \
168			    /etc/isakmpd/private/local.key -pubout \
169			    >/dev/null 2>&1
170			echo done.
171		else
172			echo failed.
173		fi
174	fi
175
176	if [ ! -f /etc/iked/private/local.key ]; then
177		# Just copy the generated isakmpd key
178		cp /etc/isakmpd/private/local.key /etc/iked/private/local.key
179		chmod 600 /etc/iked/private/local.key
180		cp /etc/isakmpd/local.pub /etc/iked/local.pub
181	fi
182
183	ssh-keygen -A
184}
185
186# create Unix sockets directories for X if needed and make sure they have
187# correct permissions
188setup_X_sockets()
189{
190	if [ -d /usr/X11R6/lib ]; then
191		for d in /tmp/.X11-unix /tmp/.ICE-unix ; do
192			if [ -d $d ]; then
193				if [ `ls -ld $d | cut -d' ' -f4` \
194				    != root ]; then
195					chown root $d
196				fi
197				if [ `ls -ld $d | cut -d' ' -f1` \
198				    != drwxrwxrwt ]; then
199					chmod 1777 $d
200				fi
201			elif [ -e $d ]; then
202				echo "Error: $d exists and isn't a directory."
203			else
204				mkdir -m 1777 $d
205			fi
206		done
207	fi
208}
209
210# End subroutines
211
212stty status '^T'
213
214# Set shell to ignore SIGINT (2), but not children;
215# shell catches SIGQUIT (3) and returns to single user after fsck.
216trap : 2
217trap : 3	# shouldn't be needed
218
219HOME=/; export HOME
220INRC=1; export INRC
221PATH=/sbin:/bin:/usr/sbin:/usr/bin
222export PATH
223
224# must set the domainname before rc.conf, so YP startup choices can be made
225if [ -f /etc/defaultdomain ]; then
226	domainname `stripcom /etc/defaultdomain`
227fi
228
229# pick up option configuration
230. /etc/rc.conf
231
232if [ X"$1" = X"shutdown" ]; then
233	random_seed
234
235	# If we are in secure level 0, assume single user mode.
236	if [ `sysctl -n kern.securelevel` -ne 0 ]; then
237		pkg_scripts=${pkg_scripts%%*( )}
238		if [ -n "${pkg_scripts}" ]; then
239			echo -n 'stopping package daemons:'
240			while [ -n "${pkg_scripts}" ]; do
241				_r=${pkg_scripts##* }
242				pkg_scripts=${pkg_scripts%%*( )${_r}}
243				[ -x /etc/rc.d/${_r} ] && /etc/rc.d/${_r} stop
244			done
245			echo '.'
246		fi
247
248		echo /etc/rc.shutdown in progress...
249		. /etc/rc.shutdown
250		echo /etc/rc.shutdown complete.
251	else
252		echo single user: not running shutdown scripts
253	fi
254
255	# bring carp interfaces down gracefully
256	ifconfig | while read a b; do
257		case $a in
258		carp+([0-9]):) ifconfig ${a%:} down ;;
259		esac
260	done
261
262	if [ X"${powerdown}" = X"YES" ]; then
263		exit 2
264	fi
265	exit 0
266fi
267
268swapctl -A -t blk
269
270if [ -e /fastboot ]; then
271	echo "Fast boot: skipping disk checks."
272elif [ X"$1" = X"autoboot" ]; then
273	echo "Automatic boot in progress: starting file system checks."
274	fsck -p
275	case $? in
276	0)
277		;;
278	2)
279		exit 1
280		;;
281	4)
282		echo "Rebooting..."
283		reboot
284		echo "Reboot failed; help!"
285		exit 1
286		;;
287	8)
288		echo "Automatic file system check failed; help!"
289		exit 1
290		;;
291	12)
292		echo "Boot interrupted."
293		exit 1
294		;;
295	130)
296		# interrupt before catcher installed
297		exit 1
298		;;
299	*)
300		echo "Unknown error; help!"
301		exit 1
302		;;
303	esac
304fi
305
306trap "echo 'Boot interrupted.'; exit 1" 3
307
308umount -a >/dev/null 2>&1
309mount -a -t nonfs,vnd
310mount -uw /		# root on nfs requires this, others aren't hurt
311rm -f /fastboot		# XXX (root now writeable)
312
313# set flags on ttys.  (do early, in case they use tty for SLIP in netstart)
314echo 'setting tty flags'
315ttyflags -a
316
317if [ -f /sbin/kbd -a -f /etc/kbdtype ]; then
318	kbd `cat /etc/kbdtype`
319fi
320
321wsconsctl_conf
322
323if [ X"${pf}" != X"NO" ]; then
324	RULES="block all"
325	RULES="$RULES\npass on lo0"
326	RULES="$RULES\npass in proto tcp from any to any port 22 keep state"
327	RULES="$RULES\npass out proto { tcp, udp } from any to any port 53 keep state"
328	RULES="$RULES\npass out inet proto icmp all icmp-type echoreq keep state"
329	RULES="$RULES\npass out inet proto udp from any port bootpc to any port bootps"
330	RULES="$RULES\npass in inet proto udp from any port bootps to any port bootpc"
331	if ifconfig lo0 inet6 >/dev/null 2>&1; then
332		RULES="$RULES\npass out inet6 proto icmp6 all icmp6-type neighbrsol"
333		RULES="$RULES\npass in inet6 proto icmp6 all icmp6-type neighbradv"
334		RULES="$RULES\npass out inet6 proto icmp6 all icmp6-type routersol"
335		RULES="$RULES\npass in inet6 proto icmp6 all icmp6-type routeradv"
336		RULES="$RULES\npass out inet6 proto udp from any port dhcpv6-client to any port dhcpv6-server"
337		RULES="$RULES\npass in inet6 proto udp from any port dhcpv6-server to any port dhcpv6-client"
338	fi
339	RULES="$RULES\npass proto carp keep state (no-sync)"
340	case `sysctl vfs.mounts.nfs 2>/dev/null` in
341	*[1-9]*)
342		# don't kill NFS
343		RULES="set reassemble yes no-df\n$RULES"
344		RULES="$RULES\npass in proto { tcp, udp } from any port { 111, 2049 } to any"
345		RULES="$RULES\npass out proto { tcp, udp } from any to any port { 111, 2049 }"
346		;;
347	esac
348	echo $RULES | pfctl -f -
349	pfctl -e
350fi
351
352# Fill net.inet.(tcp|udp).baddynamic lists from /etc/services
353fill_baddynamic udp
354fill_baddynamic tcp
355
356sysctl_conf
357
358# set hostname, turn on network
359echo 'starting network'
360ifconfig -g carp carpdemote 128
361if [ -f /etc/resolv.conf.save ]; then
362	mv -f /etc/resolv.conf.save /etc/resolv.conf
363	touch /etc/resolv.conf
364fi
365. /etc/netstart
366dmesg > /dev/random	# any write triggers an RC4 rekey
367
368if [ X"${pf}" != X"NO" ]; then
369	if [ -f ${pf_rules} ]; then
370		pfctl -f ${pf_rules}
371	fi
372	# bring up pfsync after the working ruleset has been loaded
373	if [ -f /etc/hostname.pfsync0 ]; then
374		. /etc/netstart pfsync0
375	fi
376fi
377
378mount -s /usr >/dev/null 2>&1
379mount -s /var >/dev/null 2>&1
380
381random_seed
382
383# clean up left-over files
384rm -f /etc/nologin /var/spool/lock/LCK.* /var/spool/uucp/STST/*
385(cd /var/run && { rm -rf -- *; install -c -m 664 -g utmp /dev/null utmp; })
386(cd /var/authpf && rm -rf -- *)
387
388# save a copy of the boot messages
389dmesg >/var/run/dmesg.boot
390
391make_keys
392
393echo -n 'starting early daemons:'
394start_daemon syslogd ldattach pflogd named nsd unbound ntpd
395start_daemon isakmpd iked sasyncd ldapd npppd
396echo '.'
397
398if [ X"${ipsec}" != X"NO" ]; then
399	if [ -f ${ipsec_rules} ]; then
400		ipsecctl -f ${ipsec_rules}
401	fi
402fi
403
404echo -n 'starting RPC daemons:'
405start_daemon portmap ypldap
406if [ X"`domainname`" != X"" ]; then
407	start_daemon ypserv ypbind yppasswdd
408fi
409start_daemon mountd nfsd lockd statd amd
410echo '.'
411
412mount -a
413swapctl -A -t noblk
414
415# /var/crash should be a directory or a symbolic link
416# to the crash directory if core dumps are to be saved.
417if [ -d /var/crash ]; then
418	savecore ${savecore_flags} /var/crash
419fi
420
421if [ X"${check_quotas}" = X"YES" ]; then
422	echo -n 'checking quotas:'
423	quotacheck -a
424	echo ' done.'
425	quotaon -a
426fi
427
428kvm_mkdb			# build kvm(3) databases
429dev_mkdb
430chmod 666 /dev/tty[pqrstuvwxyzPQRST]*
431chown root:wheel /dev/tty[pqrstuvwxyzPQRST]*
432
433# check the password temp/lock file
434if [ -f /etc/ptmp ]; then
435	logger -s -p auth.err \
436	    'password file may be incorrect -- /etc/ptmp exists'
437fi
438
439echo clearing /tmp
440
441# prune quickly with one rm, then use find to clean up /tmp/[lq]*
442# (not needed with mfs /tmp, but doesn't hurt there...)
443(cd /tmp && rm -rf [a-km-pr-zA-Z]*)
444(cd /tmp &&
445    find . ! -name . ! -name lost+found ! -name quota.user \
446	! -name quota.group -execdir rm -rf -- {} \; -type d -prune)
447
448setup_X_sockets
449
450[ -f /etc/rc.securelevel ] && . /etc/rc.securelevel
451if [ X"${securelevel}" != X"" ]; then
452	echo -n 'setting kernel security level: '
453	sysctl kern.securelevel=${securelevel}
454fi
455
456# patch /etc/motd
457if [ ! -f /etc/motd ]; then
458	install -c -o root -g wheel -m 664 /dev/null /etc/motd
459fi
460if T=`mktemp /tmp/_motd.XXXXXXXXXX`; then
461	sysctl -n kern.version | sed 1q > $T
462	echo "" >> $T
463	sed '1,/^$/d' < /etc/motd >> $T
464	cmp -s $T /etc/motd || cp $T /etc/motd
465	rm -f $T
466fi
467
468if [ X"${accounting}" = X"YES" ]; then
469	if [ ! -f /var/account/acct ]; then
470		touch /var/account/acct
471	fi
472	echo 'turning on accounting';	accton /var/account/acct
473fi
474
475if [ -f /sbin/ldconfig ]; then
476	echo 'creating runtime link editor directory cache.'
477	if [ -d /usr/local/lib ]; then
478		shlib_dirs="/usr/local/lib $shlib_dirs"
479	fi
480	if [ -d /usr/X11R6/lib ]; then
481		shlib_dirs="/usr/X11R6/lib $shlib_dirs"
482	fi
483	ldconfig $shlib_dirs
484fi
485
486echo 'preserving editor files.';	/usr/libexec/vi.recover
487
488echo -n 'starting network daemons:'
489start_daemon ldomd sshd snmpd ldpd ripd ospfd ospf6d bgpd ifstated
490start_daemon relayd dhcpd dhcrelay mrouted dvmrpd
491
492if ifconfig lo0 inet6 >/dev/null 2>&1; then
493	fw=`sysctl -n net.inet6.ip6.forwarding`
494	if [ X"${fw}" = X"0" ]; then
495		start_daemon rtsold
496	else
497		start_daemon route6d rtadvd
498	fi
499fi
500
501start_daemon hostapd rwhod lpd sendmail smtpd slowcgi nginx ftpd
502start_daemon ftpproxy tftpd tftpproxy identd inetd rarpd bootparamd
503start_daemon rbootd mopd spamd spamlogd kdc kadmind kpasswdd
504start_daemon ipropd_master ipropd_slave sndiod
505echo '.'
506
507# If rc.firstime exists, run it just once, and make sure it is deleted
508if [ -f /etc/rc.firsttime ]; then
509	mv /etc/rc.firsttime /etc/rc.firsttime.run
510	. /etc/rc.firsttime.run 2>&1 | tee /dev/tty |
511		mail -Es "`hostname` rc.firsttime output" root >/dev/null
512fi
513rm -f /etc/rc.firsttime.run
514
515# Run rc.d(8) scripts from packages
516if [ -n "${pkg_scripts}" ]; then
517	echo -n 'starting package daemons:'
518	for _r in $pkg_scripts; do
519		if [ -x /etc/rc.d/${_r} ]; then
520			start_daemon ${_r}
521		else
522			echo -n " ${_r}(absent)"
523		fi
524	done
525	echo '.'
526fi
527
528[ -f /etc/rc.local ] && . /etc/rc.local
529
530ifconfig -g carp -carpdemote 128	# disable carp interlock
531
532mixerctl_conf
533echo -n 'starting local daemons:'
534start_daemon apmd sensorsd hotplugd watchdogd cron wsmoused xdm
535echo '.'
536
537date
538exit 0
539