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