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