Source code pulled from OpenBSD for OpenNTPD. The place to contribute to this code is via the OpenBSD CVS tree.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

623 lines
16 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. # $OpenBSD: rc,v 1.543 2020/01/24 06:17:37 tedu Exp $
  2. # System startup script run by init on autoboot or after single-user.
  3. # Output and error are redirected to console by init, and the console is the
  4. # controlling terminal.
  5. # Turn off Strict Bourne shell.
  6. set +o sh
  7. # Subroutines (have to come first).
  8. # Strip in- and whole-line comments from a file.
  9. # Strip leading and trailing whitespace if IFS is set.
  10. # Usage: stripcom /path/to/file
  11. stripcom() {
  12. local _file=$1 _line
  13. [[ -s $_file ]] || return
  14. while read _line ; do
  15. _line=${_line%%#*}
  16. [[ -n $_line ]] && print -r -- "$_line"
  17. done <$_file
  18. }
  19. # Update resource limits based on login.conf settings.
  20. # Usage: update_limit -flag capability
  21. update_limit() {
  22. local _flag=$1 # ulimit flag
  23. local _cap=$2 _val # login.conf capability and its value
  24. local _suffix
  25. for _suffix in {,-max,-cur}; do
  26. _val=$(getcap -f /etc/login.conf -s ${_cap}${_suffix} daemon 2>/dev/null)
  27. [[ -n $_val ]] || continue
  28. [[ $_val == infinity ]] && _val=unlimited
  29. case $_suffix in
  30. -cur) ulimit -S $_flag $_val
  31. ;;
  32. -max) ulimit -H $_flag $_val
  33. ;;
  34. *) ulimit $_flag $_val
  35. return
  36. ;;
  37. esac
  38. done
  39. }
  40. # Apply sysctl.conf(5) settings.
  41. sysctl_conf() {
  42. # do not use a pipe as limits would only be applied to the subshell
  43. set -- $(stripcom /etc/sysctl.conf)
  44. while [[ $# > 0 ]] ; do
  45. sysctl "$1"
  46. case "$1" in
  47. kern.maxproc=*)
  48. update_limit -p maxproc
  49. ;;
  50. kern.maxfiles=*)
  51. update_limit -n openfiles
  52. ;;
  53. esac
  54. shift
  55. done
  56. }
  57. # Apply mixerctl.conf(5) settings.
  58. mixerctl_conf() {
  59. stripcom /etc/mixerctl.conf |
  60. while read _line; do
  61. mixerctl -q "$_line" 2>/dev/null
  62. done
  63. }
  64. # Apply wsconsctl.conf(5) settings.
  65. wsconsctl_conf() {
  66. [[ -x /sbin/wsconsctl ]] || return
  67. stripcom /etc/wsconsctl.conf |
  68. while read _line; do
  69. eval "wsconsctl $_line"
  70. done
  71. }
  72. # Push the old seed into the kernel, create a future seed and create a seed
  73. # file for the boot-loader.
  74. random_seed() {
  75. dd if=/var/db/host.random of=/dev/random bs=65536 count=1 status=none
  76. chmod 600 /var/db/host.random
  77. dd if=/dev/random of=/var/db/host.random bs=65536 count=1 status=none
  78. dd if=/dev/random of=/etc/random.seed bs=512 count=1 status=none
  79. chmod 600 /etc/random.seed
  80. }
  81. # Populate net.inet.(tcp|udp).baddynamic with the contents of /etc/services so
  82. # as to avoid randomly allocating source ports that correspond to well-known
  83. # services.
  84. # Usage: fill_baddynamic tcp|udp
  85. fill_baddynamic() {
  86. local _service=$1
  87. local _sysctl="net.inet.${_service}.baddynamic"
  88. stripcom /etc/services |
  89. {
  90. _ban=
  91. while IFS=" /" read _name _port _srv _junk; do
  92. [[ $_srv == $_service ]] || continue
  93. _ban="${_ban:+$_ban,}+$_port"
  94. # Flush before argv gets too long
  95. if ((${#_ban} > 1024)); then
  96. sysctl -q "$_sysctl=$_ban"
  97. _ban=
  98. fi
  99. done
  100. [[ -n $_ban ]] && sysctl -q "$_sysctl=$_ban"
  101. }
  102. }
  103. # Start daemon using the rc.d daemon control scripts.
  104. # Usage: start_daemon daemon1 daemon2 daemon3
  105. start_daemon() {
  106. local _daemon
  107. for _daemon; do
  108. eval "_do=\${${_daemon}_flags}"
  109. [[ $_do != NO ]] && /etc/rc.d/${_daemon} start
  110. done
  111. }
  112. # Generate keys for isakmpd, iked and sshd if they don't exist yet.
  113. make_keys() {
  114. local _isakmpd_key=/etc/isakmpd/private/local.key
  115. local _isakmpd_pub=/etc/isakmpd/local.pub
  116. local _iked_key=/etc/iked/private/local.key
  117. local _iked_pub=/etc/iked/local.pub
  118. if [[ ! -f $_isakmpd_key ]]; then
  119. echo -n "openssl: generating isakmpd/iked RSA keys... "
  120. if openssl genrsa -out $_isakmpd_key 2048 >/dev/null 2>&1 &&
  121. chmod 600 $_isakmpd_key &&
  122. openssl rsa -out $_isakmpd_pub -in $_isakmpd_key \
  123. -pubout >/dev/null 2>&1; then
  124. echo done.
  125. else
  126. echo failed.
  127. fi
  128. fi
  129. if [[ ! -f $_iked_key ]]; then
  130. # Just copy the generated isakmpd key
  131. cp $_isakmpd_key $_iked_key
  132. chmod 600 $_iked_key
  133. cp $_isakmpd_pub $_iked_pub
  134. fi
  135. ssh-keygen -A
  136. if [[ ! -f /etc/soii.key ]]; then
  137. openssl rand -hex 16 > /etc/soii.key &&
  138. chmod 600 /etc/soii.key && sysctl -q \
  139. "net.inet6.ip6.soiikey=$(</etc/soii.key)"
  140. fi
  141. }
  142. # Re-link libraries, placing the objects in a random order.
  143. reorder_libs() {
  144. local _error=false _dkdev _liba _libas _mp _ro_list _tmpdir
  145. local _relink=/usr/share/relink
  146. [[ $library_aslr == NO ]] && return
  147. # Skip if /usr/lib, /usr/libexec or /usr/share/relink are on nfs mounted
  148. # filesystems, otherwise record which ones are mounted read-only.
  149. for _dkdev in $(df /usr/{lib,libexec} $_relink |
  150. sed '1d;s/ .*//' | sort -u); do
  151. _mp=$(mount -t ffs | grep "^$_dkdev") || return
  152. if [[ $_mp == *read-only* ]]; then
  153. _ro_list="$_ro_list ${_mp%% *}"
  154. fi
  155. done
  156. echo -n 'reordering libraries:'
  157. # Remount the (read-only) filessystems in _ro_list as read-write.
  158. for _mp in $_ro_list; do
  159. if ! mount -u -w $_mp; then
  160. echo ' failed.'
  161. return
  162. fi
  163. done
  164. # Only choose the latest version of the libraries.
  165. for _liba in $_relink/usr/lib/lib{c,crypto}; do
  166. _libas="$_libas $(ls $_liba.so.+([0-9.]).a | sort -rV | head -1)"
  167. done
  168. for _liba in $_relink/usr/libexec/ld.so.a $_libas; do
  169. _tmpdir=$(mktemp -dq $_relink/_rebuild.XXXXXXXXXXXX) &&
  170. (
  171. set -o errexit
  172. _install='install -F -o root -g bin -m 0444'
  173. _lib=${_liba##*/}
  174. _lib=${_lib%.a}
  175. _lib_dir=${_liba#$_relink}
  176. _lib_dir=${_lib_dir%/*}
  177. cd $_tmpdir
  178. ar x $_liba
  179. if [[ $_lib == ld.so ]]; then
  180. args="-g -x -e _dl_start \
  181. --version-script=Symbols.map --shared -Bsymbolic \
  182. --no-undefined"
  183. [[ -f ld.script ]] && args="$args -T ld.script"
  184. ld $args -o ld.so.test $(ls *.o | sort -R)
  185. chmod u+x test-ld.so
  186. [[ $(./test-ld.so ok) == './test-ld.so: ok!' ]]
  187. $_install /usr/libexec/ld.so /usr/libexec/ld.so.save
  188. $_install ld.so.test $_lib_dir/ld.so
  189. else
  190. cc -shared -o $_lib $(ls *.so | sort -R) $(<.ldadd)
  191. [[ -s $_lib ]] && file $_lib | fgrep -q 'shared object'
  192. LD_BIND_NOW=1 LD_LIBRARY_PATH=$_tmpdir awk 'BEGIN {exit 0}'
  193. LD_BIND_NOW=1 LD_LIBRARY_PATH=$_tmpdir openssl \
  194. x509 -in /etc/ssl/cert.pem -out /dev/null
  195. $_install $_lib $_lib_dir/$_lib
  196. fi
  197. ) || { _error=true; break; }
  198. done
  199. rm -rf $_relink/_rebuild.*
  200. # Restore previous mount state if it was changed.
  201. for _mp in $_ro_list; do
  202. mount -u -r $_mp || _error=true
  203. done
  204. if $_error; then
  205. echo ' failed.'
  206. else
  207. echo ' done.'
  208. fi
  209. }
  210. # Run rc.* script and email output to root.
  211. # Usage: run_upgrade_script firsttime|sysmerge
  212. run_upgrade_script() {
  213. local _suffix=$1
  214. [[ -n $_suffix ]] || return 1
  215. if [[ -f /etc/rc.$_suffix ]]; then
  216. echo "running rc.$_suffix"
  217. mv /etc/rc.$_suffix /etc/rc.$_suffix.run
  218. . /etc/rc.$_suffix.run 2>&1 | tee /dev/tty |
  219. mail -Es "$(hostname) rc.$_suffix output" root >/dev/null
  220. fi
  221. rm -f /etc/rc.$_suffix.run
  222. }
  223. # Check filesystems, optionally by using a fsck(8) flag.
  224. # Usage: do_fsck [-flag]
  225. do_fsck() {
  226. fsck -p "$@"
  227. case $? in
  228. 0) ;;
  229. 2) exit 1
  230. ;;
  231. 4) echo "Rebooting..."
  232. reboot
  233. echo "Reboot failed; help!"
  234. exit 1
  235. ;;
  236. 8) echo "Automatic file system check failed; help!"
  237. exit 1
  238. ;;
  239. 12) echo "Boot interrupted."
  240. exit 1
  241. ;;
  242. 130) # Interrupt before catcher installed.
  243. exit 1
  244. ;;
  245. *) echo "Unknown error; help!"
  246. exit 1
  247. ;;
  248. esac
  249. }
  250. # End subroutines.
  251. stty status '^T'
  252. # Set shell to ignore SIGINT (2), but not children; shell catches SIGQUIT (3)
  253. # and returns to single user after fsck.
  254. trap : 2
  255. trap : 3 # Shouldn't be needed.
  256. export HOME=/
  257. export INRC=1
  258. export PATH=/sbin:/bin:/usr/sbin:/usr/bin
  259. # Must set the domainname before rc.conf, so YP startup choices can be made.
  260. if [[ -s /etc/defaultdomain ]]; then
  261. domainname "$(stripcom /etc/defaultdomain)"
  262. fi
  263. # Get local functions from rc.subr to load rc.conf into scope.
  264. FUNCS_ONLY=1 . /etc/rc.d/rc.subr
  265. _rc_parse_conf
  266. # If executed with the 'shutdown' parameter by the halt, reboot or shutdown:
  267. # - update seed files
  268. # - execute the rc.d scripts specified by $pkg_scripts in reverse order
  269. # - bring carp interfaces down gracefully
  270. if [[ $1 == shutdown ]]; then
  271. if echo 2>/dev/null >>/var/db/host.random ||
  272. echo 2>/dev/null >>/etc/random.seed; then
  273. random_seed
  274. else
  275. echo warning: cannot write random seed to disk
  276. fi
  277. # If we are in secure level 0, assume single user mode.
  278. if (($(sysctl -n kern.securelevel) == 0)); then
  279. echo 'single user: not running shutdown scripts'
  280. else
  281. set -A _d -- $pkg_scripts
  282. _i=${#_d[*]}
  283. if ((_i)); then
  284. echo -n 'stopping package daemons:'
  285. while ((--_i >= 0)); do
  286. [[ -x /etc/rc.d/${_d[_i]} ]] &&
  287. /etc/rc.d/${_d[_i]} stop
  288. done
  289. echo '.'
  290. fi
  291. if /etc/rc.d/vmd check > /dev/null; then
  292. echo -n 'stopping VMs'
  293. /etc/rc.d/vmd stop > /dev/null
  294. echo '.'
  295. fi
  296. [[ -f /etc/rc.shutdown ]] && sh /etc/rc.shutdown
  297. fi
  298. ifconfig | while read _if _junk; do
  299. [[ $_if == carp+([0-9]): ]] && ifconfig ${_if%:} down
  300. done
  301. exit 0
  302. fi
  303. # If bootblocks failed to give us random, try to cause some churn
  304. (dmesg; sysctl hw.{uuid,serialno,sensors} ) >/dev/random 2>&1
  305. # Add swap block-devices.
  306. swapctl -A -t blk
  307. # Run filesystem check unless a /fastboot file exists.
  308. if [[ -e /fastboot ]]; then
  309. echo "Fast boot: skipping disk checks."
  310. elif [[ $1 == autoboot ]]; then
  311. echo "Automatic boot in progress: starting file system checks."
  312. do_fsck
  313. fi
  314. # From now on, allow user to interrupt (^C) the boot process.
  315. trap "echo 'Boot interrupted.'; exit 1" 3
  316. # Unmount all filesystems except root.
  317. umount -a >/dev/null 2>&1
  318. # Mount all filesystems except those of type NFS and VND.
  319. mount -a -t nonfs,vnd
  320. # Re-mount the root filesystem read/writeable. (root on nfs requires this,
  321. # others aren't hurt.)
  322. mount -uw /
  323. chmod og-rwx /bsd
  324. ln -fh /bsd /bsd.booted
  325. rm -f /fastboot
  326. # Set flags on ttys.
  327. ttyflags -a
  328. # Set keyboard encoding.
  329. if [[ -x /sbin/kbd && -s /etc/kbdtype ]]; then
  330. kbd "$(</etc/kbdtype)"
  331. fi
  332. wsconsctl_conf
  333. # Set initial temporary pf rule set.
  334. if [[ $pf != NO ]]; then
  335. RULES="
  336. block all
  337. pass on lo0
  338. pass in proto tcp from any to any port ssh keep state
  339. pass out proto { tcp, udp } from any to any port domain keep state
  340. pass out inet proto icmp all icmp-type echoreq keep state
  341. pass out inet proto udp from any port bootpc to any port bootps
  342. pass in inet proto udp from any port bootps to any port bootpc"
  343. if ifconfig lo0 inet6 >/dev/null 2>&1; then
  344. RULES="$RULES
  345. pass out inet6 proto icmp6 all icmp6-type neighbrsol
  346. pass in inet6 proto icmp6 all icmp6-type neighbradv
  347. pass out inet6 proto icmp6 all icmp6-type routersol
  348. pass in inet6 proto icmp6 all icmp6-type routeradv
  349. pass out inet6 proto udp from any port dhcpv6-client to any port dhcpv6-server
  350. pass in inet6 proto udp from any port dhcpv6-server to any port dhcpv6-client"
  351. fi
  352. RULES="$RULES
  353. pass in proto carp keep state (no-sync)
  354. pass out proto carp !received-on any keep state (no-sync)"
  355. if (($(sysctl -n vfs.mounts.nfs 2>/dev/null) > 0)); then
  356. # Don't kill NFS.
  357. RULES="set reassemble yes no-df
  358. $RULES
  359. pass in proto { tcp, udp } from any port { sunrpc, nfsd } to any
  360. pass out proto { tcp, udp } from any to any port { sunrpc, nfsd } !received-on any"
  361. fi
  362. print -- "$RULES" | pfctl -f -
  363. pfctl -e
  364. fi
  365. fill_baddynamic udp
  366. fill_baddynamic tcp
  367. sysctl_conf
  368. start_daemon slaacd >/dev/null 2>&1
  369. echo 'starting network'
  370. # Set carp interlock by increasing the demotion counter.
  371. # Prevents carp from preempting until the system is booted.
  372. ifconfig -g carp carpdemote 128
  373. sh /etc/netstart
  374. mount -s /usr >/dev/null 2>&1
  375. mount -s /var >/dev/null 2>&1
  376. start_daemon unwind >/dev/null 2>&1
  377. # Load pf rules and bring up pfsync interface.
  378. if [[ $pf != NO ]]; then
  379. if [[ -f /etc/pf.conf ]]; then
  380. pfctl -f /etc/pf.conf
  381. fi
  382. if [[ -f /etc/hostname.pfsync0 ]]; then
  383. sh /etc/netstart pfsync0
  384. fi
  385. fi
  386. random_seed
  387. reorder_libs
  388. # Clean up left-over files.
  389. rm -f /etc/nologin /var/spool/lock/LCK.*
  390. (cd /var/run && { rm -rf -- *; install -c -m 664 -g utmp /dev/null utmp; })
  391. (cd /var/authpf && rm -rf -- *)
  392. # Save a copy of the boot messages.
  393. dmesg >/var/run/dmesg.boot
  394. make_keys
  395. echo -n 'starting early daemons:'
  396. start_daemon syslogd ldattach pflogd nsd unbound ntpd
  397. start_daemon iscsid isakmpd iked sasyncd ldapd npppd
  398. echo '.'
  399. # Load IPsec rules.
  400. if [[ $ipsec != NO && -f /etc/ipsec.conf ]]; then
  401. ipsecctl -f /etc/ipsec.conf
  402. fi
  403. echo -n 'starting RPC daemons:'
  404. start_daemon portmap ypldap
  405. rm -f /var/run/ypbind.lock
  406. if [[ -n $(domainname) ]]; then
  407. start_daemon ypserv ypbind
  408. fi
  409. start_daemon mountd nfsd lockd statd amd
  410. echo '.'
  411. # Check and mount remaining file systems and enable additional swap.
  412. mount -a
  413. swapctl -A -t noblk
  414. do_fsck -N
  415. mount -a -N
  416. # /var/crash should be a directory or a symbolic link to the crash directory
  417. # if core dumps are to be saved.
  418. if [[ -d /var/crash ]]; then
  419. savecore $savecore_flags /var/crash
  420. fi
  421. # Store ACPI tables in /var/db/acpi to be used by sendbug(1).
  422. if [[ -x /usr/sbin/acpidump ]]; then
  423. acpidump -q -o /var/db/acpi/
  424. fi
  425. if [[ $check_quotas == YES ]]; then
  426. echo -n 'checking quotas:'
  427. quotacheck -a
  428. echo ' done.'
  429. quotaon -a
  430. fi
  431. # Build kvm(3) and /dev databases.
  432. kvm_mkdb
  433. dev_mkdb
  434. # Set proper permission for the tty device files.
  435. chmod 666 /dev/tty[pqrstuvwxyzPQRST]*
  436. chown root:wheel /dev/tty[pqrstuvwxyzPQRST]*
  437. # Check for the password temp/lock file.
  438. if [[ -f /etc/ptmp ]]; then
  439. logger -s -p auth.err \
  440. 'password file may be incorrect -- /etc/ptmp exists'
  441. fi
  442. echo clearing /tmp
  443. # Prune quickly with one rm, then use find to clean up /tmp/[lqv]*
  444. # (not needed with mfs /tmp, but doesn't hurt there...).
  445. (cd /tmp && rm -rf [a-km-pr-uw-zA-Z]*)
  446. (cd /tmp &&
  447. find . -maxdepth 1 ! -name . ! -name lost+found ! -name quota.user \
  448. ! -name quota.group ! -name vi.recover -execdir rm -rf -- {} \;)
  449. # Create Unix sockets directories for X if needed and make sure they have
  450. # correct permissions.
  451. [[ -d /usr/X11R6/lib ]] && mkdir -m 1777 /tmp/.{X11,ICE}-unix
  452. [[ -f /etc/rc.securelevel ]] && sh /etc/rc.securelevel
  453. # rc.securelevel did not specifically set -1 or 2, so select the default: 1.
  454. (($(sysctl -n kern.securelevel) == 0)) && sysctl kern.securelevel=1
  455. # Patch /etc/motd.
  456. if [[ ! -f /etc/motd ]]; then
  457. install -c -o root -g wheel -m 664 /dev/null /etc/motd
  458. fi
  459. if T=$(mktemp /tmp/_motd.XXXXXXXXXX); then
  460. sysctl -n kern.version | sed 1q >$T
  461. sed -n '/^$/,$p' </etc/motd >>$T
  462. cmp -s $T /etc/motd || cp $T /etc/motd
  463. rm -f $T
  464. fi
  465. if [[ $accounting == YES ]]; then
  466. [[ ! -f /var/account/acct ]] && touch /var/account/acct
  467. echo 'turning on accounting'
  468. accton /var/account/acct
  469. fi
  470. if [[ -x /sbin/ldconfig ]]; then
  471. echo 'creating runtime link editor directory cache.'
  472. [[ -d /usr/local/lib ]] && shlib_dirs="/usr/local/lib $shlib_dirs"
  473. [[ -d /usr/X11R6/lib ]] && shlib_dirs="/usr/X11R6/lib $shlib_dirs"
  474. ldconfig $shlib_dirs
  475. fi
  476. echo 'preserving editor files.'; /usr/libexec/vi.recover
  477. # If rc.sysmerge exists, run it just once, and make sure it is deleted.
  478. run_upgrade_script sysmerge
  479. echo -n 'starting network daemons:'
  480. start_daemon ldomd sshd switchd snmpd ldpd ripd ospfd ospf6d bgpd ifstated
  481. start_daemon relayd dhcpd dhcrelay mrouted dvmrpd radiusd eigrpd route6d
  482. start_daemon rad hostapd lpd smtpd slowcgi httpd ftpd
  483. start_daemon ftpproxy ftpproxy6 tftpd tftpproxy identd inetd rarpd bootparamd
  484. start_daemon rbootd mopd vmd spamd spamlogd sndiod
  485. echo '.'
  486. # If rc.firsttime exists, run it just once, and make sure it is deleted.
  487. run_upgrade_script firsttime
  488. # Run rc.d(8) scripts from packages.
  489. if [[ -n $pkg_scripts ]]; then
  490. echo -n 'starting package daemons:'
  491. for _daemon in $pkg_scripts; do
  492. if [[ -x /etc/rc.d/$_daemon ]]; then
  493. start_daemon $_daemon
  494. else
  495. echo -n " ${_daemon}(absent)"
  496. fi
  497. done
  498. echo '.'
  499. fi
  500. [[ -f /etc/rc.local ]] && sh /etc/rc.local
  501. # Disable carp interlock.
  502. ifconfig -g carp -carpdemote 128
  503. mixerctl_conf
  504. echo -n 'starting local daemons:'
  505. start_daemon apmd sensorsd hotplugd watchdogd cron wsmoused xenodm
  506. echo '.'
  507. # Re-link the kernel, placing the objects in a random order.
  508. # Replace current with relinked kernel and inform root about it.
  509. /usr/libexec/reorder_kernel &
  510. date
  511. exit 0