1 /*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Donn Seeley at UUNET Technologies, Inc. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 char copyright[] = 13 "@(#) Copyright (c) 1991 The Regents of the University of California.\n\ 14 All rights reserved.\n"; 15 #endif /* not lint */ 16 17 #ifndef lint 18 static char sccsid[] = "@(#)init.c 6.15 (Berkeley) 04/28/93"; 19 #endif /* not lint */ 20 21 #include <sys/param.h> 22 #include <sys/sysctl.h> 23 #include <sys/wait.h> 24 25 #include <db.h> 26 #include <errno.h> 27 #include <fcntl.h> 28 #include <signal.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <syslog.h> 33 #include <time.h> 34 #include <ttyent.h> 35 #include <unistd.h> 36 37 #ifdef __STDC__ 38 #include <stdarg.h> 39 #else 40 #include <varargs.h> 41 #endif 42 43 #ifdef SECURE 44 #include <pwd.h> 45 #endif 46 47 #include "pathnames.h" 48 49 /* 50 * Until the mythical util.h arrives... 51 */ 52 extern int login_tty __P((int)); 53 extern int logout __P((const char *)); 54 extern void logwtmp __P((const char *, const char *, const char *)); 55 56 /* 57 * Sleep times; used to prevent thrashing. 58 */ 59 #define GETTY_SPACING 10 /* fork getty on a port every N secs */ 60 #define WINDOW_WAIT 3 /* wait N secs after starting window */ 61 #define STALL_TIMEOUT 30 /* wait N secs after warning */ 62 #define DEATH_WATCH 10 /* wait N secs for procs to die */ 63 64 void handle __P((sig_t, ...)); 65 void delset __P((sigset_t *, ...)); 66 67 void stall __P((char *, ...)); 68 void warning __P((char *, ...)); 69 void emergency __P((char *, ...)); 70 void disaster __P((int)); 71 void badsys __P((int)); 72 73 /* 74 * We really need a recursive typedef... 75 * The following at least guarantees that the return type of (*state_t)() 76 * is sufficiently wide to hold a function pointer. 77 */ 78 typedef long (*state_func_t) __P((void)); 79 typedef state_func_t (*state_t) __P((void)); 80 81 state_func_t single_user __P((void)); 82 state_func_t runcom __P((void)); 83 state_func_t read_ttys __P((void)); 84 state_func_t multi_user __P((void)); 85 state_func_t clean_ttys __P((void)); 86 state_func_t catatonia __P((void)); 87 state_func_t death __P((void)); 88 89 enum { AUTOBOOT, FASTBOOT } runcom_mode = AUTOBOOT; 90 91 void transition __P((state_t)); 92 state_t requested_transition = runcom; 93 94 void setctty __P((char *)); 95 96 typedef struct init_session { 97 int se_index; /* index of entry in ttys file */ 98 pid_t se_process; /* controlling process */ 99 time_t se_started; /* used to avoid thrashing */ 100 int se_flags; /* status of session */ 101 #define SE_SHUTDOWN 0x1 /* session won't be restarted */ 102 char *se_device; /* filename of port */ 103 char *se_getty; /* what to run on that port */ 104 char **se_getty_argv; /* pre-parsed argument array */ 105 char *se_window; /* window system (started only once) */ 106 char **se_window_argv; /* pre-parsed argument array */ 107 struct init_session *se_prev; 108 struct init_session *se_next; 109 } session_t; 110 111 void free_session __P((session_t *)); 112 session_t *new_session __P((session_t *, int, struct ttyent *)); 113 session_t *sessions; 114 115 char **construct_argv __P((char *)); 116 void start_window_system __P((session_t *)); 117 void collect_child __P((int)); 118 pid_t start_getty __P((session_t *)); 119 void transition_handler __P((int)); 120 void alrm_handler __P((int)); 121 int clang; 122 123 int start_logger __P((void)); 124 void clear_session_logs __P((session_t *)); 125 int logger_enable; 126 127 int start_session_db __P((void)); 128 void add_session __P((session_t *)); 129 void del_session __P((session_t *)); 130 session_t *find_session __P((pid_t)); 131 DB *session_db; 132 133 /* 134 * The mother of all processes. 135 */ 136 int 137 main(argc, argv) 138 int argc; 139 char **argv; 140 { 141 int c; 142 struct sigaction sa; 143 sigset_t mask; 144 145 146 /* Dispose of random users. */ 147 if (getuid() != 0) { 148 (void)fprintf(stderr, "init: %s\n", strerror(EPERM)); 149 exit (1); 150 } 151 152 /* System V users like to reexec init. */ 153 if (getpid() != 1) { 154 (void)fprintf(stderr, "init: already running\n"); 155 exit (1); 156 } 157 158 /* 159 * Note that this does NOT open a file... 160 * Does 'init' deserve its own facility number? 161 */ 162 openlog("init", LOG_CONS|LOG_ODELAY, LOG_AUTH); 163 164 /* 165 * Create an initial session. 166 */ 167 if (setsid() < 0) 168 syslog(LOG_ERR, "setsid failed (initial) %m"); 169 170 /* 171 * This code assumes that we always get arguments through flags, 172 * never through bits set in some random machine register. 173 */ 174 while ((c = getopt(argc, argv, "sf")) != -1) 175 switch (c) { 176 case 's': 177 requested_transition = single_user; 178 break; 179 case 'f': 180 runcom_mode = FASTBOOT; 181 break; 182 default: 183 warning("unrecognized flag '-%c'", c); 184 break; 185 } 186 187 if (optind != argc) 188 warning("ignoring excess arguments"); 189 190 /* 191 * We catch or block signals rather than ignore them, 192 * so that they get reset on exec. 193 */ 194 handle(badsys, SIGSYS, 0); 195 handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, 196 SIGBUS, SIGXCPU, SIGXFSZ, 0); 197 handle(transition_handler, SIGHUP, SIGTERM, SIGTSTP, 0); 198 handle(alrm_handler, SIGALRM, 0); 199 sigfillset(&mask); 200 delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS, 201 SIGXCPU, SIGXFSZ, SIGHUP, SIGTERM, SIGTSTP, SIGALRM, 0); 202 sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); 203 sigemptyset(&sa.sa_mask); 204 sa.sa_flags = 0; 205 sa.sa_handler = SIG_IGN; 206 (void) sigaction(SIGTTIN, &sa, (struct sigaction *)0); 207 (void) sigaction(SIGTTOU, &sa, (struct sigaction *)0); 208 209 /* 210 * Paranoia. 211 */ 212 close(0); 213 close(1); 214 close(2); 215 216 /* 217 * Start the state machine. 218 */ 219 transition(requested_transition); 220 221 /* 222 * Should never reach here. 223 */ 224 return 1; 225 } 226 227 /* 228 * Associate a function with a signal handler. 229 */ 230 void 231 #ifdef __STDC__ 232 handle(sig_t handler, ...) 233 #else 234 handle(va_alist) 235 va_dcl 236 #endif 237 { 238 int sig; 239 struct sigaction sa; 240 int mask_everything; 241 va_list ap; 242 #ifndef __STDC__ 243 sig_t handler; 244 245 va_start(ap); 246 handler = va_arg(ap, sig_t); 247 #else 248 va_start(ap, handler); 249 #endif 250 251 sa.sa_handler = handler; 252 sigfillset(&mask_everything); 253 254 while (sig = va_arg(ap, int)) { 255 sa.sa_mask = mask_everything; 256 /* XXX SA_RESTART? */ 257 sa.sa_flags = sig == SIGCHLD ? SA_NOCLDSTOP : 0; 258 sigaction(sig, &sa, (struct sigaction *) 0); 259 } 260 } 261 262 /* 263 * Delete a set of signals from a mask. 264 */ 265 void 266 #ifdef __STDC__ 267 delset(sigset_t *maskp, ...) 268 #else 269 delset(va_alist) 270 va_dcl 271 #endif 272 { 273 int sig; 274 va_list ap; 275 #ifndef __STDC__ 276 sigset_t *maskp; 277 278 va_start(ap); 279 maskp = va_arg(ap, sigset_t *); 280 #else 281 va_start(ap, maskp); 282 #endif 283 284 while (sig = va_arg(ap, int)) 285 sigdelset(maskp, sig); 286 } 287 288 /* 289 * Log a message and sleep for a while (to give someone an opportunity 290 * to read it and to save log or hardcopy output if the problem is chronic). 291 * NB: should send a message to the session logger to avoid blocking. 292 */ 293 void 294 #ifdef __STDC__ 295 stall(char *message, ...) 296 #else 297 stall(va_alist) 298 va_dcl 299 #endif 300 { 301 pid_t pid; 302 va_list ap; 303 #ifndef __STDC__ 304 char *message; 305 306 va_start(ap); 307 message = va_arg(ap, char *); 308 #else 309 va_start(ap, message); 310 #endif 311 312 vsyslog(LOG_ALERT, message, ap); 313 va_end(ap); 314 sleep(STALL_TIMEOUT); 315 } 316 317 /* 318 * Like stall(), but doesn't sleep. 319 * If cpp had variadic macros, the two functions could be #defines for another. 320 * NB: should send a message to the session logger to avoid blocking. 321 */ 322 void 323 #ifdef __STDC__ 324 warning(char *message, ...) 325 #else 326 warning(va_alist) 327 va_dcl 328 #endif 329 { 330 va_list ap; 331 #ifndef __STDC__ 332 char *message; 333 334 va_start(ap); 335 message = va_arg(ap, char *); 336 #else 337 va_start(ap, message); 338 #endif 339 340 vsyslog(LOG_ALERT, message, ap); 341 va_end(ap); 342 } 343 344 /* 345 * Log an emergency message. 346 * NB: should send a message to the session logger to avoid blocking. 347 */ 348 void 349 #ifdef __STDC__ 350 emergency(char *message, ...) 351 #else 352 emergency(va_alist) 353 va_dcl 354 #endif 355 { 356 va_list ap; 357 #ifndef __STDC__ 358 char *message; 359 360 va_start(ap); 361 message = va_arg(ap, char *); 362 #else 363 va_start(ap, message); 364 #endif 365 366 vsyslog(LOG_EMERG, message, ap); 367 va_end(ap); 368 } 369 370 /* 371 * Catch a SIGSYS signal. 372 * 373 * These may arise if a system does not support sysctl. 374 * We tolerate up to 25 of these, then throw in the towel. 375 */ 376 void 377 badsys(sig) 378 int sig; 379 { 380 static int badcount = 0; 381 382 if (badcount++ < 25) 383 return; 384 disaster(sig); 385 } 386 387 /* 388 * Catch an unexpected signal. 389 */ 390 void 391 disaster(sig) 392 int sig; 393 { 394 emergency("fatal signal: %s", 395 sig < (unsigned) NSIG ? sys_siglist[sig] : "unknown signal"); 396 397 sleep(STALL_TIMEOUT); 398 _exit(sig); /* reboot */ 399 } 400 401 /* 402 * Get the security level of the kernel. 403 */ 404 int 405 getsecuritylevel() 406 { 407 int name[2], curlevel; 408 size_t len; 409 extern int errno; 410 411 name[0] = CTL_KERN; 412 name[1] = KERN_SECURELVL; 413 len = sizeof curlevel; 414 if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) { 415 emergency("cannot get kernel security level: %s", 416 strerror(errno)); 417 return (-1); 418 } 419 return (curlevel); 420 } 421 422 /* 423 * Set the security level of the kernel. 424 */ 425 setsecuritylevel(newlevel) 426 int newlevel; 427 { 428 int name[2], len, curlevel; 429 extern int errno; 430 431 curlevel = getsecuritylevel(); 432 if (newlevel == curlevel) 433 return; 434 name[0] = CTL_KERN; 435 name[1] = KERN_SECURELVL; 436 if (sysctl(name, 2, NULL, NULL, &newlevel, sizeof newlevel) == -1) { 437 emergency( 438 "cannot change kernel security level from %d to %d: %s", 439 curlevel, newlevel, strerror(errno)); 440 return; 441 } 442 #ifdef SECURE 443 warning("kernel security level changed from %d to %d", 444 curlevel, newlevel); 445 #endif 446 } 447 448 /* 449 * Change states in the finite state machine. 450 * The initial state is passed as an argument. 451 */ 452 void 453 transition(s) 454 state_t s; 455 { 456 for (;;) 457 s = (state_t) (*s)(); 458 } 459 460 /* 461 * We send requests for session logging to another process for two reasons. 462 * First, we don't want to block if the log files go away (e.g. because 463 * one or more are on hard-mounted NFS systems whose server crashes). 464 * Second, despite all the crud already contained in init, it still isn't 465 * right that init should care about session logging record formats and files. 466 * We could use explicit 'Unix' IPC for this, but let's try to be POSIX... 467 */ 468 int 469 start_logger() 470 { 471 static char *argv[] = { _PATH_SLOGGER, 0 }; 472 int fd, pfd[2]; 473 pid_t pid; 474 sigset_t mask; 475 476 if (pipe(pfd) == -1) { 477 warning("session logging disabled: can't make pipe to %s: %m", 478 argv[0]); 479 return -1; 480 } 481 if ((pid = fork()) == -1) { 482 emergency("session logging disabled: can't fork for %s: %m", 483 argv[0]); 484 return -1; 485 } 486 487 if (pid == 0) { 488 close(pfd[1]); 489 if (pfd[0] != 0) { 490 dup2(pfd[0], 0); 491 close(pfd[0]); 492 } 493 if ((fd = open(_PATH_DEVNULL, O_WRONLY)) != -1) { 494 if (fd != 1) 495 dup2(fd, 1); 496 if (fd != 2) 497 dup2(fd, 2); 498 if (fd != 1 && fd != 2) 499 close(fd); 500 } else { 501 /* paranoid */ 502 close(1); 503 close(2); 504 } 505 sigemptyset(&mask); 506 sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); 507 execv(argv[0], argv); 508 stall("can't exec %s: %m", argv[0]); 509 _exit(1); 510 } 511 512 close(pfd[0]); 513 fcntl(pfd[1], F_SETFD, FD_CLOEXEC); 514 fcntl(pfd[1], F_SETFL, O_NONBLOCK); 515 516 return pfd[1]; 517 } 518 519 /* 520 * Close out the accounting files for a login session. 521 * NB: should send a message to the session logger to avoid blocking. 522 */ 523 void 524 clear_session_logs(sp) 525 session_t *sp; 526 { 527 char *line = sp->se_device + sizeof(_PATH_DEV) - 1; 528 529 if (logout(line)) 530 logwtmp(line, "", ""); 531 } 532 533 /* 534 * Start a session and allocate a controlling terminal. 535 * Only called by children of init after forking. 536 */ 537 void 538 setctty(name) 539 char *name; 540 { 541 int fd; 542 543 (void) revoke(name); 544 if ((fd = open(name, O_RDWR)) == -1) { 545 stall("can't open %s: %m", name); 546 _exit(1); 547 } 548 if (login_tty(fd) == -1) { 549 stall("can't get %s for controlling terminal: %m", name); 550 _exit(1); 551 } 552 } 553 554 /* 555 * Bring the system up single user. 556 */ 557 state_func_t 558 single_user() 559 { 560 pid_t pid, wpid; 561 int status; 562 sigset_t mask; 563 char *shell = _PATH_BSHELL; 564 char *argv[2]; 565 #ifdef SECURE 566 struct ttyent *typ; 567 struct passwd *pp; 568 static const char banner[] = 569 "Enter root password, or ^D to go multi-user\n"; 570 char *password; 571 #endif 572 573 /* 574 * If the kernel is in secure mode, downgrade it to insecure mode. 575 */ 576 if (getsecuritylevel() > 0) 577 setsecuritylevel(0); 578 579 if ((pid = fork()) == 0) { 580 /* 581 * Start the single user session. 582 */ 583 setctty(_PATH_CONSOLE); 584 585 #ifdef SECURE 586 /* 587 * Check the root password. 588 * We don't care if the console is 'on' by default; 589 * it's the only tty that can be 'off' and 'secure'. 590 */ 591 typ = getttynam("console"); 592 pp = getpwnam("root"); 593 if (typ && (typ->ty_status & TTY_SECURE) == 0 && pp) { 594 write(2, banner, sizeof banner - 1); 595 for (;;) { 596 password = getpass("Password:"); 597 if (password == 0 || *password == '\0') 598 _exit(0); 599 password = crypt(password, pp->pw_passwd); 600 if (strcmp(password, pp->pw_passwd) == 0) 601 break; 602 warning("single-user login failed\n"); 603 } 604 } 605 endttyent(); 606 endpwent(); 607 #endif /* SECURE */ 608 609 #ifdef DEBUGSHELL 610 { 611 char altshell[128], *cp = altshell; 612 int num; 613 614 #define SHREQUEST \ 615 "Enter pathname of shell or RETURN for sh: " 616 (void)write(STDERR_FILENO, 617 SHREQUEST, sizeof(SHREQUEST) - 1); 618 while ((num = read(STDIN_FILENO, cp, 1)) != -1 && 619 num != 0 && *cp != '\n' && cp < &altshell[127]) 620 cp++; 621 *cp = '\0'; 622 if (altshell[0] != '\0') 623 shell = altshell; 624 } 625 #endif /* DEBUGSHELL */ 626 627 /* 628 * Unblock signals. 629 * We catch all the interesting ones, 630 * and those are reset to SIG_DFL on exec. 631 */ 632 sigemptyset(&mask); 633 sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); 634 635 /* 636 * Fire off a shell. 637 * If the default one doesn't work, try the Bourne shell. 638 */ 639 argv[0] = "-sh"; 640 argv[1] = 0; 641 execv(shell, argv); 642 emergency("can't exec %s for single user: %m", shell); 643 execv(_PATH_BSHELL, argv); 644 emergency("can't exec %s for single user: %m", _PATH_BSHELL); 645 sleep(STALL_TIMEOUT); 646 _exit(1); 647 } 648 649 if (pid == -1) { 650 /* 651 * We are seriously hosed. Do our best. 652 */ 653 emergency("can't fork single-user shell, trying again"); 654 while (waitpid(-1, (int *) 0, WNOHANG) > 0) 655 continue; 656 return (state_func_t) single_user; 657 } 658 659 requested_transition = 0; 660 do { 661 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) 662 collect_child(wpid); 663 if (wpid == -1) { 664 if (errno == EINTR) 665 continue; 666 warning("wait for single-user shell failed: %m; restarting"); 667 return (state_func_t) single_user; 668 } 669 if (wpid == pid && WIFSTOPPED(status)) { 670 warning("init: shell stopped, restarting\n"); 671 kill(pid, SIGCONT); 672 wpid = -1; 673 } 674 } while (wpid != pid && !requested_transition); 675 676 if (requested_transition) 677 return (state_func_t) requested_transition; 678 679 if (!WIFEXITED(status)) { 680 if (WTERMSIG(status) == SIGKILL) { 681 /* 682 * reboot(8) killed shell? 683 */ 684 warning("single user shell terminated."); 685 sleep(STALL_TIMEOUT); 686 _exit(0); 687 } else { 688 warning("single user shell terminated, restarting"); 689 return (state_func_t) single_user; 690 } 691 } 692 693 runcom_mode = FASTBOOT; 694 return (state_func_t) runcom; 695 } 696 697 /* 698 * Run the system startup script. 699 */ 700 state_func_t 701 runcom() 702 { 703 pid_t pid, wpid; 704 int status; 705 char *argv[4]; 706 struct sigaction sa; 707 708 if ((pid = fork()) == 0) { 709 sigemptyset(&sa.sa_mask); 710 sa.sa_flags = 0; 711 sa.sa_handler = SIG_IGN; 712 (void) sigaction(SIGTSTP, &sa, (struct sigaction *)0); 713 (void) sigaction(SIGHUP, &sa, (struct sigaction *)0); 714 715 setctty(_PATH_CONSOLE); 716 717 argv[0] = "sh"; 718 argv[1] = _PATH_RUNCOM; 719 argv[2] = runcom_mode == AUTOBOOT ? "autoboot" : 0; 720 argv[3] = 0; 721 722 sigprocmask(SIG_SETMASK, &sa.sa_mask, (sigset_t *) 0); 723 724 execv(_PATH_BSHELL, argv); 725 stall("can't exec %s for %s: %m", _PATH_BSHELL, _PATH_RUNCOM); 726 _exit(1); /* force single user mode */ 727 } 728 729 if (pid == -1) { 730 emergency("can't fork for %s on %s: %m", 731 _PATH_BSHELL, _PATH_RUNCOM); 732 while (waitpid(-1, (int *) 0, WNOHANG) > 0) 733 continue; 734 sleep(STALL_TIMEOUT); 735 return (state_func_t) single_user; 736 } 737 738 /* 739 * Copied from single_user(). This is a bit paranoid. 740 */ 741 do { 742 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) 743 collect_child(wpid); 744 if (wpid == -1) { 745 if (errno == EINTR) 746 continue; 747 warning("wait for %s on %s failed: %m; going to single user mode", 748 _PATH_BSHELL, _PATH_RUNCOM); 749 return (state_func_t) single_user; 750 } 751 if (wpid == pid && WIFSTOPPED(status)) { 752 warning("init: %s on %s stopped, restarting\n", 753 _PATH_BSHELL, _PATH_RUNCOM); 754 kill(pid, SIGCONT); 755 wpid = -1; 756 } 757 } while (wpid != pid); 758 759 if (!WIFEXITED(status)) { 760 warning("%s on %s terminated abnormally, going to single user mode", 761 _PATH_BSHELL, _PATH_RUNCOM); 762 return (state_func_t) single_user; 763 } 764 765 if (WEXITSTATUS(status)) 766 return (state_func_t) single_user; 767 768 runcom_mode = AUTOBOOT; /* the default */ 769 /* NB: should send a message to the session logger to avoid blocking. */ 770 logwtmp("~", "reboot", ""); 771 return (state_func_t) read_ttys; 772 } 773 774 /* 775 * Open the session database. 776 * 777 * NB: We could pass in the size here; is it necessary? 778 */ 779 int 780 start_session_db() 781 { 782 if (session_db && (*session_db->close)(session_db)) 783 emergency("session database close: %s", strerror(errno)); 784 if ((session_db = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL)) == 0) { 785 emergency("session database open: %s", strerror(errno)); 786 return (1); 787 } 788 return (0); 789 790 } 791 792 /* 793 * Add a new login session. 794 */ 795 void 796 add_session(sp) 797 session_t *sp; 798 { 799 DBT key; 800 DBT data; 801 802 key.data = &sp->se_process; 803 key.size = sizeof sp->se_process; 804 data.data = &sp; 805 data.size = sizeof sp; 806 807 if ((*session_db->put)(session_db, &key, &data, 0)) 808 emergency("insert %d: %s", sp->se_process, strerror(errno)); 809 } 810 811 /* 812 * Delete an old login session. 813 */ 814 void 815 del_session(sp) 816 session_t *sp; 817 { 818 DBT key; 819 820 key.data = &sp->se_process; 821 key.size = sizeof sp->se_process; 822 823 if ((*session_db->del)(session_db, &key, 0)) 824 emergency("delete %d: %s", sp->se_process, strerror(errno)); 825 } 826 827 /* 828 * Look up a login session by pid. 829 */ 830 session_t * 831 #ifdef __STDC__ 832 find_session(pid_t pid) 833 #else 834 find_session(pid) 835 pid_t pid; 836 #endif 837 { 838 DBT key; 839 DBT data; 840 session_t *ret; 841 842 key.data = &pid; 843 key.size = sizeof pid; 844 if ((*session_db->get)(session_db, &key, &data, 0) != 0) 845 return 0; 846 bcopy(data.data, (char *)&ret, sizeof(ret)); 847 return ret; 848 } 849 850 /* 851 * Construct an argument vector from a command line. 852 */ 853 char ** 854 construct_argv(command) 855 char *command; 856 { 857 register int argc = 0; 858 register char **argv = (char **) malloc(((strlen(command) + 1) / 2 + 1) 859 * sizeof (char *)); 860 static const char separators[] = " \t"; 861 862 if ((argv[argc++] = strtok(command, separators)) == 0) 863 return 0; 864 while (argv[argc++] = strtok((char *) 0, separators)) 865 continue; 866 return argv; 867 } 868 869 /* 870 * Deallocate a session descriptor. 871 */ 872 void 873 free_session(sp) 874 register session_t *sp; 875 { 876 free(sp->se_device); 877 free(sp->se_getty); 878 free(sp->se_getty_argv); 879 if (sp->se_window) { 880 free(sp->se_window); 881 free(sp->se_window_argv); 882 } 883 free(sp); 884 } 885 886 /* 887 * Allocate a new session descriptor. 888 */ 889 session_t * 890 new_session(sprev, session_index, typ) 891 session_t *sprev; 892 int session_index; 893 register struct ttyent *typ; 894 { 895 register session_t *sp; 896 897 if ((typ->ty_status & TTY_ON) == 0 || 898 typ->ty_name == 0 || 899 typ->ty_getty == 0) 900 return 0; 901 902 sp = (session_t *) malloc(sizeof (session_t)); 903 904 sp->se_index = session_index; 905 sp->se_process = 0; 906 sp->se_started = 0; 907 sp->se_flags = 0; 908 sp->se_window = 0; 909 910 sp->se_device = malloc(sizeof(_PATH_DEV) + strlen(typ->ty_name)); 911 (void) sprintf(sp->se_device, "%s%s", _PATH_DEV, typ->ty_name); 912 913 sp->se_getty = strdup(typ->ty_getty); 914 sp->se_getty_argv = construct_argv(sp->se_getty); 915 if (sp->se_getty_argv == 0) { 916 warning("can't parse getty for port %s", 917 sp->se_device); 918 free_session(sp); 919 return 0; 920 } 921 if (typ->ty_window) { 922 sp->se_window = strdup(typ->ty_window); 923 sp->se_window_argv = construct_argv(sp->se_window); 924 if (sp->se_window_argv == 0) { 925 warning("can't parse window for port %s", 926 sp->se_device); 927 free_session(sp); 928 return 0; 929 } 930 } 931 932 sp->se_next = 0; 933 if (sprev == 0) { 934 sessions = sp; 935 sp->se_prev = 0; 936 } else { 937 sprev->se_next = sp; 938 sp->se_prev = sprev; 939 } 940 941 return sp; 942 } 943 944 /* 945 * Walk the list of ttys and create sessions for each active line. 946 */ 947 state_func_t 948 read_ttys() 949 { 950 int session_index = 0; 951 register session_t *sp, *snext; 952 register struct ttyent *typ; 953 954 /* 955 * Destroy any previous session state. 956 * There shouldn't be any, but just in case... 957 */ 958 for (sp = sessions; sp; sp = snext) { 959 if (sp->se_process) 960 clear_session_logs(sp); 961 snext = sp->se_next; 962 free_session(sp); 963 } 964 sessions = 0; 965 if (start_session_db()) 966 return (state_func_t) single_user; 967 968 /* 969 * Allocate a session entry for each active port. 970 * Note that sp starts at 0. 971 */ 972 while (typ = getttyent()) 973 if (snext = new_session(sp, ++session_index, typ)) 974 sp = snext; 975 976 endttyent(); 977 978 logger_enable = 1; 979 return (state_func_t) multi_user; 980 } 981 982 /* 983 * Start a window system running. 984 */ 985 void 986 start_window_system(sp) 987 session_t *sp; 988 { 989 pid_t pid; 990 sigset_t mask; 991 992 if ((pid = fork()) == -1) { 993 emergency("can't fork for window system on port %s: %m", 994 sp->se_device); 995 /* hope that getty fails and we can try again */ 996 return; 997 } 998 999 if (pid) 1000 return; 1001 1002 sigemptyset(&mask); 1003 sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); 1004 1005 if (setsid() < 0) 1006 emergency("setsid failed (window) %m"); 1007 1008 execv(sp->se_window_argv[0], sp->se_window_argv); 1009 stall("can't exec window system '%s' for port %s: %m", 1010 sp->se_window_argv[0], sp->se_device); 1011 _exit(1); 1012 } 1013 1014 /* 1015 * Start a login session running. 1016 */ 1017 pid_t 1018 start_getty(sp) 1019 session_t *sp; 1020 { 1021 pid_t pid; 1022 sigset_t mask; 1023 time_t current_time = time((time_t *) 0); 1024 1025 /* 1026 * fork(), not vfork() -- we can't afford to block. 1027 */ 1028 if ((pid = fork()) == -1) { 1029 emergency("can't fork for getty on port %s: %m", sp->se_device); 1030 return -1; 1031 } 1032 1033 if (pid) 1034 return pid; 1035 1036 if (current_time > sp->se_started && 1037 current_time - sp->se_started < GETTY_SPACING) { 1038 warning("getty repeating too quickly on port %s, sleeping", 1039 sp->se_device); 1040 sleep((unsigned) GETTY_SPACING - 1041 (current_time - sp->se_started)); 1042 } 1043 1044 if (sp->se_window) { 1045 start_window_system(sp); 1046 sleep(WINDOW_WAIT); 1047 } 1048 1049 setctty(sp->se_device); 1050 1051 sigemptyset(&mask); 1052 sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); 1053 1054 execv(sp->se_getty_argv[0], sp->se_getty_argv); 1055 stall("can't exec getty '%s' for port %s: %m", 1056 sp->se_getty_argv[0], sp->se_device); 1057 _exit(1); 1058 } 1059 1060 /* 1061 * Collect exit status for a child. 1062 * If an exiting login, start a new login running. 1063 */ 1064 void 1065 collect_child(pid) 1066 pid_t pid; 1067 { 1068 register session_t *sp, *sprev, *snext; 1069 1070 if (! sessions) 1071 return; 1072 1073 if (! (sp = find_session(pid))) 1074 return; 1075 1076 clear_session_logs(sp); 1077 del_session(sp); 1078 sp->se_process = 0; 1079 1080 if (sp->se_flags & SE_SHUTDOWN) { 1081 if (sprev = sp->se_prev) 1082 sprev->se_next = sp->se_next; 1083 else 1084 sessions = sp->se_next; 1085 if (snext = sp->se_next) 1086 snext->se_prev = sp->se_prev; 1087 free_session(sp); 1088 return; 1089 } 1090 1091 if ((pid = start_getty(sp)) == -1) { 1092 /* serious trouble */ 1093 requested_transition = clean_ttys; 1094 return; 1095 } 1096 1097 sp->se_process = pid; 1098 sp->se_started = time((time_t *) 0); 1099 add_session(sp); 1100 } 1101 1102 /* 1103 * Catch a signal and request a state transition. 1104 */ 1105 void 1106 transition_handler(sig) 1107 int sig; 1108 { 1109 1110 switch (sig) { 1111 case SIGHUP: 1112 requested_transition = clean_ttys; 1113 break; 1114 case SIGTERM: 1115 requested_transition = death; 1116 break; 1117 case SIGTSTP: 1118 requested_transition = catatonia; 1119 break; 1120 default: 1121 requested_transition = 0; 1122 break; 1123 } 1124 } 1125 1126 /* 1127 * Take the system multiuser. 1128 */ 1129 state_func_t 1130 multi_user() 1131 { 1132 pid_t pid; 1133 register session_t *sp; 1134 1135 requested_transition = 0; 1136 logger_enable = 1; 1137 1138 /* 1139 * If the administrator has not set the security level to -1 1140 * to indicate that the kernel should not run multiuser in secure 1141 * mode, and the run script has not set a higher level of security 1142 * than level 1, then put the kernel into secure mode. 1143 */ 1144 if (getsecuritylevel() == 0) 1145 setsecuritylevel(1); 1146 1147 for (sp = sessions; sp; sp = sp->se_next) { 1148 if (sp->se_process) 1149 continue; 1150 if ((pid = start_getty(sp)) == -1) { 1151 /* serious trouble */ 1152 requested_transition = clean_ttys; 1153 break; 1154 } 1155 sp->se_process = pid; 1156 sp->se_started = time((time_t *) 0); 1157 add_session(sp); 1158 } 1159 1160 while (!requested_transition) 1161 if ((pid = waitpid(-1, (int *) 0, 0)) != -1) 1162 collect_child(pid); 1163 1164 return (state_func_t) requested_transition; 1165 } 1166 1167 /* 1168 * This is an n-squared algorithm. We hope it isn't run often... 1169 */ 1170 state_func_t 1171 clean_ttys() 1172 { 1173 register session_t *sp, *sprev; 1174 register struct ttyent *typ; 1175 register int session_index = 0; 1176 register int devlen; 1177 1178 if (! sessions) 1179 return (state_func_t) multi_user; 1180 1181 devlen = sizeof(_PATH_DEV) - 1; 1182 while (typ = getttyent()) { 1183 ++session_index; 1184 1185 for (sp = sessions; sp; sprev = sp, sp = sp->se_next) 1186 if (strcmp(typ->ty_name, sp->se_device + devlen) == 0) 1187 break; 1188 1189 if (sp) { 1190 if (sp->se_index != session_index) { 1191 warning("port %s changed utmp index from %d to %d", 1192 sp->se_device, sp->se_index, 1193 session_index); 1194 sp->se_index = session_index; 1195 } 1196 if (typ->ty_status & TTY_ON) 1197 sp->se_flags &= ~SE_SHUTDOWN; 1198 else { 1199 sp->se_flags |= SE_SHUTDOWN; 1200 kill(sp->se_process, SIGHUP); 1201 } 1202 continue; 1203 } 1204 1205 new_session(sprev, session_index, typ); 1206 } 1207 1208 endttyent(); 1209 1210 return (state_func_t) multi_user; 1211 } 1212 1213 /* 1214 * Block further logins. 1215 */ 1216 state_func_t 1217 catatonia() 1218 { 1219 register session_t *sp; 1220 1221 for (sp = sessions; sp; sp = sp->se_next) 1222 sp->se_flags |= SE_SHUTDOWN; 1223 1224 return (state_func_t) multi_user; 1225 } 1226 1227 /* 1228 * Note SIGALRM. 1229 */ 1230 void 1231 alrm_handler(sig) 1232 int sig; 1233 { 1234 clang = 1; 1235 } 1236 1237 /* 1238 * Bring the system down to single user. 1239 */ 1240 state_func_t 1241 death() 1242 { 1243 register session_t *sp; 1244 register int i; 1245 pid_t pid; 1246 static const int death_sigs[3] = { SIGHUP, SIGTERM, SIGKILL }; 1247 1248 for (sp = sessions; sp; sp = sp->se_next) 1249 sp->se_flags |= SE_SHUTDOWN; 1250 1251 /* NB: should send a message to the session logger to avoid blocking. */ 1252 logwtmp("~", "shutdown", ""); 1253 logger_enable = 0; 1254 1255 for (i = 0; i < 3; ++i) { 1256 if (kill(-1, death_sigs[i]) == -1 && errno == ESRCH) 1257 return (state_func_t) single_user; 1258 1259 clang = 0; 1260 alarm(DEATH_WATCH); 1261 do 1262 if ((pid = waitpid(-1, (int *)0, 0)) != -1) 1263 collect_child(pid); 1264 while (clang == 0 && errno != ECHILD); 1265 1266 if (errno == ECHILD) 1267 return (state_func_t) single_user; 1268 } 1269 1270 warning("some processes wouldn't die"); 1271 1272 return (state_func_t) single_user; 1273 } 1274