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