1 /* $NetBSD: init.c,v 1.109 2021/10/11 20:23:25 jmcneill Exp $ */ 2 3 /*- 4 * Copyright (c) 1991, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Donn Seeley at Berkeley Software Design, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include <sys/cdefs.h> 36 #ifndef lint 37 __COPYRIGHT("@(#) Copyright (c) 1991, 1993\ 38 The Regents of the University of California. All rights reserved."); 39 #endif /* not lint */ 40 41 #ifndef lint 42 #if 0 43 static char sccsid[] = "@(#)init.c 8.2 (Berkeley) 4/28/95"; 44 #else 45 __RCSID("$NetBSD: init.c,v 1.109 2021/10/11 20:23:25 jmcneill Exp $"); 46 #endif 47 #endif /* not lint */ 48 49 #include <sys/param.h> 50 #include <sys/sysctl.h> 51 #include <sys/wait.h> 52 #include <sys/mman.h> 53 #include <sys/stat.h> 54 #include <sys/mount.h> 55 #include <machine/cpu.h> 56 57 #include <db.h> 58 #include <errno.h> 59 #include <fcntl.h> 60 #include <signal.h> 61 #include <stdio.h> 62 #include <stdlib.h> 63 #include <string.h> 64 #include <syslog.h> 65 #include <time.h> 66 #include <ttyent.h> 67 #include <unistd.h> 68 #include <util.h> 69 #include <paths.h> 70 #include <err.h> 71 #ifdef SUPPORT_UTMP 72 #include <utmp.h> 73 #endif 74 #ifdef SUPPORT_UTMPX 75 #include <utmpx.h> 76 #endif 77 78 #include <stdarg.h> 79 80 #ifdef SECURE 81 #include <pwd.h> 82 #endif 83 84 #include "pathnames.h" 85 86 #define XSTR(x) #x 87 #define STR(x) XSTR(x) 88 89 /* 90 * Sleep times; used to prevent thrashing. 91 */ 92 #define GETTY_SPACING 5 /* N secs minimum getty spacing */ 93 #define GETTY_SLEEP 30 /* sleep N secs after spacing problem */ 94 #define GETTY_NSPACE 5 /* N retries before spacing problem */ 95 #define WINDOW_WAIT 3 /* wait N secs after starting window */ 96 #define STALL_TIMEOUT 30 /* wait N secs after warning */ 97 #define DEATH_WATCH 10 /* wait N secs for procs to die */ 98 99 static const struct timespec dtrtime = {.tv_sec = 0, .tv_nsec = 250000}; 100 101 #if defined(RESCUEDIR) 102 #define INIT_BSHELL RESCUEDIR "/sh" 103 #define INIT_MOUNT_MFS RESCUEDIR "/mount_mfs" 104 #define INIT_PATH RESCUEDIR ":" _PATH_STDPATH 105 #else 106 #define INIT_BSHELL _PATH_BSHELL 107 #define INIT_MOUNT_MFS "/sbin/mount_mfs" 108 #define INIT_PATH _PATH_STDPATH 109 #endif 110 111 static void handle(sig_t, ...); 112 static void delset(sigset_t *, ...); 113 114 static void stall(const char *, ...) __sysloglike(1, 2); 115 static void warning(const char *, ...) __sysloglike(1, 2); 116 static void emergency(const char *, ...) __sysloglike(1, 2); 117 __dead static void disaster(int); 118 static void badsys(int); 119 120 /* 121 * We really need a recursive typedef... 122 * The following at least guarantees that the return type of (*state_t)() 123 * is sufficiently wide to hold a function pointer. 124 */ 125 typedef long (*state_func_t)(void); 126 typedef state_func_t (*state_t)(void); 127 128 #define DEATH 'd' 129 #define SINGLE_USER 's' 130 #define RUNCOM 'r' 131 #define READ_TTYS 't' 132 #define MULTI_USER 'm' 133 #define CLEAN_TTYS 'T' 134 #define CATATONIA 'c' 135 136 static state_func_t single_user(void); 137 #ifndef LETS_GET_SMALL 138 static state_func_t runcom(void); 139 static state_func_t read_ttys(void); 140 static state_func_t multi_user(void); 141 static state_func_t clean_ttys(void); 142 static state_func_t catatonia(void); 143 static state_func_t death(void); 144 #endif 145 146 static enum { AUTOBOOT, FASTBOOT } runcom_mode = AUTOBOOT; 147 148 static void transition(state_t); 149 static void setctty(const char *); 150 151 typedef struct init_session { 152 int se_index; /* index of entry in ttys file */ 153 pid_t se_process; /* controlling process */ 154 struct timeval se_started; /* used to avoid thrashing */ 155 int se_nspace; /* spacing count */ 156 int se_flags; /* status of session */ 157 #define SE_SHUTDOWN 0x1 /* session won't be restarted */ 158 #define SE_PRESENT 0x2 /* session is in /etc/ttys */ 159 char *se_device; /* filename of port */ 160 char *se_getty; /* what to run on that port */ 161 char **se_getty_argv; /* pre-parsed argument array */ 162 char *se_window; /* window system (started only once) */ 163 char **se_window_argv; /* pre-parsed argument array */ 164 struct init_session *se_prev; 165 struct init_session *se_next; 166 } session_t; 167 168 static void collect_child(pid_t, int); 169 static int clang; 170 static void transition_handler(int); 171 static void alrm_handler(int); 172 static int has_securelevel(void); 173 static int securelevel_present; 174 175 #ifndef LETS_GET_SMALL 176 static int do_setttyent(void); 177 static void start_window_system(session_t *); 178 static char **construct_argv(char *); 179 static int setupargv(session_t *, struct ttyent *); 180 static pid_t start_getty(session_t *); 181 static void free_session(session_t *); 182 static session_t *new_session(session_t *, int, struct ttyent *); 183 static session_t *sessions; 184 static void setsecuritylevel(int); 185 static int getsecuritylevel(void); 186 static int start_session_db(void); 187 static void add_session(session_t *); 188 static void del_session(session_t *); 189 static session_t *find_session(pid_t); 190 static DB *session_db; 191 static state_t requested_transition = runcom; 192 193 static void clear_session_logs(session_t *, int); 194 static state_func_t runetcrc(int); 195 #ifdef SUPPORT_UTMPX 196 static struct timeval boot_time; 197 static state_t current_state = death; 198 static void session_utmpx(const session_t *, int); 199 static void make_utmpx(const char *, const char *, int, pid_t, 200 const struct timeval *, int); 201 static char get_runlevel(const state_t); 202 static void utmpx_set_runlevel(char, char); 203 #endif 204 205 #ifdef CHROOT 206 static int did_multiuser_chroot = 0; 207 static char rootdir[PATH_MAX]; 208 static int shouldchroot(void); 209 static int createsysctlnode(void); 210 #endif /* CHROOT */ 211 212 #else /* LETS_GET_SMALL */ 213 static state_t requested_transition = single_user; 214 #endif /* !LETS_GET_SMALL */ 215 216 #ifdef MFS_DEV_IF_NO_CONSOLE 217 218 static int mfs_dev(void); 219 220 #endif 221 222 /* 223 * The mother of all processes. 224 */ 225 int 226 main(int argc, char **argv) 227 { 228 struct sigaction sa; 229 sigset_t mask; 230 #ifndef LETS_GET_SMALL 231 int c; 232 233 #ifdef SUPPORT_UTMPX 234 (void)gettimeofday(&boot_time, NULL); 235 #endif /* SUPPORT_UTMPX */ 236 237 /* Dispose of random users. */ 238 if (getuid() != 0) { 239 errno = EPERM; 240 err(1, NULL); 241 } 242 243 /* System V users like to reexec init. */ 244 if (getpid() != 1) 245 errx(1, "already running"); 246 #endif 247 248 /* 249 * Create an initial session. 250 */ 251 if (setsid() < 0) 252 warn("initial setsid() failed"); 253 254 /* 255 * Establish an initial user so that programs running 256 * single user do not freak out and die (like passwd). 257 */ 258 if (setlogin("root") < 0) 259 warn("setlogin() failed"); 260 261 262 #ifdef MFS_DEV_IF_NO_CONSOLE 263 if (mfs_dev() == -1) 264 requested_transition = single_user; 265 #endif 266 267 #ifndef LETS_GET_SMALL 268 /* 269 * Note that this does NOT open a file... 270 * Does 'init' deserve its own facility number? 271 */ 272 openlog("init", LOG_CONS, LOG_AUTH); 273 #endif /* LETS_GET_SMALL */ 274 275 276 #ifndef LETS_GET_SMALL 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, "sf")) != -1) 282 switch (c) { 283 case 's': 284 requested_transition = single_user; 285 break; 286 case 'f': 287 runcom_mode = FASTBOOT; 288 break; 289 default: 290 warning("unrecognized flag `%c'", c); 291 break; 292 } 293 294 if (optind != argc) 295 warning("ignoring excess arguments"); 296 #else /* LETS_GET_SMALL */ 297 requested_transition = single_user; 298 #endif /* LETS_GET_SMALL */ 299 300 /* 301 * We catch or block signals rather than ignore them, 302 * so that they get reset on exec. 303 */ 304 handle(badsys, SIGSYS, 0); 305 handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, 306 SIGBUS, SIGXCPU, SIGXFSZ, 0); 307 handle(transition_handler, SIGHUP, SIGTERM, SIGTSTP, 0); 308 handle(alrm_handler, SIGALRM, 0); 309 (void)sigfillset(&mask); 310 delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS, 311 SIGXCPU, SIGXFSZ, SIGHUP, SIGTERM, SIGTSTP, SIGALRM, 0); 312 (void)sigprocmask(SIG_SETMASK, &mask, NULL); 313 (void)sigemptyset(&sa.sa_mask); 314 sa.sa_flags = 0; 315 sa.sa_handler = SIG_IGN; 316 (void)sigaction(SIGTTIN, &sa, NULL); 317 (void)sigaction(SIGTTOU, &sa, NULL); 318 319 /* 320 * Paranoia. 321 */ 322 (void)close(0); 323 (void)close(1); 324 (void)close(2); 325 326 #if !defined(LETS_GET_SMALL) && defined(CHROOT) 327 /* Create "init.root" sysctl node. */ 328 (void)createsysctlnode(); 329 #endif /* !LETS_GET_SMALL && CHROOT*/ 330 331 /* 332 * Securelevel might not be supported by the kernel. Query for it, and 333 * set a variable indicating whether we should attempt anything with it 334 * or not. 335 */ 336 securelevel_present = has_securelevel(); 337 338 /* 339 * Start the state machine. 340 */ 341 transition(requested_transition); 342 343 /* 344 * Should never reach here. 345 */ 346 return 1; 347 } 348 349 /* 350 * Associate a function with a signal handler. 351 */ 352 static void 353 handle(sig_t handler, ...) 354 { 355 int sig; 356 struct sigaction sa; 357 sigset_t mask_everything; 358 va_list ap; 359 360 va_start(ap, handler); 361 362 sa.sa_handler = handler; 363 (void)sigfillset(&mask_everything); 364 365 while ((sig = va_arg(ap, int)) != 0) { 366 sa.sa_mask = mask_everything; 367 /* XXX SA_RESTART? */ 368 sa.sa_flags = sig == SIGCHLD ? SA_NOCLDSTOP : 0; 369 (void)sigaction(sig, &sa, NULL); 370 } 371 va_end(ap); 372 } 373 374 /* 375 * Delete a set of signals from a mask. 376 */ 377 static void 378 delset(sigset_t *maskp, ...) 379 { 380 int sig; 381 va_list ap; 382 383 va_start(ap, maskp); 384 385 while ((sig = va_arg(ap, int)) != 0) 386 (void)sigdelset(maskp, sig); 387 va_end(ap); 388 } 389 390 #if 0 /* Enable to get error messages from init ! */ 391 #define vsyslog(level, fmt, ap) print_console(level, fmt, ap) 392 #define closelog() 393 394 static void 395 print_console(int level, const char *message, va_list ap) 396 { 397 /* 398 * XXX: syslog seems to just plain not work in console-only 399 * XXX: situation... that should be fixed. Let's leave this 400 * XXX: note + code here in case someone gets in trouble and 401 * XXX: wants to debug. -- Jachym Holecek <freza@liberouter.org> 402 */ 403 char errbuf[1024]; 404 int fd, len; 405 406 /* We can't do anything on errors, anyway... */ 407 fd = open(_PATH_CONSOLE, O_WRONLY); 408 if (fd == -1) 409 return ; 410 411 /* %m will get lost... */ 412 len = vsnprintf(errbuf, sizeof(errbuf), message, ap); 413 (void)write(fd, (void *)errbuf, len); 414 (void)close(fd); 415 } 416 #endif 417 418 /* 419 * Log a message and sleep for a while (to give someone an opportunity 420 * to read it and to save log or hardcopy output if the problem is chronic). 421 * NB: should send a message to the session logger to avoid blocking. 422 */ 423 static void 424 stall(const char *message, ...) 425 { 426 va_list ap; 427 428 va_start(ap, message); 429 vsyslog(LOG_ALERT, message, ap); 430 va_end(ap); 431 closelog(); 432 (void)sleep(STALL_TIMEOUT); 433 } 434 435 /* 436 * Like stall(), but doesn't sleep. 437 * If cpp had variadic macros, the two functions could be #defines for another. 438 * NB: should send a message to the session logger to avoid blocking. 439 */ 440 static void 441 warning(const char *message, ...) 442 { 443 va_list ap; 444 445 va_start(ap, message); 446 vsyslog(LOG_ALERT, message, ap); 447 va_end(ap); 448 closelog(); 449 } 450 451 /* 452 * Log an emergency message. 453 * NB: should send a message to the session logger to avoid blocking. 454 */ 455 static void 456 emergency(const char *message, ...) 457 { 458 va_list ap; 459 460 va_start(ap, message); 461 vsyslog(LOG_EMERG, message, ap); 462 va_end(ap); 463 closelog(); 464 } 465 466 /* 467 * Catch a SIGSYS signal. 468 * 469 * These may arise if a system does not support sysctl. 470 * We tolerate up to 25 of these, then throw in the towel. 471 */ 472 static void 473 badsys(int sig) 474 { 475 static int badcount = 0; 476 477 if (badcount++ < 25) 478 return; 479 disaster(sig); 480 } 481 482 /* 483 * Catch an unexpected signal. 484 */ 485 static void 486 disaster(int sig) 487 { 488 489 emergency("fatal signal: %s", strsignal(sig)); 490 (void)sleep(STALL_TIMEOUT); 491 _exit(sig); /* reboot */ 492 } 493 494 /* 495 * Check if securelevel is present. 496 */ 497 static int 498 has_securelevel(void) 499 { 500 #ifdef KERN_SECURELVL 501 int name[2], curlevel; 502 size_t len; 503 504 name[0] = CTL_KERN; 505 name[1] = KERN_SECURELVL; 506 len = sizeof curlevel; 507 if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) { 508 /* If it doesn't exist, it's okay. */ 509 if (errno == ENOENT) 510 return 0; 511 } 512 return 1; 513 #else 514 return 0; 515 #endif 516 } 517 518 /* 519 * Get the security level of the kernel. 520 */ 521 static int 522 getsecuritylevel(void) 523 { 524 #ifdef KERN_SECURELVL 525 int name[2], curlevel; 526 size_t len; 527 528 if (!securelevel_present) 529 return -1; 530 531 name[0] = CTL_KERN; 532 name[1] = KERN_SECURELVL; 533 len = sizeof curlevel; 534 if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) { 535 emergency("cannot get kernel security level: %m"); 536 return -1; 537 } 538 return curlevel; 539 #else 540 return -1; 541 #endif 542 } 543 544 /* 545 * Set the security level of the kernel. 546 */ 547 static void 548 setsecuritylevel(int newlevel) 549 { 550 #ifdef KERN_SECURELVL 551 int name[2], curlevel; 552 553 if (!securelevel_present) 554 return; 555 556 curlevel = getsecuritylevel(); 557 if (newlevel == curlevel) 558 return; 559 name[0] = CTL_KERN; 560 name[1] = KERN_SECURELVL; 561 if (sysctl(name, 2, NULL, NULL, &newlevel, sizeof newlevel) == -1) { 562 emergency("cannot change kernel security level from" 563 " %d to %d: %m", curlevel, newlevel); 564 return; 565 } 566 #ifdef SECURE 567 warning("kernel security level changed from %d to %d", 568 curlevel, newlevel); 569 #endif 570 #endif 571 } 572 573 /* 574 * Change states in the finite state machine. 575 * The initial state is passed as an argument. 576 */ 577 static void 578 transition(state_t s) 579 { 580 581 if (s == NULL) 582 return; 583 for (;;) { 584 #ifdef SUPPORT_UTMPX 585 #ifndef LETS_GET_SMALL 586 utmpx_set_runlevel(get_runlevel(current_state), 587 get_runlevel(s)); 588 current_state = s; 589 #endif 590 #endif 591 s = (state_t)(*s)(); 592 } 593 } 594 595 #ifndef LETS_GET_SMALL 596 /* 597 * Close out the accounting files for a login session. 598 * NB: should send a message to the session logger to avoid blocking. 599 */ 600 static void 601 clear_session_logs(session_t *sp, int status) 602 { 603 #if defined(SUPPORT_UTMP) || defined(SUPPORT_UTMPX) 604 char *line = sp->se_device + sizeof(_PATH_DEV) - 1; 605 #endif 606 607 #ifdef SUPPORT_UTMPX 608 if (logoutx(line, status, DEAD_PROCESS)) 609 logwtmpx(line, "", "", status, DEAD_PROCESS); 610 #endif 611 #ifdef SUPPORT_UTMP 612 if (logout(line)) 613 logwtmp(line, "", ""); 614 #endif 615 } 616 #endif 617 618 /* 619 * Start a session and allocate a controlling terminal. 620 * Only called by children of init after forking. 621 */ 622 static void 623 setctty(const char *name) 624 { 625 int fd; 626 627 (void)revoke(name); 628 (void)nanosleep(&dtrtime, NULL); /* leave DTR low for a bit */ 629 if ((fd = open(name, O_RDWR)) == -1) { 630 stall("can't open %s: %m", name); 631 _exit(1); 632 } 633 if (login_tty(fd) == -1) { 634 stall("can't get %s for controlling terminal: %m", name); 635 _exit(2); 636 } 637 } 638 639 /* 640 * Bring the system up single user. 641 */ 642 static state_func_t 643 single_user(void) 644 { 645 pid_t pid, wpid; 646 int status; 647 int from_securitylevel; 648 sigset_t mask; 649 struct sigaction sa, satstp, sahup; 650 #ifdef ALTSHELL 651 const char *shell = INIT_BSHELL; 652 #endif 653 const char *argv[2]; 654 #ifdef SECURE 655 struct ttyent *typ; 656 struct passwd *pp; 657 char *clear, *password; 658 #endif 659 #ifdef ALTSHELL 660 char altshell[128]; 661 #endif /* ALTSHELL */ 662 663 #if !defined(LETS_GET_SMALL) && defined(CHROOT) 664 /* Clear previous idea, just in case. */ 665 did_multiuser_chroot = 0; 666 #endif /* !LETS_GET_SMALL && CHROOT */ 667 668 /* 669 * If the kernel is in secure mode, downgrade it to insecure mode. 670 */ 671 from_securitylevel = getsecuritylevel(); 672 if (from_securitylevel > 0) 673 setsecuritylevel(0); 674 675 (void)sigemptyset(&sa.sa_mask); 676 sa.sa_flags = 0; 677 sa.sa_handler = SIG_IGN; 678 (void)sigaction(SIGTSTP, &sa, &satstp); 679 (void)sigaction(SIGHUP, &sa, &sahup); 680 if ((pid = fork()) == 0) { 681 /* 682 * Start the single user session. 683 */ 684 if (access(_PATH_CONSTTY, F_OK) == 0) 685 setctty(_PATH_CONSTTY); 686 else 687 setctty(_PATH_CONSOLE); 688 689 #ifdef SECURE 690 /* 691 * Check the root password. 692 * We don't care if the console is 'on' by default; 693 * it's the only tty that can be 'off' and 'secure'. 694 */ 695 typ = getttynam("console"); 696 pp = getpwnam("root"); 697 if (typ && (from_securitylevel >=2 || (typ->ty_status 698 & TTY_SECURE) == 0) && pp && *pp->pw_passwd != '\0') { 699 (void)fprintf(stderr, 700 "Enter root password, or ^D to go multi-user\n"); 701 for (;;) { 702 clear = getpass("Password:"); 703 if (clear == 0 || *clear == '\0') 704 _exit(0); 705 password = crypt(clear, pp->pw_passwd); 706 (void)memset(clear, 0, _PASSWORD_LEN); 707 if (strcmp(password, pp->pw_passwd) == 0) 708 break; 709 warning("single-user login failed"); 710 } 711 } 712 (void)endttyent(); 713 endpwent(); 714 #endif /* SECURE */ 715 716 #ifdef ALTSHELL 717 (void)fprintf(stderr, 718 "Enter pathname of shell or RETURN for %s: ", shell); 719 if (fgets(altshell, sizeof(altshell), stdin) == NULL) { 720 altshell[0] = '\0'; 721 } else { 722 /* nuke \n */ 723 char *p; 724 725 if ((p = strchr(altshell, '\n')) != NULL) 726 *p = '\0'; 727 } 728 729 if (altshell[0]) 730 shell = altshell; 731 #endif /* ALTSHELL */ 732 733 /* 734 * Unblock signals. 735 * We catch all the interesting ones, 736 * and those are reset to SIG_DFL on exec. 737 */ 738 (void)sigemptyset(&mask); 739 (void)sigprocmask(SIG_SETMASK, &mask, NULL); 740 741 /* 742 * Fire off a shell. 743 * If the default one doesn't work, try the Bourne shell. 744 */ 745 argv[0] = "-sh"; 746 argv[1] = 0; 747 (void)setenv("PATH", INIT_PATH, 1); 748 #ifdef ALTSHELL 749 if (altshell[0]) 750 argv[0] = altshell; 751 (void)execv(shell, __UNCONST(argv)); 752 emergency("can't exec `%s' for single user: %m", shell); 753 argv[0] = "-sh"; 754 #endif /* ALTSHELL */ 755 (void)execv(INIT_BSHELL, __UNCONST(argv)); 756 emergency("can't exec `%s' for single user: %m", INIT_BSHELL); 757 (void)sleep(STALL_TIMEOUT); 758 _exit(3); 759 } 760 761 if (pid == -1) { 762 /* 763 * We are seriously hosed. Do our best. 764 */ 765 emergency("can't fork single-user shell: %m, trying again"); 766 while (waitpid(-1, NULL, WNOHANG) > 0) 767 continue; 768 (void)sigaction(SIGTSTP, &satstp, NULL); 769 (void)sigaction(SIGHUP, &sahup, NULL); 770 return (state_func_t)single_user; 771 } 772 773 requested_transition = 0; 774 do { 775 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) 776 collect_child(wpid, status); 777 if (wpid == -1) { 778 if (errno == EINTR) 779 continue; 780 warning("wait for single-user shell failed: %m; " 781 "restarting"); 782 return (state_func_t)single_user; 783 } 784 if (wpid == pid && WIFSTOPPED(status)) { 785 warning("shell stopped, restarting"); 786 (void)kill(pid, SIGCONT); 787 wpid = -1; 788 } 789 } while (wpid != pid && !requested_transition); 790 791 if (requested_transition) { 792 (void)sigaction(SIGTSTP, &satstp, NULL); 793 (void)sigaction(SIGHUP, &sahup, NULL); 794 return (state_func_t)requested_transition; 795 } 796 797 if (WIFSIGNALED(status)) { 798 if (WTERMSIG(status) == SIGKILL) { 799 /* executed /sbin/reboot; wait for the end quietly */ 800 sigset_t s; 801 802 (void)sigfillset(&s); 803 for (;;) 804 (void)sigsuspend(&s); 805 } else { 806 warning("single user shell terminated (%x), restarting", 807 status); 808 (void)sigaction(SIGTSTP, &satstp, NULL); 809 (void)sigaction(SIGHUP, &sahup, NULL); 810 return (state_func_t)single_user; 811 } 812 } 813 814 runcom_mode = FASTBOOT; 815 (void)sigaction(SIGTSTP, &satstp, NULL); 816 (void)sigaction(SIGHUP, &sahup, NULL); 817 #ifndef LETS_GET_SMALL 818 return (state_func_t)runcom; 819 #else /* LETS_GET_SMALL */ 820 return (state_func_t)single_user; 821 #endif /* LETS_GET_SMALL */ 822 } 823 824 #ifndef LETS_GET_SMALL 825 826 /* ARGSUSED */ 827 static state_func_t 828 runetcrc(int trychroot) 829 { 830 pid_t pid, wpid; 831 int status; 832 const char *argv[4]; 833 struct sigaction sa; 834 835 switch ((pid = fork())) { 836 case 0: 837 (void)sigemptyset(&sa.sa_mask); 838 sa.sa_flags = 0; 839 sa.sa_handler = SIG_IGN; 840 (void)sigaction(SIGTSTP, &sa, NULL); 841 (void)sigaction(SIGHUP, &sa, NULL); 842 843 setctty(_PATH_CONSOLE); 844 845 argv[0] = "sh"; 846 argv[1] = _PATH_RUNCOM; 847 argv[2] = (runcom_mode == AUTOBOOT ? "autoboot" : 0); 848 argv[3] = 0; 849 850 (void)sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL); 851 852 #ifdef CHROOT 853 if (trychroot) 854 if (chroot(rootdir) != 0) { 855 warning("failed to chroot to `%s': %m", 856 rootdir); 857 _exit(4); /* force single user mode */ 858 } 859 #endif /* CHROOT */ 860 861 (void)execv(INIT_BSHELL, __UNCONST(argv)); 862 stall("can't exec `%s' for `%s': %m", INIT_BSHELL, _PATH_RUNCOM); 863 _exit(5); /* force single user mode */ 864 /*NOTREACHED*/ 865 case -1: 866 emergency("can't fork for `%s' on `%s': %m", INIT_BSHELL, 867 _PATH_RUNCOM); 868 while (waitpid(-1, NULL, WNOHANG) > 0) 869 continue; 870 (void)sleep(STALL_TIMEOUT); 871 return (state_func_t)single_user; 872 default: 873 break; 874 } 875 876 /* 877 * Copied from single_user(). This is a bit paranoid. 878 */ 879 do { 880 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) 881 collect_child(wpid, status); 882 if (wpid == -1) { 883 if (errno == EINTR) 884 continue; 885 warning("wait for `%s' on `%s' failed: %m; going to " 886 "single user mode", INIT_BSHELL, _PATH_RUNCOM); 887 return (state_func_t)single_user; 888 } 889 if (wpid == pid && WIFSTOPPED(status)) { 890 warning("`%s' on `%s' stopped, restarting", 891 INIT_BSHELL, _PATH_RUNCOM); 892 (void)kill(pid, SIGCONT); 893 wpid = -1; 894 } 895 } while (wpid != pid); 896 897 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM && 898 requested_transition == catatonia) { 899 /* /etc/rc executed /sbin/reboot; wait for the end quietly */ 900 sigset_t s; 901 902 (void)sigfillset(&s); 903 for (;;) 904 (void)sigsuspend(&s); 905 } 906 907 if (!WIFEXITED(status)) { 908 warning("`%s' on `%s' terminated abnormally, going to " 909 "single user mode", INIT_BSHELL, _PATH_RUNCOM); 910 return (state_func_t)single_user; 911 } 912 913 if (WEXITSTATUS(status)) 914 return (state_func_t)single_user; 915 916 return (state_func_t)read_ttys; 917 } 918 919 /* 920 * Run the system startup script. 921 */ 922 static state_func_t 923 runcom(void) 924 { 925 state_func_t next_step; 926 927 /* Run /etc/rc and choose next state depending on the result. */ 928 next_step = runetcrc(0); 929 if (next_step != (state_func_t)read_ttys) 930 return (state_func_t)next_step; 931 932 #ifdef CHROOT 933 /* 934 * If init.root sysctl does not point to "/", we'll chroot and run 935 * The Real(tm) /etc/rc now. Global variable rootdir will tell us 936 * where to go. 937 */ 938 if (shouldchroot()) { 939 next_step = runetcrc(1); 940 if (next_step != (state_func_t)read_ttys) 941 return (state_func_t)next_step; 942 943 did_multiuser_chroot = 1; 944 } else { 945 did_multiuser_chroot = 0; 946 } 947 #endif /* CHROOT */ 948 949 /* 950 * Regardless of whether in chroot or not, we booted successfully. 951 * It's time to spawn gettys (ie. next_step's value at this point). 952 */ 953 runcom_mode = AUTOBOOT; /* the default */ 954 /* NB: should send a message to the session logger to avoid blocking. */ 955 #ifdef SUPPORT_UTMPX 956 logwtmpx("~", "reboot", "", 0, INIT_PROCESS); 957 #endif 958 #ifdef SUPPORT_UTMP 959 logwtmp("~", "reboot", ""); 960 #endif 961 return (state_func_t)read_ttys; 962 } 963 964 /* 965 * Open the session database. 966 * 967 * NB: We could pass in the size here; is it necessary? 968 */ 969 static int 970 start_session_db(void) 971 { 972 973 if (session_db && (*session_db->close)(session_db)) 974 emergency("session database close: %m"); 975 if ((session_db = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL)) == 0) { 976 emergency("session database open: %m"); 977 return 1; 978 } 979 return 0; 980 981 } 982 983 /* 984 * Add a new login session. 985 */ 986 static void 987 add_session(session_t *sp) 988 { 989 DBT key; 990 DBT data; 991 992 if (session_db == NULL) 993 return; 994 995 key.data = &sp->se_process; 996 key.size = sizeof sp->se_process; 997 data.data = &sp; 998 data.size = sizeof sp; 999 1000 if ((*session_db->put)(session_db, &key, &data, 0)) 1001 emergency("insert %d: %m", sp->se_process); 1002 #ifdef SUPPORT_UTMPX 1003 session_utmpx(sp, 1); 1004 #endif 1005 } 1006 1007 /* 1008 * Delete an old login session. 1009 */ 1010 static void 1011 del_session(session_t *sp) 1012 { 1013 DBT key; 1014 1015 key.data = &sp->se_process; 1016 key.size = sizeof sp->se_process; 1017 1018 if ((*session_db->del)(session_db, &key, 0)) 1019 emergency("delete %d: %m", sp->se_process); 1020 #ifdef SUPPORT_UTMPX 1021 session_utmpx(sp, 0); 1022 #endif 1023 } 1024 1025 /* 1026 * Look up a login session by pid. 1027 */ 1028 static session_t * 1029 find_session(pid_t pid) 1030 { 1031 DBT key; 1032 DBT data; 1033 session_t *ret; 1034 1035 if (session_db == NULL) 1036 return NULL; 1037 1038 key.data = &pid; 1039 key.size = sizeof pid; 1040 if ((*session_db->get)(session_db, &key, &data, 0) != 0) 1041 return 0; 1042 (void)memmove(&ret, data.data, sizeof(ret)); 1043 return ret; 1044 } 1045 1046 /* 1047 * Construct an argument vector from a command line. 1048 */ 1049 static char ** 1050 construct_argv(char *command) 1051 { 1052 int argc = 0; 1053 char **argv = malloc(((strlen(command) + 1) / 2 + 1) * sizeof (char *)); 1054 static const char separators[] = " \t"; 1055 1056 if (argv == NULL) 1057 return NULL; 1058 1059 if ((argv[argc++] = strtok(command, separators)) == 0) { 1060 free(argv); 1061 return NULL; 1062 } 1063 while ((argv[argc++] = strtok(NULL, separators)) != NULL) 1064 continue; 1065 return argv; 1066 } 1067 1068 /* 1069 * Deallocate a session descriptor. 1070 */ 1071 static void 1072 free_session(session_t *sp) 1073 { 1074 1075 free(sp->se_device); 1076 if (sp->se_getty) { 1077 free(sp->se_getty); 1078 free(sp->se_getty_argv); 1079 } 1080 if (sp->se_window) { 1081 free(sp->se_window); 1082 free(sp->se_window_argv); 1083 } 1084 free(sp); 1085 } 1086 1087 /* 1088 * Allocate a new session descriptor. 1089 */ 1090 static session_t * 1091 new_session(session_t *sprev, int session_index, struct ttyent *typ) 1092 { 1093 session_t *sp; 1094 1095 if ((typ->ty_status & TTY_ON) == 0 || typ->ty_name == NULL || 1096 typ->ty_getty == NULL) 1097 return NULL; 1098 1099 sp = malloc(sizeof (session_t)); 1100 if (sp == NULL) 1101 return NULL; 1102 (void)memset(sp, 0, sizeof *sp); 1103 1104 sp->se_flags = SE_PRESENT; 1105 sp->se_index = session_index; 1106 1107 (void)asprintf(&sp->se_device, "%s%s", _PATH_DEV, typ->ty_name); 1108 if (!sp->se_device) { 1109 free(sp); 1110 return NULL; 1111 } 1112 1113 if (setupargv(sp, typ) == 0) { 1114 free_session(sp); 1115 return NULL; 1116 } 1117 1118 sp->se_next = NULL; 1119 if (sprev == NULL) { 1120 sessions = sp; 1121 sp->se_prev = NULL; 1122 } else { 1123 sprev->se_next = sp; 1124 sp->se_prev = sprev; 1125 } 1126 1127 return sp; 1128 } 1129 1130 /* 1131 * Calculate getty and if useful window argv vectors. 1132 */ 1133 static int 1134 setupargv(session_t *sp, struct ttyent *typ) 1135 { 1136 1137 if (sp->se_getty) { 1138 free(sp->se_getty); 1139 free(sp->se_getty_argv); 1140 } 1141 (void)asprintf(&sp->se_getty, "%s %s", typ->ty_getty, typ->ty_name); 1142 if (!sp->se_getty) 1143 return 0; 1144 sp->se_getty_argv = construct_argv(sp->se_getty); 1145 if (sp->se_getty_argv == NULL) { 1146 warning("can't parse getty for port `%s'", sp->se_device); 1147 free(sp->se_getty); 1148 sp->se_getty = NULL; 1149 return 0; 1150 } 1151 if (typ->ty_window) { 1152 if (sp->se_window) 1153 free(sp->se_window); 1154 sp->se_window = strdup(typ->ty_window); 1155 sp->se_window_argv = construct_argv(sp->se_window); 1156 if (sp->se_window_argv == NULL) { 1157 warning("can't parse window for port `%s'", 1158 sp->se_device); 1159 free(sp->se_window); 1160 sp->se_window = NULL; 1161 return 0; 1162 } 1163 } 1164 return 1; 1165 } 1166 1167 /* 1168 * Walk the list of ttys and create sessions for each active line. 1169 */ 1170 static state_func_t 1171 read_ttys(void) 1172 { 1173 int session_index = 0; 1174 session_t *sp, *snext; 1175 struct ttyent *typ; 1176 1177 #ifdef SUPPORT_UTMPX 1178 if (sessions == NULL) { 1179 struct stat st; 1180 1181 make_utmpx("", BOOT_MSG, BOOT_TIME, 0, &boot_time, 0); 1182 1183 /* 1184 * If wtmpx is not empty, pick the down time from there 1185 */ 1186 if (stat(_PATH_WTMPX, &st) != -1 && st.st_size != 0) { 1187 struct timeval down_time; 1188 1189 TIMESPEC_TO_TIMEVAL(&down_time, 1190 st.st_atime > st.st_mtime ? 1191 &st.st_atimespec : &st.st_mtimespec); 1192 make_utmpx("", DOWN_MSG, DOWN_TIME, 0, &down_time, 0); 1193 } 1194 } 1195 #endif 1196 /* 1197 * Destroy any previous session state. 1198 * There shouldn't be any, but just in case... 1199 */ 1200 for (sp = sessions; sp; sp = snext) { 1201 #ifndef LETS_GET_SMALL 1202 if (sp->se_process) 1203 clear_session_logs(sp, 0); 1204 #endif 1205 snext = sp->se_next; 1206 free_session(sp); 1207 } 1208 sessions = NULL; 1209 1210 if (start_session_db()) { 1211 warning("start_session_db failed, death"); 1212 #ifdef CHROOT 1213 /* If /etc/rc ran in chroot, we want to kill any survivors. */ 1214 if (did_multiuser_chroot) 1215 return (state_func_t)death; 1216 else 1217 #endif /* CHROOT */ 1218 return (state_func_t)single_user; 1219 } 1220 1221 (void)do_setttyent(); 1222 1223 /* 1224 * Allocate a session entry for each active port. 1225 * Note that sp starts at 0. 1226 */ 1227 while ((typ = getttyent()) != NULL) 1228 if ((snext = new_session(sp, ++session_index, typ)) != NULL) 1229 sp = snext; 1230 (void)endttyent(); 1231 1232 return (state_func_t)multi_user; 1233 } 1234 1235 /* 1236 * Start a window system running. 1237 */ 1238 static void 1239 start_window_system(session_t *sp) 1240 { 1241 pid_t pid; 1242 sigset_t mask; 1243 1244 if ((pid = fork()) == -1) { 1245 emergency("can't fork for window system on port `%s': %m", 1246 sp->se_device); 1247 /* hope that getty fails and we can try again */ 1248 return; 1249 } 1250 1251 if (pid) 1252 return; 1253 1254 (void)sigemptyset(&mask); 1255 (void)sigprocmask(SIG_SETMASK, &mask, NULL); 1256 1257 if (setsid() < 0) 1258 emergency("setsid failed (window): %m"); 1259 1260 (void)execv(sp->se_window_argv[0], sp->se_window_argv); 1261 stall("can't exec window system `%s' for port `%s': %m", 1262 sp->se_window_argv[0], sp->se_device); 1263 _exit(6); 1264 } 1265 1266 /* 1267 * Start a login session running. 1268 */ 1269 static pid_t 1270 start_getty(session_t *sp) 1271 { 1272 pid_t pid; 1273 sigset_t mask; 1274 time_t current_time = time(NULL); 1275 bool do_sleep = false; 1276 1277 if (current_time >= sp->se_started.tv_sec && 1278 current_time - sp->se_started.tv_sec < GETTY_SPACING) { 1279 if (++sp->se_nspace > GETTY_NSPACE) { 1280 sp->se_nspace = 0; 1281 do_sleep = true; 1282 } 1283 } else { 1284 sp->se_nspace = 0; 1285 } 1286 1287 /* 1288 * fork(), not vfork() -- we can't afford to block. 1289 */ 1290 if ((pid = fork()) == -1) { 1291 emergency("can't fork for getty on port `%s': %m", 1292 sp->se_device); 1293 return -1; 1294 } 1295 1296 if (pid) 1297 return pid; 1298 1299 #ifdef CHROOT 1300 /* If /etc/rc did proceed inside chroot, we have to try as well. */ 1301 if (did_multiuser_chroot) 1302 if (chroot(rootdir) != 0) { 1303 stall("can't chroot getty `%s' inside `%s': %m", 1304 sp->se_getty_argv[0], rootdir); 1305 _exit(7); 1306 } 1307 #endif /* CHROOT */ 1308 1309 if (do_sleep) { 1310 warning("getty repeating too quickly on port `%s', sleeping", 1311 sp->se_device); 1312 (void)sleep(GETTY_SLEEP); 1313 } 1314 1315 if (sp->se_window) { 1316 start_window_system(sp); 1317 (void)sleep(WINDOW_WAIT); 1318 } 1319 1320 (void)sigemptyset(&mask); 1321 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); 1322 1323 (void)execv(sp->se_getty_argv[0], sp->se_getty_argv); 1324 stall("can't exec getty `%s' for port `%s': %m", 1325 sp->se_getty_argv[0], sp->se_device); 1326 _exit(8); 1327 /*NOTREACHED*/ 1328 } 1329 #ifdef SUPPORT_UTMPX 1330 static void 1331 session_utmpx(const session_t *sp, int add) 1332 { 1333 const char *name = sp->se_getty ? sp->se_getty : 1334 (sp->se_window ? sp->se_window : ""); 1335 const char *line = sp->se_device + sizeof(_PATH_DEV) - 1; 1336 1337 make_utmpx(name, line, add ? LOGIN_PROCESS : DEAD_PROCESS, 1338 sp->se_process, &sp->se_started, sp->se_index); 1339 } 1340 1341 static void 1342 make_utmpx(const char *name, const char *line, int type, pid_t pid, 1343 const struct timeval *tv, int session) 1344 { 1345 struct utmpx ut; 1346 const char *eline; 1347 1348 (void)memset(&ut, 0, sizeof(ut)); 1349 (void)strlcpy(ut.ut_name, name, sizeof(ut.ut_name)); 1350 ut.ut_type = type; 1351 (void)strlcpy(ut.ut_line, line, sizeof(ut.ut_line)); 1352 ut.ut_pid = pid; 1353 if (tv) 1354 ut.ut_tv = *tv; 1355 else 1356 (void)gettimeofday(&ut.ut_tv, NULL); 1357 ut.ut_session = session; 1358 1359 eline = line + strlen(line); 1360 if ((size_t)(eline - line) >= sizeof(ut.ut_id)) 1361 line = eline - sizeof(ut.ut_id); 1362 (void)strncpy(ut.ut_id, line, sizeof(ut.ut_id)); 1363 1364 if (pututxline(&ut) == NULL) 1365 warning("can't add utmpx record for `%s': %m", ut.ut_line); 1366 endutxent(); 1367 } 1368 1369 static char 1370 get_runlevel(const state_t s) 1371 { 1372 if (s == (state_t)single_user) 1373 return SINGLE_USER; 1374 if (s == (state_t)runcom) 1375 return RUNCOM; 1376 if (s == (state_t)read_ttys) 1377 return READ_TTYS; 1378 if (s == (state_t)multi_user) 1379 return MULTI_USER; 1380 if (s == (state_t)clean_ttys) 1381 return CLEAN_TTYS; 1382 if (s == (state_t)catatonia) 1383 return CATATONIA; 1384 return DEATH; 1385 } 1386 1387 static void 1388 utmpx_set_runlevel(char old, char new) 1389 { 1390 struct utmpx ut; 1391 1392 /* 1393 * Don't record any transitions until we did the first transition 1394 * to read ttys, which is when we are guaranteed to have a read-write 1395 * /var. Perhaps use a different variable for this? 1396 */ 1397 if (sessions == NULL) 1398 return; 1399 1400 (void)memset(&ut, 0, sizeof(ut)); 1401 (void)snprintf(ut.ut_line, sizeof(ut.ut_line), RUNLVL_MSG, new); 1402 ut.ut_type = RUN_LVL; 1403 (void)gettimeofday(&ut.ut_tv, NULL); 1404 ut.ut_exit.e_exit = old; 1405 ut.ut_exit.e_termination = new; 1406 if (pututxline(&ut) == NULL) 1407 warning("can't add utmpx record for `runlevel': %m"); 1408 endutxent(); 1409 } 1410 #endif /* SUPPORT_UTMPX */ 1411 1412 #endif /* LETS_GET_SMALL */ 1413 1414 /* 1415 * Collect exit status for a child. 1416 * If an exiting login, start a new login running. 1417 */ 1418 static void 1419 collect_child(pid_t pid, int status) 1420 { 1421 #ifndef LETS_GET_SMALL 1422 session_t *sp, *sprev, *snext; 1423 1424 if (! sessions) 1425 return; 1426 1427 if ((sp = find_session(pid)) == NULL) 1428 return; 1429 1430 clear_session_logs(sp, status); 1431 del_session(sp); 1432 sp->se_process = 0; 1433 1434 if (sp->se_flags & SE_SHUTDOWN) { 1435 if ((sprev = sp->se_prev) != NULL) 1436 sprev->se_next = sp->se_next; 1437 else 1438 sessions = sp->se_next; 1439 if ((snext = sp->se_next) != NULL) 1440 snext->se_prev = sp->se_prev; 1441 free_session(sp); 1442 return; 1443 } 1444 1445 if ((pid = start_getty(sp)) == -1) { 1446 /* serious trouble */ 1447 requested_transition = clean_ttys; 1448 return; 1449 } 1450 1451 sp->se_process = pid; 1452 (void)gettimeofday(&sp->se_started, NULL); 1453 add_session(sp); 1454 #endif /* LETS_GET_SMALL */ 1455 } 1456 1457 /* 1458 * Catch a signal and request a state transition. 1459 */ 1460 static void 1461 transition_handler(int sig) 1462 { 1463 1464 switch (sig) { 1465 #ifndef LETS_GET_SMALL 1466 case SIGHUP: 1467 requested_transition = clean_ttys; 1468 break; 1469 case SIGTERM: 1470 requested_transition = death; 1471 break; 1472 case SIGTSTP: 1473 requested_transition = catatonia; 1474 break; 1475 #endif /* LETS_GET_SMALL */ 1476 default: 1477 requested_transition = 0; 1478 break; 1479 } 1480 } 1481 1482 #ifndef LETS_GET_SMALL 1483 /* 1484 * Take the system multiuser. 1485 */ 1486 static state_func_t 1487 multi_user(void) 1488 { 1489 pid_t pid; 1490 int status; 1491 session_t *sp; 1492 1493 requested_transition = 0; 1494 1495 /* 1496 * If the administrator has not set the security level to -1 1497 * to indicate that the kernel should not run multiuser in secure 1498 * mode, and the run script has not set a higher level of security 1499 * than level 1, then put the kernel into secure mode. 1500 */ 1501 if (getsecuritylevel() == 0) 1502 setsecuritylevel(1); 1503 1504 for (sp = sessions; sp; sp = sp->se_next) { 1505 if (sp->se_process) 1506 continue; 1507 if ((pid = start_getty(sp)) == -1) { 1508 /* serious trouble */ 1509 requested_transition = clean_ttys; 1510 break; 1511 } 1512 sp->se_process = pid; 1513 (void)gettimeofday(&sp->se_started, NULL); 1514 add_session(sp); 1515 } 1516 1517 while (!requested_transition) 1518 if ((pid = waitpid(-1, &status, 0)) != -1) 1519 collect_child(pid, status); 1520 1521 return (state_func_t)requested_transition; 1522 } 1523 1524 /* 1525 * This is an n-squared algorithm. We hope it isn't run often... 1526 */ 1527 static state_func_t 1528 clean_ttys(void) 1529 { 1530 session_t *sp, *sprev; 1531 struct ttyent *typ; 1532 int session_index = 0; 1533 int devlen; 1534 1535 for (sp = sessions; sp; sp = sp->se_next) 1536 sp->se_flags &= ~SE_PRESENT; 1537 1538 (void)do_setttyent(); 1539 1540 devlen = sizeof(_PATH_DEV) - 1; 1541 while ((typ = getttyent()) != NULL) { 1542 ++session_index; 1543 1544 for (sprev = 0, sp = sessions; sp; sprev = sp, sp = sp->se_next) 1545 if (strcmp(typ->ty_name, sp->se_device + devlen) == 0) 1546 break; 1547 1548 if (sp) { 1549 sp->se_flags |= SE_PRESENT; 1550 if (sp->se_index != session_index) { 1551 warning("port `%s' changed utmp index from " 1552 "%d to %d", sp->se_device, sp->se_index, 1553 session_index); 1554 sp->se_index = session_index; 1555 } 1556 if ((typ->ty_status & TTY_ON) == 0 || 1557 typ->ty_getty == 0) { 1558 sp->se_flags |= SE_SHUTDOWN; 1559 if (sp->se_process != 0) 1560 (void)kill(sp->se_process, SIGHUP); 1561 continue; 1562 } 1563 sp->se_flags &= ~SE_SHUTDOWN; 1564 if (setupargv(sp, typ) == 0) { 1565 warning("can't parse getty for port `%s'", 1566 sp->se_device); 1567 sp->se_flags |= SE_SHUTDOWN; 1568 if (sp->se_process != 0) 1569 (void)kill(sp->se_process, SIGHUP); 1570 } else { 1571 sp->se_nspace = 0; 1572 } 1573 continue; 1574 } 1575 1576 (void)new_session(sprev, session_index, typ); 1577 } 1578 1579 (void)endttyent(); 1580 1581 for (sp = sessions; sp; sp = sp->se_next) 1582 if ((sp->se_flags & SE_PRESENT) == 0) { 1583 sp->se_flags |= SE_SHUTDOWN; 1584 if (sp->se_process != 0) 1585 (void)kill(sp->se_process, SIGHUP); 1586 } 1587 1588 return (state_func_t)multi_user; 1589 } 1590 1591 /* 1592 * Block further logins. 1593 */ 1594 static state_func_t 1595 catatonia(void) 1596 { 1597 session_t *sp; 1598 1599 for (sp = sessions; sp; sp = sp->se_next) 1600 sp->se_flags |= SE_SHUTDOWN; 1601 1602 return (state_func_t)multi_user; 1603 } 1604 #endif /* LETS_GET_SMALL */ 1605 1606 /* 1607 * Note SIGALRM. 1608 */ 1609 static void 1610 /*ARGSUSED*/ 1611 alrm_handler(int sig) 1612 { 1613 1614 clang = 1; 1615 } 1616 1617 #ifndef LETS_GET_SMALL 1618 /* 1619 * Bring the system down to single user. 1620 */ 1621 static state_func_t 1622 death(void) 1623 { 1624 session_t *sp; 1625 int i, status; 1626 pid_t pid; 1627 static const int death_sigs[3] = { SIGHUP, SIGTERM, SIGKILL }; 1628 1629 for (sp = sessions; sp; sp = sp->se_next) 1630 sp->se_flags |= SE_SHUTDOWN; 1631 1632 /* NB: should send a message to the session logger to avoid blocking. */ 1633 #ifdef SUPPORT_UTMPX 1634 logwtmpx("~", "shutdown", "", 0, INIT_PROCESS); 1635 #endif 1636 #ifdef SUPPORT_UTMP 1637 logwtmp("~", "shutdown", ""); 1638 #endif 1639 1640 for (i = 0; i < 3; ++i) { 1641 if (kill(-1, death_sigs[i]) == -1 && errno == ESRCH) 1642 return (state_func_t)single_user; 1643 1644 clang = 0; 1645 (void)alarm(DEATH_WATCH); 1646 do 1647 if ((pid = waitpid(-1, &status, 0)) != -1) 1648 collect_child(pid, status); 1649 while (clang == 0 && errno != ECHILD); 1650 1651 if (errno == ECHILD) 1652 return (state_func_t)single_user; 1653 } 1654 1655 warning("some processes would not die; ps axl advised"); 1656 1657 return (state_func_t)single_user; 1658 } 1659 #endif /* LETS_GET_SMALL */ 1660 1661 #ifdef MFS_DEV_IF_NO_CONSOLE 1662 1663 static int 1664 mfs_dev(void) 1665 { 1666 /* 1667 * We cannot print errors so we bail out silently... 1668 */ 1669 pid_t pid; 1670 int status; 1671 1672 /* If we have /dev/console, assume all is OK */ 1673 if (access(_PATH_CONSOLE, F_OK) == 0) 1674 return 0; 1675 1676 #if 0 /* Useful for testing MAKEDEV */ 1677 /* Mount an mfs over /mnt so we can create a console entry */ 1678 switch ((pid = fork())) { 1679 case 0: 1680 (void)execl(INIT_MOUNT_MFS, "mount_mfs", 1681 "-b", "4096", "-f", "512", 1682 "-s", 64, "-n", 10, 1683 "-p", "0755", 1684 "swap", "/mnt", NULL); 1685 _exit(9); 1686 /*NOTREACHED*/ 1687 1688 case -1: 1689 return(-1); 1690 1691 default: 1692 if (waitpid(pid, &status, 0) == -1) 1693 return(-1); 1694 if (status != 0) 1695 return(-1); 1696 break; 1697 } 1698 1699 { 1700 dev_t dev; 1701 #ifdef CPU_CONSDEV 1702 static int name[2] = { CTL_MACHDEP, CPU_CONSDEV }; 1703 size_t olen; 1704 olen = sizeof(dev); 1705 if (sysctl(name, sizeof(name) / sizeof(name[0]), &dev, &olen, 1706 NULL, 0) == -1) 1707 #endif 1708 dev = makedev(0, 0); 1709 1710 /* Make a console for us, so we can see things happening */ 1711 if (mknod("/mnt/console", 0666 | S_IFCHR, dev) == -1) 1712 return(-1); 1713 (void)freopen("/mnt/console", "a", stderr); 1714 } 1715 1716 #endif 1717 1718 /* Run the makedev script to create devices */ 1719 switch ((pid = fork())) { 1720 case 0: 1721 (void)dup2(2, 1); /* Give the script stdout */ 1722 if (chdir("/dev") == 0) 1723 (void)execl(INIT_BSHELL, "sh", 1724 access("./MAKEDEV", X_OK) == 0 1725 ? "./MAKEDEV" : "/etc/MAKEDEV", 1726 "-MM", "init", NULL); 1727 _exit(10); 1728 /* NOTREACHED */ 1729 1730 case -1: 1731 break; 1732 1733 default: 1734 if (waitpid(pid, &status, 0) == -1) 1735 break; 1736 if (status != 0) 1737 warn("MAKEDEV exit status %d", status); 1738 /* 1739 * If /dev/console got created, then return 0 1740 * regardless of MAKEDEV exit status. 1741 */ 1742 if (access(_PATH_CONSOLE, F_OK) == 0) 1743 return 0; 1744 _exit(11); 1745 } 1746 warn("Unable to run MAKEDEV"); 1747 _exit(12); 1748 } 1749 #endif 1750 1751 #ifndef LETS_GET_SMALL 1752 static int 1753 do_setttyent(void) 1754 { 1755 (void)endttyent(); 1756 #ifdef CHROOT 1757 if (did_multiuser_chroot) { 1758 char path[PATH_MAX]; 1759 1760 (void)snprintf(path, sizeof(path), "%s/%s", rootdir, _PATH_TTYS); 1761 1762 return setttyentpath(path); 1763 } else 1764 #endif /* CHROOT */ 1765 return setttyent(); 1766 } 1767 #endif 1768 1769 #if !defined(LETS_GET_SMALL) && defined(CHROOT) 1770 1771 static int 1772 createsysctlnode(void) 1773 { 1774 struct sysctlnode node; 1775 int mib[2]; 1776 size_t len; 1777 1778 /* 1779 * Create top-level dynamic sysctl node. Its child nodes will only 1780 * be readable by the superuser, since regular mortals should not 1781 * care ("Sssh, it's a secret!"). 1782 */ 1783 len = sizeof(struct sysctlnode); 1784 mib[0] = CTL_CREATE; 1785 1786 (void)memset(&node, 0, len); 1787 node.sysctl_flags = SYSCTL_VERSION | CTLFLAG_READWRITE | 1788 CTLFLAG_PRIVATE | CTLTYPE_NODE; 1789 node.sysctl_num = CTL_CREATE; 1790 (void)snprintf(node.sysctl_name, SYSCTL_NAMELEN, "init"); 1791 if (sysctl(&mib[0], 1, &node, &len, &node, len) == -1) { 1792 warning("could not create init node: %m"); 1793 return -1; 1794 } 1795 1796 /* 1797 * Create second level dynamic node capable of holding pathname. 1798 * Provide "/" as the default value. 1799 */ 1800 len = sizeof(struct sysctlnode); 1801 mib[0] = node.sysctl_num; 1802 mib[1] = CTL_CREATE; 1803 1804 (void)memset(&node, 0, len); 1805 node.sysctl_flags = SYSCTL_VERSION | CTLFLAG_READWRITE | 1806 CTLTYPE_STRING | CTLFLAG_OWNDATA; 1807 node.sysctl_size = _POSIX_PATH_MAX; 1808 node.sysctl_data = __UNCONST("/"); 1809 node.sysctl_num = CTL_CREATE; 1810 (void)snprintf(node.sysctl_name, SYSCTL_NAMELEN, "root"); 1811 if (sysctl(&mib[0], 2, NULL, NULL, &node, len) == -1) { 1812 warning("could not create init.root node: %m"); 1813 return -1; 1814 } 1815 1816 return 0; 1817 } 1818 1819 static int 1820 shouldchroot(void) 1821 { 1822 struct sysctlnode node; 1823 size_t len, cnt; 1824 int mib; 1825 1826 len = sizeof(struct sysctlnode); 1827 1828 if (sysctlbyname("init.root", rootdir, &len, NULL, 0) == -1) { 1829 warning("could not read init.root: %m"); 1830 1831 /* Child killed our node. Recreate it. */ 1832 if (errno == ENOENT) { 1833 /* Destroy whatever is left, recreate from scratch. */ 1834 if (sysctlnametomib("init", &mib, &cnt) != -1) { 1835 (void)memset(&node, 0, sizeof(node)); 1836 node.sysctl_flags = SYSCTL_VERSION; 1837 node.sysctl_num = mib; 1838 mib = CTL_DESTROY; 1839 1840 (void)sysctl(&mib, 1, NULL, NULL, &node, 1841 sizeof(node)); 1842 } 1843 1844 (void)createsysctlnode(); 1845 } 1846 1847 /* We certainly won't chroot. */ 1848 return 0; 1849 } 1850 1851 if (rootdir[len] != '\0' || strlen(rootdir) != len - 1) { 1852 warning("init.root is not a string"); 1853 return 0; 1854 } 1855 1856 if (strcmp(rootdir, "/") == 0) 1857 return 0; 1858 1859 return 1; 1860 } 1861 1862 #endif /* !LETS_GET_SMALL && CHROOT */ 1863