1 /* $NetBSD: init.c,v 1.68 2004/10/12 10:08:09 dan 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\n" 38 " The Regents of the University of California. All rights reserved.\n"); 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.68 2004/10/12 10:08:09 dan 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 <sys/sysctl.h> 56 #include <machine/cpu.h> 57 58 #include <db.h> 59 #include <errno.h> 60 #include <fcntl.h> 61 #include <signal.h> 62 #include <stdio.h> 63 #include <stdlib.h> 64 #include <string.h> 65 #include <syslog.h> 66 #include <time.h> 67 #include <ttyent.h> 68 #include <unistd.h> 69 #include <util.h> 70 #include <paths.h> 71 #include <err.h> 72 73 #include <stdarg.h> 74 75 #ifdef SECURE 76 #include <pwd.h> 77 #endif 78 79 #include "pathnames.h" 80 81 #define XSTR(x) #x 82 #define STR(x) XSTR(x) 83 84 /* 85 * Sleep times; used to prevent thrashing. 86 */ 87 #define GETTY_SPACING 5 /* N secs minimum getty spacing */ 88 #define GETTY_SLEEP 30 /* sleep N secs after spacing problem */ 89 #define WINDOW_WAIT 3 /* wait N secs after starting window */ 90 #define STALL_TIMEOUT 30 /* wait N secs after warning */ 91 #define DEATH_WATCH 10 /* wait N secs for procs to die */ 92 93 const struct timespec dtrtime = {.tv_sec = 0, .tv_nsec = 250000}; 94 95 #if defined(RESCUEDIR) 96 #define INIT_BSHELL RESCUEDIR "/sh" 97 #define INIT_MOUNT_MFS RESCUEDIR "/mount_mfs" 98 #define INIT_PATH RESCUEDIR ":" _PATH_STDPATH 99 #else 100 #define INIT_BSHELL _PATH_BSHELL 101 #define INIT_MOUNT_MFS "/sbin/mount_mfs" 102 #define INIT_PATH _PATH_STDPATH 103 #endif 104 105 int main(int, char *[]); 106 107 void handle(sig_t, ...); 108 void delset(sigset_t *, ...); 109 110 void stall(const char *, ...) 111 __attribute__((__format__(__printf__,1,2))); 112 void warning(const char *, ...) 113 __attribute__((__format__(__printf__,1,2))); 114 void emergency(const char *, ...) 115 __attribute__((__format__(__printf__,1,2))); 116 void disaster(int); 117 void badsys(int); 118 119 /* 120 * We really need a recursive typedef... 121 * The following at least guarantees that the return type of (*state_t)() 122 * is sufficiently wide to hold a function pointer. 123 */ 124 typedef long (*state_func_t)(void); 125 typedef state_func_t (*state_t)(void); 126 127 state_func_t single_user(void); 128 state_func_t runcom(void); 129 state_func_t read_ttys(void); 130 state_func_t multi_user(void); 131 state_func_t clean_ttys(void); 132 state_func_t catatonia(void); 133 state_func_t death(void); 134 135 enum { AUTOBOOT, FASTBOOT } runcom_mode = AUTOBOOT; 136 137 void transition(state_t); 138 #ifndef LETS_GET_SMALL 139 state_t requested_transition = runcom; 140 #else /* LETS_GET_SMALL */ 141 state_t requested_transition = single_user; 142 #endif /* LETS_GET_SMALL */ 143 144 void setctty(const char *); 145 146 typedef struct init_session { 147 int se_index; /* index of entry in ttys file */ 148 pid_t se_process; /* controlling process */ 149 time_t se_started; /* used to avoid thrashing */ 150 int se_flags; /* status of session */ 151 #define SE_SHUTDOWN 0x1 /* session won't be restarted */ 152 #define SE_PRESENT 0x2 /* session is in /etc/ttys */ 153 char *se_device; /* filename of port */ 154 char *se_getty; /* what to run on that port */ 155 char **se_getty_argv; /* pre-parsed argument array */ 156 char *se_window; /* window system (started only once) */ 157 char **se_window_argv; /* pre-parsed argument array */ 158 struct init_session *se_prev; 159 struct init_session *se_next; 160 } session_t; 161 162 void free_session(session_t *); 163 session_t *new_session(session_t *, int, struct ttyent *); 164 session_t *sessions; 165 166 char **construct_argv(char *); 167 void start_window_system(session_t *); 168 void collect_child(pid_t, int); 169 pid_t start_getty(session_t *); 170 void transition_handler(int); 171 void alrm_handler(int); 172 void setsecuritylevel(int); 173 int getsecuritylevel(void); 174 int setupargv(session_t *, struct ttyent *); 175 int clang; 176 177 #ifndef LETS_GET_SMALL 178 void clear_session_logs(session_t *, int); 179 #endif 180 181 int start_session_db(void); 182 void add_session(session_t *); 183 void del_session(session_t *); 184 session_t *find_session(pid_t); 185 DB *session_db; 186 187 #ifdef MFS_DEV_IF_NO_CONSOLE 188 189 #define NINODE 896 190 #define FSSIZE ((8192 /* boot area */ \ 191 + 2 * 8192 /* two copies of superblock */ \ 192 + 4096 /* cylinder group info */ \ 193 + NINODE * (128 + 18) /* inode and directory entry */ \ 194 + mfile[0].len /* size of MAKEDEV file */ \ 195 + 2 * 4096) / 512) /* some slack */ 196 197 struct mappedfile { 198 const char *path; 199 char *buf; 200 int len; 201 } mfile[] = { 202 { "/dev/MAKEDEV", NULL, 0 }, 203 { "/dev/MAKEDEV.local", NULL, 0 } 204 }; 205 206 static int mfs_dev(void); 207 static void mapfile(struct mappedfile *); 208 static void writefile(struct mappedfile *); 209 210 #endif 211 212 /* 213 * The mother of all processes. 214 */ 215 int 216 main(int argc, char **argv) 217 { 218 struct sigaction sa; 219 sigset_t mask; 220 #ifndef LETS_GET_SMALL 221 int c; 222 223 /* Dispose of random users. */ 224 if (getuid() != 0) { 225 errno = EPERM; 226 err(1, NULL); 227 } 228 229 /* System V users like to reexec init. */ 230 if (getpid() != 1) 231 errx(1, "already running"); 232 #endif 233 234 /* 235 * Create an initial session. 236 */ 237 if (setsid() < 0) 238 warn("initial setsid() failed"); 239 240 /* 241 * Establish an initial user so that programs running 242 * single user do not freak out and die (like passwd). 243 */ 244 if (setlogin("root") < 0) 245 warn("setlogin() failed"); 246 247 248 #ifdef MFS_DEV_IF_NO_CONSOLE 249 if (mfs_dev() == -1) 250 requested_transition = single_user; 251 #endif 252 253 #ifndef LETS_GET_SMALL 254 /* 255 * Note that this does NOT open a file... 256 * Does 'init' deserve its own facility number? 257 */ 258 openlog("init", LOG_CONS, LOG_AUTH); 259 #endif /* LETS_GET_SMALL */ 260 261 262 #ifndef LETS_GET_SMALL 263 /* 264 * This code assumes that we always get arguments through flags, 265 * never through bits set in some random machine register. 266 */ 267 while ((c = getopt(argc, argv, "sf")) != -1) 268 switch (c) { 269 case 's': 270 requested_transition = single_user; 271 break; 272 case 'f': 273 runcom_mode = FASTBOOT; 274 break; 275 default: 276 warning("unrecognized flag '-%c'", c); 277 break; 278 } 279 280 if (optind != argc) 281 warning("ignoring excess arguments"); 282 #else /* LETS_GET_SMALL */ 283 requested_transition = single_user; 284 #endif /* LETS_GET_SMALL */ 285 286 /* 287 * We catch or block signals rather than ignore them, 288 * so that they get reset on exec. 289 */ 290 handle(badsys, SIGSYS, 0); 291 handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, 292 SIGBUS, SIGXCPU, SIGXFSZ, 0); 293 handle(transition_handler, SIGHUP, SIGTERM, SIGTSTP, 0); 294 handle(alrm_handler, SIGALRM, 0); 295 (void)sigfillset(&mask); 296 delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS, 297 SIGXCPU, SIGXFSZ, SIGHUP, SIGTERM, SIGTSTP, SIGALRM, 0); 298 (void)sigprocmask(SIG_SETMASK, &mask, NULL); 299 (void)sigemptyset(&sa.sa_mask); 300 sa.sa_flags = 0; 301 sa.sa_handler = SIG_IGN; 302 (void)sigaction(SIGTTIN, &sa, NULL); 303 (void)sigaction(SIGTTOU, &sa, NULL); 304 305 /* 306 * Paranoia. 307 */ 308 (void)close(0); 309 (void)close(1); 310 (void)close(2); 311 312 /* 313 * Start the state machine. 314 */ 315 transition(requested_transition); 316 317 /* 318 * Should never reach here. 319 */ 320 return 1; 321 } 322 323 /* 324 * Associate a function with a signal handler. 325 */ 326 void 327 handle(sig_t handler, ...) 328 { 329 int sig; 330 struct sigaction sa; 331 sigset_t mask_everything; 332 va_list ap; 333 334 va_start(ap, handler); 335 336 sa.sa_handler = handler; 337 (void)sigfillset(&mask_everything); 338 339 while ((sig = va_arg(ap, int)) != 0) { 340 sa.sa_mask = mask_everything; 341 /* XXX SA_RESTART? */ 342 sa.sa_flags = sig == SIGCHLD ? SA_NOCLDSTOP : 0; 343 (void)sigaction(sig, &sa, NULL); 344 } 345 va_end(ap); 346 } 347 348 /* 349 * Delete a set of signals from a mask. 350 */ 351 void 352 delset(sigset_t *maskp, ...) 353 { 354 int sig; 355 va_list ap; 356 357 va_start(ap, maskp); 358 359 while ((sig = va_arg(ap, int)) != 0) 360 (void)sigdelset(maskp, sig); 361 va_end(ap); 362 } 363 364 /* 365 * Log a message and sleep for a while (to give someone an opportunity 366 * to read it and to save log or hardcopy output if the problem is chronic). 367 * NB: should send a message to the session logger to avoid blocking. 368 */ 369 void 370 stall(const char *message, ...) 371 { 372 va_list ap; 373 374 va_start(ap, message); 375 vsyslog(LOG_ALERT, message, ap); 376 va_end(ap); 377 closelog(); 378 (void)sleep(STALL_TIMEOUT); 379 } 380 381 /* 382 * Like stall(), but doesn't sleep. 383 * If cpp had variadic macros, the two functions could be #defines for another. 384 * NB: should send a message to the session logger to avoid blocking. 385 */ 386 void 387 warning(const char *message, ...) 388 { 389 va_list ap; 390 391 va_start(ap, message); 392 vsyslog(LOG_ALERT, message, ap); 393 va_end(ap); 394 closelog(); 395 } 396 397 /* 398 * Log an emergency message. 399 * NB: should send a message to the session logger to avoid blocking. 400 */ 401 void 402 emergency(const char *message, ...) 403 { 404 va_list ap; 405 406 va_start(ap, message); 407 vsyslog(LOG_EMERG, message, ap); 408 va_end(ap); 409 closelog(); 410 } 411 412 /* 413 * Catch a SIGSYS signal. 414 * 415 * These may arise if a system does not support sysctl. 416 * We tolerate up to 25 of these, then throw in the towel. 417 */ 418 void 419 badsys(int sig) 420 { 421 static int badcount = 0; 422 423 if (badcount++ < 25) 424 return; 425 disaster(sig); 426 } 427 428 /* 429 * Catch an unexpected signal. 430 */ 431 void 432 disaster(int sig) 433 { 434 435 emergency("fatal signal: %s", strsignal(sig)); 436 (void)sleep(STALL_TIMEOUT); 437 _exit(sig); /* reboot */ 438 } 439 440 /* 441 * Get the security level of the kernel. 442 */ 443 int 444 getsecuritylevel(void) 445 { 446 #ifdef KERN_SECURELVL 447 int name[2], curlevel; 448 size_t len; 449 450 name[0] = CTL_KERN; 451 name[1] = KERN_SECURELVL; 452 len = sizeof curlevel; 453 if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) { 454 emergency("cannot get kernel security level: %m"); 455 return (-1); 456 } 457 return (curlevel); 458 #else 459 return (-1); 460 #endif 461 } 462 463 /* 464 * Set the security level of the kernel. 465 */ 466 void 467 setsecuritylevel(int newlevel) 468 { 469 #ifdef KERN_SECURELVL 470 int name[2], curlevel; 471 472 curlevel = getsecuritylevel(); 473 if (newlevel == curlevel) 474 return; 475 name[0] = CTL_KERN; 476 name[1] = KERN_SECURELVL; 477 if (sysctl(name, 2, NULL, NULL, &newlevel, sizeof newlevel) == -1) { 478 emergency( "cannot change kernel security level from" 479 " %d to %d: %m", curlevel, newlevel); 480 return; 481 } 482 #ifdef SECURE 483 warning("kernel security level changed from %d to %d", 484 curlevel, newlevel); 485 #endif 486 #endif 487 } 488 489 /* 490 * Change states in the finite state machine. 491 * The initial state is passed as an argument. 492 */ 493 void 494 transition(state_t s) 495 { 496 497 if (s == NULL) 498 return; 499 for (;;) 500 s = (state_t)(*s)(); 501 } 502 503 #ifndef LETS_GET_SMALL 504 /* 505 * Close out the accounting files for a login session. 506 * NB: should send a message to the session logger to avoid blocking. 507 */ 508 void 509 clear_session_logs(session_t *sp, int status) 510 { 511 char *line = sp->se_device + sizeof(_PATH_DEV) - 1; 512 513 #ifdef SUPPORT_UTMPX 514 if (logoutx(line, status, DEAD_PROCESS)) 515 logwtmpx(line, "", "", status, DEAD_PROCESS); 516 #endif 517 #ifdef SUPPORT_UTMP 518 if (logout(line)) 519 logwtmp(line, "", ""); 520 #endif 521 } 522 #endif 523 524 /* 525 * Start a session and allocate a controlling terminal. 526 * Only called by children of init after forking. 527 */ 528 void 529 setctty(const char *name) 530 { 531 int fd; 532 533 (void) revoke(name); 534 nanosleep(&dtrtime, NULL); /* leave DTR low for a bit */ 535 if ((fd = open(name, O_RDWR)) == -1) { 536 stall("can't open %s: %m", name); 537 _exit(1); 538 } 539 if (login_tty(fd) == -1) { 540 stall("can't get %s for controlling terminal: %m", name); 541 _exit(1); 542 } 543 } 544 545 /* 546 * Bring the system up single user. 547 */ 548 state_func_t 549 single_user(void) 550 { 551 pid_t pid, wpid; 552 int status; 553 int from_securitylevel; 554 sigset_t mask; 555 struct sigaction sa, satstp, sahup; 556 #ifdef ALTSHELL 557 const char *shell = INIT_BSHELL; 558 #endif 559 char *argv[2]; 560 #ifdef SECURE 561 struct ttyent *typ; 562 struct passwd *pp; 563 char *clear, *password; 564 #endif 565 #ifdef ALTSHELL 566 char altshell[128]; 567 #endif /* ALTSHELL */ 568 569 /* 570 * If the kernel is in secure mode, downgrade it to insecure mode. 571 */ 572 from_securitylevel = getsecuritylevel(); 573 if (from_securitylevel > 0) 574 setsecuritylevel(0); 575 576 (void)sigemptyset(&sa.sa_mask); 577 sa.sa_flags = 0; 578 sa.sa_handler = SIG_IGN; 579 (void)sigaction(SIGTSTP, &sa, &satstp); 580 (void)sigaction(SIGHUP, &sa, &sahup); 581 if ((pid = fork()) == 0) { 582 /* 583 * Start the single user session. 584 */ 585 if (access(_PATH_CONSTTY, F_OK) == 0) 586 setctty(_PATH_CONSTTY); 587 else 588 setctty(_PATH_CONSOLE); 589 590 #ifdef SECURE 591 /* 592 * Check the root password. 593 * We don't care if the console is 'on' by default; 594 * it's the only tty that can be 'off' and 'secure'. 595 */ 596 typ = getttynam("console"); 597 pp = getpwnam("root"); 598 if (typ && (from_securitylevel >=2 || (typ->ty_status 599 & TTY_SECURE) == 0) && pp && *pp->pw_passwd != '\0') { 600 (void)fprintf(stderr, 601 "Enter root password, or ^D to go multi-user\n"); 602 for (;;) { 603 clear = getpass("Password:"); 604 if (clear == 0 || *clear == '\0') 605 _exit(0); 606 password = crypt(clear, pp->pw_passwd); 607 (void)memset(clear, 0, _PASSWORD_LEN); 608 if (strcmp(password, pp->pw_passwd) == 0) 609 break; 610 warning("single-user login failed\n"); 611 } 612 } 613 endttyent(); 614 endpwent(); 615 #endif /* SECURE */ 616 617 #ifdef ALTSHELL 618 (void)fprintf(stderr, 619 "Enter pathname of shell or RETURN for %s: ", shell); 620 if (fgets(altshell, sizeof(altshell), stdin) == NULL) { 621 altshell[0] = '\0'; 622 } else { 623 /* nuke \n */ 624 char *p; 625 626 if ((p = strchr(altshell, '\n')) != NULL) 627 *p = '\0'; 628 } 629 630 if (altshell[0]) 631 shell = altshell; 632 #endif /* ALTSHELL */ 633 634 /* 635 * Unblock signals. 636 * We catch all the interesting ones, 637 * and those are reset to SIG_DFL on exec. 638 */ 639 (void)sigemptyset(&mask); 640 (void)sigprocmask(SIG_SETMASK, &mask, NULL); 641 642 /* 643 * Fire off a shell. 644 * If the default one doesn't work, try the Bourne shell. 645 */ 646 argv[0] = "-sh"; 647 argv[1] = 0; 648 setenv("PATH", INIT_PATH, 1); 649 #ifdef ALTSHELL 650 if (altshell[0]) 651 argv[0] = altshell; 652 (void)execv(shell, argv); 653 emergency("can't exec %s for single user: %m", shell); 654 argv[0] = "-sh"; 655 #endif /* ALTSHELL */ 656 (void)execv(INIT_BSHELL, argv); 657 emergency("can't exec %s for single user: %m", INIT_BSHELL); 658 (void)sleep(STALL_TIMEOUT); 659 _exit(1); 660 } 661 662 if (pid == -1) { 663 /* 664 * We are seriously hosed. Do our best. 665 */ 666 emergency("can't fork single-user shell, trying again"); 667 while (waitpid(-1, NULL, WNOHANG) > 0) 668 continue; 669 (void)sigaction(SIGTSTP, &satstp, NULL); 670 (void)sigaction(SIGHUP, &sahup, NULL); 671 return (state_func_t) single_user; 672 } 673 674 requested_transition = 0; 675 do { 676 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) 677 collect_child(wpid, status); 678 if (wpid == -1) { 679 if (errno == EINTR) 680 continue; 681 warning("wait for single-user shell failed: %m; " 682 "restarting"); 683 return (state_func_t)single_user; 684 } 685 if (wpid == pid && WIFSTOPPED(status)) { 686 warning("init: shell stopped, restarting\n"); 687 kill(pid, SIGCONT); 688 wpid = -1; 689 } 690 } while (wpid != pid && !requested_transition); 691 692 if (requested_transition) { 693 (void)sigaction(SIGTSTP, &satstp, NULL); 694 (void)sigaction(SIGHUP, &sahup, NULL); 695 return (state_func_t)requested_transition; 696 } 697 698 if (WIFSIGNALED(status)) { 699 if (WTERMSIG(status) == SIGKILL) { 700 /* executed /sbin/reboot; wait for the end quietly */ 701 sigset_t s; 702 703 (void)sigfillset(&s); 704 for (;;) 705 (void)sigsuspend(&s); 706 } else { 707 warning("single user shell terminated, restarting"); 708 (void)sigaction(SIGTSTP, &satstp, NULL); 709 (void)sigaction(SIGHUP, &sahup, NULL); 710 return (state_func_t) single_user; 711 } 712 } 713 714 runcom_mode = FASTBOOT; 715 (void)sigaction(SIGTSTP, &satstp, NULL); 716 (void)sigaction(SIGHUP, &sahup, NULL); 717 #ifndef LETS_GET_SMALL 718 return (state_func_t) runcom; 719 #else /* LETS_GET_SMALL */ 720 return (state_func_t) single_user; 721 #endif /* LETS_GET_SMALL */ 722 } 723 724 #ifndef LETS_GET_SMALL 725 /* 726 * Run the system startup script. 727 */ 728 state_func_t 729 runcom(void) 730 { 731 pid_t pid, wpid; 732 int status; 733 char *argv[4]; 734 struct sigaction sa; 735 736 switch ((pid = fork())) { 737 case 0: 738 (void)sigemptyset(&sa.sa_mask); 739 sa.sa_flags = 0; 740 sa.sa_handler = SIG_IGN; 741 (void)sigaction(SIGTSTP, &sa, NULL); 742 (void)sigaction(SIGHUP, &sa, NULL); 743 744 setctty(_PATH_CONSOLE); 745 746 argv[0] = "sh"; 747 argv[1] = _PATH_RUNCOM; 748 argv[2] = runcom_mode == AUTOBOOT ? "autoboot" : 0; 749 argv[3] = 0; 750 751 (void)sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL); 752 753 (void)execv(INIT_BSHELL, argv); 754 stall("can't exec %s for %s: %m", INIT_BSHELL, _PATH_RUNCOM); 755 _exit(1); /* force single user mode */ 756 /*NOTREACHED*/ 757 case -1: 758 emergency("can't fork for %s on %s: %m", INIT_BSHELL, 759 _PATH_RUNCOM); 760 while (waitpid(-1, NULL, WNOHANG) > 0) 761 continue; 762 (void)sleep(STALL_TIMEOUT); 763 return (state_func_t)single_user; 764 default: 765 break; 766 } 767 768 /* 769 * Copied from single_user(). This is a bit paranoid. 770 */ 771 do { 772 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) 773 collect_child(wpid, status); 774 if (wpid == -1) { 775 if (errno == EINTR) 776 continue; 777 warning("wait for %s on %s failed: %m; going to " 778 "single user mode", INIT_BSHELL, _PATH_RUNCOM); 779 return (state_func_t)single_user; 780 } 781 if (wpid == pid && WIFSTOPPED(status)) { 782 warning("init: %s on %s stopped, restarting\n", 783 INIT_BSHELL, _PATH_RUNCOM); 784 (void)kill(pid, SIGCONT); 785 wpid = -1; 786 } 787 } while (wpid != pid); 788 789 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM && 790 requested_transition == catatonia) { 791 /* /etc/rc executed /sbin/reboot; wait for the end quietly */ 792 sigset_t s; 793 794 (void)sigfillset(&s); 795 for (;;) 796 (void)sigsuspend(&s); 797 } 798 799 if (!WIFEXITED(status)) { 800 warning("%s on %s terminated abnormally, going to " 801 "single user mode", INIT_BSHELL, _PATH_RUNCOM); 802 return (state_func_t)single_user; 803 } 804 805 if (WEXITSTATUS(status)) 806 return (state_func_t)single_user; 807 808 runcom_mode = AUTOBOOT; /* the default */ 809 /* NB: should send a message to the session logger to avoid blocking. */ 810 #ifdef SUPPORT_UTMPX 811 logwtmpx("~", "reboot", "", 0, INIT_PROCESS); 812 #endif 813 #ifdef SUPPORT_UTMP 814 logwtmp("~", "reboot", ""); 815 #endif 816 return (state_func_t) read_ttys; 817 } 818 819 /* 820 * Open the session database. 821 * 822 * NB: We could pass in the size here; is it necessary? 823 */ 824 int 825 start_session_db(void) 826 { 827 828 if (session_db && (*session_db->close)(session_db)) 829 emergency("session database close: %m"); 830 if ((session_db = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL)) == 0) { 831 emergency("session database open: %m"); 832 return (1); 833 } 834 return (0); 835 836 } 837 838 /* 839 * Add a new login session. 840 */ 841 void 842 add_session(session_t *sp) 843 { 844 DBT key; 845 DBT data; 846 847 if (session_db == NULL) 848 return; 849 850 key.data = &sp->se_process; 851 key.size = sizeof sp->se_process; 852 data.data = &sp; 853 data.size = sizeof sp; 854 855 if ((*session_db->put)(session_db, &key, &data, 0)) 856 emergency("insert %d: %m", sp->se_process); 857 } 858 859 /* 860 * Delete an old login session. 861 */ 862 void 863 del_session(session_t *sp) 864 { 865 DBT key; 866 867 key.data = &sp->se_process; 868 key.size = sizeof sp->se_process; 869 870 if ((*session_db->del)(session_db, &key, 0)) 871 emergency("delete %d: %m", sp->se_process); 872 } 873 874 /* 875 * Look up a login session by pid. 876 */ 877 session_t * 878 find_session(pid_t pid) 879 { 880 DBT key; 881 DBT data; 882 session_t *ret; 883 884 if (session_db == NULL) 885 return NULL; 886 887 key.data = &pid; 888 key.size = sizeof pid; 889 if ((*session_db->get)(session_db, &key, &data, 0) != 0) 890 return 0; 891 (void)memmove(&ret, data.data, sizeof(ret)); 892 return ret; 893 } 894 895 /* 896 * Construct an argument vector from a command line. 897 */ 898 char ** 899 construct_argv(char *command) 900 { 901 int argc = 0; 902 char **argv = malloc(((strlen(command) + 1) / 2 + 1) * sizeof (char *)); 903 static const char separators[] = " \t"; 904 905 if ((argv[argc++] = strtok(command, separators)) == 0) 906 return (NULL); 907 while ((argv[argc++] = strtok(NULL, separators)) != NULL) 908 continue; 909 return (argv); 910 } 911 912 /* 913 * Deallocate a session descriptor. 914 */ 915 void 916 free_session(session_t *sp) 917 { 918 919 free(sp->se_device); 920 if (sp->se_getty) { 921 free(sp->se_getty); 922 free(sp->se_getty_argv); 923 } 924 if (sp->se_window) { 925 free(sp->se_window); 926 free(sp->se_window_argv); 927 } 928 free(sp); 929 } 930 931 /* 932 * Allocate a new session descriptor. 933 */ 934 session_t * 935 new_session(session_t *sprev, int session_index, struct ttyent *typ) 936 { 937 session_t *sp; 938 939 if ((typ->ty_status & TTY_ON) == 0 || typ->ty_name == NULL || 940 typ->ty_getty == NULL) 941 return (NULL); 942 943 sp = malloc(sizeof (session_t)); 944 if (sp == NULL) 945 return NULL; 946 memset(sp, 0, sizeof *sp); 947 948 sp->se_flags = SE_PRESENT; 949 sp->se_index = session_index; 950 951 (void)asprintf(&sp->se_device, "%s%s", _PATH_DEV, typ->ty_name); 952 if (!sp->se_device) 953 return NULL; 954 955 if (setupargv(sp, typ) == 0) { 956 free_session(sp); 957 return (NULL); 958 } 959 960 sp->se_next = NULL; 961 if (sprev == NULL) { 962 sessions = sp; 963 sp->se_prev = NULL; 964 } else { 965 sprev->se_next = sp; 966 sp->se_prev = sprev; 967 } 968 969 return (sp); 970 } 971 972 /* 973 * Calculate getty and if useful window argv vectors. 974 */ 975 int 976 setupargv(session_t *sp, struct ttyent *typ) 977 { 978 979 if (sp->se_getty) { 980 free(sp->se_getty); 981 free(sp->se_getty_argv); 982 } 983 (void)asprintf(&sp->se_getty, "%s %s", typ->ty_getty, typ->ty_name); 984 if (!sp->se_getty) 985 return (0); 986 sp->se_getty_argv = construct_argv(sp->se_getty); 987 if (sp->se_getty_argv == NULL) { 988 warning("can't parse getty for port %s", sp->se_device); 989 free(sp->se_getty); 990 sp->se_getty = NULL; 991 return (0); 992 } 993 if (typ->ty_window) { 994 if (sp->se_window) 995 free(sp->se_window); 996 sp->se_window = strdup(typ->ty_window); 997 sp->se_window_argv = construct_argv(sp->se_window); 998 if (sp->se_window_argv == NULL) { 999 warning("can't parse window for port %s", 1000 sp->se_device); 1001 free(sp->se_window); 1002 sp->se_window = NULL; 1003 return (0); 1004 } 1005 } 1006 return (1); 1007 } 1008 1009 /* 1010 * Walk the list of ttys and create sessions for each active line. 1011 */ 1012 state_func_t 1013 read_ttys(void) 1014 { 1015 int session_index = 0; 1016 session_t *sp, *snext; 1017 struct ttyent *typ; 1018 1019 /* 1020 * Destroy any previous session state. 1021 * There shouldn't be any, but just in case... 1022 */ 1023 for (sp = sessions; sp; sp = snext) { 1024 #ifndef LETS_GET_SMALL 1025 if (sp->se_process) 1026 clear_session_logs(sp, 0); 1027 #endif 1028 snext = sp->se_next; 1029 free_session(sp); 1030 } 1031 sessions = NULL; 1032 if (start_session_db()) 1033 return (state_func_t)single_user; 1034 1035 /* 1036 * Allocate a session entry for each active port. 1037 * Note that sp starts at 0. 1038 */ 1039 while ((typ = getttyent()) != NULL) 1040 if ((snext = new_session(sp, ++session_index, typ)) != NULL) 1041 sp = snext; 1042 1043 endttyent(); 1044 1045 return (state_func_t)multi_user; 1046 } 1047 1048 /* 1049 * Start a window system running. 1050 */ 1051 void 1052 start_window_system(session_t *sp) 1053 { 1054 pid_t pid; 1055 sigset_t mask; 1056 1057 if ((pid = fork()) == -1) { 1058 emergency("can't fork for window system on port %s: %m", 1059 sp->se_device); 1060 /* hope that getty fails and we can try again */ 1061 return; 1062 } 1063 1064 if (pid) 1065 return; 1066 1067 sigemptyset(&mask); 1068 sigprocmask(SIG_SETMASK, &mask, NULL); 1069 1070 if (setsid() < 0) 1071 emergency("setsid failed (window) %m"); 1072 1073 (void)execv(sp->se_window_argv[0], sp->se_window_argv); 1074 stall("can't exec window system '%s' for port %s: %m", 1075 sp->se_window_argv[0], sp->se_device); 1076 _exit(1); 1077 } 1078 1079 /* 1080 * Start a login session running. 1081 */ 1082 pid_t 1083 start_getty(session_t *sp) 1084 { 1085 pid_t pid; 1086 sigset_t mask; 1087 time_t current_time = time(NULL); 1088 1089 /* 1090 * fork(), not vfork() -- we can't afford to block. 1091 */ 1092 if ((pid = fork()) == -1) { 1093 emergency("can't fork for getty on port %s: %m", sp->se_device); 1094 return -1; 1095 } 1096 1097 if (pid) 1098 return pid; 1099 1100 if (current_time > sp->se_started && 1101 current_time - sp->se_started < GETTY_SPACING) { 1102 warning("getty repeating too quickly on port %s, sleeping", 1103 sp->se_device); 1104 (void)sleep(GETTY_SLEEP); 1105 } 1106 1107 if (sp->se_window) { 1108 start_window_system(sp); 1109 (void)sleep(WINDOW_WAIT); 1110 } 1111 1112 (void)sigemptyset(&mask); 1113 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); 1114 1115 (void)execv(sp->se_getty_argv[0], sp->se_getty_argv); 1116 stall("can't exec getty '%s' for port %s: %m", 1117 sp->se_getty_argv[0], sp->se_device); 1118 _exit(1); 1119 /*NOTREACHED*/ 1120 } 1121 #endif /* LETS_GET_SMALL */ 1122 1123 /* 1124 * Collect exit status for a child. 1125 * If an exiting login, start a new login running. 1126 */ 1127 void 1128 collect_child(pid_t pid, int status) 1129 { 1130 #ifndef LETS_GET_SMALL 1131 session_t *sp, *sprev, *snext; 1132 1133 if (! sessions) 1134 return; 1135 1136 if ((sp = find_session(pid)) == NULL) 1137 return; 1138 1139 clear_session_logs(sp, status); 1140 del_session(sp); 1141 sp->se_process = 0; 1142 1143 if (sp->se_flags & SE_SHUTDOWN) { 1144 if ((sprev = sp->se_prev) != NULL) 1145 sprev->se_next = sp->se_next; 1146 else 1147 sessions = sp->se_next; 1148 if ((snext = sp->se_next) != NULL) 1149 snext->se_prev = sp->se_prev; 1150 free_session(sp); 1151 return; 1152 } 1153 1154 if ((pid = start_getty(sp)) == -1) { 1155 /* serious trouble */ 1156 requested_transition = clean_ttys; 1157 return; 1158 } 1159 1160 sp->se_process = pid; 1161 sp->se_started = time(NULL); 1162 add_session(sp); 1163 #endif /* LETS_GET_SMALL */ 1164 } 1165 1166 /* 1167 * Catch a signal and request a state transition. 1168 */ 1169 void 1170 transition_handler(int sig) 1171 { 1172 1173 switch (sig) { 1174 #ifndef LETS_GET_SMALL 1175 case SIGHUP: 1176 requested_transition = clean_ttys; 1177 break; 1178 case SIGTERM: 1179 requested_transition = death; 1180 break; 1181 case SIGTSTP: 1182 requested_transition = catatonia; 1183 break; 1184 #endif /* LETS_GET_SMALL */ 1185 default: 1186 requested_transition = 0; 1187 break; 1188 } 1189 } 1190 1191 #ifndef LETS_GET_SMALL 1192 /* 1193 * Take the system multiuser. 1194 */ 1195 state_func_t 1196 multi_user(void) 1197 { 1198 pid_t pid; 1199 int status; 1200 session_t *sp; 1201 1202 requested_transition = 0; 1203 1204 /* 1205 * If the administrator has not set the security level to -1 1206 * to indicate that the kernel should not run multiuser in secure 1207 * mode, and the run script has not set a higher level of security 1208 * than level 1, then put the kernel into secure mode. 1209 */ 1210 if (getsecuritylevel() == 0) 1211 setsecuritylevel(1); 1212 1213 for (sp = sessions; sp; sp = sp->se_next) { 1214 if (sp->se_process) 1215 continue; 1216 if ((pid = start_getty(sp)) == -1) { 1217 /* serious trouble */ 1218 requested_transition = clean_ttys; 1219 break; 1220 } 1221 sp->se_process = pid; 1222 sp->se_started = time(NULL); 1223 add_session(sp); 1224 } 1225 1226 while (!requested_transition) 1227 if ((pid = waitpid(-1, &status, 0)) != -1) 1228 collect_child(pid, status); 1229 1230 return (state_func_t)requested_transition; 1231 } 1232 1233 /* 1234 * This is an n-squared algorithm. We hope it isn't run often... 1235 */ 1236 state_func_t 1237 clean_ttys(void) 1238 { 1239 session_t *sp, *sprev; 1240 struct ttyent *typ; 1241 int session_index = 0; 1242 int devlen; 1243 1244 for (sp = sessions; sp; sp = sp->se_next) 1245 sp->se_flags &= ~SE_PRESENT; 1246 1247 devlen = sizeof(_PATH_DEV) - 1; 1248 while ((typ = getttyent()) != NULL) { 1249 ++session_index; 1250 1251 for (sprev = 0, sp = sessions; sp; sprev = sp, sp = sp->se_next) 1252 if (strcmp(typ->ty_name, sp->se_device + devlen) == 0) 1253 break; 1254 1255 if (sp) { 1256 sp->se_flags |= SE_PRESENT; 1257 if (sp->se_index != session_index) { 1258 warning("port %s changed utmp index from " 1259 "%d to %d", sp->se_device, sp->se_index, 1260 session_index); 1261 sp->se_index = session_index; 1262 } 1263 if ((typ->ty_status & TTY_ON) == 0 || 1264 typ->ty_getty == 0) { 1265 sp->se_flags |= SE_SHUTDOWN; 1266 if (sp->se_process != 0) 1267 (void)kill(sp->se_process, SIGHUP); 1268 continue; 1269 } 1270 sp->se_flags &= ~SE_SHUTDOWN; 1271 if (setupargv(sp, typ) == 0) { 1272 warning("can't parse getty for port %s", 1273 sp->se_device); 1274 sp->se_flags |= SE_SHUTDOWN; 1275 if (sp->se_process != 0) 1276 (void)kill(sp->se_process, SIGHUP); 1277 } 1278 continue; 1279 } 1280 1281 new_session(sprev, session_index, typ); 1282 } 1283 1284 endttyent(); 1285 1286 for (sp = sessions; sp; sp = sp->se_next) 1287 if ((sp->se_flags & SE_PRESENT) == 0) { 1288 sp->se_flags |= SE_SHUTDOWN; 1289 if (sp->se_process != 0) 1290 (void)kill(sp->se_process, SIGHUP); 1291 } 1292 1293 return (state_func_t)multi_user; 1294 } 1295 1296 /* 1297 * Block further logins. 1298 */ 1299 state_func_t 1300 catatonia(void) 1301 { 1302 session_t *sp; 1303 1304 for (sp = sessions; sp; sp = sp->se_next) 1305 sp->se_flags |= SE_SHUTDOWN; 1306 1307 return (state_func_t)multi_user; 1308 } 1309 #endif /* LETS_GET_SMALL */ 1310 1311 /* 1312 * Note SIGALRM. 1313 */ 1314 void 1315 /*ARGSUSED*/ 1316 alrm_handler(int sig) 1317 { 1318 1319 clang = 1; 1320 } 1321 1322 #ifndef LETS_GET_SMALL 1323 /* 1324 * Bring the system down to single user. 1325 */ 1326 state_func_t 1327 death(void) 1328 { 1329 session_t *sp; 1330 int i, status; 1331 pid_t pid; 1332 static const int death_sigs[3] = { SIGHUP, SIGTERM, SIGKILL }; 1333 1334 for (sp = sessions; sp; sp = sp->se_next) 1335 sp->se_flags |= SE_SHUTDOWN; 1336 1337 /* NB: should send a message to the session logger to avoid blocking. */ 1338 #ifdef SUPPORT_UTMPX 1339 logwtmpx("~", "shutdown", "", 0, INIT_PROCESS); 1340 #endif 1341 #ifdef SUPPORT_UTMP 1342 logwtmp("~", "shutdown", ""); 1343 #endif 1344 1345 for (i = 0; i < 3; ++i) { 1346 if (kill(-1, death_sigs[i]) == -1 && errno == ESRCH) 1347 return (state_func_t)single_user; 1348 1349 clang = 0; 1350 alarm(DEATH_WATCH); 1351 do 1352 if ((pid = waitpid(-1, &status, 0)) != -1) 1353 collect_child(pid, status); 1354 while (clang == 0 && errno != ECHILD); 1355 1356 if (errno == ECHILD) 1357 return (state_func_t)single_user; 1358 } 1359 1360 warning("some processes would not die; ps axl advised"); 1361 1362 return (state_func_t)single_user; 1363 } 1364 #endif /* LETS_GET_SMALL */ 1365 1366 #ifdef MFS_DEV_IF_NO_CONSOLE 1367 1368 static void 1369 mapfile(struct mappedfile *mf) 1370 { 1371 int fd; 1372 struct stat st; 1373 1374 if (lstat(mf->path, &st) == -1) 1375 return; 1376 1377 if ((st.st_mode & S_IFMT) == S_IFLNK) { 1378 mf->buf = malloc(st.st_size + 1); 1379 mf->buf[st.st_size] = 0; 1380 if (readlink(mf->path, mf->buf, st.st_size) != st.st_size) 1381 return; 1382 mf->len = -1; 1383 return; 1384 } 1385 1386 if ((fd = open(mf->path, O_RDONLY)) == -1) 1387 return; 1388 mf->buf = mmap(0, (size_t)st.st_size, PROT_READ, 1389 MAP_FILE|MAP_SHARED, fd, (off_t)0); 1390 (void)close(fd); 1391 if (mf->buf == MAP_FAILED) 1392 return; 1393 mf->len = st.st_size; 1394 } 1395 1396 static void 1397 writefile(struct mappedfile *mf) 1398 { 1399 int fd; 1400 1401 if (mf->len == -1) { 1402 symlink(mf->buf, mf->path); 1403 free(mf->buf); 1404 return; 1405 } 1406 1407 if (mf->len == 0) 1408 return; 1409 fd = open(mf->path, O_WRONLY | O_CREAT | O_TRUNC, 0755); 1410 if (fd == -1) 1411 return; 1412 (void)write(fd, mf->buf, mf->len); 1413 (void)munmap(mf->buf, mf->len); 1414 (void)close(fd); 1415 } 1416 1417 static int 1418 mfs_dev(void) 1419 { 1420 /* 1421 * We cannot print errors so we bail out silently... 1422 */ 1423 pid_t pid; 1424 int status; 1425 dev_t dev; 1426 char *fs_size; 1427 #ifdef CPU_CONSDEV 1428 static int name[2] = { CTL_MACHDEP, CPU_CONSDEV }; 1429 size_t olen; 1430 #endif 1431 1432 /* If we have /dev/console, assume all is OK */ 1433 if (access(_PATH_CONSOLE, F_OK) != -1) 1434 return(0); 1435 1436 /* Grab the contents of MAKEDEV */ 1437 mapfile(&mfile[0]); 1438 1439 /* Grab the contents of MAKEDEV.local */ 1440 mapfile(&mfile[1]); 1441 1442 /* Mount an mfs over /dev so we can create devices */ 1443 switch ((pid = fork())) { 1444 case 0: 1445 asprintf(&fs_size, "%d", FSSIZE); 1446 (void)execl(INIT_MOUNT_MFS, "mount_mfs", 1447 "-b", "4096", "-f", "512", 1448 "-s", fs_size, "-n", STR(NINODE), 1449 "-p", "0755", 1450 "swap", "/dev", NULL); 1451 _exit(1); 1452 /*NOTREACHED*/ 1453 1454 case -1: 1455 return(-1); 1456 1457 default: 1458 if (waitpid(pid, &status, 0) == -1) 1459 return(-1); 1460 if (status != 0) 1461 return(-1); 1462 break; 1463 } 1464 1465 #ifdef CPU_CONSDEV 1466 olen = sizeof(dev); 1467 if (sysctl(name, sizeof(name) / sizeof(name[0]), &dev, &olen, 1468 NULL, 0) == -1) 1469 #endif 1470 dev = makedev(0, 0); 1471 1472 /* Make a console for us, so we can see things happening */ 1473 if (mknod(_PATH_CONSOLE, 0666 | S_IFCHR, dev) == -1) 1474 return(-1); 1475 1476 (void)freopen(_PATH_CONSOLE, "a", stderr); 1477 1478 warnx("Creating mfs /dev (%d blocks, %d inodes)", FSSIZE, NINODE); 1479 1480 /* Create a MAKEDEV script in the mfs /dev */ 1481 writefile(&mfile[0]); 1482 1483 /* Create a MAKEDEV.local script in the mfs /dev */ 1484 writefile(&mfile[1]); 1485 1486 /* Run the makedev script to create devices */ 1487 switch ((pid = fork())) { 1488 case 0: 1489 dup2(2, 1); /* Give the script stdout */ 1490 if (chdir("/dev") == 0) 1491 (void)execl(INIT_BSHELL, "sh", 1492 mfile[0].len ? "./MAKEDEV" : "/etc/MAKEDEV", 1493 "init", NULL); 1494 _exit(1); 1495 1496 case -1: 1497 break; 1498 1499 default: 1500 if (waitpid(pid, &status, 0) == -1) 1501 break; 1502 if (status != 0) { 1503 errno = EINVAL; 1504 break; 1505 } 1506 return 0; 1507 } 1508 warn("Unable to run MAKEDEV"); 1509 return (-1); 1510 } 1511 #endif 1512