1/*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Donn Seeley at Berkeley Software Design, Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 4. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33#ifndef lint 34static const char copyright[] = 35"@(#) Copyright (c) 1991, 1993\n\ 36 The Regents of the University of California. All rights reserved.\n"; 37#endif /* not lint */ 38 39#ifndef lint 40#if 0 41static char sccsid[] = "@(#)init.c 8.1 (Berkeley) 7/15/93"; 42#endif 43static const char rcsid[] = 44 "$FreeBSD: stable/11/sbin/init/init.c 365534 2020-09-09 22:40:39Z brooks $"; 45#endif /* not lint */ 46 47#include <sys/param.h> 48#include <sys/ioctl.h> 49#include <sys/mman.h> 50#include <sys/mount.h> 51#include <sys/sysctl.h> 52#include <sys/wait.h> 53#include <sys/stat.h> 54#include <sys/uio.h> 55 56#include <db.h> 57#include <errno.h> 58#include <fcntl.h> 59#include <kenv.h> 60#include <libutil.h> 61#include <paths.h> 62#include <signal.h> 63#include <stdio.h> 64#include <stdlib.h> 65#include <string.h> 66#include <syslog.h> 67#include <time.h> 68#include <ttyent.h> 69#include <unistd.h> 70#include <sys/reboot.h> 71#include <err.h> 72 73#include <stdarg.h> 74 75#ifdef SECURE 76#include <pwd.h> 77#endif 78 79#ifdef LOGIN_CAP 80#include <login_cap.h> 81#endif 82 83#include "mntopts.h" 84#include "pathnames.h" 85 86/* 87 * Sleep times; used to prevent thrashing. 88 */ 89#define GETTY_SPACING 5 /* N secs minimum getty spacing */ 90#define GETTY_SLEEP 30 /* sleep N secs after spacing problem */ 91#define GETTY_NSPACE 3 /* max. spacing count to bring reaction */ 92#define WINDOW_WAIT 3 /* wait N secs after starting window */ 93#define STALL_TIMEOUT 30 /* wait N secs after warning */ 94#define DEATH_WATCH 10 /* wait N secs for procs to die */ 95#define DEATH_SCRIPT 120 /* wait for 2min for /etc/rc.shutdown */ 96#define RESOURCE_RC "daemon" 97#define RESOURCE_WINDOW "default" 98#define RESOURCE_GETTY "default" 99 100static void handle(sig_t, ...); 101static void delset(sigset_t *, ...); 102 103static void stall(const char *, ...) __printflike(1, 2); 104static void warning(const char *, ...) __printflike(1, 2); 105static void emergency(const char *, ...) __printflike(1, 2); 106static void disaster(int); 107static void revoke_ttys(void); 108static int runshutdown(void); 109static char *strk(char *); 110 111/* 112 * We really need a recursive typedef... 113 * The following at least guarantees that the return type of (*state_t)() 114 * is sufficiently wide to hold a function pointer. 115 */ 116typedef long (*state_func_t)(void); 117typedef state_func_t (*state_t)(void); 118 119static state_func_t single_user(void); 120static state_func_t runcom(void); 121static state_func_t read_ttys(void); 122static state_func_t multi_user(void); 123static state_func_t clean_ttys(void); 124static state_func_t catatonia(void); 125static state_func_t death(void); 126static state_func_t death_single(void); 127static state_func_t reroot(void); 128static state_func_t reroot_phase_two(void); 129 130static state_func_t run_script(const char *); 131 132static enum { AUTOBOOT, FASTBOOT } runcom_mode = AUTOBOOT; 133#define FALSE 0 134#define TRUE 1 135 136static int Reboot = FALSE; 137static int howto = RB_AUTOBOOT; 138 139static int devfs; 140static char *init_path_argv0; 141 142static void transition(state_t); 143static state_t requested_transition; 144static state_t current_state = death_single; 145 146static void execute_script(char *argv[]); 147static void open_console(void); 148static const char *get_shell(void); 149static void replace_init(char *path); 150static void write_stderr(const char *message); 151 152typedef struct init_session { 153 pid_t se_process; /* controlling process */ 154 time_t se_started; /* used to avoid thrashing */ 155 int se_flags; /* status of session */ 156#define SE_SHUTDOWN 0x1 /* session won't be restarted */ 157#define SE_PRESENT 0x2 /* session is in /etc/ttys */ 158#define SE_IFEXISTS 0x4 /* session defined as "onifexists" */ 159#define SE_IFCONSOLE 0x8 /* session defined as "onifconsole" */ 160 int se_nspace; /* spacing count */ 161 char *se_device; /* filename of port */ 162 char *se_getty; /* what to run on that port */ 163 char *se_getty_argv_space; /* pre-parsed argument array space */ 164 char **se_getty_argv; /* pre-parsed argument array */ 165 char *se_window; /* window system (started only once) */ 166 char *se_window_argv_space; /* pre-parsed argument array space */ 167 char **se_window_argv; /* pre-parsed argument array */ 168 char *se_type; /* default terminal type */ 169 struct init_session *se_prev; 170 struct init_session *se_next; 171} session_t; 172 173static void free_session(session_t *); 174static session_t *new_session(session_t *, struct ttyent *); 175static session_t *sessions; 176 177static char **construct_argv(char *); 178static void start_window_system(session_t *); 179static void collect_child(pid_t); 180static pid_t start_getty(session_t *); 181static void transition_handler(int); 182static void alrm_handler(int); 183static void setsecuritylevel(int); 184static int getsecuritylevel(void); 185static int setupargv(session_t *, struct ttyent *); 186#ifdef LOGIN_CAP 187static void setprocresources(const char *); 188#endif 189static int clang; 190 191static int start_session_db(void); 192static void add_session(session_t *); 193static void del_session(session_t *); 194static session_t *find_session(pid_t); 195static DB *session_db; 196 197/* 198 * The mother of all processes. 199 */ 200int 201main(int argc, char *argv[]) 202{ 203 state_t initial_transition = runcom; 204 char kenv_value[PATH_MAX]; 205 int c, error; 206 struct sigaction sa; 207 sigset_t mask; 208 209 /* Dispose of random users. */ 210 if (getuid() != 0) 211 errx(1, "%s", strerror(EPERM)); 212 213 /* System V users like to reexec init. */ 214 if (getpid() != 1) { 215#ifdef COMPAT_SYSV_INIT 216 /* So give them what they want */ 217 if (argc > 1) { 218 if (strlen(argv[1]) == 1) { 219 char runlevel = *argv[1]; 220 int sig; 221 222 switch (runlevel) { 223 case '0': /* halt + poweroff */ 224 sig = SIGUSR2; 225 break; 226 case '1': /* single-user */ 227 sig = SIGTERM; 228 break; 229 case '6': /* reboot */ 230 sig = SIGINT; 231 break; 232 case 'c': /* block further logins */ 233 sig = SIGTSTP; 234 break; 235 case 'q': /* rescan /etc/ttys */ 236 sig = SIGHUP; 237 break; 238 case 'r': /* remount root */ 239 sig = SIGEMT; 240 break; 241 default: 242 goto invalid; 243 } 244 kill(1, sig); 245 _exit(0); 246 } else 247invalid: 248 errx(1, "invalid run-level ``%s''", argv[1]); 249 } else 250#endif 251 errx(1, "already running"); 252 } 253 254 init_path_argv0 = strdup(argv[0]); 255 if (init_path_argv0 == NULL) 256 err(1, "strdup"); 257 258 /* 259 * Note that this does NOT open a file... 260 * Does 'init' deserve its own facility number? 261 */ 262 openlog("init", LOG_CONS, LOG_AUTH); 263 264 /* 265 * Create an initial session. 266 */ 267 if (setsid() < 0 && (errno != EPERM || getsid(0) != 1)) 268 warning("initial setsid() failed: %m"); 269 270 /* 271 * Establish an initial user so that programs running 272 * single user do not freak out and die (like passwd). 273 */ 274 if (setlogin("root") < 0) 275 warning("setlogin() failed: %m"); 276 277 /* 278 * This code assumes that we always get arguments through flags, 279 * never through bits set in some random machine register. 280 */ 281 while ((c = getopt(argc, argv, "dsfr")) != -1) 282 switch (c) { 283 case 'd': 284 devfs = 1; 285 break; 286 case 's': 287 initial_transition = single_user; 288 break; 289 case 'f': 290 runcom_mode = FASTBOOT; 291 break; 292 case 'r': 293 initial_transition = reroot_phase_two; 294 break; 295 default: 296 warning("unrecognized flag '-%c'", c); 297 break; 298 } 299 300 if (optind != argc) 301 warning("ignoring excess arguments"); 302 303 /* 304 * We catch or block signals rather than ignore them, 305 * so that they get reset on exec. 306 */ 307 handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS, 308 SIGXCPU, SIGXFSZ, 0); 309 handle(transition_handler, SIGHUP, SIGINT, SIGEMT, SIGTERM, SIGTSTP, 310 SIGUSR1, SIGUSR2, 0); 311 handle(alrm_handler, SIGALRM, 0); 312 sigfillset(&mask); 313 delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS, 314 SIGXCPU, SIGXFSZ, SIGHUP, SIGINT, SIGEMT, SIGTERM, SIGTSTP, 315 SIGALRM, SIGUSR1, SIGUSR2, 0); 316 sigprocmask(SIG_SETMASK, &mask, NULL); 317 sigemptyset(&sa.sa_mask); 318 sa.sa_flags = 0; 319 sa.sa_handler = SIG_IGN; 320 sigaction(SIGTTIN, &sa, NULL); 321 sigaction(SIGTTOU, &sa, NULL); 322 323 /* 324 * Paranoia. 325 */ 326 close(0); 327 close(1); 328 close(2); 329 330 if (kenv(KENV_GET, "init_exec", kenv_value, sizeof(kenv_value)) > 0) { 331 replace_init(kenv_value); 332 _exit(0); /* reboot */ 333 } 334 335 if (kenv(KENV_GET, "init_script", kenv_value, sizeof(kenv_value)) > 0) { 336 state_func_t next_transition; 337 338 if ((next_transition = run_script(kenv_value)) != NULL) 339 initial_transition = (state_t) next_transition; 340 } 341 342 if (kenv(KENV_GET, "init_chroot", kenv_value, sizeof(kenv_value)) > 0) { 343 if (chdir(kenv_value) != 0 || chroot(".") != 0) 344 warning("Can't chroot to %s: %m", kenv_value); 345 } 346 347 /* 348 * Additional check if devfs needs to be mounted: 349 * If "/" and "/dev" have the same device number, 350 * then it hasn't been mounted yet. 351 */ 352 if (!devfs) { 353 struct stat stst; 354 dev_t root_devno; 355 356 stat("/", &stst); 357 root_devno = stst.st_dev; 358 if (stat("/dev", &stst) != 0) 359 warning("Can't stat /dev: %m"); 360 else if (stst.st_dev == root_devno) 361 devfs++; 362 } 363 364 if (devfs) { 365 struct iovec iov[4]; 366 char *s; 367 int i; 368 369 char _fstype[] = "fstype"; 370 char _devfs[] = "devfs"; 371 char _fspath[] = "fspath"; 372 char _path_dev[]= _PATH_DEV; 373 374 iov[0].iov_base = _fstype; 375 iov[0].iov_len = sizeof(_fstype); 376 iov[1].iov_base = _devfs; 377 iov[1].iov_len = sizeof(_devfs); 378 iov[2].iov_base = _fspath; 379 iov[2].iov_len = sizeof(_fspath); 380 /* 381 * Try to avoid the trailing slash in _PATH_DEV. 382 * Be *very* defensive. 383 */ 384 s = strdup(_PATH_DEV); 385 if (s != NULL) { 386 i = strlen(s); 387 if (i > 0 && s[i - 1] == '/') 388 s[i - 1] = '\0'; 389 iov[3].iov_base = s; 390 iov[3].iov_len = strlen(s) + 1; 391 } else { 392 iov[3].iov_base = _path_dev; 393 iov[3].iov_len = sizeof(_path_dev); 394 } 395 nmount(iov, 4, 0); 396 if (s != NULL) 397 free(s); 398 } 399 400 if (initial_transition != reroot_phase_two) { 401 /* 402 * Unmount reroot leftovers. This runs after init(8) 403 * gets reexecuted after reroot_phase_two() is done. 404 */ 405 error = unmount(_PATH_REROOT, MNT_FORCE); 406 if (error != 0 && errno != EINVAL) 407 warning("Cannot unmount %s: %m", _PATH_REROOT); 408 } 409 410 /* 411 * Start the state machine. 412 */ 413 transition(initial_transition); 414 415 /* 416 * Should never reach here. 417 */ 418 return 1; 419} 420 421/* 422 * Associate a function with a signal handler. 423 */ 424static void 425handle(sig_t handler, ...) 426{ 427 int sig; 428 struct sigaction sa; 429 sigset_t mask_everything; 430 va_list ap; 431 va_start(ap, handler); 432 433 sa.sa_handler = handler; 434 sigfillset(&mask_everything); 435 436 while ((sig = va_arg(ap, int)) != 0) { 437 sa.sa_mask = mask_everything; 438 /* XXX SA_RESTART? */ 439 sa.sa_flags = sig == SIGCHLD ? SA_NOCLDSTOP : 0; 440 sigaction(sig, &sa, NULL); 441 } 442 va_end(ap); 443} 444 445/* 446 * Delete a set of signals from a mask. 447 */ 448static void 449delset(sigset_t *maskp, ...) 450{ 451 int sig; 452 va_list ap; 453 va_start(ap, maskp); 454 455 while ((sig = va_arg(ap, int)) != 0) 456 sigdelset(maskp, sig); 457 va_end(ap); 458} 459 460/* 461 * Log a message and sleep for a while (to give someone an opportunity 462 * to read it and to save log or hardcopy output if the problem is chronic). 463 * NB: should send a message to the session logger to avoid blocking. 464 */ 465static void 466stall(const char *message, ...) 467{ 468 va_list ap; 469 va_start(ap, message); 470 471 vsyslog(LOG_ALERT, message, ap); 472 va_end(ap); 473 sleep(STALL_TIMEOUT); 474} 475 476/* 477 * Like stall(), but doesn't sleep. 478 * If cpp had variadic macros, the two functions could be #defines for another. 479 * NB: should send a message to the session logger to avoid blocking. 480 */ 481static void 482warning(const char *message, ...) 483{ 484 va_list ap; 485 va_start(ap, message); 486 487 vsyslog(LOG_ALERT, message, ap); 488 va_end(ap); 489} 490 491/* 492 * Log an emergency message. 493 * NB: should send a message to the session logger to avoid blocking. 494 */ 495static void 496emergency(const char *message, ...) 497{ 498 va_list ap; 499 va_start(ap, message); 500 501 vsyslog(LOG_EMERG, message, ap); 502 va_end(ap); 503} 504 505/* 506 * Catch an unexpected signal. 507 */ 508static void 509disaster(int sig) 510{ 511 512 emergency("fatal signal: %s", 513 (unsigned)sig < NSIG ? sys_siglist[sig] : "unknown signal"); 514 515 sleep(STALL_TIMEOUT); 516 _exit(sig); /* reboot */ 517} 518 519/* 520 * Get the security level of the kernel. 521 */ 522static int 523getsecuritylevel(void) 524{ 525#ifdef KERN_SECURELVL 526 int name[2], curlevel; 527 size_t len; 528 529 name[0] = CTL_KERN; 530 name[1] = KERN_SECURELVL; 531 len = sizeof curlevel; 532 if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) { 533 emergency("cannot get kernel security level: %s", 534 strerror(errno)); 535 return (-1); 536 } 537 return (curlevel); 538#else 539 return (-1); 540#endif 541} 542 543/* 544 * Set the security level of the kernel. 545 */ 546static void 547setsecuritylevel(int newlevel) 548{ 549#ifdef KERN_SECURELVL 550 int name[2], curlevel; 551 552 curlevel = getsecuritylevel(); 553 if (newlevel == curlevel) 554 return; 555 name[0] = CTL_KERN; 556 name[1] = KERN_SECURELVL; 557 if (sysctl(name, 2, NULL, NULL, &newlevel, sizeof newlevel) == -1) { 558 emergency( 559 "cannot change kernel security level from %d to %d: %s", 560 curlevel, newlevel, strerror(errno)); 561 return; 562 } 563#ifdef SECURE 564 warning("kernel security level changed from %d to %d", 565 curlevel, newlevel); 566#endif 567#endif 568} 569 570/* 571 * Change states in the finite state machine. 572 * The initial state is passed as an argument. 573 */ 574static void 575transition(state_t s) 576{ 577 578 current_state = s; 579 for (;;) 580 current_state = (state_t) (*current_state)(); 581} 582 583/* 584 * Start a session and allocate a controlling terminal. 585 * Only called by children of init after forking. 586 */ 587static void 588open_console(void) 589{ 590 int fd; 591 592 /* 593 * Try to open /dev/console. Open the device with O_NONBLOCK to 594 * prevent potential blocking on a carrier. 595 */ 596 revoke(_PATH_CONSOLE); 597 if ((fd = open(_PATH_CONSOLE, O_RDWR | O_NONBLOCK)) != -1) { 598 (void)fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK); 599 if (login_tty(fd) == 0) 600 return; 601 close(fd); 602 } 603 604 /* No luck. Log output to file if possible. */ 605 if ((fd = open(_PATH_DEVNULL, O_RDWR)) == -1) { 606 stall("cannot open null device."); 607 _exit(1); 608 } 609 if (fd != STDIN_FILENO) { 610 dup2(fd, STDIN_FILENO); 611 close(fd); 612 } 613 fd = open(_PATH_INITLOG, O_WRONLY | O_APPEND | O_CREAT, 0644); 614 if (fd == -1) 615 dup2(STDIN_FILENO, STDOUT_FILENO); 616 else if (fd != STDOUT_FILENO) { 617 dup2(fd, STDOUT_FILENO); 618 close(fd); 619 } 620 dup2(STDOUT_FILENO, STDERR_FILENO); 621} 622 623static const char * 624get_shell(void) 625{ 626 static char kenv_value[PATH_MAX]; 627 628 if (kenv(KENV_GET, "init_shell", kenv_value, sizeof(kenv_value)) > 0) 629 return kenv_value; 630 else 631 return _PATH_BSHELL; 632} 633 634static void 635write_stderr(const char *message) 636{ 637 638 write(STDERR_FILENO, message, strlen(message)); 639} 640 641static int 642read_file(const char *path, void **bufp, size_t *bufsizep) 643{ 644 struct stat sb; 645 size_t bufsize; 646 void *buf; 647 ssize_t nbytes; 648 int error, fd; 649 650 fd = open(path, O_RDONLY); 651 if (fd < 0) { 652 emergency("%s: %s", path, strerror(errno)); 653 return (-1); 654 } 655 656 error = fstat(fd, &sb); 657 if (error != 0) { 658 emergency("fstat: %s", strerror(errno)); 659 close(fd); 660 return (error); 661 } 662 663 bufsize = sb.st_size; 664 buf = malloc(bufsize); 665 if (buf == NULL) { 666 emergency("malloc: %s", strerror(errno)); 667 close(fd); 668 return (error); 669 } 670 671 nbytes = read(fd, buf, bufsize); 672 if (nbytes != (ssize_t)bufsize) { 673 emergency("read: %s", strerror(errno)); 674 close(fd); 675 free(buf); 676 return (error); 677 } 678 679 error = close(fd); 680 if (error != 0) { 681 emergency("close: %s", strerror(errno)); 682 free(buf); 683 return (error); 684 } 685 686 *bufp = buf; 687 *bufsizep = bufsize; 688 689 return (0); 690} 691 692static int 693create_file(const char *path, const void *buf, size_t bufsize) 694{ 695 ssize_t nbytes; 696 int error, fd; 697 698 fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0700); 699 if (fd < 0) { 700 emergency("%s: %s", path, strerror(errno)); 701 return (-1); 702 } 703 704 nbytes = write(fd, buf, bufsize); 705 if (nbytes != (ssize_t)bufsize) { 706 emergency("write: %s", strerror(errno)); 707 close(fd); 708 return (-1); 709 } 710 711 error = close(fd); 712 if (error != 0) { 713 emergency("close: %s", strerror(errno)); 714 return (-1); 715 } 716 717 return (0); 718} 719 720static int 721mount_tmpfs(const char *fspath) 722{ 723 struct iovec *iov; 724 char errmsg[255]; 725 int error, iovlen; 726 727 iov = NULL; 728 iovlen = 0; 729 memset(errmsg, 0, sizeof(errmsg)); 730 build_iovec(&iov, &iovlen, "fstype", 731 __DECONST(void *, "tmpfs"), (size_t)-1); 732 build_iovec(&iov, &iovlen, "fspath", 733 __DECONST(void *, fspath), (size_t)-1); 734 build_iovec(&iov, &iovlen, "errmsg", 735 errmsg, sizeof(errmsg)); 736 737 error = nmount(iov, iovlen, 0); 738 if (error != 0) { 739 if (*errmsg != '\0') { 740 emergency("cannot mount tmpfs on %s: %s: %s", 741 fspath, errmsg, strerror(errno)); 742 } else { 743 emergency("cannot mount tmpfs on %s: %s", 744 fspath, strerror(errno)); 745 } 746 return (error); 747 } 748 return (0); 749} 750 751static state_func_t 752reroot(void) 753{ 754 void *buf; 755 size_t bufsize; 756 int error; 757 758 buf = NULL; 759 bufsize = 0; 760 761 revoke_ttys(); 762 runshutdown(); 763 764 /* 765 * Make sure nobody can interfere with our scheme. 766 * Ignore ESRCH, which can apparently happen when 767 * there are no processes to kill. 768 */ 769 error = kill(-1, SIGKILL); 770 if (error != 0 && errno != ESRCH) { 771 emergency("kill(2) failed: %s", strerror(errno)); 772 goto out; 773 } 774 775 /* 776 * Copy the init binary into tmpfs, so that we can unmount 777 * the old rootfs without committing suicide. 778 */ 779 error = read_file(init_path_argv0, &buf, &bufsize); 780 if (error != 0) 781 goto out; 782 error = mount_tmpfs(_PATH_REROOT); 783 if (error != 0) 784 goto out; 785 error = create_file(_PATH_REROOT_INIT, buf, bufsize); 786 if (error != 0) 787 goto out; 788 789 /* 790 * Execute the temporary init. 791 */ 792 execl(_PATH_REROOT_INIT, _PATH_REROOT_INIT, "-r", NULL); 793 emergency("cannot exec %s: %s", _PATH_REROOT_INIT, strerror(errno)); 794 795out: 796 emergency("reroot failed; going to single user mode"); 797 free(buf); 798 return (state_func_t) single_user; 799} 800 801static state_func_t 802reroot_phase_two(void) 803{ 804 char init_path[PATH_MAX], *path, *path_component; 805 size_t init_path_len; 806 int nbytes, error; 807 808 /* 809 * Ask the kernel to mount the new rootfs. 810 */ 811 error = reboot(RB_REROOT); 812 if (error != 0) { 813 emergency("RB_REBOOT failed: %s", strerror(errno)); 814 goto out; 815 } 816 817 /* 818 * Figure out where the destination init(8) binary is. Note that 819 * the path could be different than what we've started with. Use 820 * the value from kenv, if set, or the one from sysctl otherwise. 821 * The latter defaults to a hardcoded value, but can be overridden 822 * by a build time option. 823 */ 824 nbytes = kenv(KENV_GET, "init_path", init_path, sizeof(init_path)); 825 if (nbytes <= 0) { 826 init_path_len = sizeof(init_path); 827 error = sysctlbyname("kern.init_path", 828 init_path, &init_path_len, NULL, 0); 829 if (error != 0) { 830 emergency("failed to retrieve kern.init_path: %s", 831 strerror(errno)); 832 goto out; 833 } 834 } 835 836 /* 837 * Repeat the init search logic from sys/kern/init_path.c 838 */ 839 path_component = init_path; 840 while ((path = strsep(&path_component, ":")) != NULL) { 841 /* 842 * Execute init(8) from the new rootfs. 843 */ 844 execl(path, path, NULL); 845 } 846 emergency("cannot exec init from %s: %s", init_path, strerror(errno)); 847 848out: 849 emergency("reroot failed; going to single user mode"); 850 return (state_func_t) single_user; 851} 852 853/* 854 * Bring the system up single user. 855 */ 856static state_func_t 857single_user(void) 858{ 859 pid_t pid, wpid; 860 int status; 861 sigset_t mask; 862 const char *shell; 863 char *argv[2]; 864 struct timeval tv, tn; 865#ifdef SECURE 866 struct ttyent *typ; 867 struct passwd *pp; 868 static const char banner[] = 869 "Enter root password, or ^D to go multi-user\n"; 870 char *clear, *password; 871#endif 872#ifdef DEBUGSHELL 873 char altshell[128]; 874#endif 875 876 if (Reboot) { 877 /* Instead of going single user, let's reboot the machine */ 878 sync(); 879 if (reboot(howto) == -1) { 880 emergency("reboot(%#x) failed, %s", howto, 881 strerror(errno)); 882 _exit(1); /* panic and reboot */ 883 } 884 warning("reboot(%#x) returned", howto); 885 _exit(0); /* panic as well */ 886 } 887 888 shell = get_shell(); 889 890 if ((pid = fork()) == 0) { 891 /* 892 * Start the single user session. 893 */ 894 open_console(); 895 896#ifdef SECURE 897 /* 898 * Check the root password. 899 * We don't care if the console is 'on' by default; 900 * it's the only tty that can be 'off' and 'secure'. 901 */ 902 typ = getttynam("console"); 903 pp = getpwnam("root"); 904 if (typ && (typ->ty_status & TTY_SECURE) == 0 && 905 pp && *pp->pw_passwd) { 906 write_stderr(banner); 907 for (;;) { 908 clear = getpass("Password:"); 909 if (clear == NULL || *clear == '\0') 910 _exit(0); 911 password = crypt(clear, pp->pw_passwd); 912 bzero(clear, _PASSWORD_LEN); 913 if (password == NULL || 914 strcmp(password, pp->pw_passwd) == 0) 915 break; 916 warning("single-user login failed\n"); 917 } 918 } 919 endttyent(); 920 endpwent(); 921#endif /* SECURE */ 922 923#ifdef DEBUGSHELL 924 { 925 char *cp = altshell; 926 int num; 927 928#define SHREQUEST "Enter full pathname of shell or RETURN for " 929 write_stderr(SHREQUEST); 930 write_stderr(shell); 931 write_stderr(": "); 932 while ((num = read(STDIN_FILENO, cp, 1)) != -1 && 933 num != 0 && *cp != '\n' && cp < &altshell[127]) 934 cp++; 935 *cp = '\0'; 936 if (altshell[0] != '\0') 937 shell = altshell; 938 } 939#endif /* DEBUGSHELL */ 940 941 /* 942 * Unblock signals. 943 * We catch all the interesting ones, 944 * and those are reset to SIG_DFL on exec. 945 */ 946 sigemptyset(&mask); 947 sigprocmask(SIG_SETMASK, &mask, NULL); 948 949 /* 950 * Fire off a shell. 951 * If the default one doesn't work, try the Bourne shell. 952 */ 953 954 char name[] = "-sh"; 955 956 argv[0] = name; 957 argv[1] = NULL; 958 execv(shell, argv); 959 emergency("can't exec %s for single user: %m", shell); 960 execv(_PATH_BSHELL, argv); 961 emergency("can't exec %s for single user: %m", _PATH_BSHELL); 962 sleep(STALL_TIMEOUT); 963 _exit(1); 964 } 965 966 if (pid == -1) { 967 /* 968 * We are seriously hosed. Do our best. 969 */ 970 emergency("can't fork single-user shell, trying again"); 971 while (waitpid(-1, (int *) 0, WNOHANG) > 0) 972 continue; 973 return (state_func_t) single_user; 974 } 975 976 requested_transition = 0; 977 do { 978 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) 979 collect_child(wpid); 980 if (wpid == -1) { 981 if (errno == EINTR) 982 continue; 983 warning("wait for single-user shell failed: %m; restarting"); 984 return (state_func_t) single_user; 985 } 986 if (wpid == pid && WIFSTOPPED(status)) { 987 warning("init: shell stopped, restarting\n"); 988 kill(pid, SIGCONT); 989 wpid = -1; 990 } 991 } while (wpid != pid && !requested_transition); 992 993 if (requested_transition) 994 return (state_func_t) requested_transition; 995 996 if (!WIFEXITED(status)) { 997 if (WTERMSIG(status) == SIGKILL) { 998 /* 999 * reboot(8) killed shell? 1000 */ 1001 warning("single user shell terminated."); 1002 gettimeofday(&tv, NULL); 1003 tn = tv; 1004 tv.tv_sec += STALL_TIMEOUT; 1005 while (tv.tv_sec > tn.tv_sec || (tv.tv_sec == 1006 tn.tv_sec && tv.tv_usec > tn.tv_usec)) { 1007 sleep(1); 1008 gettimeofday(&tn, NULL); 1009 } 1010 _exit(0); 1011 } else { 1012 warning("single user shell terminated, restarting"); 1013 return (state_func_t) single_user; 1014 } 1015 } 1016 1017 runcom_mode = FASTBOOT; 1018 return (state_func_t) runcom; 1019} 1020 1021/* 1022 * Run the system startup script. 1023 */ 1024static state_func_t 1025runcom(void) 1026{ 1027 state_func_t next_transition; 1028 1029 if ((next_transition = run_script(_PATH_RUNCOM)) != NULL) 1030 return next_transition; 1031 1032 runcom_mode = AUTOBOOT; /* the default */ 1033 return (state_func_t) read_ttys; 1034} 1035 1036static void 1037execute_script(char *argv[]) 1038{ 1039 struct sigaction sa; 1040 const char *shell, *script; 1041 int error; 1042 1043 bzero(&sa, sizeof(sa)); 1044 sigemptyset(&sa.sa_mask); 1045 sa.sa_handler = SIG_IGN; 1046 sigaction(SIGTSTP, &sa, NULL); 1047 sigaction(SIGHUP, &sa, NULL); 1048 1049 open_console(); 1050 1051 sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL); 1052#ifdef LOGIN_CAP 1053 setprocresources(RESOURCE_RC); 1054#endif 1055 1056 /* 1057 * Try to directly execute the script first. If it 1058 * fails, try the old method of passing the script path 1059 * to sh(1). Don't complain if it fails because of 1060 * the missing execute bit. 1061 */ 1062 script = argv[1]; 1063 error = access(script, X_OK); 1064 if (error == 0) { 1065 execv(script, argv + 1); 1066 warning("can't exec %s: %m", script); 1067 } else if (errno != EACCES) { 1068 warning("can't access %s: %m", script); 1069 } 1070 1071 shell = get_shell(); 1072 execv(shell, argv); 1073 stall("can't exec %s for %s: %m", shell, script); 1074} 1075 1076/* 1077 * Execute binary, replacing init(8) as PID 1. 1078 */ 1079static void 1080replace_init(char *path) 1081{ 1082 char *argv[3]; 1083 char sh[] = "sh"; 1084 1085 argv[0] = sh; 1086 argv[1] = path; 1087 argv[2] = NULL; 1088 1089 execute_script(argv); 1090} 1091 1092/* 1093 * Run a shell script. 1094 * Returns 0 on success, otherwise the next transition to enter: 1095 * - single_user if fork/execv/waitpid failed, or if the script 1096 * terminated with a signal or exit code != 0. 1097 * - death_single if a SIGTERM was delivered to init(8). 1098 */ 1099static state_func_t 1100run_script(const char *script) 1101{ 1102 pid_t pid, wpid; 1103 int status; 1104 char *argv[4]; 1105 const char *shell; 1106 1107 shell = get_shell(); 1108 1109 if ((pid = fork()) == 0) { 1110 1111 char _sh[] = "sh"; 1112 char _autoboot[] = "autoboot"; 1113 1114 argv[0] = _sh; 1115 argv[1] = __DECONST(char *, script); 1116 argv[2] = runcom_mode == AUTOBOOT ? _autoboot : 0; 1117 argv[3] = NULL; 1118 1119 execute_script(argv); 1120 sleep(STALL_TIMEOUT); 1121 _exit(1); /* force single user mode */ 1122 } 1123 1124 if (pid == -1) { 1125 emergency("can't fork for %s on %s: %m", shell, script); 1126 while (waitpid(-1, (int *) 0, WNOHANG) > 0) 1127 continue; 1128 sleep(STALL_TIMEOUT); 1129 return (state_func_t) single_user; 1130 } 1131 1132 /* 1133 * Copied from single_user(). This is a bit paranoid. 1134 */ 1135 requested_transition = 0; 1136 do { 1137 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) 1138 collect_child(wpid); 1139 if (wpid == -1) { 1140 if (requested_transition == death_single || 1141 requested_transition == reroot) 1142 return (state_func_t) requested_transition; 1143 if (errno == EINTR) 1144 continue; 1145 warning("wait for %s on %s failed: %m; going to " 1146 "single user mode", shell, script); 1147 return (state_func_t) single_user; 1148 } 1149 if (wpid == pid && WIFSTOPPED(status)) { 1150 warning("init: %s on %s stopped, restarting\n", 1151 shell, script); 1152 kill(pid, SIGCONT); 1153 wpid = -1; 1154 } 1155 } while (wpid != pid); 1156 1157 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM && 1158 requested_transition == catatonia) { 1159 /* /etc/rc executed /sbin/reboot; wait for the end quietly */ 1160 sigset_t s; 1161 1162 sigfillset(&s); 1163 for (;;) 1164 sigsuspend(&s); 1165 } 1166 1167 if (!WIFEXITED(status)) { 1168 warning("%s on %s terminated abnormally, going to single " 1169 "user mode", shell, script); 1170 return (state_func_t) single_user; 1171 } 1172 1173 if (WEXITSTATUS(status)) 1174 return (state_func_t) single_user; 1175 1176 return (state_func_t) 0; 1177} 1178 1179/* 1180 * Open the session database. 1181 * 1182 * NB: We could pass in the size here; is it necessary? 1183 */ 1184static int 1185start_session_db(void) 1186{ 1187 if (session_db && (*session_db->close)(session_db)) 1188 emergency("session database close: %s", strerror(errno)); 1189 if ((session_db = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL)) == NULL) { 1190 emergency("session database open: %s", strerror(errno)); 1191 return (1); 1192 } 1193 return (0); 1194 1195} 1196 1197/* 1198 * Add a new login session. 1199 */ 1200static void 1201add_session(session_t *sp) 1202{ 1203 DBT key; 1204 DBT data; 1205 1206 key.data = &sp->se_process; 1207 key.size = sizeof sp->se_process; 1208 data.data = &sp; 1209 data.size = sizeof sp; 1210 1211 if ((*session_db->put)(session_db, &key, &data, 0)) 1212 emergency("insert %d: %s", sp->se_process, strerror(errno)); 1213} 1214 1215/* 1216 * Delete an old login session. 1217 */ 1218static void 1219del_session(session_t *sp) 1220{ 1221 DBT key; 1222 1223 key.data = &sp->se_process; 1224 key.size = sizeof sp->se_process; 1225 1226 if ((*session_db->del)(session_db, &key, 0)) 1227 emergency("delete %d: %s", sp->se_process, strerror(errno)); 1228} 1229 1230/* 1231 * Look up a login session by pid. 1232 */ 1233static session_t * 1234find_session(pid_t pid) 1235{ 1236 DBT key; 1237 DBT data; 1238 session_t *ret; 1239 1240 key.data = &pid; 1241 key.size = sizeof pid; 1242 if ((*session_db->get)(session_db, &key, &data, 0) != 0) 1243 return 0; 1244 bcopy(data.data, (char *)&ret, sizeof(ret)); 1245 return ret; 1246} 1247 1248/* 1249 * Construct an argument vector from a command line. 1250 */ 1251static char ** 1252construct_argv(char *command) 1253{ 1254 int argc = 0; 1255 char **argv = (char **) malloc(((strlen(command) + 1) / 2 + 1) 1256 * sizeof (char *)); 1257 1258 if ((argv[argc++] = strk(command)) == NULL) { 1259 free(argv); 1260 return (NULL); 1261 } 1262 while ((argv[argc++] = strk((char *) 0)) != NULL) 1263 continue; 1264 return argv; 1265} 1266 1267/* 1268 * Deallocate a session descriptor. 1269 */ 1270static void 1271free_session(session_t *sp) 1272{ 1273 free(sp->se_device); 1274 if (sp->se_getty) { 1275 free(sp->se_getty); 1276 free(sp->se_getty_argv_space); 1277 free(sp->se_getty_argv); 1278 } 1279 if (sp->se_window) { 1280 free(sp->se_window); 1281 free(sp->se_window_argv_space); 1282 free(sp->se_window_argv); 1283 } 1284 if (sp->se_type) 1285 free(sp->se_type); 1286 free(sp); 1287} 1288 1289/* 1290 * Allocate a new session descriptor. 1291 * Mark it SE_PRESENT. 1292 */ 1293static session_t * 1294new_session(session_t *sprev, struct ttyent *typ) 1295{ 1296 session_t *sp; 1297 1298 if ((typ->ty_status & TTY_ON) == 0 || 1299 typ->ty_name == 0 || 1300 typ->ty_getty == 0) 1301 return 0; 1302 1303 sp = (session_t *) calloc(1, sizeof (session_t)); 1304 1305 sp->se_flags |= SE_PRESENT; 1306 1307 if ((typ->ty_status & TTY_IFEXISTS) != 0) 1308 sp->se_flags |= SE_IFEXISTS; 1309 1310 if ((typ->ty_status & TTY_IFCONSOLE) != 0) 1311 sp->se_flags |= SE_IFCONSOLE; 1312 1313 if (asprintf(&sp->se_device, "%s%s", _PATH_DEV, typ->ty_name) < 0) 1314 err(1, "asprintf"); 1315 1316 if (setupargv(sp, typ) == 0) { 1317 free_session(sp); 1318 return (0); 1319 } 1320 1321 sp->se_next = 0; 1322 if (sprev == NULL) { 1323 sessions = sp; 1324 sp->se_prev = 0; 1325 } else { 1326 sprev->se_next = sp; 1327 sp->se_prev = sprev; 1328 } 1329 1330 return sp; 1331} 1332 1333/* 1334 * Calculate getty and if useful window argv vectors. 1335 */ 1336static int 1337setupargv(session_t *sp, struct ttyent *typ) 1338{ 1339 1340 if (sp->se_getty) { 1341 free(sp->se_getty); 1342 free(sp->se_getty_argv_space); 1343 free(sp->se_getty_argv); 1344 } 1345 if (asprintf(&sp->se_getty, "%s %s", typ->ty_getty, typ->ty_name) < 0) 1346 err(1, "asprintf"); 1347 sp->se_getty_argv_space = strdup(sp->se_getty); 1348 sp->se_getty_argv = construct_argv(sp->se_getty_argv_space); 1349 if (sp->se_getty_argv == NULL) { 1350 warning("can't parse getty for port %s", sp->se_device); 1351 free(sp->se_getty); 1352 free(sp->se_getty_argv_space); 1353 sp->se_getty = sp->se_getty_argv_space = 0; 1354 return (0); 1355 } 1356 if (sp->se_window) { 1357 free(sp->se_window); 1358 free(sp->se_window_argv_space); 1359 free(sp->se_window_argv); 1360 } 1361 sp->se_window = sp->se_window_argv_space = 0; 1362 sp->se_window_argv = 0; 1363 if (typ->ty_window) { 1364 sp->se_window = strdup(typ->ty_window); 1365 sp->se_window_argv_space = strdup(sp->se_window); 1366 sp->se_window_argv = construct_argv(sp->se_window_argv_space); 1367 if (sp->se_window_argv == NULL) { 1368 warning("can't parse window for port %s", 1369 sp->se_device); 1370 free(sp->se_window_argv_space); 1371 free(sp->se_window); 1372 sp->se_window = sp->se_window_argv_space = 0; 1373 return (0); 1374 } 1375 } 1376 if (sp->se_type) 1377 free(sp->se_type); 1378 sp->se_type = typ->ty_type ? strdup(typ->ty_type) : 0; 1379 return (1); 1380} 1381 1382/* 1383 * Walk the list of ttys and create sessions for each active line. 1384 */ 1385static state_func_t 1386read_ttys(void) 1387{ 1388 session_t *sp, *snext; 1389 struct ttyent *typ; 1390 1391 /* 1392 * Destroy any previous session state. 1393 * There shouldn't be any, but just in case... 1394 */ 1395 for (sp = sessions; sp; sp = snext) { 1396 snext = sp->se_next; 1397 free_session(sp); 1398 } 1399 sessions = 0; 1400 if (start_session_db()) 1401 return (state_func_t) single_user; 1402 1403 /* 1404 * Allocate a session entry for each active port. 1405 * Note that sp starts at 0. 1406 */ 1407 while ((typ = getttyent()) != NULL) 1408 if ((snext = new_session(sp, typ)) != NULL) 1409 sp = snext; 1410 1411 endttyent(); 1412 1413 return (state_func_t) multi_user; 1414} 1415 1416/* 1417 * Start a window system running. 1418 */ 1419static void 1420start_window_system(session_t *sp) 1421{ 1422 pid_t pid; 1423 sigset_t mask; 1424 char term[64], *env[2]; 1425 int status; 1426 1427 if ((pid = fork()) == -1) { 1428 emergency("can't fork for window system on port %s: %m", 1429 sp->se_device); 1430 /* hope that getty fails and we can try again */ 1431 return; 1432 } 1433 if (pid) { 1434 waitpid(-1, &status, 0); 1435 return; 1436 } 1437 1438 /* reparent window process to the init to not make a zombie on exit */ 1439 if ((pid = fork()) == -1) { 1440 emergency("can't fork for window system on port %s: %m", 1441 sp->se_device); 1442 _exit(1); 1443 } 1444 if (pid) 1445 _exit(0); 1446 1447 sigemptyset(&mask); 1448 sigprocmask(SIG_SETMASK, &mask, NULL); 1449 1450 if (setsid() < 0) 1451 emergency("setsid failed (window) %m"); 1452 1453#ifdef LOGIN_CAP 1454 setprocresources(RESOURCE_WINDOW); 1455#endif 1456 if (sp->se_type) { 1457 /* Don't use malloc after fork */ 1458 strcpy(term, "TERM="); 1459 strlcat(term, sp->se_type, sizeof(term)); 1460 env[0] = term; 1461 env[1] = NULL; 1462 } 1463 else 1464 env[0] = NULL; 1465 execve(sp->se_window_argv[0], sp->se_window_argv, env); 1466 stall("can't exec window system '%s' for port %s: %m", 1467 sp->se_window_argv[0], sp->se_device); 1468 _exit(1); 1469} 1470 1471/* 1472 * Start a login session running. 1473 */ 1474static pid_t 1475start_getty(session_t *sp) 1476{ 1477 pid_t pid; 1478 sigset_t mask; 1479 time_t current_time = time((time_t *) 0); 1480 int too_quick = 0; 1481 char term[64], *env[2]; 1482 1483 if (current_time >= sp->se_started && 1484 current_time - sp->se_started < GETTY_SPACING) { 1485 if (++sp->se_nspace > GETTY_NSPACE) { 1486 sp->se_nspace = 0; 1487 too_quick = 1; 1488 } 1489 } else 1490 sp->se_nspace = 0; 1491 1492 /* 1493 * fork(), not vfork() -- we can't afford to block. 1494 */ 1495 if ((pid = fork()) == -1) { 1496 emergency("can't fork for getty on port %s: %m", sp->se_device); 1497 return -1; 1498 } 1499 1500 if (pid) 1501 return pid; 1502 1503 if (too_quick) { 1504 warning("getty repeating too quickly on port %s, sleeping %d secs", 1505 sp->se_device, GETTY_SLEEP); 1506 sleep((unsigned) GETTY_SLEEP); 1507 } 1508 1509 if (sp->se_window) { 1510 start_window_system(sp); 1511 sleep(WINDOW_WAIT); 1512 } 1513 1514 sigemptyset(&mask); 1515 sigprocmask(SIG_SETMASK, &mask, NULL); 1516 1517#ifdef LOGIN_CAP 1518 setprocresources(RESOURCE_GETTY); 1519#endif 1520 if (sp->se_type) { 1521 /* Don't use malloc after fork */ 1522 strcpy(term, "TERM="); 1523 strlcat(term, sp->se_type, sizeof(term)); 1524 env[0] = term; 1525 env[1] = NULL; 1526 } else 1527 env[0] = NULL; 1528 execve(sp->se_getty_argv[0], sp->se_getty_argv, env); 1529 stall("can't exec getty '%s' for port %s: %m", 1530 sp->se_getty_argv[0], sp->se_device); 1531 _exit(1); 1532} 1533 1534/* 1535 * Return 1 if the session is defined as "onifexists" 1536 * or "onifconsole" and the device node does not exist. 1537 */ 1538static int 1539session_has_no_tty(session_t *sp) 1540{ 1541 int fd; 1542 1543 if ((sp->se_flags & SE_IFEXISTS) == 0 && 1544 (sp->se_flags & SE_IFCONSOLE) == 0) 1545 return (0); 1546 1547 fd = open(sp->se_device, O_RDONLY | O_NONBLOCK, 0); 1548 if (fd < 0) { 1549 if (errno == ENOENT) 1550 return (1); 1551 return (0); 1552 } 1553 1554 close(fd); 1555 return (0); 1556} 1557 1558/* 1559 * Collect exit status for a child. 1560 * If an exiting login, start a new login running. 1561 */ 1562static void 1563collect_child(pid_t pid) 1564{ 1565 session_t *sp, *sprev, *snext; 1566 1567 if (! sessions) 1568 return; 1569 1570 if (! (sp = find_session(pid))) 1571 return; 1572 1573 del_session(sp); 1574 sp->se_process = 0; 1575 1576 if (sp->se_flags & SE_SHUTDOWN || 1577 session_has_no_tty(sp)) { 1578 if ((sprev = sp->se_prev) != NULL) 1579 sprev->se_next = sp->se_next; 1580 else 1581 sessions = sp->se_next; 1582 if ((snext = sp->se_next) != NULL) 1583 snext->se_prev = sp->se_prev; 1584 free_session(sp); 1585 return; 1586 } 1587 1588 if ((pid = start_getty(sp)) == -1) { 1589 /* serious trouble */ 1590 requested_transition = clean_ttys; 1591 return; 1592 } 1593 1594 sp->se_process = pid; 1595 sp->se_started = time((time_t *) 0); 1596 add_session(sp); 1597} 1598 1599/* 1600 * Catch a signal and request a state transition. 1601 */ 1602static void 1603transition_handler(int sig) 1604{ 1605 1606 switch (sig) { 1607 case SIGHUP: 1608 if (current_state == read_ttys || current_state == multi_user || 1609 current_state == clean_ttys || current_state == catatonia) 1610 requested_transition = clean_ttys; 1611 break; 1612 case SIGUSR2: 1613 howto = RB_POWEROFF; 1614 case SIGUSR1: 1615 howto |= RB_HALT; 1616 case SIGINT: 1617 Reboot = TRUE; 1618 case SIGTERM: 1619 if (current_state == read_ttys || current_state == multi_user || 1620 current_state == clean_ttys || current_state == catatonia) 1621 requested_transition = death; 1622 else 1623 requested_transition = death_single; 1624 break; 1625 case SIGTSTP: 1626 if (current_state == runcom || current_state == read_ttys || 1627 current_state == clean_ttys || 1628 current_state == multi_user || current_state == catatonia) 1629 requested_transition = catatonia; 1630 break; 1631 case SIGEMT: 1632 requested_transition = reroot; 1633 break; 1634 default: 1635 requested_transition = 0; 1636 break; 1637 } 1638} 1639 1640/* 1641 * Take the system multiuser. 1642 */ 1643static state_func_t 1644multi_user(void) 1645{ 1646 pid_t pid; 1647 session_t *sp; 1648 1649 requested_transition = 0; 1650 1651 /* 1652 * If the administrator has not set the security level to -1 1653 * to indicate that the kernel should not run multiuser in secure 1654 * mode, and the run script has not set a higher level of security 1655 * than level 1, then put the kernel into secure mode. 1656 */ 1657 if (getsecuritylevel() == 0) 1658 setsecuritylevel(1); 1659 1660 for (sp = sessions; sp; sp = sp->se_next) { 1661 if (sp->se_process) 1662 continue; 1663 if (session_has_no_tty(sp)) 1664 continue; 1665 if ((pid = start_getty(sp)) == -1) { 1666 /* serious trouble */ 1667 requested_transition = clean_ttys; 1668 break; 1669 } 1670 sp->se_process = pid; 1671 sp->se_started = time((time_t *) 0); 1672 add_session(sp); 1673 } 1674 1675 while (!requested_transition) 1676 if ((pid = waitpid(-1, (int *) 0, 0)) != -1) 1677 collect_child(pid); 1678 1679 return (state_func_t) requested_transition; 1680} 1681 1682/* 1683 * This is an (n*2)+(n^2) algorithm. We hope it isn't run often... 1684 */ 1685static state_func_t 1686clean_ttys(void) 1687{ 1688 session_t *sp, *sprev; 1689 struct ttyent *typ; 1690 int devlen; 1691 char *old_getty, *old_window, *old_type; 1692 1693 /* 1694 * mark all sessions for death, (!SE_PRESENT) 1695 * as we find or create new ones they'll be marked as keepers, 1696 * we'll later nuke all the ones not found in /etc/ttys 1697 */ 1698 for (sp = sessions; sp != NULL; sp = sp->se_next) 1699 sp->se_flags &= ~SE_PRESENT; 1700 1701 devlen = sizeof(_PATH_DEV) - 1; 1702 while ((typ = getttyent()) != NULL) { 1703 for (sprev = 0, sp = sessions; sp; sprev = sp, sp = sp->se_next) 1704 if (strcmp(typ->ty_name, sp->se_device + devlen) == 0) 1705 break; 1706 1707 if (sp) { 1708 /* we want this one to live */ 1709 sp->se_flags |= SE_PRESENT; 1710 if ((typ->ty_status & TTY_ON) == 0 || 1711 typ->ty_getty == 0) { 1712 sp->se_flags |= SE_SHUTDOWN; 1713 kill(sp->se_process, SIGHUP); 1714 continue; 1715 } 1716 sp->se_flags &= ~SE_SHUTDOWN; 1717 old_getty = sp->se_getty ? strdup(sp->se_getty) : 0; 1718 old_window = sp->se_window ? strdup(sp->se_window) : 0; 1719 old_type = sp->se_type ? strdup(sp->se_type) : 0; 1720 if (setupargv(sp, typ) == 0) { 1721 warning("can't parse getty for port %s", 1722 sp->se_device); 1723 sp->se_flags |= SE_SHUTDOWN; 1724 kill(sp->se_process, SIGHUP); 1725 } 1726 else if ( !old_getty 1727 || (!old_type && sp->se_type) 1728 || (old_type && !sp->se_type) 1729 || (!old_window && sp->se_window) 1730 || (old_window && !sp->se_window) 1731 || (strcmp(old_getty, sp->se_getty) != 0) 1732 || (old_window && strcmp(old_window, sp->se_window) != 0) 1733 || (old_type && strcmp(old_type, sp->se_type) != 0) 1734 ) { 1735 /* Don't set SE_SHUTDOWN here */ 1736 sp->se_nspace = 0; 1737 sp->se_started = 0; 1738 kill(sp->se_process, SIGHUP); 1739 } 1740 if (old_getty) 1741 free(old_getty); 1742 if (old_window) 1743 free(old_window); 1744 if (old_type) 1745 free(old_type); 1746 continue; 1747 } 1748 1749 new_session(sprev, typ); 1750 } 1751 1752 endttyent(); 1753 1754 /* 1755 * sweep through and kill all deleted sessions 1756 * ones who's /etc/ttys line was deleted (SE_PRESENT unset) 1757 */ 1758 for (sp = sessions; sp != NULL; sp = sp->se_next) { 1759 if ((sp->se_flags & SE_PRESENT) == 0) { 1760 sp->se_flags |= SE_SHUTDOWN; 1761 kill(sp->se_process, SIGHUP); 1762 } 1763 } 1764 1765 return (state_func_t) multi_user; 1766} 1767 1768/* 1769 * Block further logins. 1770 */ 1771static state_func_t 1772catatonia(void) 1773{ 1774 session_t *sp; 1775 1776 for (sp = sessions; sp; sp = sp->se_next) 1777 sp->se_flags |= SE_SHUTDOWN; 1778 1779 return (state_func_t) multi_user; 1780} 1781 1782/* 1783 * Note SIGALRM. 1784 */ 1785static void 1786alrm_handler(int sig) 1787{ 1788 1789 (void)sig; 1790 clang = 1; 1791} 1792 1793/* 1794 * Bring the system down to single user. 1795 */ 1796static state_func_t 1797death(void) 1798{ 1799 int block, blocked; 1800 size_t len; 1801 1802 /* Temporarily block suspend. */ 1803 len = sizeof(blocked); 1804 block = 1; 1805 if (sysctlbyname("kern.suspend_blocked", &blocked, &len, 1806 &block, sizeof(block)) == -1) 1807 blocked = 0; 1808 1809 /* 1810 * Also revoke the TTY here. Because runshutdown() may reopen 1811 * the TTY whose getty we're killing here, there is no guarantee 1812 * runshutdown() will perform the initial open() call, causing 1813 * the terminal attributes to be misconfigured. 1814 */ 1815 revoke_ttys(); 1816 1817 /* Try to run the rc.shutdown script within a period of time */ 1818 runshutdown(); 1819 1820 /* Unblock suspend if we blocked it. */ 1821 if (!blocked) 1822 sysctlbyname("kern.suspend_blocked", NULL, NULL, 1823 &blocked, sizeof(blocked)); 1824 1825 return (state_func_t) death_single; 1826} 1827 1828/* 1829 * Do what is necessary to reinitialize single user mode or reboot 1830 * from an incomplete state. 1831 */ 1832static state_func_t 1833death_single(void) 1834{ 1835 int i; 1836 pid_t pid; 1837 static const int death_sigs[2] = { SIGTERM, SIGKILL }; 1838 1839 revoke(_PATH_CONSOLE); 1840 1841 for (i = 0; i < 2; ++i) { 1842 if (kill(-1, death_sigs[i]) == -1 && errno == ESRCH) 1843 return (state_func_t) single_user; 1844 1845 clang = 0; 1846 alarm(DEATH_WATCH); 1847 do 1848 if ((pid = waitpid(-1, (int *)0, 0)) != -1) 1849 collect_child(pid); 1850 while (clang == 0 && errno != ECHILD); 1851 1852 if (errno == ECHILD) 1853 return (state_func_t) single_user; 1854 } 1855 1856 warning("some processes would not die; ps axl advised"); 1857 1858 return (state_func_t) single_user; 1859} 1860 1861static void 1862revoke_ttys(void) 1863{ 1864 session_t *sp; 1865 1866 for (sp = sessions; sp; sp = sp->se_next) { 1867 sp->se_flags |= SE_SHUTDOWN; 1868 kill(sp->se_process, SIGHUP); 1869 revoke(sp->se_device); 1870 } 1871} 1872 1873/* 1874 * Run the system shutdown script. 1875 * 1876 * Exit codes: XXX I should document more 1877 * -2 shutdown script terminated abnormally 1878 * -1 fatal error - can't run script 1879 * 0 good. 1880 * >0 some error (exit code) 1881 */ 1882static int 1883runshutdown(void) 1884{ 1885 pid_t pid, wpid; 1886 int status; 1887 int shutdowntimeout; 1888 size_t len; 1889 char *argv[4]; 1890 struct stat sb; 1891 1892 /* 1893 * rc.shutdown is optional, so to prevent any unnecessary 1894 * complaints from the shell we simply don't run it if the 1895 * file does not exist. If the stat() here fails for other 1896 * reasons, we'll let the shell complain. 1897 */ 1898 if (stat(_PATH_RUNDOWN, &sb) == -1 && errno == ENOENT) 1899 return 0; 1900 1901 if ((pid = fork()) == 0) { 1902 char _sh[] = "sh"; 1903 char _reboot[] = "reboot"; 1904 char _single[] = "single"; 1905 char _path_rundown[] = _PATH_RUNDOWN; 1906 1907 argv[0] = _sh; 1908 argv[1] = _path_rundown; 1909 argv[2] = Reboot ? _reboot : _single; 1910 argv[3] = NULL; 1911 1912 execute_script(argv); 1913 _exit(1); /* force single user mode */ 1914 } 1915 1916 if (pid == -1) { 1917 emergency("can't fork for %s: %m", _PATH_RUNDOWN); 1918 while (waitpid(-1, (int *) 0, WNOHANG) > 0) 1919 continue; 1920 sleep(STALL_TIMEOUT); 1921 return -1; 1922 } 1923 1924 len = sizeof(shutdowntimeout); 1925 if (sysctlbyname("kern.init_shutdown_timeout", &shutdowntimeout, &len, 1926 NULL, 0) == -1 || shutdowntimeout < 2) 1927 shutdowntimeout = DEATH_SCRIPT; 1928 alarm(shutdowntimeout); 1929 clang = 0; 1930 /* 1931 * Copied from single_user(). This is a bit paranoid. 1932 * Use the same ALRM handler. 1933 */ 1934 do { 1935 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) 1936 collect_child(wpid); 1937 if (clang == 1) { 1938 /* we were waiting for the sub-shell */ 1939 kill(wpid, SIGTERM); 1940 warning("timeout expired for %s: %m; going to " 1941 "single user mode", _PATH_RUNDOWN); 1942 return -1; 1943 } 1944 if (wpid == -1) { 1945 if (errno == EINTR) 1946 continue; 1947 warning("wait for %s failed: %m; going to " 1948 "single user mode", _PATH_RUNDOWN); 1949 return -1; 1950 } 1951 if (wpid == pid && WIFSTOPPED(status)) { 1952 warning("init: %s stopped, restarting\n", 1953 _PATH_RUNDOWN); 1954 kill(pid, SIGCONT); 1955 wpid = -1; 1956 } 1957 } while (wpid != pid && !clang); 1958 1959 /* Turn off the alarm */ 1960 alarm(0); 1961 1962 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM && 1963 requested_transition == catatonia) { 1964 /* 1965 * /etc/rc.shutdown executed /sbin/reboot; 1966 * wait for the end quietly 1967 */ 1968 sigset_t s; 1969 1970 sigfillset(&s); 1971 for (;;) 1972 sigsuspend(&s); 1973 } 1974 1975 if (!WIFEXITED(status)) { 1976 warning("%s terminated abnormally, going to " 1977 "single user mode", _PATH_RUNDOWN); 1978 return -2; 1979 } 1980 1981 if ((status = WEXITSTATUS(status)) != 0) 1982 warning("%s returned status %d", _PATH_RUNDOWN, status); 1983 1984 return status; 1985} 1986 1987static char * 1988strk(char *p) 1989{ 1990 static char *t; 1991 char *q; 1992 int c; 1993 1994 if (p) 1995 t = p; 1996 if (!t) 1997 return 0; 1998 1999 c = *t; 2000 while (c == ' ' || c == '\t' ) 2001 c = *++t; 2002 if (!c) { 2003 t = 0; 2004 return 0; 2005 } 2006 q = t; 2007 if (c == '\'') { 2008 c = *++t; 2009 q = t; 2010 while (c && c != '\'') 2011 c = *++t; 2012 if (!c) /* unterminated string */ 2013 q = t = 0; 2014 else 2015 *t++ = 0; 2016 } else { 2017 while (c && c != ' ' && c != '\t' ) 2018 c = *++t; 2019 *t++ = 0; 2020 if (!c) 2021 t = 0; 2022 } 2023 return q; 2024} 2025 2026#ifdef LOGIN_CAP 2027static void 2028setprocresources(const char *cname) 2029{ 2030 login_cap_t *lc; 2031 if ((lc = login_getclassbyname(cname, NULL)) != NULL) { 2032 setusercontext(lc, (struct passwd*)NULL, 0, 2033 LOGIN_SETPRIORITY | LOGIN_SETRESOURCES | 2034 LOGIN_SETLOGINCLASS | LOGIN_SETCPUMASK); 2035 login_close(lc); 2036 } 2037} 2038#endif 2039