1 /* $NetBSD: init.c,v 1.106 2015/06/16 23:18:55 christos 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.106 2015/06/16 23:18:55 christos 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 #ifdef KERN_SECURELVL 548 int name[2], curlevel; 549 size_t len; 550 551 name[0] = CTL_KERN; 552 name[1] = KERN_SECURELVL; 553 len = sizeof curlevel; 554 if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) { 555 /* If it doesn't exist, it's okay. */ 556 if (errno == ENOENT) 557 return 0; 558 } 559 return 1; 560 #else 561 return 0; 562 #endif 563 } 564 565 /* 566 * Get the security level of the kernel. 567 */ 568 static int 569 getsecuritylevel(void) 570 { 571 #ifdef KERN_SECURELVL 572 int name[2], curlevel; 573 size_t len; 574 575 if (!securelevel_present) 576 return -1; 577 578 name[0] = CTL_KERN; 579 name[1] = KERN_SECURELVL; 580 len = sizeof curlevel; 581 if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) { 582 emergency("cannot get kernel security level: %m"); 583 return -1; 584 } 585 return curlevel; 586 #else 587 return -1; 588 #endif 589 } 590 591 /* 592 * Set the security level of the kernel. 593 */ 594 static void 595 setsecuritylevel(int newlevel) 596 { 597 #ifdef KERN_SECURELVL 598 int name[2], curlevel; 599 600 if (!securelevel_present) 601 return; 602 603 curlevel = getsecuritylevel(); 604 if (newlevel == curlevel) 605 return; 606 name[0] = CTL_KERN; 607 name[1] = KERN_SECURELVL; 608 if (sysctl(name, 2, NULL, NULL, &newlevel, sizeof newlevel) == -1) { 609 emergency("cannot change kernel security level from" 610 " %d to %d: %m", curlevel, newlevel); 611 return; 612 } 613 #ifdef SECURE 614 warning("kernel security level changed from %d to %d", 615 curlevel, newlevel); 616 #endif 617 #endif 618 } 619 620 /* 621 * Change states in the finite state machine. 622 * The initial state is passed as an argument. 623 */ 624 static void 625 transition(state_t s) 626 { 627 628 if (s == NULL) 629 return; 630 for (;;) { 631 #ifdef SUPPORT_UTMPX 632 #ifndef LETS_GET_SMALL 633 utmpx_set_runlevel(get_runlevel(current_state), 634 get_runlevel(s)); 635 current_state = s; 636 #endif 637 #endif 638 s = (state_t)(*s)(); 639 } 640 } 641 642 #ifndef LETS_GET_SMALL 643 /* 644 * Close out the accounting files for a login session. 645 * NB: should send a message to the session logger to avoid blocking. 646 */ 647 static void 648 clear_session_logs(session_t *sp, int status) 649 { 650 #if defined(SUPPORT_UTMP) || defined(SUPPORT_UTMPX) 651 char *line = sp->se_device + sizeof(_PATH_DEV) - 1; 652 #endif 653 654 #ifdef SUPPORT_UTMPX 655 if (logoutx(line, status, DEAD_PROCESS)) 656 logwtmpx(line, "", "", status, DEAD_PROCESS); 657 #endif 658 #ifdef SUPPORT_UTMP 659 if (logout(line)) 660 logwtmp(line, "", ""); 661 #endif 662 } 663 #endif 664 665 /* 666 * Start a session and allocate a controlling terminal. 667 * Only called by children of init after forking. 668 */ 669 static void 670 setctty(const char *name) 671 { 672 int fd; 673 674 #if !defined(__minix) 675 (void)revoke(name); 676 #else 677 if (setsid() < 0) 678 warn("child setsid() failed"); 679 #endif /* !defined(__minix) */ 680 (void)nanosleep(&dtrtime, NULL); /* leave DTR low for a bit */ 681 if ((fd = open(name, O_RDWR)) == -1) { 682 stall("can't open %s: %m", name); 683 _exit(1); 684 } 685 if (login_tty(fd) == -1) { 686 stall("can't get %s for controlling terminal: %m", name); 687 _exit(2); 688 } 689 } 690 691 /* 692 * Bring the system up single user. 693 */ 694 static state_func_t 695 single_user(void) 696 { 697 pid_t pid, wpid; 698 int status; 699 int from_securitylevel; 700 sigset_t mask; 701 struct sigaction sa, satstp, sahup; 702 #ifdef ALTSHELL 703 const char *shell = INIT_BSHELL; 704 #endif 705 const char *argv[2]; 706 #ifdef SECURE 707 struct ttyent *typ; 708 struct passwd *pp; 709 char *clear, *password; 710 #endif 711 #ifdef ALTSHELL 712 char altshell[128]; 713 #endif /* ALTSHELL */ 714 715 #if !defined(LETS_GET_SMALL) && defined(CHROOT) 716 /* Clear previous idea, just in case. */ 717 did_multiuser_chroot = 0; 718 #endif /* !LETS_GET_SMALL && CHROOT */ 719 720 /* 721 * If the kernel is in secure mode, downgrade it to insecure mode. 722 */ 723 from_securitylevel = getsecuritylevel(); 724 if (from_securitylevel > 0) 725 setsecuritylevel(0); 726 727 (void)sigemptyset(&sa.sa_mask); 728 sa.sa_flags = 0; 729 sa.sa_handler = SIG_IGN; 730 (void)sigaction(SIGTSTP, &sa, &satstp); 731 (void)sigaction(SIGHUP, &sa, &sahup); 732 if ((pid = fork()) == 0) { 733 /* 734 * Start the single user session. 735 */ 736 if (access(_PATH_CONSTTY, F_OK) == 0) 737 setctty(_PATH_CONSTTY); 738 else 739 setctty(_PATH_CONSOLE); 740 741 #ifdef SECURE 742 /* 743 * Check the root password. 744 * We don't care if the console is 'on' by default; 745 * it's the only tty that can be 'off' and 'secure'. 746 */ 747 typ = getttynam("console"); 748 pp = getpwnam("root"); 749 if (typ && (from_securitylevel >=2 || (typ->ty_status 750 & TTY_SECURE) == 0) && pp && *pp->pw_passwd != '\0') { 751 (void)fprintf(stderr, 752 "Enter root password, or ^D to go multi-user\n"); 753 for (;;) { 754 clear = getpass("Password:"); 755 if (clear == 0 || *clear == '\0') 756 _exit(0); 757 password = crypt(clear, pp->pw_passwd); 758 (void)memset(clear, 0, _PASSWORD_LEN); 759 if (strcmp(password, pp->pw_passwd) == 0) 760 break; 761 warning("single-user login failed"); 762 } 763 } 764 (void)endttyent(); 765 endpwent(); 766 #endif /* SECURE */ 767 768 #ifdef ALTSHELL 769 (void)fprintf(stderr, 770 "Enter pathname of shell or RETURN for %s: ", shell); 771 if (fgets(altshell, sizeof(altshell), stdin) == NULL) { 772 altshell[0] = '\0'; 773 } else { 774 /* nuke \n */ 775 char *p; 776 777 if ((p = strchr(altshell, '\n')) != NULL) 778 *p = '\0'; 779 } 780 781 if (altshell[0]) 782 shell = altshell; 783 #endif /* ALTSHELL */ 784 785 /* 786 * Unblock signals. 787 * We catch all the interesting ones, 788 * and those are reset to SIG_DFL on exec. 789 */ 790 (void)sigemptyset(&mask); 791 (void)sigprocmask(SIG_SETMASK, &mask, NULL); 792 793 /* 794 * Fire off a shell. 795 * If the default one doesn't work, try the Bourne shell. 796 */ 797 argv[0] = "-sh"; 798 argv[1] = 0; 799 (void)setenv("PATH", INIT_PATH, 1); 800 #ifdef ALTSHELL 801 if (altshell[0]) 802 argv[0] = altshell; 803 (void)execv(shell, __UNCONST(argv)); 804 emergency("can't exec `%s' for single user: %m", shell); 805 argv[0] = "-sh"; 806 #endif /* ALTSHELL */ 807 (void)execv(INIT_BSHELL, __UNCONST(argv)); 808 emergency("can't exec `%s' for single user: %m", INIT_BSHELL); 809 (void)sleep(STALL_TIMEOUT); 810 _exit(3); 811 } 812 813 if (pid == -1) { 814 /* 815 * We are seriously hosed. Do our best. 816 */ 817 emergency("can't fork single-user shell: %m, trying again"); 818 while (waitpid(-1, NULL, WNOHANG) > 0) 819 continue; 820 (void)sigaction(SIGTSTP, &satstp, NULL); 821 (void)sigaction(SIGHUP, &sahup, NULL); 822 return (state_func_t)single_user; 823 } 824 825 requested_transition = 0; 826 do { 827 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) 828 collect_child(wpid, status); 829 if (wpid == -1) { 830 if (errno == EINTR) 831 continue; 832 warning("wait for single-user shell failed: %m; " 833 "restarting"); 834 return (state_func_t)single_user; 835 } 836 if (wpid == pid && WIFSTOPPED(status)) { 837 warning("shell stopped, restarting"); 838 (void)kill(pid, SIGCONT); 839 wpid = -1; 840 } 841 } while (wpid != pid && !requested_transition); 842 843 if (requested_transition) { 844 (void)sigaction(SIGTSTP, &satstp, NULL); 845 (void)sigaction(SIGHUP, &sahup, NULL); 846 return (state_func_t)requested_transition; 847 } 848 849 if (WIFSIGNALED(status)) { 850 if (WTERMSIG(status) == SIGKILL) { 851 /* executed /sbin/reboot; wait for the end quietly */ 852 sigset_t s; 853 854 (void)sigfillset(&s); 855 for (;;) 856 (void)sigsuspend(&s); 857 } else { 858 warning("single user shell terminated (%x), restarting", 859 status); 860 (void)sigaction(SIGTSTP, &satstp, NULL); 861 (void)sigaction(SIGHUP, &sahup, NULL); 862 return (state_func_t)single_user; 863 } 864 } 865 866 runcom_mode = FASTBOOT; 867 (void)sigaction(SIGTSTP, &satstp, NULL); 868 (void)sigaction(SIGHUP, &sahup, NULL); 869 #ifndef LETS_GET_SMALL 870 return (state_func_t)runcom; 871 #else /* LETS_GET_SMALL */ 872 return (state_func_t)single_user; 873 #endif /* LETS_GET_SMALL */ 874 } 875 876 #ifndef LETS_GET_SMALL 877 878 /* ARGSUSED */ 879 static state_func_t 880 runetcrc(int trychroot) 881 { 882 pid_t pid, wpid; 883 int status; 884 const char *argv[4]; 885 struct sigaction sa; 886 887 switch ((pid = fork())) { 888 case 0: 889 (void)sigemptyset(&sa.sa_mask); 890 sa.sa_flags = 0; 891 sa.sa_handler = SIG_IGN; 892 (void)sigaction(SIGTSTP, &sa, NULL); 893 (void)sigaction(SIGHUP, &sa, NULL); 894 895 setctty(_PATH_CONSOLE); 896 897 argv[0] = "sh"; 898 argv[1] = _PATH_RUNCOM; 899 argv[2] = (runcom_mode == AUTOBOOT ? "autoboot" : 0); 900 argv[3] = 0; 901 902 (void)sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL); 903 904 #ifdef CHROOT 905 if (trychroot) 906 if (chroot(rootdir) != 0) { 907 warning("failed to chroot to `%s': %m", 908 rootdir); 909 _exit(4); /* force single user mode */ 910 } 911 #endif /* CHROOT */ 912 913 (void)execv(INIT_BSHELL, __UNCONST(argv)); 914 stall("can't exec `%s' for `%s': %m", INIT_BSHELL, _PATH_RUNCOM); 915 _exit(5); /* force single user mode */ 916 /*NOTREACHED*/ 917 case -1: 918 emergency("can't fork for `%s' on `%s': %m", INIT_BSHELL, 919 _PATH_RUNCOM); 920 while (waitpid(-1, NULL, WNOHANG) > 0) 921 continue; 922 (void)sleep(STALL_TIMEOUT); 923 return (state_func_t)single_user; 924 default: 925 break; 926 } 927 928 /* 929 * Copied from single_user(). This is a bit paranoid. 930 */ 931 do { 932 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) 933 collect_child(wpid, status); 934 if (wpid == -1) { 935 if (errno == EINTR) 936 continue; 937 warning("wait for `%s' on `%s' failed: %m; going to " 938 "single user mode", INIT_BSHELL, _PATH_RUNCOM); 939 return (state_func_t)single_user; 940 } 941 if (wpid == pid && WIFSTOPPED(status)) { 942 warning("`%s' on `%s' stopped, restarting", 943 INIT_BSHELL, _PATH_RUNCOM); 944 (void)kill(pid, SIGCONT); 945 wpid = -1; 946 } 947 } while (wpid != pid); 948 949 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM && 950 requested_transition == catatonia) { 951 /* /etc/rc executed /sbin/reboot; wait for the end quietly */ 952 sigset_t s; 953 954 (void)sigfillset(&s); 955 for (;;) 956 (void)sigsuspend(&s); 957 } 958 959 if (!WIFEXITED(status)) { 960 warning("`%s' on `%s' terminated abnormally, going to " 961 "single user mode", INIT_BSHELL, _PATH_RUNCOM); 962 return (state_func_t)single_user; 963 } 964 965 if (WEXITSTATUS(status)) 966 return (state_func_t)single_user; 967 968 return (state_func_t)read_ttys; 969 } 970 971 /* 972 * Run the system startup script. 973 */ 974 static state_func_t 975 runcom(void) 976 { 977 state_func_t next_step; 978 979 /* Run /etc/rc and choose next state depending on the result. */ 980 next_step = runetcrc(0); 981 if (next_step != (state_func_t)read_ttys) 982 return (state_func_t)next_step; 983 984 #ifdef CHROOT 985 /* 986 * If init.root sysctl does not point to "/", we'll chroot and run 987 * The Real(tm) /etc/rc now. Global variable rootdir will tell us 988 * where to go. 989 */ 990 if (shouldchroot()) { 991 next_step = runetcrc(1); 992 if (next_step != (state_func_t)read_ttys) 993 return (state_func_t)next_step; 994 995 did_multiuser_chroot = 1; 996 } else { 997 did_multiuser_chroot = 0; 998 } 999 #endif /* CHROOT */ 1000 1001 /* 1002 * Regardless of whether in chroot or not, we booted successfuly. 1003 * It's time to spawn gettys (ie. next_step's value at this point). 1004 */ 1005 runcom_mode = AUTOBOOT; /* the default */ 1006 /* NB: should send a message to the session logger to avoid blocking. */ 1007 #ifdef SUPPORT_UTMPX 1008 logwtmpx("~", "reboot", "", 0, INIT_PROCESS); 1009 #endif 1010 #ifdef SUPPORT_UTMP 1011 logwtmp("~", "reboot", ""); 1012 #endif 1013 return (state_func_t)read_ttys; 1014 } 1015 1016 /* 1017 * Open the session database. 1018 * 1019 * NB: We could pass in the size here; is it necessary? 1020 */ 1021 static int 1022 start_session_db(void) 1023 { 1024 1025 if (session_db && (*session_db->close)(session_db)) 1026 emergency("session database close: %m"); 1027 if ((session_db = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL)) == 0) { 1028 emergency("session database open: %m"); 1029 return 1; 1030 } 1031 return 0; 1032 1033 } 1034 1035 /* 1036 * Add a new login session. 1037 */ 1038 static void 1039 add_session(session_t *sp) 1040 { 1041 DBT key; 1042 DBT data; 1043 1044 if (session_db == NULL) 1045 return; 1046 1047 key.data = &sp->se_process; 1048 key.size = sizeof sp->se_process; 1049 data.data = &sp; 1050 data.size = sizeof sp; 1051 1052 if ((*session_db->put)(session_db, &key, &data, 0)) 1053 emergency("insert %d: %m", sp->se_process); 1054 #ifdef SUPPORT_UTMPX 1055 session_utmpx(sp, 1); 1056 #endif 1057 } 1058 1059 /* 1060 * Delete an old login session. 1061 */ 1062 static void 1063 del_session(session_t *sp) 1064 { 1065 DBT key; 1066 1067 key.data = &sp->se_process; 1068 key.size = sizeof sp->se_process; 1069 1070 if ((*session_db->del)(session_db, &key, 0)) 1071 emergency("delete %d: %m", sp->se_process); 1072 #ifdef SUPPORT_UTMPX 1073 session_utmpx(sp, 0); 1074 #endif 1075 } 1076 1077 /* 1078 * Look up a login session by pid. 1079 */ 1080 static session_t * 1081 find_session(pid_t pid) 1082 { 1083 DBT key; 1084 DBT data; 1085 session_t *ret; 1086 1087 if (session_db == NULL) 1088 return NULL; 1089 1090 key.data = &pid; 1091 key.size = sizeof pid; 1092 if ((*session_db->get)(session_db, &key, &data, 0) != 0) 1093 return 0; 1094 (void)memmove(&ret, data.data, sizeof(ret)); 1095 return ret; 1096 } 1097 1098 /* 1099 * Construct an argument vector from a command line. 1100 */ 1101 static char ** 1102 construct_argv(char *command) 1103 { 1104 int argc = 0; 1105 char **argv = malloc(((strlen(command) + 1) / 2 + 1) * sizeof (char *)); 1106 static const char separators[] = " \t"; 1107 1108 if (argv == NULL) 1109 return NULL; 1110 1111 if ((argv[argc++] = strtok(command, separators)) == 0) { 1112 free(argv); 1113 return NULL; 1114 } 1115 while ((argv[argc++] = strtok(NULL, separators)) != NULL) 1116 continue; 1117 return argv; 1118 } 1119 1120 /* 1121 * Deallocate a session descriptor. 1122 */ 1123 static void 1124 free_session(session_t *sp) 1125 { 1126 1127 free(sp->se_device); 1128 if (sp->se_getty) { 1129 free(sp->se_getty); 1130 free(sp->se_getty_argv); 1131 } 1132 if (sp->se_window) { 1133 free(sp->se_window); 1134 free(sp->se_window_argv); 1135 } 1136 free(sp); 1137 } 1138 1139 /* 1140 * Allocate a new session descriptor. 1141 */ 1142 static session_t * 1143 new_session(session_t *sprev, int session_index, struct ttyent *typ) 1144 { 1145 session_t *sp; 1146 1147 if ((typ->ty_status & TTY_ON) == 0 || typ->ty_name == NULL || 1148 typ->ty_getty == NULL) 1149 return NULL; 1150 1151 sp = malloc(sizeof (session_t)); 1152 if (sp == NULL) 1153 return NULL; 1154 (void)memset(sp, 0, sizeof *sp); 1155 1156 sp->se_flags = SE_PRESENT; 1157 sp->se_index = session_index; 1158 1159 (void)asprintf(&sp->se_device, "%s%s", _PATH_DEV, typ->ty_name); 1160 if (!sp->se_device) { 1161 free(sp); 1162 return NULL; 1163 } 1164 1165 if (setupargv(sp, typ) == 0) { 1166 free_session(sp); 1167 return NULL; 1168 } 1169 1170 sp->se_next = NULL; 1171 if (sprev == NULL) { 1172 sessions = sp; 1173 sp->se_prev = NULL; 1174 } else { 1175 sprev->se_next = sp; 1176 sp->se_prev = sprev; 1177 } 1178 1179 return sp; 1180 } 1181 1182 /* 1183 * Calculate getty and if useful window argv vectors. 1184 */ 1185 static int 1186 setupargv(session_t *sp, struct ttyent *typ) 1187 { 1188 1189 if (sp->se_getty) { 1190 free(sp->se_getty); 1191 free(sp->se_getty_argv); 1192 } 1193 (void)asprintf(&sp->se_getty, "%s %s", typ->ty_getty, typ->ty_name); 1194 if (!sp->se_getty) 1195 return 0; 1196 sp->se_getty_argv = construct_argv(sp->se_getty); 1197 if (sp->se_getty_argv == NULL) { 1198 warning("can't parse getty for port `%s'", sp->se_device); 1199 free(sp->se_getty); 1200 sp->se_getty = NULL; 1201 return 0; 1202 } 1203 if (typ->ty_window) { 1204 if (sp->se_window) 1205 free(sp->se_window); 1206 sp->se_window = strdup(typ->ty_window); 1207 sp->se_window_argv = construct_argv(sp->se_window); 1208 if (sp->se_window_argv == NULL) { 1209 warning("can't parse window for port `%s'", 1210 sp->se_device); 1211 free(sp->se_window); 1212 sp->se_window = NULL; 1213 return 0; 1214 } 1215 } 1216 return 1; 1217 } 1218 1219 /* 1220 * Walk the list of ttys and create sessions for each active line. 1221 */ 1222 static state_func_t 1223 read_ttys(void) 1224 { 1225 int session_index = 0; 1226 session_t *sp, *snext; 1227 struct ttyent *typ; 1228 1229 #ifdef SUPPORT_UTMPX 1230 if (sessions == NULL) { 1231 struct stat st; 1232 1233 make_utmpx("", BOOT_MSG, BOOT_TIME, 0, &boot_time, 0); 1234 1235 /* 1236 * If wtmpx is not empty, pick the down time from there 1237 */ 1238 if (stat(_PATH_WTMPX, &st) != -1 && st.st_size != 0) { 1239 struct timeval down_time; 1240 1241 TIMESPEC_TO_TIMEVAL(&down_time, 1242 st.st_atime > st.st_mtime ? 1243 &st.st_atimespec : &st.st_mtimespec); 1244 make_utmpx("", DOWN_MSG, DOWN_TIME, 0, &down_time, 0); 1245 } 1246 } 1247 #endif 1248 /* 1249 * Destroy any previous session state. 1250 * There shouldn't be any, but just in case... 1251 */ 1252 for (sp = sessions; sp; sp = snext) { 1253 #ifndef LETS_GET_SMALL 1254 if (sp->se_process) 1255 clear_session_logs(sp, 0); 1256 #endif 1257 snext = sp->se_next; 1258 free_session(sp); 1259 } 1260 sessions = NULL; 1261 1262 if (start_session_db()) { 1263 warning("start_session_db failed, death"); 1264 #ifdef CHROOT 1265 /* If /etc/rc ran in chroot, we want to kill any survivors. */ 1266 if (did_multiuser_chroot) 1267 return (state_func_t)death; 1268 else 1269 #endif /* CHROOT */ 1270 return (state_func_t)single_user; 1271 } 1272 1273 (void)do_setttyent(); 1274 1275 /* 1276 * Allocate a session entry for each active port. 1277 * Note that sp starts at 0. 1278 */ 1279 while ((typ = getttyent()) != NULL) 1280 if ((snext = new_session(sp, ++session_index, typ)) != NULL) 1281 sp = snext; 1282 (void)endttyent(); 1283 1284 return (state_func_t)multi_user; 1285 } 1286 1287 /* 1288 * Start a window system running. 1289 */ 1290 static void 1291 start_window_system(session_t *sp) 1292 { 1293 pid_t pid; 1294 sigset_t mask; 1295 1296 if ((pid = fork()) == -1) { 1297 emergency("can't fork for window system on port `%s': %m", 1298 sp->se_device); 1299 /* hope that getty fails and we can try again */ 1300 return; 1301 } 1302 1303 if (pid) 1304 return; 1305 1306 (void)sigemptyset(&mask); 1307 (void)sigprocmask(SIG_SETMASK, &mask, NULL); 1308 1309 if (setsid() < 0) 1310 emergency("setsid failed (window): %m"); 1311 1312 (void)execv(sp->se_window_argv[0], sp->se_window_argv); 1313 stall("can't exec window system `%s' for port `%s': %m", 1314 sp->se_window_argv[0], sp->se_device); 1315 _exit(6); 1316 } 1317 1318 /* 1319 * Start a login session running. 1320 */ 1321 static pid_t 1322 start_getty(session_t *sp) 1323 { 1324 pid_t pid; 1325 sigset_t mask; 1326 time_t current_time = time(NULL); 1327 1328 /* 1329 * fork(), not vfork() -- we can't afford to block. 1330 */ 1331 if ((pid = fork()) == -1) { 1332 emergency("can't fork for getty on port `%s': %m", 1333 sp->se_device); 1334 return -1; 1335 } 1336 1337 if (pid) 1338 return pid; 1339 1340 #ifdef CHROOT 1341 /* If /etc/rc did proceed inside chroot, we have to try as well. */ 1342 if (did_multiuser_chroot) 1343 if (chroot(rootdir) != 0) { 1344 stall("can't chroot getty `%s' inside `%s': %m", 1345 sp->se_getty_argv[0], rootdir); 1346 _exit(7); 1347 } 1348 #endif /* CHROOT */ 1349 1350 if (current_time > sp->se_started.tv_sec && 1351 current_time - sp->se_started.tv_sec < GETTY_SPACING) { 1352 warning("getty repeating too quickly on port `%s', sleeping", 1353 sp->se_device); 1354 (void)sleep(GETTY_SLEEP); 1355 } 1356 1357 if (sp->se_window) { 1358 start_window_system(sp); 1359 (void)sleep(WINDOW_WAIT); 1360 } 1361 1362 (void)sigemptyset(&mask); 1363 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); 1364 1365 (void)execv(sp->se_getty_argv[0], sp->se_getty_argv); 1366 stall("can't exec getty `%s' for port `%s': %m", 1367 sp->se_getty_argv[0], sp->se_device); 1368 _exit(8); 1369 /*NOTREACHED*/ 1370 } 1371 #ifdef SUPPORT_UTMPX 1372 static void 1373 session_utmpx(const session_t *sp, int add) 1374 { 1375 const char *name = sp->se_getty ? sp->se_getty : 1376 (sp->se_window ? sp->se_window : ""); 1377 const char *line = sp->se_device + sizeof(_PATH_DEV) - 1; 1378 1379 make_utmpx(name, line, add ? LOGIN_PROCESS : DEAD_PROCESS, 1380 sp->se_process, &sp->se_started, sp->se_index); 1381 } 1382 1383 static void 1384 make_utmpx(const char *name, const char *line, int type, pid_t pid, 1385 const struct timeval *tv, int session) 1386 { 1387 struct utmpx ut; 1388 const char *eline; 1389 1390 (void)memset(&ut, 0, sizeof(ut)); 1391 (void)strlcpy(ut.ut_name, name, sizeof(ut.ut_name)); 1392 ut.ut_type = type; 1393 (void)strlcpy(ut.ut_line, line, sizeof(ut.ut_line)); 1394 ut.ut_pid = pid; 1395 if (tv) 1396 ut.ut_tv = *tv; 1397 else 1398 (void)gettimeofday(&ut.ut_tv, NULL); 1399 ut.ut_session = session; 1400 1401 eline = line + strlen(line); 1402 if ((size_t)(eline - line) >= sizeof(ut.ut_id)) 1403 line = eline - sizeof(ut.ut_id); 1404 (void)strncpy(ut.ut_id, line, sizeof(ut.ut_id)); 1405 1406 if (pututxline(&ut) == NULL) 1407 warning("can't add utmpx record for `%s': %m", ut.ut_line); 1408 endutxent(); 1409 } 1410 1411 static char 1412 get_runlevel(const state_t s) 1413 { 1414 if (s == (state_t)single_user) 1415 return SINGLE_USER; 1416 if (s == (state_t)runcom) 1417 return RUNCOM; 1418 if (s == (state_t)read_ttys) 1419 return READ_TTYS; 1420 if (s == (state_t)multi_user) 1421 return MULTI_USER; 1422 if (s == (state_t)clean_ttys) 1423 return CLEAN_TTYS; 1424 if (s == (state_t)catatonia) 1425 return CATATONIA; 1426 return DEATH; 1427 } 1428 1429 static void 1430 utmpx_set_runlevel(char old, char new) 1431 { 1432 struct utmpx ut; 1433 1434 /* 1435 * Don't record any transitions until we did the first transition 1436 * to read ttys, which is when we are guaranteed to have a read-write 1437 * /var. Perhaps use a different variable for this? 1438 */ 1439 if (sessions == NULL) 1440 return; 1441 1442 (void)memset(&ut, 0, sizeof(ut)); 1443 (void)snprintf(ut.ut_line, sizeof(ut.ut_line), RUNLVL_MSG, new); 1444 ut.ut_type = RUN_LVL; 1445 (void)gettimeofday(&ut.ut_tv, NULL); 1446 ut.ut_exit.e_exit = old; 1447 ut.ut_exit.e_termination = new; 1448 if (pututxline(&ut) == NULL) 1449 warning("can't add utmpx record for `runlevel': %m"); 1450 endutxent(); 1451 } 1452 #endif /* SUPPORT_UTMPX */ 1453 1454 #endif /* LETS_GET_SMALL */ 1455 1456 /* 1457 * Collect exit status for a child. 1458 * If an exiting login, start a new login running. 1459 */ 1460 static void 1461 collect_child(pid_t pid, int status) 1462 { 1463 #ifndef LETS_GET_SMALL 1464 session_t *sp, *sprev, *snext; 1465 1466 if (! sessions) 1467 return; 1468 1469 if ((sp = find_session(pid)) == NULL) 1470 return; 1471 1472 clear_session_logs(sp, status); 1473 del_session(sp); 1474 sp->se_process = 0; 1475 1476 if (sp->se_flags & SE_SHUTDOWN) { 1477 if ((sprev = sp->se_prev) != NULL) 1478 sprev->se_next = sp->se_next; 1479 else 1480 sessions = sp->se_next; 1481 if ((snext = sp->se_next) != NULL) 1482 snext->se_prev = sp->se_prev; 1483 free_session(sp); 1484 return; 1485 } 1486 1487 if ((pid = start_getty(sp)) == -1) { 1488 /* serious trouble */ 1489 requested_transition = clean_ttys; 1490 return; 1491 } 1492 1493 sp->se_process = pid; 1494 (void)gettimeofday(&sp->se_started, NULL); 1495 add_session(sp); 1496 #endif /* LETS_GET_SMALL */ 1497 } 1498 1499 /* 1500 * Catch a signal and request a state transition. 1501 */ 1502 static void 1503 transition_handler(int sig) 1504 { 1505 1506 switch (sig) { 1507 #ifndef LETS_GET_SMALL 1508 case SIGHUP: 1509 requested_transition = clean_ttys; 1510 break; 1511 case SIGTERM: 1512 requested_transition = death; 1513 break; 1514 case SIGTSTP: 1515 requested_transition = catatonia; 1516 break; 1517 #endif /* LETS_GET_SMALL */ 1518 default: 1519 requested_transition = 0; 1520 break; 1521 } 1522 } 1523 1524 #ifndef LETS_GET_SMALL 1525 /* 1526 * Take the system multiuser. 1527 */ 1528 static state_func_t 1529 multi_user(void) 1530 { 1531 pid_t pid; 1532 int status; 1533 session_t *sp; 1534 1535 requested_transition = 0; 1536 1537 /* 1538 * If the administrator has not set the security level to -1 1539 * to indicate that the kernel should not run multiuser in secure 1540 * mode, and the run script has not set a higher level of security 1541 * than level 1, then put the kernel into secure mode. 1542 */ 1543 if (getsecuritylevel() == 0) 1544 setsecuritylevel(1); 1545 1546 for (sp = sessions; sp; sp = sp->se_next) { 1547 if (sp->se_process) 1548 continue; 1549 if ((pid = start_getty(sp)) == -1) { 1550 /* serious trouble */ 1551 requested_transition = clean_ttys; 1552 break; 1553 } 1554 sp->se_process = pid; 1555 (void)gettimeofday(&sp->se_started, NULL); 1556 add_session(sp); 1557 } 1558 1559 while (!requested_transition) 1560 if ((pid = waitpid(-1, &status, 0)) != -1) 1561 collect_child(pid, status); 1562 1563 return (state_func_t)requested_transition; 1564 } 1565 1566 /* 1567 * This is an n-squared algorithm. We hope it isn't run often... 1568 */ 1569 static state_func_t 1570 clean_ttys(void) 1571 { 1572 session_t *sp, *sprev; 1573 struct ttyent *typ; 1574 int session_index = 0; 1575 int devlen; 1576 1577 for (sp = sessions; sp; sp = sp->se_next) 1578 sp->se_flags &= ~SE_PRESENT; 1579 1580 (void)do_setttyent(); 1581 1582 devlen = sizeof(_PATH_DEV) - 1; 1583 while ((typ = getttyent()) != NULL) { 1584 ++session_index; 1585 1586 for (sprev = 0, sp = sessions; sp; sprev = sp, sp = sp->se_next) 1587 if (strcmp(typ->ty_name, sp->se_device + devlen) == 0) 1588 break; 1589 1590 if (sp) { 1591 sp->se_flags |= SE_PRESENT; 1592 if (sp->se_index != session_index) { 1593 warning("port `%s' changed utmp index from " 1594 "%d to %d", sp->se_device, sp->se_index, 1595 session_index); 1596 sp->se_index = session_index; 1597 } 1598 if ((typ->ty_status & TTY_ON) == 0 || 1599 typ->ty_getty == 0) { 1600 sp->se_flags |= SE_SHUTDOWN; 1601 if (sp->se_process != 0) 1602 (void)kill(sp->se_process, SIGHUP); 1603 continue; 1604 } 1605 sp->se_flags &= ~SE_SHUTDOWN; 1606 if (setupargv(sp, typ) == 0) { 1607 warning("can't parse getty for port `%s'", 1608 sp->se_device); 1609 sp->se_flags |= SE_SHUTDOWN; 1610 if (sp->se_process != 0) 1611 (void)kill(sp->se_process, SIGHUP); 1612 } 1613 continue; 1614 } 1615 1616 (void)new_session(sprev, session_index, typ); 1617 } 1618 1619 (void)endttyent(); 1620 1621 for (sp = sessions; sp; sp = sp->se_next) 1622 if ((sp->se_flags & SE_PRESENT) == 0) { 1623 sp->se_flags |= SE_SHUTDOWN; 1624 if (sp->se_process != 0) 1625 (void)kill(sp->se_process, SIGHUP); 1626 } 1627 1628 return (state_func_t)multi_user; 1629 } 1630 1631 /* 1632 * Block further logins. 1633 */ 1634 static state_func_t 1635 catatonia(void) 1636 { 1637 session_t *sp; 1638 1639 for (sp = sessions; sp; sp = sp->se_next) 1640 sp->se_flags |= SE_SHUTDOWN; 1641 1642 return (state_func_t)multi_user; 1643 } 1644 #endif /* LETS_GET_SMALL */ 1645 1646 /* 1647 * Note SIGALRM. 1648 */ 1649 static void 1650 /*ARGSUSED*/ 1651 alrm_handler(int sig) 1652 { 1653 1654 clang = 1; 1655 } 1656 1657 #ifndef LETS_GET_SMALL 1658 /* 1659 * Bring the system down to single user. 1660 */ 1661 static state_func_t 1662 death(void) 1663 { 1664 session_t *sp; 1665 int i, status; 1666 pid_t pid; 1667 static const int death_sigs[3] = { SIGHUP, SIGTERM, SIGKILL }; 1668 1669 for (sp = sessions; sp; sp = sp->se_next) 1670 sp->se_flags |= SE_SHUTDOWN; 1671 1672 /* NB: should send a message to the session logger to avoid blocking. */ 1673 #ifdef SUPPORT_UTMPX 1674 logwtmpx("~", "shutdown", "", 0, INIT_PROCESS); 1675 #endif 1676 #ifdef SUPPORT_UTMP 1677 logwtmp("~", "shutdown", ""); 1678 #endif 1679 1680 for (i = 0; i < 3; ++i) { 1681 if (kill(-1, death_sigs[i]) == -1 && errno == ESRCH) 1682 return (state_func_t)single_user; 1683 1684 clang = 0; 1685 (void)alarm(DEATH_WATCH); 1686 do 1687 if ((pid = waitpid(-1, &status, 0)) != -1) 1688 collect_child(pid, status); 1689 while (clang == 0 && errno != ECHILD); 1690 1691 if (errno == ECHILD) 1692 return (state_func_t)single_user; 1693 } 1694 1695 warning("some processes would not die; ps axl advised"); 1696 1697 return (state_func_t)single_user; 1698 } 1699 #endif /* LETS_GET_SMALL */ 1700 1701 #ifdef MFS_DEV_IF_NO_CONSOLE 1702 1703 static int 1704 mfs_dev(void) 1705 { 1706 /* 1707 * We cannot print errors so we bail out silently... 1708 */ 1709 pid_t pid; 1710 int status; 1711 1712 /* If we have /dev/console, assume all is OK */ 1713 if (access(_PATH_CONSOLE, F_OK) == 0) 1714 return 0; 1715 1716 #if 0 /* Useful for testing MAKEDEV */ 1717 /* Mount an mfs over /mnt so we can create a console entry */ 1718 switch ((pid = fork())) { 1719 case 0: 1720 (void)execl(INIT_MOUNT_MFS, "mount_mfs", 1721 "-b", "4096", "-f", "512", 1722 "-s", 64, "-n", 10, 1723 "-p", "0755", 1724 "swap", "/mnt", NULL); 1725 _exit(9); 1726 /*NOTREACHED*/ 1727 1728 case -1: 1729 return(-1); 1730 1731 default: 1732 if (waitpid(pid, &status, 0) == -1) 1733 return(-1); 1734 if (status != 0) 1735 return(-1); 1736 break; 1737 } 1738 1739 { 1740 dev_t dev; 1741 #ifdef CPU_CONSDEV 1742 static int name[2] = { CTL_MACHDEP, CPU_CONSDEV }; 1743 size_t olen; 1744 olen = sizeof(dev); 1745 if (sysctl(name, sizeof(name) / sizeof(name[0]), &dev, &olen, 1746 NULL, 0) == -1) 1747 #endif 1748 dev = makedev(0, 0); 1749 1750 /* Make a console for us, so we can see things happening */ 1751 if (mknod("/mnt/console", 0666 | S_IFCHR, dev) == -1) 1752 return(-1); 1753 (void)freopen("/mnt/console", "a", stderr); 1754 } 1755 1756 #endif 1757 1758 /* Run the makedev script to create devices */ 1759 switch ((pid = fork())) { 1760 case 0: 1761 (void)dup2(2, 1); /* Give the script stdout */ 1762 if (chdir("/dev") == 0) 1763 (void)execl(INIT_BSHELL, "sh", 1764 access("./MAKEDEV", X_OK) == 0 1765 ? "./MAKEDEV" : "/etc/MAKEDEV", 1766 "-MM", "init", NULL); 1767 _exit(10); 1768 /* NOTREACHED */ 1769 1770 case -1: 1771 break; 1772 1773 default: 1774 if (waitpid(pid, &status, 0) == -1) 1775 break; 1776 if (status != 0) 1777 warn("MAKEDEV exit status %d", status); 1778 /* 1779 * If /dev/console got created, then return 0 1780 * regardless of MAKEDEV exit status. 1781 */ 1782 if (access(_PATH_CONSOLE, F_OK) == 0) 1783 return 0; 1784 _exit(11); 1785 } 1786 warn("Unable to run MAKEDEV"); 1787 _exit(12); 1788 } 1789 #endif 1790 1791 #ifndef LETS_GET_SMALL 1792 static int 1793 do_setttyent(void) 1794 { 1795 (void)endttyent(); 1796 #ifdef CHROOT 1797 if (did_multiuser_chroot) { 1798 char path[PATH_MAX]; 1799 1800 (void)snprintf(path, sizeof(path), "%s/%s", rootdir, _PATH_TTYS); 1801 1802 return setttyentpath(path); 1803 } else 1804 #endif /* CHROOT */ 1805 return setttyent(); 1806 } 1807 #endif 1808 1809 #if !defined(LETS_GET_SMALL) && defined(CHROOT) 1810 1811 static int 1812 createsysctlnode(void) 1813 { 1814 struct sysctlnode node; 1815 int mib[2]; 1816 size_t len; 1817 1818 /* 1819 * Create top-level dynamic sysctl node. Its child nodes will only 1820 * be readable by the superuser, since regular mortals should not 1821 * care ("Sssh, it's a secret!"). 1822 */ 1823 len = sizeof(struct sysctlnode); 1824 mib[0] = CTL_CREATE; 1825 1826 (void)memset(&node, 0, len); 1827 node.sysctl_flags = SYSCTL_VERSION | CTLFLAG_READWRITE | 1828 CTLFLAG_PRIVATE | CTLTYPE_NODE; 1829 node.sysctl_num = CTL_CREATE; 1830 (void)snprintf(node.sysctl_name, SYSCTL_NAMELEN, "init"); 1831 if (sysctl(&mib[0], 1, &node, &len, &node, len) == -1) { 1832 warning("could not create init node: %m"); 1833 return -1; 1834 } 1835 1836 /* 1837 * Create second level dynamic node capable of holding pathname. 1838 * Provide "/" as the default value. 1839 */ 1840 len = sizeof(struct sysctlnode); 1841 mib[0] = node.sysctl_num; 1842 mib[1] = CTL_CREATE; 1843 1844 (void)memset(&node, 0, len); 1845 node.sysctl_flags = SYSCTL_VERSION | CTLFLAG_READWRITE | 1846 CTLTYPE_STRING | CTLFLAG_OWNDATA; 1847 node.sysctl_size = _POSIX_PATH_MAX; 1848 node.sysctl_data = __UNCONST("/"); 1849 node.sysctl_num = CTL_CREATE; 1850 (void)snprintf(node.sysctl_name, SYSCTL_NAMELEN, "root"); 1851 if (sysctl(&mib[0], 2, NULL, NULL, &node, len) == -1) { 1852 warning("could not create init.root node: %m"); 1853 return -1; 1854 } 1855 1856 return 0; 1857 } 1858 1859 static int 1860 shouldchroot(void) 1861 { 1862 struct sysctlnode node; 1863 size_t len, cnt; 1864 int mib; 1865 1866 len = sizeof(struct sysctlnode); 1867 1868 if (sysctlbyname("init.root", rootdir, &len, NULL, 0) == -1) { 1869 warning("could not read init.root: %m"); 1870 1871 /* Child killed our node. Recreate it. */ 1872 if (errno == ENOENT) { 1873 /* Destroy whatever is left, recreate from scratch. */ 1874 if (sysctlnametomib("init", &mib, &cnt) != -1) { 1875 (void)memset(&node, 0, sizeof(node)); 1876 node.sysctl_flags = SYSCTL_VERSION; 1877 node.sysctl_num = mib; 1878 mib = CTL_DESTROY; 1879 1880 (void)sysctl(&mib, 1, NULL, NULL, &node, 1881 sizeof(node)); 1882 } 1883 1884 (void)createsysctlnode(); 1885 } 1886 1887 /* We certainly won't chroot. */ 1888 return 0; 1889 } 1890 1891 if (rootdir[len] != '\0' || strlen(rootdir) != len - 1) { 1892 warning("init.root is not a string"); 1893 return 0; 1894 } 1895 1896 if (strcmp(rootdir, "/") == 0) 1897 return 0; 1898 1899 return 1; 1900 } 1901 1902 #endif /* !LETS_GET_SMALL && CHROOT */ 1903