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