1# $OpenBSD: rc,v 1.444 2014/11/17 18:19:08 deraadt 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 # push the old seed into the kernel 105 dd if=/var/db/host.random of=/dev/random bs=65536 count=1 status=none 106 chmod 600 /var/db/host.random 107 # ... and create a future seed 108 dd if=/dev/random of=/var/db/host.random bs=65536 count=1 status=none 109 # and create a seed file for the boot-loader 110 dd if=/dev/random of=/etc/random.seed bs=512 count=1 status=none 111 chmod 600 /etc/random.seed 112} 113 114fill_baddynamic() 115{ 116 local _service=$1 117 local _sysctl="net.inet.${_service}.baddynamic" 118 stripcom /etc/services | 119 { 120 # Variables are local 121 while IFS=" /" read _name _port _srv _junk; do 122 [ "x${_srv}" = "x${_service}" ] || continue 123 _ban="${_ban:+${_ban},}+${_port}" 124 # Flush before argv gets too long 125 if [ ${#_ban} -gt 1024 ]; then 126 sysctl -q ${_sysctl}=${_ban} 127 _ban="" 128 fi 129 done 130 [ "${_ban}" ] && sysctl -q ${_sysctl}=${_ban} 131 } 132} 133 134start_daemon() 135{ 136 local _n 137 for _n; do 138 eval _do=\${${_n}_flags} 139 if [ X"${_do}" != X"NO" ]; then 140 /etc/rc.d/${_n} start 141 fi 142 done 143} 144 145make_keys() 146{ 147 if [ ! -f /etc/isakmpd/private/local.key ]; then 148 echo -n "openssl: generating isakmpd/iked RSA key... " 149 if openssl genrsa -out /etc/isakmpd/private/local.key 2048 \ 150 >/dev/null 2>&1; then 151 chmod 600 /etc/isakmpd/private/local.key 152 openssl rsa -out /etc/isakmpd/local.pub -in \ 153 /etc/isakmpd/private/local.key -pubout \ 154 >/dev/null 2>&1 155 echo done. 156 else 157 echo failed. 158 fi 159 fi 160 161 if [ ! -f /etc/iked/private/local.key ]; then 162 # Just copy the generated isakmpd key 163 cp /etc/isakmpd/private/local.key /etc/iked/private/local.key 164 chmod 600 /etc/iked/private/local.key 165 cp /etc/isakmpd/local.pub /etc/iked/local.pub 166 fi 167 168 ssh-keygen -A 169} 170 171# create Unix sockets directories for X if needed and make sure they have 172# correct permissions 173setup_X_sockets() 174{ 175 if [ -d /usr/X11R6/lib ]; then 176 for d in /tmp/.X11-unix /tmp/.ICE-unix ; do 177 if [ -d $d ]; then 178 if [ `ls -ld $d | cut -d' ' -f4` \ 179 != root ]; then 180 chown root $d 181 fi 182 if [ `ls -ld $d | cut -d' ' -f1` \ 183 != drwxrwxrwt ]; then 184 chmod 1777 $d 185 fi 186 elif [ -e $d ]; then 187 echo "Error: $d exists and isn't a directory." 188 else 189 mkdir -m 1777 $d 190 fi 191 done 192 fi 193} 194 195do_fsck() 196{ 197 local _flags=$1 198 199 fsck -p $_flags 200 case $? in 201 0) 202 ;; 203 2) 204 exit 1 205 ;; 206 4) 207 echo "Rebooting..." 208 reboot 209 echo "Reboot failed; help!" 210 exit 1 211 ;; 212 8) 213 echo "Automatic file system check failed; help!" 214 exit 1 215 ;; 216 12) 217 echo "Boot interrupted." 218 exit 1 219 ;; 220 130) 221 # interrupt before catcher installed 222 exit 1 223 ;; 224 *) 225 echo "Unknown error; help!" 226 exit 1 227 ;; 228 esac 229} 230 231# End subroutines 232 233stty status '^T' 234 235# Set shell to ignore SIGINT (2), but not children; 236# shell catches SIGQUIT (3) and returns to single user after fsck. 237trap : 2 238trap : 3 # shouldn't be needed 239 240HOME=/; export HOME 241INRC=1; export INRC 242PATH=/sbin:/bin:/usr/sbin:/usr/bin 243export PATH 244 245# must set the domainname before rc.conf, so YP startup choices can be made 246if [ -f /etc/defaultdomain ]; then 247 domainname `stripcom /etc/defaultdomain` 248fi 249 250# need to get local functions from rc.subr 251FUNCS_ONLY=1 . /etc/rc.d/rc.subr 252 253# load rc.conf into scope 254_rc_parse_conf 255 256if [ X"$1" = X"shutdown" ]; then 257 if echo 2>/dev/null >>/var/db/host.random || \ 258 echo 2>/dev/null >>/etc/random.seed; then 259 random_seed 260 else 261 echo warning: cannot write random seed to disk 262 fi 263 264 # If we are in secure level 0, assume single user mode. 265 if [ `sysctl -n kern.securelevel` -ne 0 ]; then 266 pkg_scripts=${pkg_scripts%%*( )} 267 if [ -n "${pkg_scripts}" ]; then 268 echo -n 'stopping package daemons:' 269 while [ -n "${pkg_scripts}" ]; do 270 _r=${pkg_scripts##* } 271 pkg_scripts=${pkg_scripts%%*( )${_r}} 272 [ -x /etc/rc.d/${_r} ] && /etc/rc.d/${_r} stop 273 done 274 echo '.' 275 fi 276 277 [ -f /etc/rc.shutdown ] && sh /etc/rc.shutdown 278 else 279 echo single user: not running shutdown scripts 280 fi 281 282 # bring carp interfaces down gracefully 283 ifconfig | while read a b; do 284 case $a in 285 carp+([0-9]):) ifconfig ${a%:} down ;; 286 esac 287 done 288 289 exit 0 290fi 291 292swapctl -A -t blk 293 294if [ -e /fastboot ]; then 295 echo "Fast boot: skipping disk checks." 296elif [ X"$1" = X"autoboot" ]; then 297 echo "Automatic boot in progress: starting file system checks." 298 do_fsck 299fi 300 301trap "echo 'Boot interrupted.'; exit 1" 3 302 303umount -a >/dev/null 2>&1 304mount -a -t nonfs,vnd 305mount -uw / # root on nfs requires this, others aren't hurt 306rm -f /fastboot # XXX (root now writeable) 307 308# set flags on ttys. (do early, in case they use tty for SLIP in netstart) 309echo 'setting tty flags' 310ttyflags -a 311 312if [ -f /sbin/kbd -a -f /etc/kbdtype ]; then 313 kbd `cat /etc/kbdtype` 314fi 315 316wsconsctl_conf 317 318if [ X"${pf}" != X"NO" ]; then 319 RULES="block all" 320 RULES="$RULES\npass on lo0" 321 RULES="$RULES\npass in proto tcp from any to any port 22 keep state" 322 RULES="$RULES\npass out proto { tcp, udp } from any to any port 53 keep state" 323 RULES="$RULES\npass out inet proto icmp all icmp-type echoreq keep state" 324 RULES="$RULES\npass out inet proto udp from any port bootpc to any port bootps" 325 RULES="$RULES\npass in inet proto udp from any port bootps to any port bootpc" 326 if ifconfig lo0 inet6 >/dev/null 2>&1; then 327 RULES="$RULES\npass out inet6 proto icmp6 all icmp6-type neighbrsol" 328 RULES="$RULES\npass in inet6 proto icmp6 all icmp6-type neighbradv" 329 RULES="$RULES\npass out inet6 proto icmp6 all icmp6-type routersol" 330 RULES="$RULES\npass in inet6 proto icmp6 all icmp6-type routeradv" 331 RULES="$RULES\npass out inet6 proto udp from any port dhcpv6-client to any port dhcpv6-server" 332 RULES="$RULES\npass in inet6 proto udp from any port dhcpv6-server to any port dhcpv6-client" 333 fi 334 RULES="$RULES\npass in proto carp keep state (no-sync)" 335 RULES="$RULES\npass out proto carp !received-on any keep state (no-sync)" 336 case `sysctl vfs.mounts.nfs 2>/dev/null` in 337 *[1-9]*) 338 # don't kill NFS 339 RULES="set reassemble yes no-df\n$RULES" 340 RULES="$RULES\npass in proto { tcp, udp } from any port { 111, 2049 } to any" 341 RULES="$RULES\npass out proto { tcp, udp } from any to any port { 111, 2049 } !received-on any" 342 ;; 343 esac 344 echo $RULES | pfctl -f - 345 pfctl -e 346fi 347 348# Fill net.inet.(tcp|udp).baddynamic lists from /etc/services 349fill_baddynamic udp 350fill_baddynamic tcp 351 352sysctl_conf 353 354# set hostname, turn on network 355echo 'starting network' 356ifconfig -g carp carpdemote 128 357if [ -f /etc/resolv.conf.save ]; then 358 mv -f /etc/resolv.conf.save /etc/resolv.conf 359 touch /etc/resolv.conf 360fi 361sh /etc/netstart 362dmesg > /dev/random # any write triggers an RC4 rekey 363 364if [ X"${pf}" != X"NO" ]; then 365 if [ -f ${pf_rules} ]; then 366 pfctl -f ${pf_rules} 367 fi 368 # bring up pfsync after the working ruleset has been loaded 369 if [ -f /etc/hostname.pfsync0 ]; then 370 sh /etc/netstart pfsync0 371 fi 372fi 373 374mount -s /usr >/dev/null 2>&1 375mount -s /var >/dev/null 2>&1 376 377random_seed 378 379# clean up left-over files 380rm -f /etc/nologin /var/spool/lock/LCK.* /var/spool/uucp/STST/* 381(cd /var/run && { rm -rf -- *; install -c -m 664 -g utmp /dev/null utmp; }) 382(cd /var/authpf && rm -rf -- *) 383 384# save a copy of the boot messages 385dmesg >/var/run/dmesg.boot 386 387make_keys 388 389echo -n 'starting early daemons:' 390start_daemon syslogd ldattach pflogd nsd unbound ntpd 391start_daemon iscsid isakmpd iked sasyncd ldapd npppd 392echo '.' 393 394if [ X"${ipsec}" != X"NO" ]; then 395 if [ -f ${ipsec_rules} ]; then 396 ipsecctl -f ${ipsec_rules} 397 fi 398fi 399 400echo -n 'starting RPC daemons:' 401start_daemon portmap ypldap 402if [ X"`domainname`" != X"" ]; then 403 start_daemon ypserv ypbind yppasswdd 404fi 405start_daemon mountd nfsd lockd statd amd 406echo '.' 407 408mount -a 409swapctl -A -t noblk 410 411# check and mount networked filesystems 412do_fsck -N 413mount -a -N 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/[lqv]* 442# (not needed with mfs /tmp, but doesn't hurt there...) 443(cd /tmp && rm -rf [a-km-pr-uw-zA-Z]*) 444(cd /tmp && 445 find . -maxdepth 1 ! -name . ! -name lost+found ! -name quota.user \ 446 ! -name quota.group ! -name vi.recover -execdir rm -rf -- {} \;) 447 448setup_X_sockets 449 450[ -f /etc/rc.securelevel ] && sh /etc/rc.securelevel 451# rc.securelevel did not specifically set -1 or 2, so select the default: 1 452if [ `sysctl -n kern.securelevel` -eq 0 ]; then 453 sysctl kern.securelevel=1 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 lpd smtpd slowcgi httpd ftpd 502start_daemon ftpproxy tftpd tftpproxy identd inetd rarpd bootparamd 503start_daemon rbootd mopd spamd spamlogd sndiod 504echo '.' 505 506# If rc.firstime exists, run it just once, and make sure it is deleted 507if [ -f /etc/rc.firsttime ]; then 508 mv /etc/rc.firsttime /etc/rc.firsttime.run 509 . /etc/rc.firsttime.run 2>&1 | tee /dev/tty | 510 mail -Es "`hostname` rc.firsttime output" root >/dev/null 511fi 512rm -f /etc/rc.firsttime.run 513 514# Run rc.d(8) scripts from packages 515if [ -n "${pkg_scripts}" ]; then 516 echo -n 'starting package daemons:' 517 for _r in $pkg_scripts; do 518 if [ -x /etc/rc.d/${_r} ]; then 519 start_daemon ${_r} 520 else 521 echo -n " ${_r}(absent)" 522 fi 523 done 524 echo '.' 525fi 526 527[ -f /etc/rc.local ] && sh /etc/rc.local 528 529ifconfig -g carp -carpdemote 128 # disable carp interlock 530 531mixerctl_conf 532echo -n 'starting local daemons:' 533start_daemon apmd sensorsd hotplugd watchdogd cron wsmoused xdm 534echo '.' 535 536date 537exit 0 538