1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Donn Seeley at Berkeley Software Design, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #include <sys/param.h>
36 #include <sys/boottrace.h>
37 #include <sys/ioctl.h>
38 #include <sys/mman.h>
39 #include <sys/mount.h>
40 #include <sys/reboot.h>
41 #include <sys/stat.h>
42 #include <sys/sysctl.h>
43 #include <sys/uio.h>
44 #include <sys/wait.h>
45
46 #include <db.h>
47 #include <err.h>
48 #include <errno.h>
49 #include <fcntl.h>
50 #include <kenv.h>
51 #include <libutil.h>
52 #include <mntopts.h>
53 #include <paths.h>
54 #include <signal.h>
55 #include <stdarg.h>
56 #include <stdbool.h>
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <string.h>
60 #include <syslog.h>
61 #include <time.h>
62 #include <ttyent.h>
63 #include <unistd.h>
64
65 #ifdef SECURE
66 #include <pwd.h>
67 #endif
68
69 #ifdef LOGIN_CAP
70 #include <login_cap.h>
71 #endif
72
73 #include "pathnames.h"
74
75 /*
76 * Sleep times; used to prevent thrashing.
77 */
78 #define GETTY_SPACING 5 /* N secs minimum getty spacing */
79 #define GETTY_SLEEP 30 /* sleep N secs after spacing problem */
80 #define GETTY_NSPACE 3 /* max. spacing count to bring reaction */
81 #define WINDOW_WAIT 3 /* wait N secs after starting window */
82 #define STALL_TIMEOUT 30 /* wait N secs after warning */
83 #define DEATH_WATCH 10 /* wait N secs for procs to die */
84 #define DEATH_SCRIPT 120 /* wait for 2min for /etc/rc.shutdown */
85 #define RESOURCE_RC "daemon"
86 #define RESOURCE_WINDOW "default"
87 #define RESOURCE_GETTY "default"
88 #define SCRIPT_ARGV_SIZE 3 /* size of argv passed to execute_script, can be increased if needed */
89
90 static void handle(sig_t, ...);
91 static void delset(sigset_t *, ...);
92
93 static void stall(const char *, ...) __printflike(1, 2);
94 static void warning(const char *, ...) __printflike(1, 2);
95 static void emergency(const char *, ...) __printflike(1, 2);
96 static void disaster(int);
97 static void revoke_ttys(void);
98 static int runshutdown(void);
99 static char *strk(char *);
100 static void runfinal(void);
101
102 /*
103 * We really need a recursive typedef...
104 * The following at least guarantees that the return type of (*state_t)()
105 * is sufficiently wide to hold a function pointer.
106 */
107 typedef long (*state_func_t)(void);
108 typedef state_func_t (*state_t)(void);
109
110 static state_func_t single_user(void);
111 static state_func_t runcom(void);
112 static state_func_t read_ttys(void);
113 static state_func_t multi_user(void);
114 static state_func_t clean_ttys(void);
115 static state_func_t catatonia(void);
116 static state_func_t death(void);
117 static state_func_t death_single(void);
118 static state_func_t reroot(void);
119 #ifdef RESCUE
120 static state_func_t reroot_phase_two(void);
121 #endif
122
123 static state_func_t run_script(const char *);
124
125 static enum { AUTOBOOT, FASTBOOT } runcom_mode = AUTOBOOT;
126
127 static bool Reboot = false;
128 static int howto = RB_AUTOBOOT;
129
130 static bool devfs = false;
131 static char *init_path_argv0;
132
133 static void transition(state_t);
134 static state_t requested_transition;
135 static state_t current_state = death_single;
136
137 static void execute_script(char *argv[]);
138 static void open_console(void);
139 static const char *get_shell(void);
140 static void replace_init(char *path);
141 static void write_stderr(const char *message);
142
143 typedef struct init_session {
144 pid_t se_process; /* controlling process */
145 time_t se_started; /* used to avoid thrashing */
146 int se_flags; /* status of session */
147 #define SE_SHUTDOWN 0x1 /* session won't be restarted */
148 #define SE_PRESENT 0x2 /* session is in /etc/ttys */
149 #define SE_IFEXISTS 0x4 /* session defined as "onifexists" */
150 #define SE_IFCONSOLE 0x8 /* session defined as "onifconsole" */
151 int se_nspace; /* spacing count */
152 char *se_device; /* filename of port */
153 char *se_getty; /* what to run on that port */
154 char *se_getty_argv_space; /* pre-parsed argument array space */
155 char **se_getty_argv; /* pre-parsed argument array */
156 char *se_window; /* window system (started only once) */
157 char *se_window_argv_space; /* pre-parsed argument array space */
158 char **se_window_argv; /* pre-parsed argument array */
159 char *se_type; /* default terminal type */
160 struct init_session *se_prev;
161 struct init_session *se_next;
162 } session_t;
163
164 static void free_session(session_t *);
165 static session_t *new_session(session_t *, struct ttyent *);
166 static session_t *sessions;
167
168 static char **construct_argv(char *);
169 static void start_window_system(session_t *);
170 static void collect_child(pid_t);
171 static pid_t start_getty(session_t *);
172 static void transition_handler(int);
173 static void alrm_handler(int);
174 static void setsecuritylevel(int);
175 static int getsecuritylevel(void);
176 static int setupargv(session_t *, struct ttyent *);
177 #ifdef LOGIN_CAP
178 static void setprocresources(const char *);
179 #endif
180 static bool clang;
181
182 static int start_session_db(void);
183 static void add_session(session_t *);
184 static void del_session(session_t *);
185 static session_t *find_session(pid_t);
186 static DB *session_db;
187
188 /*
189 * The mother of all processes.
190 */
191 int
main(int argc,char * argv[])192 main(int argc, char *argv[])
193 {
194 state_t initial_transition = runcom;
195 char kenv_value[PATH_MAX];
196 int c, error;
197 struct sigaction sa;
198 sigset_t mask;
199
200 /* Dispose of random users. */
201 if (getuid() != 0)
202 errx(1, "%s", strerror(EPERM));
203
204 BOOTTRACE("init(8) starting...");
205
206 /* System V users like to reexec init. */
207 if (getpid() != 1) {
208 #ifdef COMPAT_SYSV_INIT
209 /* So give them what they want */
210 if (argc > 1) {
211 if (strlen(argv[1]) == 1) {
212 char runlevel = *argv[1];
213 int sig;
214
215 switch (runlevel) {
216 case '0': /* halt + poweroff */
217 sig = SIGUSR2;
218 break;
219 case '1': /* single-user */
220 sig = SIGTERM;
221 break;
222 case '6': /* reboot */
223 sig = SIGINT;
224 break;
225 case 'c': /* block further logins */
226 sig = SIGTSTP;
227 break;
228 case 'q': /* rescan /etc/ttys */
229 sig = SIGHUP;
230 break;
231 case 'r': /* remount root */
232 sig = SIGEMT;
233 break;
234 default:
235 goto invalid;
236 }
237 kill(1, sig);
238 _exit(0);
239 } else
240 invalid:
241 errx(1, "invalid run-level ``%s''", argv[1]);
242 } else
243 #endif
244 errx(1, "already running");
245 }
246
247 init_path_argv0 = strdup(argv[0]);
248 if (init_path_argv0 == NULL)
249 err(1, "strdup");
250
251 /*
252 * Note that this does NOT open a file...
253 * Does 'init' deserve its own facility number?
254 */
255 openlog("init", LOG_CONS, LOG_AUTH);
256
257 /*
258 * Create an initial session.
259 */
260 if (setsid() < 0 && (errno != EPERM || getsid(0) != 1))
261 warning("initial setsid() failed: %m");
262
263 /*
264 * Establish an initial user so that programs running
265 * single user do not freak out and die (like passwd).
266 */
267 if (setlogin("root") < 0)
268 warning("setlogin() failed: %m");
269
270 /*
271 * This code assumes that we always get arguments through flags,
272 * never through bits set in some random machine register.
273 */
274 while ((c = getopt(argc, argv, "dsf"
275 #ifdef RESCUE
276 "r"
277 #endif
278 )) != -1)
279 switch (c) {
280 case 'd':
281 devfs = true;
282 break;
283 case 's':
284 initial_transition = single_user;
285 break;
286 case 'f':
287 runcom_mode = FASTBOOT;
288 break;
289 #ifdef RESCUE
290 case 'r':
291 initial_transition = reroot_phase_two;
292 break;
293 #endif
294 default:
295 warning("unrecognized flag '-%c'", c);
296 break;
297 }
298
299 if (optind != argc)
300 warning("ignoring excess arguments");
301
302 /*
303 * We catch or block signals rather than ignore them,
304 * so that they get reset on exec.
305 */
306 handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS,
307 SIGXCPU, SIGXFSZ, 0);
308 handle(transition_handler, SIGHUP, SIGINT, SIGEMT, SIGTERM, SIGTSTP,
309 SIGUSR1, SIGUSR2, SIGWINCH, 0);
310 handle(alrm_handler, SIGALRM, 0);
311 sigfillset(&mask);
312 delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS,
313 SIGXCPU, SIGXFSZ, SIGHUP, SIGINT, SIGEMT, SIGTERM, SIGTSTP,
314 SIGALRM, SIGUSR1, SIGUSR2, SIGWINCH, 0);
315 sigprocmask(SIG_SETMASK, &mask, NULL);
316 sigemptyset(&sa.sa_mask);
317 sa.sa_flags = 0;
318 sa.sa_handler = SIG_IGN;
319 sigaction(SIGTTIN, &sa, NULL);
320 sigaction(SIGTTOU, &sa, NULL);
321
322 /*
323 * Paranoia.
324 */
325 close(0);
326 close(1);
327 close(2);
328
329 if (kenv(KENV_GET, "init_exec", kenv_value, sizeof(kenv_value)) > 0) {
330 replace_init(kenv_value);
331 _exit(0); /* reboot */
332 }
333
334 if (kenv(KENV_GET, "init_script", kenv_value, sizeof(kenv_value)) > 0) {
335 state_func_t next_transition;
336
337 if ((next_transition = run_script(kenv_value)) != NULL)
338 initial_transition = (state_t) next_transition;
339 }
340
341 if (kenv(KENV_GET, "init_chroot", kenv_value, sizeof(kenv_value)) > 0) {
342 if (chdir(kenv_value) != 0 || chroot(".") != 0)
343 warning("Can't chroot to %s: %m", kenv_value);
344 }
345
346 /*
347 * Additional check if devfs needs to be mounted:
348 * If "/" and "/dev" have the same device number,
349 * then it hasn't been mounted yet.
350 */
351 if (!devfs) {
352 struct stat stst;
353 dev_t root_devno;
354
355 stat("/", &stst);
356 root_devno = stst.st_dev;
357 if (stat("/dev", &stst) != 0)
358 warning("Can't stat /dev: %m");
359 else if (stst.st_dev == root_devno)
360 devfs = true;
361 }
362
363 if (devfs) {
364 struct iovec iov[4];
365 char *s;
366 int i;
367
368 char _fstype[] = "fstype";
369 char _devfs[] = "devfs";
370 char _fspath[] = "fspath";
371 char _path_dev[]= _PATH_DEV;
372
373 iov[0].iov_base = _fstype;
374 iov[0].iov_len = sizeof(_fstype);
375 iov[1].iov_base = _devfs;
376 iov[1].iov_len = sizeof(_devfs);
377 iov[2].iov_base = _fspath;
378 iov[2].iov_len = sizeof(_fspath);
379 /*
380 * Try to avoid the trailing slash in _PATH_DEV.
381 * Be *very* defensive.
382 */
383 s = strdup(_PATH_DEV);
384 if (s != NULL) {
385 i = strlen(s);
386 if (i > 0 && s[i - 1] == '/')
387 s[i - 1] = '\0';
388 iov[3].iov_base = s;
389 iov[3].iov_len = strlen(s) + 1;
390 } else {
391 iov[3].iov_base = _path_dev;
392 iov[3].iov_len = sizeof(_path_dev);
393 }
394 nmount(iov, 4, 0);
395 if (s != NULL)
396 free(s);
397 }
398
399 #ifdef RESCUE
400 if (initial_transition != reroot_phase_two)
401 #endif
402 {
403 /*
404 * Unmount reroot leftovers. This runs after init(8)
405 * gets reexecuted after reroot_phase_two() is done.
406 */
407 error = unmount(_PATH_REROOT, MNT_FORCE);
408 if (error != 0 && errno != EINVAL)
409 warning("Cannot unmount %s: %m", _PATH_REROOT);
410 }
411
412 /*
413 * Start the state machine.
414 */
415 transition(initial_transition);
416
417 /*
418 * Should never reach here.
419 */
420 return 1;
421 }
422
423 /*
424 * Associate a function with a signal handler.
425 */
426 static void
handle(sig_t handler,...)427 handle(sig_t handler, ...)
428 {
429 int sig;
430 struct sigaction sa;
431 sigset_t mask_everything;
432 va_list ap;
433 va_start(ap, handler);
434
435 sa.sa_handler = handler;
436 sigfillset(&mask_everything);
437
438 while ((sig = va_arg(ap, int)) != 0) {
439 sa.sa_mask = mask_everything;
440 /* XXX SA_RESTART? */
441 sa.sa_flags = sig == SIGCHLD ? SA_NOCLDSTOP : 0;
442 sigaction(sig, &sa, NULL);
443 }
444 va_end(ap);
445 }
446
447 /*
448 * Delete a set of signals from a mask.
449 */
450 static void
delset(sigset_t * maskp,...)451 delset(sigset_t *maskp, ...)
452 {
453 int sig;
454 va_list ap;
455 va_start(ap, maskp);
456
457 while ((sig = va_arg(ap, int)) != 0)
458 sigdelset(maskp, sig);
459 va_end(ap);
460 }
461
462 /*
463 * Log a message and sleep for a while (to give someone an opportunity
464 * to read it and to save log or hardcopy output if the problem is chronic).
465 * NB: should send a message to the session logger to avoid blocking.
466 */
467 static void
stall(const char * message,...)468 stall(const char *message, ...)
469 {
470 va_list ap;
471 va_start(ap, message);
472
473 vsyslog(LOG_ALERT, message, ap);
474 va_end(ap);
475 sleep(STALL_TIMEOUT);
476 }
477
478 /*
479 * Like stall(), but doesn't sleep.
480 * If cpp had variadic macros, the two functions could be #defines for another.
481 * NB: should send a message to the session logger to avoid blocking.
482 */
483 static void
warning(const char * message,...)484 warning(const char *message, ...)
485 {
486 va_list ap;
487 va_start(ap, message);
488
489 vsyslog(LOG_ALERT, message, ap);
490 va_end(ap);
491 }
492
493 /*
494 * Log an emergency message.
495 * NB: should send a message to the session logger to avoid blocking.
496 */
497 static void
emergency(const char * message,...)498 emergency(const char *message, ...)
499 {
500 va_list ap;
501 va_start(ap, message);
502
503 vsyslog(LOG_EMERG, message, ap);
504 va_end(ap);
505 }
506
507 /*
508 * Catch an unexpected signal.
509 */
510 static void
disaster(int sig)511 disaster(int sig)
512 {
513
514 emergency("fatal signal: %s",
515 (unsigned)sig < NSIG ? sys_siglist[sig] : "unknown signal");
516
517 sleep(STALL_TIMEOUT);
518 _exit(sig); /* reboot */
519 }
520
521 /*
522 * Get the security level of the kernel.
523 */
524 static int
getsecuritylevel(void)525 getsecuritylevel(void)
526 {
527 #ifdef KERN_SECURELVL
528 int name[2], curlevel;
529 size_t len;
530
531 name[0] = CTL_KERN;
532 name[1] = KERN_SECURELVL;
533 len = sizeof curlevel;
534 if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) {
535 emergency("cannot get kernel security level: %m");
536 return (-1);
537 }
538 return (curlevel);
539 #else
540 return (-1);
541 #endif
542 }
543
544 /*
545 * Set the security level of the kernel.
546 */
547 static void
setsecuritylevel(int newlevel)548 setsecuritylevel(int newlevel)
549 {
550 #ifdef KERN_SECURELVL
551 int name[2], curlevel;
552
553 curlevel = getsecuritylevel();
554 if (newlevel == curlevel)
555 return;
556 name[0] = CTL_KERN;
557 name[1] = KERN_SECURELVL;
558 if (sysctl(name, 2, NULL, NULL, &newlevel, sizeof newlevel) == -1) {
559 emergency(
560 "cannot change kernel security level from %d to %d: %m",
561 curlevel, newlevel);
562 return;
563 }
564 #ifdef SECURE
565 warning("kernel security level changed from %d to %d",
566 curlevel, newlevel);
567 #endif
568 #endif
569 }
570
571 /*
572 * Change states in the finite state machine.
573 * The initial state is passed as an argument.
574 */
575 static void
transition(state_t s)576 transition(state_t s)
577 {
578
579 current_state = s;
580 for (;;)
581 current_state = (state_t) (*current_state)();
582 }
583
584 /*
585 * Start a session and allocate a controlling terminal.
586 * Only called by children of init after forking.
587 */
588 static void
open_console(void)589 open_console(void)
590 {
591 int fd;
592
593 /*
594 * Try to open /dev/console. Open the device with O_NONBLOCK to
595 * prevent potential blocking on a carrier.
596 */
597 revoke(_PATH_CONSOLE);
598 if ((fd = open(_PATH_CONSOLE, O_RDWR | O_NONBLOCK)) != -1) {
599 (void)fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
600 if (login_tty(fd) == 0)
601 return;
602 close(fd);
603 }
604
605 /* No luck. Log output to file if possible. */
606 if ((fd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
607 stall("cannot open null device.");
608 _exit(1);
609 }
610 if (fd != STDIN_FILENO) {
611 dup2(fd, STDIN_FILENO);
612 close(fd);
613 }
614 fd = open(_PATH_INITLOG, O_WRONLY | O_APPEND | O_CREAT, 0644);
615 if (fd == -1)
616 dup2(STDIN_FILENO, STDOUT_FILENO);
617 else if (fd != STDOUT_FILENO) {
618 dup2(fd, STDOUT_FILENO);
619 close(fd);
620 }
621 dup2(STDOUT_FILENO, STDERR_FILENO);
622 }
623
624 static const char *
get_shell(void)625 get_shell(void)
626 {
627 static char kenv_value[PATH_MAX];
628
629 if (kenv(KENV_GET, "init_shell", kenv_value, sizeof(kenv_value)) > 0)
630 return kenv_value;
631 else
632 return _PATH_BSHELL;
633 }
634
635 static void
write_stderr(const char * message)636 write_stderr(const char *message)
637 {
638
639 write(STDERR_FILENO, message, strlen(message));
640 }
641
642 #ifdef RESCUE
643 static int
read_file(const char * path,void ** bufp,size_t * bufsizep)644 read_file(const char *path, void **bufp, size_t *bufsizep)
645 {
646 struct stat sb;
647 size_t bufsize;
648 void *buf;
649 ssize_t nbytes;
650 int error, fd;
651
652 fd = open(path, O_RDONLY);
653 if (fd < 0) {
654 emergency("%s: %m", path);
655 return (-1);
656 }
657
658 error = fstat(fd, &sb);
659 if (error != 0) {
660 emergency("fstat: %m");
661 close(fd);
662 return (error);
663 }
664
665 bufsize = sb.st_size;
666 buf = malloc(bufsize);
667 if (buf == NULL) {
668 emergency("malloc: %m");
669 close(fd);
670 return (error);
671 }
672
673 nbytes = read(fd, buf, bufsize);
674 if (nbytes != (ssize_t)bufsize) {
675 emergency("read: %m");
676 close(fd);
677 free(buf);
678 return (error);
679 }
680
681 error = close(fd);
682 if (error != 0) {
683 emergency("close: %m");
684 free(buf);
685 return (error);
686 }
687
688 *bufp = buf;
689 *bufsizep = bufsize;
690
691 return (0);
692 }
693 #endif /* RESCUE */
694
695 static int
create_file(const char * path,const void * buf,size_t bufsize)696 create_file(const char *path, const void *buf, size_t bufsize)
697 {
698 ssize_t nbytes;
699 int error, fd;
700
701 fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0700);
702 if (fd < 0) {
703 emergency("%s: %m", path);
704 return (-1);
705 }
706
707 nbytes = write(fd, buf, bufsize);
708 if (nbytes != (ssize_t)bufsize) {
709 emergency("write: %m");
710 close(fd);
711 return (-1);
712 }
713
714 error = close(fd);
715 if (error != 0) {
716 emergency("close: %m");
717 return (-1);
718 }
719
720 return (0);
721 }
722
723 static int
mount_tmpfs(const char * fspath)724 mount_tmpfs(const char *fspath)
725 {
726 struct iovec *iov;
727 char errmsg[255];
728 int error, iovlen;
729
730 iov = NULL;
731 iovlen = 0;
732 memset(errmsg, 0, sizeof(errmsg));
733 build_iovec(&iov, &iovlen, "fstype",
734 __DECONST(void *, "tmpfs"), (size_t)-1);
735 build_iovec(&iov, &iovlen, "fspath",
736 __DECONST(void *, fspath), (size_t)-1);
737 build_iovec(&iov, &iovlen, "errmsg",
738 errmsg, sizeof(errmsg));
739
740 error = nmount(iov, iovlen, 0);
741 if (error != 0) {
742 if (*errmsg != '\0') {
743 emergency("cannot mount tmpfs on %s: %s: %m",
744 fspath, errmsg);
745 } else {
746 emergency("cannot mount tmpfs on %s: %m",
747 fspath);
748 }
749 return (error);
750 }
751 return (0);
752 }
753
754 #ifndef RESCUE
755 extern char reroot_seed_start[], reroot_seed_end[];
756
757 static state_func_t
reroot(void)758 reroot(void)
759 {
760 int error;
761
762 revoke_ttys();
763 runshutdown();
764
765 /*
766 * Make sure nobody can interfere with our scheme.
767 * Ignore ESRCH, which can apparently happen when
768 * there are no processes to kill.
769 */
770 error = kill(-1, SIGKILL);
771 if (error != 0 && errno != ESRCH) {
772 emergency("kill(2) failed: %m");
773 goto out;
774 }
775
776 error = mount_tmpfs(_PATH_REROOT);
777 if (error != 0)
778 goto out;
779 error = create_file(_PATH_REROOT_INIT, reroot_seed_start,
780 reroot_seed_end - reroot_seed_start);
781 if (error != 0)
782 goto out;
783
784 /*
785 * Execute the temporary init.
786 */
787 execl(_PATH_REROOT_INIT, _PATH_REROOT_INIT, NULL);
788 emergency("cannot exec %s: %m", _PATH_REROOT_INIT);
789
790 out:
791 emergency("reroot failed; going to single user mode");
792 return (state_func_t) single_user;
793 }
794
795 #else /* !RESCUE */
796
797 static state_func_t
reroot_phase_two(void)798 reroot_phase_two(void)
799 {
800 char init_path[PATH_MAX], *path, *path_component;
801 size_t init_path_len;
802 int nbytes, error;
803
804 /*
805 * Ask the kernel to mount the new rootfs.
806 */
807 error = reboot(RB_REROOT);
808 if (error != 0) {
809 emergency("RB_REBOOT failed: %m");
810 goto out;
811 }
812
813 /*
814 * Figure out where the destination init(8) binary is. Note that
815 * the path could be different than what we've started with. Use
816 * the value from kenv, if set, or the one from sysctl otherwise.
817 * The latter defaults to a hardcoded value, but can be overridden
818 * by a build time option.
819 */
820 nbytes = kenv(KENV_GET, "init_path", init_path, sizeof(init_path));
821 if (nbytes <= 0) {
822 init_path_len = sizeof(init_path);
823 error = sysctlbyname("kern.init_path",
824 init_path, &init_path_len, NULL, 0);
825 if (error != 0) {
826 emergency("failed to retrieve kern.init_path: %m");
827 goto out;
828 }
829 }
830
831 /*
832 * Repeat the init search logic from sys/kern/init_path.c
833 */
834 path_component = init_path;
835 while ((path = strsep(&path_component, ":")) != NULL) {
836 /*
837 * Execute init(8) from the new rootfs.
838 */
839 execl(path, path, NULL);
840 }
841 emergency("cannot exec init from %s: %m", init_path);
842
843 out:
844 emergency("reroot failed; going to single user mode");
845 return (state_func_t) single_user;
846 }
847
848 static state_func_t
reroot(void)849 reroot(void)
850 {
851 void *buf;
852 size_t bufsize;
853 int error;
854
855 buf = NULL;
856 bufsize = 0;
857
858 revoke_ttys();
859 runshutdown();
860
861 /*
862 * Make sure nobody can interfere with our scheme.
863 * Ignore ESRCH, which can apparently happen when
864 * there are no processes to kill.
865 */
866 error = kill(-1, SIGKILL);
867 if (error != 0 && errno != ESRCH) {
868 emergency("kill(2) failed: %m");
869 goto out;
870 }
871
872 /*
873 * Copy the init binary into tmpfs, so that we can unmount
874 * the old rootfs without committing suicide.
875 */
876 error = read_file(init_path_argv0, &buf, &bufsize);
877 if (error != 0)
878 goto out;
879 error = mount_tmpfs(_PATH_REROOT);
880 if (error != 0)
881 goto out;
882 error = create_file(_PATH_REROOT_INIT, buf, bufsize);
883 if (error != 0)
884 goto out;
885
886 /*
887 * Execute the temporary init.
888 */
889 execl(_PATH_REROOT_INIT, _PATH_REROOT_INIT, "-r", NULL);
890 emergency("cannot exec %s: %m", _PATH_REROOT_INIT);
891
892 out:
893 emergency("reroot failed; going to single user mode");
894 return (state_func_t) single_user;
895 }
896
897 #endif /* !RESCUE */
898
899 /*
900 * Bring the system up single user.
901 */
902 static state_func_t
single_user(void)903 single_user(void)
904 {
905 pid_t pid, wpid;
906 int status;
907 sigset_t mask;
908 const char *shell;
909 char *argv[2];
910 struct timeval tv, tn;
911 struct passwd *pp;
912 #ifdef SECURE
913 struct ttyent *typ;
914 static const char banner[] =
915 "Enter root password, or ^D to go multi-user\n";
916 char *clear, *password;
917 #endif
918 #ifdef DEBUGSHELL
919 char altshell[128];
920 #endif
921
922 if (Reboot) {
923 /* Instead of going single user, let's reboot the machine */
924 BOOTTRACE("shutting down the system");
925 sync();
926 /* Run scripts after all processes have been terminated. */
927 runfinal();
928 if (reboot(howto) == -1) {
929 emergency("reboot(%#x) failed, %m", howto);
930 _exit(1); /* panic and reboot */
931 }
932 warning("reboot(%#x) returned", howto);
933 _exit(0); /* panic as well */
934 }
935
936 BOOTTRACE("going to single user mode");
937 shell = get_shell();
938
939 if ((pid = fork()) == 0) {
940 /*
941 * Start the single user session.
942 */
943 open_console();
944
945 pp = getpwnam("root");
946 #ifdef SECURE
947 /*
948 * Check the root password.
949 * We don't care if the console is 'on' by default;
950 * it's the only tty that can be 'off' and 'secure'.
951 */
952 typ = getttynam("console");
953 if (typ && (typ->ty_status & TTY_SECURE) == 0 &&
954 pp && *pp->pw_passwd) {
955 write_stderr(banner);
956 for (;;) {
957 clear = getpass("Password:");
958 if (clear == NULL || *clear == '\0')
959 _exit(0);
960 password = crypt(clear, pp->pw_passwd);
961 explicit_bzero(clear, _PASSWORD_LEN);
962 if (password != NULL &&
963 strcmp(password, pp->pw_passwd) == 0)
964 break;
965 warning("single-user login failed\n");
966 }
967 }
968 endttyent();
969 #endif /* SECURE */
970
971 #ifdef DEBUGSHELL
972 {
973 char *cp = altshell;
974 int num;
975
976 #define SHREQUEST "Enter full pathname of shell or RETURN for "
977 write_stderr(SHREQUEST);
978 write_stderr(shell);
979 write_stderr(": ");
980 while ((num = read(STDIN_FILENO, cp, 1)) != -1 &&
981 num != 0 && *cp != '\n' && cp < &altshell[127])
982 cp++;
983 *cp = '\0';
984 if (altshell[0] != '\0')
985 shell = altshell;
986 }
987 #endif /* DEBUGSHELL */
988
989 if (pp != NULL && pp->pw_dir != NULL && *pp->pw_dir != '\0' &&
990 chdir(pp->pw_dir) == 0) {
991 setenv("HOME", pp->pw_dir, 1);
992 } else {
993 chdir("/");
994 setenv("HOME", "/", 1);
995 }
996 endpwent();
997
998 /*
999 * Unblock signals.
1000 * We catch all the interesting ones,
1001 * and those are reset to SIG_DFL on exec.
1002 */
1003 sigemptyset(&mask);
1004 sigprocmask(SIG_SETMASK, &mask, NULL);
1005
1006 /*
1007 * Fire off a shell.
1008 * If the default one doesn't work, try the Bourne shell.
1009 */
1010
1011 char name[] = "-sh";
1012
1013 argv[0] = name;
1014 argv[1] = NULL;
1015 execv(shell, argv);
1016 emergency("can't exec %s for single user: %m", shell);
1017 execv(_PATH_BSHELL, argv);
1018 emergency("can't exec %s for single user: %m", _PATH_BSHELL);
1019 sleep(STALL_TIMEOUT);
1020 _exit(1);
1021 }
1022
1023 if (pid == -1) {
1024 /*
1025 * We are seriously hosed. Do our best.
1026 */
1027 emergency("can't fork single-user shell, trying again");
1028 while (waitpid(-1, (int *) 0, WNOHANG) > 0)
1029 continue;
1030 return (state_func_t) single_user;
1031 }
1032
1033 requested_transition = 0;
1034 do {
1035 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
1036 collect_child(wpid);
1037 if (wpid == -1) {
1038 if (errno == EINTR)
1039 continue;
1040 warning("wait for single-user shell failed: %m; restarting");
1041 return (state_func_t) single_user;
1042 }
1043 if (wpid == pid && WIFSTOPPED(status)) {
1044 warning("init: shell stopped, restarting\n");
1045 kill(pid, SIGCONT);
1046 wpid = -1;
1047 }
1048 } while (wpid != pid && !requested_transition);
1049
1050 if (requested_transition)
1051 return (state_func_t) requested_transition;
1052
1053 if (!WIFEXITED(status)) {
1054 if (WTERMSIG(status) == SIGKILL) {
1055 /*
1056 * reboot(8) killed shell?
1057 */
1058 warning("single user shell terminated.");
1059 gettimeofday(&tv, NULL);
1060 tn = tv;
1061 tv.tv_sec += STALL_TIMEOUT;
1062 while (tv.tv_sec > tn.tv_sec || (tv.tv_sec ==
1063 tn.tv_sec && tv.tv_usec > tn.tv_usec)) {
1064 sleep(1);
1065 gettimeofday(&tn, NULL);
1066 }
1067 _exit(0);
1068 } else {
1069 warning("single user shell terminated, restarting");
1070 return (state_func_t) single_user;
1071 }
1072 }
1073
1074 runcom_mode = FASTBOOT;
1075 return (state_func_t) runcom;
1076 }
1077
1078 /*
1079 * Run the system startup script.
1080 */
1081 static state_func_t
runcom(void)1082 runcom(void)
1083 {
1084 state_func_t next_transition;
1085 char runcom_path[PATH_MAX];
1086 const char *rc_script;
1087
1088 /*
1089 * Allow overriding /etc/rc via the init_rc kenv variable.
1090 * This is useful for testing alternative service managers
1091 * without modifying /etc/rc.
1092 */
1093 if (kenv(KENV_GET, "init_rc", runcom_path, sizeof(runcom_path)) > 0)
1094 rc_script = runcom_path;
1095 else
1096 rc_script = _PATH_RUNCOM;
1097
1098 BOOTTRACE("%s starting...", rc_script);
1099 if ((next_transition = run_script(rc_script)) != NULL)
1100 return next_transition;
1101 BOOTTRACE("%s finished", rc_script);
1102
1103 runcom_mode = AUTOBOOT; /* the default */
1104 return (state_func_t) read_ttys;
1105 }
1106
1107 static void
execute_script(char * argv[])1108 execute_script(char *argv[])
1109 {
1110 struct sigaction sa;
1111 char* sh_argv[3 + SCRIPT_ARGV_SIZE];
1112 const char *shell, *script;
1113 int error, sh_argv_len, i;
1114
1115 bzero(&sa, sizeof(sa));
1116 sigemptyset(&sa.sa_mask);
1117 sa.sa_handler = SIG_IGN;
1118 sigaction(SIGTSTP, &sa, NULL);
1119 sigaction(SIGHUP, &sa, NULL);
1120
1121 open_console();
1122
1123 sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);
1124 #ifdef LOGIN_CAP
1125 setprocresources(RESOURCE_RC);
1126 #endif
1127
1128 /*
1129 * Try to directly execute the script first. If it
1130 * fails, try the old method of passing the script path
1131 * to sh(1). Don't complain if it fails because of
1132 * the missing execute bit.
1133 */
1134 script = argv[0];
1135 error = access(script, X_OK);
1136 if (error == 0) {
1137 execv(script, argv);
1138 warning("can't directly exec %s: %m", script);
1139 } else if (errno != EACCES) {
1140 warning("can't access %s: %m", script);
1141 }
1142
1143 shell = get_shell();
1144 sh_argv[0] = __DECONST(char*, shell);
1145 sh_argv_len = 1;
1146 #ifdef SECURE
1147 if (strcmp(shell, _PATH_BSHELL) == 0) {
1148 sh_argv[1] = __DECONST(char*, "-o");
1149 sh_argv[2] = __DECONST(char*, "verify");
1150 sh_argv_len = 3;
1151 }
1152 #endif
1153 for (i = 0; i != SCRIPT_ARGV_SIZE; ++i)
1154 sh_argv[i + sh_argv_len] = argv[i];
1155 execv(shell, sh_argv);
1156 stall("can't exec %s for %s: %m", shell, script);
1157 }
1158
1159 /*
1160 * Execute binary, replacing init(8) as PID 1.
1161 */
1162 static void
replace_init(char * path)1163 replace_init(char *path)
1164 {
1165 char *argv[SCRIPT_ARGV_SIZE];
1166
1167 argv[0] = path;
1168 argv[1] = NULL;
1169
1170 execute_script(argv);
1171 }
1172
1173 /*
1174 * Run a shell script.
1175 * Returns 0 on success, otherwise the next transition to enter:
1176 * - single_user if fork/execv/waitpid failed, or if the script
1177 * terminated with a signal or exit code != 0.
1178 * - death_single if a SIGTERM was delivered to init(8).
1179 */
1180 static state_func_t
run_script(const char * script)1181 run_script(const char *script)
1182 {
1183 pid_t pid, wpid;
1184 int status;
1185 char *argv[SCRIPT_ARGV_SIZE];
1186 const char *shell;
1187
1188 shell = get_shell();
1189
1190 if ((pid = fork()) == 0) {
1191
1192 char _autoboot[] = "autoboot";
1193
1194 argv[0] = __DECONST(char *, script);
1195 argv[1] = runcom_mode == AUTOBOOT ? _autoboot : NULL;
1196 argv[2] = NULL;
1197
1198 execute_script(argv);
1199 sleep(STALL_TIMEOUT);
1200 _exit(1); /* force single user mode */
1201 }
1202
1203 if (pid == -1) {
1204 emergency("can't fork for %s on %s: %m", shell, script);
1205 while (waitpid(-1, (int *) 0, WNOHANG) > 0)
1206 continue;
1207 sleep(STALL_TIMEOUT);
1208 return (state_func_t) single_user;
1209 }
1210
1211 /*
1212 * Copied from single_user(). This is a bit paranoid.
1213 */
1214 requested_transition = 0;
1215 do {
1216 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
1217 collect_child(wpid);
1218 if (requested_transition == death_single ||
1219 requested_transition == reroot)
1220 return (state_func_t) requested_transition;
1221 if (wpid == -1) {
1222 if (errno == EINTR)
1223 continue;
1224 warning("wait for %s on %s failed: %m; going to "
1225 "single user mode", shell, script);
1226 return (state_func_t) single_user;
1227 }
1228 if (wpid == pid && WIFSTOPPED(status)) {
1229 warning("init: %s on %s stopped, restarting\n",
1230 shell, script);
1231 kill(pid, SIGCONT);
1232 wpid = -1;
1233 }
1234 } while (wpid != pid);
1235
1236 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM &&
1237 requested_transition == catatonia) {
1238 /* /etc/rc executed /sbin/reboot; wait for the end quietly */
1239 sigset_t s;
1240
1241 sigfillset(&s);
1242 for (;;)
1243 sigsuspend(&s);
1244 }
1245
1246 if (!WIFEXITED(status)) {
1247 warning("%s on %s terminated abnormally, going to single "
1248 "user mode", shell, script);
1249 return (state_func_t) single_user;
1250 }
1251
1252 if (WEXITSTATUS(status))
1253 return (state_func_t) single_user;
1254
1255 return (state_func_t) 0;
1256 }
1257
1258 /*
1259 * Open the session database.
1260 *
1261 * NB: We could pass in the size here; is it necessary?
1262 */
1263 static int
start_session_db(void)1264 start_session_db(void)
1265 {
1266 if (session_db && (*session_db->close)(session_db))
1267 emergency("session database close: %m");
1268 if ((session_db = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL)) == NULL) {
1269 emergency("session database open: %m");
1270 return (1);
1271 }
1272 return (0);
1273
1274 }
1275
1276 /*
1277 * Add a new login session.
1278 */
1279 static void
add_session(session_t * sp)1280 add_session(session_t *sp)
1281 {
1282 DBT key;
1283 DBT data;
1284
1285 key.data = &sp->se_process;
1286 key.size = sizeof sp->se_process;
1287 data.data = &sp;
1288 data.size = sizeof sp;
1289
1290 if ((*session_db->put)(session_db, &key, &data, 0))
1291 emergency("insert %d: %m", sp->se_process);
1292 }
1293
1294 /*
1295 * Delete an old login session.
1296 */
1297 static void
del_session(session_t * sp)1298 del_session(session_t *sp)
1299 {
1300 DBT key;
1301
1302 key.data = &sp->se_process;
1303 key.size = sizeof sp->se_process;
1304
1305 if ((*session_db->del)(session_db, &key, 0))
1306 emergency("delete %d: %m", sp->se_process);
1307 }
1308
1309 /*
1310 * Look up a login session by pid.
1311 */
1312 static session_t *
find_session(pid_t pid)1313 find_session(pid_t pid)
1314 {
1315 DBT key;
1316 DBT data;
1317 session_t *ret;
1318
1319 key.data = &pid;
1320 key.size = sizeof pid;
1321 if ((*session_db->get)(session_db, &key, &data, 0) != 0)
1322 return 0;
1323 bcopy(data.data, (char *)&ret, sizeof(ret));
1324 return ret;
1325 }
1326
1327 /*
1328 * Construct an argument vector from a command line.
1329 */
1330 static char **
construct_argv(char * command)1331 construct_argv(char *command)
1332 {
1333 int argc = 0;
1334 char **argv = (char **) malloc(((strlen(command) + 1) / 2 + 1)
1335 * sizeof (char *));
1336
1337 if ((argv[argc++] = strk(command)) == NULL) {
1338 free(argv);
1339 return (NULL);
1340 }
1341 while ((argv[argc++] = strk((char *) 0)) != NULL)
1342 continue;
1343 return argv;
1344 }
1345
1346 /*
1347 * Deallocate a session descriptor.
1348 */
1349 static void
free_session(session_t * sp)1350 free_session(session_t *sp)
1351 {
1352 free(sp->se_device);
1353 if (sp->se_getty) {
1354 free(sp->se_getty);
1355 free(sp->se_getty_argv_space);
1356 free(sp->se_getty_argv);
1357 }
1358 if (sp->se_window) {
1359 free(sp->se_window);
1360 free(sp->se_window_argv_space);
1361 free(sp->se_window_argv);
1362 }
1363 if (sp->se_type)
1364 free(sp->se_type);
1365 free(sp);
1366 }
1367
1368 /*
1369 * Allocate a new session descriptor.
1370 * Mark it SE_PRESENT.
1371 */
1372 static session_t *
new_session(session_t * sprev,struct ttyent * typ)1373 new_session(session_t *sprev, struct ttyent *typ)
1374 {
1375 session_t *sp;
1376
1377 if ((typ->ty_status & TTY_ON) == 0 ||
1378 typ->ty_name == 0 ||
1379 typ->ty_getty == 0)
1380 return 0;
1381
1382 sp = (session_t *) calloc(1, sizeof (session_t));
1383
1384 sp->se_flags |= SE_PRESENT;
1385
1386 if ((typ->ty_status & TTY_IFEXISTS) != 0)
1387 sp->se_flags |= SE_IFEXISTS;
1388
1389 if ((typ->ty_status & TTY_IFCONSOLE) != 0)
1390 sp->se_flags |= SE_IFCONSOLE;
1391
1392 if (asprintf(&sp->se_device, "%s%s", _PATH_DEV, typ->ty_name) < 0)
1393 err(1, "asprintf");
1394
1395 if (setupargv(sp, typ) == 0) {
1396 free_session(sp);
1397 return (0);
1398 }
1399
1400 sp->se_next = 0;
1401 if (sprev == NULL) {
1402 sessions = sp;
1403 sp->se_prev = 0;
1404 } else {
1405 sprev->se_next = sp;
1406 sp->se_prev = sprev;
1407 }
1408
1409 return sp;
1410 }
1411
1412 /*
1413 * Calculate getty and if useful window argv vectors.
1414 */
1415 static int
setupargv(session_t * sp,struct ttyent * typ)1416 setupargv(session_t *sp, struct ttyent *typ)
1417 {
1418
1419 if (sp->se_getty) {
1420 free(sp->se_getty);
1421 free(sp->se_getty_argv_space);
1422 free(sp->se_getty_argv);
1423 }
1424 if (asprintf(&sp->se_getty, "%s %s", typ->ty_getty, typ->ty_name) < 0)
1425 err(1, "asprintf");
1426 sp->se_getty_argv_space = strdup(sp->se_getty);
1427 sp->se_getty_argv = construct_argv(sp->se_getty_argv_space);
1428 if (sp->se_getty_argv == NULL) {
1429 warning("can't parse getty for port %s", sp->se_device);
1430 free(sp->se_getty);
1431 free(sp->se_getty_argv_space);
1432 sp->se_getty = sp->se_getty_argv_space = 0;
1433 return (0);
1434 }
1435 if (sp->se_window) {
1436 free(sp->se_window);
1437 free(sp->se_window_argv_space);
1438 free(sp->se_window_argv);
1439 }
1440 sp->se_window = sp->se_window_argv_space = 0;
1441 sp->se_window_argv = 0;
1442 if (typ->ty_window) {
1443 sp->se_window = strdup(typ->ty_window);
1444 sp->se_window_argv_space = strdup(sp->se_window);
1445 sp->se_window_argv = construct_argv(sp->se_window_argv_space);
1446 if (sp->se_window_argv == NULL) {
1447 warning("can't parse window for port %s",
1448 sp->se_device);
1449 free(sp->se_window_argv_space);
1450 free(sp->se_window);
1451 sp->se_window = sp->se_window_argv_space = 0;
1452 return (0);
1453 }
1454 }
1455 if (sp->se_type)
1456 free(sp->se_type);
1457 sp->se_type = typ->ty_type ? strdup(typ->ty_type) : 0;
1458 return (1);
1459 }
1460
1461 /*
1462 * Walk the list of ttys and create sessions for each active line.
1463 */
1464 static state_func_t
read_ttys(void)1465 read_ttys(void)
1466 {
1467 session_t *sp, *snext;
1468 struct ttyent *typ;
1469
1470 /*
1471 * Destroy any previous session state.
1472 * There shouldn't be any, but just in case...
1473 */
1474 for (sp = sessions; sp; sp = snext) {
1475 snext = sp->se_next;
1476 free_session(sp);
1477 }
1478 sessions = 0;
1479 if (start_session_db())
1480 return (state_func_t) single_user;
1481
1482 /*
1483 * Allocate a session entry for each active port.
1484 * Note that sp starts at 0.
1485 */
1486 while ((typ = getttyent()) != NULL)
1487 if ((snext = new_session(sp, typ)) != NULL)
1488 sp = snext;
1489
1490 endttyent();
1491
1492 return (state_func_t) multi_user;
1493 }
1494
1495 /*
1496 * Start a window system running.
1497 */
1498 static void
start_window_system(session_t * sp)1499 start_window_system(session_t *sp)
1500 {
1501 pid_t pid;
1502 sigset_t mask;
1503 char term[64], *env[2];
1504 int status;
1505
1506 if ((pid = fork()) == -1) {
1507 emergency("can't fork for window system on port %s: %m",
1508 sp->se_device);
1509 /* hope that getty fails and we can try again */
1510 return;
1511 }
1512 if (pid) {
1513 waitpid(-1, &status, 0);
1514 return;
1515 }
1516
1517 /* reparent window process to the init to not make a zombie on exit */
1518 if ((pid = fork()) == -1) {
1519 emergency("can't fork for window system on port %s: %m",
1520 sp->se_device);
1521 _exit(1);
1522 }
1523 if (pid)
1524 _exit(0);
1525
1526 sigemptyset(&mask);
1527 sigprocmask(SIG_SETMASK, &mask, NULL);
1528
1529 if (setsid() < 0)
1530 emergency("setsid failed (window) %m");
1531
1532 #ifdef LOGIN_CAP
1533 setprocresources(RESOURCE_WINDOW);
1534 #endif
1535 if (sp->se_type) {
1536 /* Don't use malloc after fork */
1537 strcpy(term, "TERM=");
1538 strlcat(term, sp->se_type, sizeof(term));
1539 env[0] = term;
1540 env[1] = NULL;
1541 }
1542 else
1543 env[0] = NULL;
1544 execve(sp->se_window_argv[0], sp->se_window_argv, env);
1545 stall("can't exec window system '%s' for port %s: %m",
1546 sp->se_window_argv[0], sp->se_device);
1547 _exit(1);
1548 }
1549
1550 /*
1551 * Start a login session running.
1552 */
1553 static pid_t
start_getty(session_t * sp)1554 start_getty(session_t *sp)
1555 {
1556 pid_t pid;
1557 sigset_t mask;
1558 time_t current_time = time((time_t *) 0);
1559 int too_quick = 0;
1560 char term[64], *env[2];
1561
1562 if (current_time >= sp->se_started &&
1563 current_time - sp->se_started < GETTY_SPACING) {
1564 if (++sp->se_nspace > GETTY_NSPACE) {
1565 sp->se_nspace = 0;
1566 too_quick = 1;
1567 }
1568 } else
1569 sp->se_nspace = 0;
1570
1571 /*
1572 * fork(), not vfork() -- we can't afford to block.
1573 */
1574 if ((pid = fork()) == -1) {
1575 emergency("can't fork for getty on port %s: %m", sp->se_device);
1576 return -1;
1577 }
1578
1579 if (pid)
1580 return pid;
1581
1582 if (too_quick) {
1583 warning("getty repeating too quickly on port %s, sleeping %d secs",
1584 sp->se_device, GETTY_SLEEP);
1585 sleep((unsigned) GETTY_SLEEP);
1586 }
1587
1588 if (sp->se_window) {
1589 start_window_system(sp);
1590 sleep(WINDOW_WAIT);
1591 }
1592
1593 sigemptyset(&mask);
1594 sigprocmask(SIG_SETMASK, &mask, NULL);
1595
1596 #ifdef LOGIN_CAP
1597 setprocresources(RESOURCE_GETTY);
1598 #endif
1599 if (sp->se_type) {
1600 /* Don't use malloc after fork */
1601 strcpy(term, "TERM=");
1602 strlcat(term, sp->se_type, sizeof(term));
1603 env[0] = term;
1604 env[1] = NULL;
1605 } else
1606 env[0] = NULL;
1607 execve(sp->se_getty_argv[0], sp->se_getty_argv, env);
1608 stall("can't exec getty '%s' for port %s: %m",
1609 sp->se_getty_argv[0], sp->se_device);
1610 _exit(1);
1611 }
1612
1613 /*
1614 * Return 1 if the session is defined as "onifexists"
1615 * or "onifconsole" and the device node does not exist.
1616 */
1617 static int
session_has_no_tty(session_t * sp)1618 session_has_no_tty(session_t *sp)
1619 {
1620 int fd;
1621
1622 if ((sp->se_flags & SE_IFEXISTS) == 0 &&
1623 (sp->se_flags & SE_IFCONSOLE) == 0)
1624 return (0);
1625
1626 fd = open(sp->se_device, O_RDONLY | O_NONBLOCK, 0);
1627 if (fd < 0) {
1628 if (errno == ENOENT)
1629 return (1);
1630 return (0);
1631 }
1632
1633 close(fd);
1634 return (0);
1635 }
1636
1637 /*
1638 * Collect exit status for a child.
1639 * If an exiting login, start a new login running.
1640 */
1641 static void
collect_child(pid_t pid)1642 collect_child(pid_t pid)
1643 {
1644 session_t *sp, *sprev, *snext;
1645
1646 if (! sessions)
1647 return;
1648
1649 if (! (sp = find_session(pid)))
1650 return;
1651
1652 del_session(sp);
1653 sp->se_process = 0;
1654
1655 if (sp->se_flags & SE_SHUTDOWN ||
1656 session_has_no_tty(sp)) {
1657 if ((sprev = sp->se_prev) != NULL)
1658 sprev->se_next = sp->se_next;
1659 else
1660 sessions = sp->se_next;
1661 if ((snext = sp->se_next) != NULL)
1662 snext->se_prev = sp->se_prev;
1663 free_session(sp);
1664 return;
1665 }
1666
1667 if ((pid = start_getty(sp)) == -1) {
1668 /* serious trouble */
1669 requested_transition = clean_ttys;
1670 return;
1671 }
1672
1673 sp->se_process = pid;
1674 sp->se_started = time((time_t *) 0);
1675 add_session(sp);
1676 }
1677
1678 static const char *
get_current_state(void)1679 get_current_state(void)
1680 {
1681
1682 if (current_state == single_user)
1683 return ("single-user");
1684 if (current_state == runcom)
1685 return ("runcom");
1686 if (current_state == read_ttys)
1687 return ("read-ttys");
1688 if (current_state == multi_user)
1689 return ("multi-user");
1690 if (current_state == clean_ttys)
1691 return ("clean-ttys");
1692 if (current_state == catatonia)
1693 return ("catatonia");
1694 if (current_state == death)
1695 return ("death");
1696 if (current_state == death_single)
1697 return ("death-single");
1698 return ("unknown");
1699 }
1700
1701 static void
boottrace_transition(int sig)1702 boottrace_transition(int sig)
1703 {
1704 const char *action;
1705
1706 switch (sig) {
1707 case SIGUSR2:
1708 action = "halt & poweroff";
1709 break;
1710 case SIGUSR1:
1711 action = "halt";
1712 break;
1713 case SIGINT:
1714 action = "reboot";
1715 break;
1716 case SIGWINCH:
1717 action = "powercycle";
1718 break;
1719 case SIGTERM:
1720 action = Reboot ? "reboot" : "single-user";
1721 break;
1722 default:
1723 BOOTTRACE("signal %d from %s", sig, get_current_state());
1724 return;
1725 }
1726
1727 /* Trace the shutdown reason. */
1728 SHUTTRACE("%s from %s", action, get_current_state());
1729 }
1730
1731 /*
1732 * Catch a signal and request a state transition.
1733 */
1734 static void
transition_handler(int sig)1735 transition_handler(int sig)
1736 {
1737
1738 boottrace_transition(sig);
1739 switch (sig) {
1740 case SIGHUP:
1741 if (current_state == read_ttys || current_state == multi_user ||
1742 current_state == clean_ttys || current_state == catatonia)
1743 requested_transition = clean_ttys;
1744 break;
1745 case SIGUSR2:
1746 howto = RB_POWEROFF;
1747 case SIGUSR1:
1748 howto |= RB_HALT;
1749 case SIGWINCH:
1750 case SIGINT:
1751 if (sig == SIGWINCH)
1752 howto |= RB_POWERCYCLE;
1753 Reboot = true;
1754 case SIGTERM:
1755 if (current_state == read_ttys || current_state == multi_user ||
1756 current_state == clean_ttys || current_state == catatonia)
1757 requested_transition = death;
1758 else
1759 requested_transition = death_single;
1760 break;
1761 case SIGTSTP:
1762 if (current_state == runcom || current_state == read_ttys ||
1763 current_state == clean_ttys ||
1764 current_state == multi_user || current_state == catatonia)
1765 requested_transition = catatonia;
1766 break;
1767 case SIGEMT:
1768 requested_transition = reroot;
1769 break;
1770 default:
1771 requested_transition = 0;
1772 break;
1773 }
1774 }
1775
1776 /*
1777 * Take the system multiuser.
1778 */
1779 static state_func_t
multi_user(void)1780 multi_user(void)
1781 {
1782 static bool inmultiuser = false;
1783 pid_t pid;
1784 session_t *sp;
1785
1786 requested_transition = 0;
1787
1788 /*
1789 * If the administrator has not set the security level to -1
1790 * to indicate that the kernel should not run multiuser in secure
1791 * mode, and the run script has not set a higher level of security
1792 * than level 1, then put the kernel into secure mode.
1793 */
1794 if (getsecuritylevel() == 0)
1795 setsecuritylevel(1);
1796
1797 for (sp = sessions; sp; sp = sp->se_next) {
1798 if (sp->se_process)
1799 continue;
1800 if (session_has_no_tty(sp))
1801 continue;
1802 if ((pid = start_getty(sp)) == -1) {
1803 /* serious trouble */
1804 requested_transition = clean_ttys;
1805 break;
1806 }
1807 sp->se_process = pid;
1808 sp->se_started = time((time_t *) 0);
1809 add_session(sp);
1810 }
1811
1812 if (requested_transition == 0 && !inmultiuser) {
1813 inmultiuser = true;
1814 /* This marks the change from boot-time tracing to run-time. */
1815 RUNTRACE("multi-user start");
1816 }
1817 while (!requested_transition)
1818 if ((pid = waitpid(-1, (int *) 0, 0)) != -1)
1819 collect_child(pid);
1820
1821 return (state_func_t) requested_transition;
1822 }
1823
1824 /*
1825 * This is an (n*2)+(n^2) algorithm. We hope it isn't run often...
1826 */
1827 static state_func_t
clean_ttys(void)1828 clean_ttys(void)
1829 {
1830 session_t *sp, *sprev;
1831 struct ttyent *typ;
1832 int devlen;
1833 char *old_getty, *old_window, *old_type;
1834
1835 /*
1836 * mark all sessions for death, (!SE_PRESENT)
1837 * as we find or create new ones they'll be marked as keepers,
1838 * we'll later nuke all the ones not found in /etc/ttys
1839 */
1840 for (sp = sessions; sp != NULL; sp = sp->se_next)
1841 sp->se_flags &= ~SE_PRESENT;
1842
1843 devlen = sizeof(_PATH_DEV) - 1;
1844 while ((typ = getttyent()) != NULL) {
1845 for (sprev = 0, sp = sessions; sp; sprev = sp, sp = sp->se_next)
1846 if (strcmp(typ->ty_name, sp->se_device + devlen) == 0)
1847 break;
1848
1849 if (sp) {
1850 /* we want this one to live */
1851 sp->se_flags |= SE_PRESENT;
1852 if ((typ->ty_status & TTY_ON) == 0 ||
1853 typ->ty_getty == 0) {
1854 sp->se_flags |= SE_SHUTDOWN;
1855 kill(sp->se_process, SIGHUP);
1856 continue;
1857 }
1858 sp->se_flags &= ~SE_SHUTDOWN;
1859 old_getty = sp->se_getty ? strdup(sp->se_getty) : 0;
1860 old_window = sp->se_window ? strdup(sp->se_window) : 0;
1861 old_type = sp->se_type ? strdup(sp->se_type) : 0;
1862 if (setupargv(sp, typ) == 0) {
1863 warning("can't parse getty for port %s",
1864 sp->se_device);
1865 sp->se_flags |= SE_SHUTDOWN;
1866 kill(sp->se_process, SIGHUP);
1867 }
1868 else if ( !old_getty
1869 || (!old_type && sp->se_type)
1870 || (old_type && !sp->se_type)
1871 || (!old_window && sp->se_window)
1872 || (old_window && !sp->se_window)
1873 || (strcmp(old_getty, sp->se_getty) != 0)
1874 || (old_window && strcmp(old_window, sp->se_window) != 0)
1875 || (old_type && strcmp(old_type, sp->se_type) != 0)
1876 ) {
1877 /* Don't set SE_SHUTDOWN here */
1878 sp->se_nspace = 0;
1879 sp->se_started = 0;
1880 kill(sp->se_process, SIGHUP);
1881 }
1882 if (old_getty)
1883 free(old_getty);
1884 if (old_window)
1885 free(old_window);
1886 if (old_type)
1887 free(old_type);
1888 continue;
1889 }
1890
1891 new_session(sprev, typ);
1892 }
1893
1894 endttyent();
1895
1896 /*
1897 * sweep through and kill all deleted sessions
1898 * ones who's /etc/ttys line was deleted (SE_PRESENT unset)
1899 */
1900 for (sp = sessions; sp != NULL; sp = sp->se_next) {
1901 if ((sp->se_flags & SE_PRESENT) == 0) {
1902 sp->se_flags |= SE_SHUTDOWN;
1903 kill(sp->se_process, SIGHUP);
1904 }
1905 }
1906
1907 return (state_func_t) multi_user;
1908 }
1909
1910 /*
1911 * Block further logins.
1912 */
1913 static state_func_t
catatonia(void)1914 catatonia(void)
1915 {
1916 session_t *sp;
1917
1918 for (sp = sessions; sp; sp = sp->se_next)
1919 sp->se_flags |= SE_SHUTDOWN;
1920
1921 return (state_func_t) multi_user;
1922 }
1923
1924 /*
1925 * Note SIGALRM.
1926 */
1927 static void
alrm_handler(int sig)1928 alrm_handler(int sig)
1929 {
1930
1931 (void)sig;
1932 clang = true;
1933 }
1934
1935 /*
1936 * Bring the system down to single user.
1937 */
1938 static state_func_t
death(void)1939 death(void)
1940 {
1941 int block, blocked;
1942 size_t len;
1943
1944 /* Temporarily block suspend. */
1945 len = sizeof(blocked);
1946 block = 1;
1947 if (sysctlbyname("kern.suspend_blocked", &blocked, &len,
1948 &block, sizeof(block)) == -1)
1949 blocked = 0;
1950
1951 /*
1952 * Also revoke the TTY here. Because runshutdown() may reopen
1953 * the TTY whose getty we're killing here, there is no guarantee
1954 * runshutdown() will perform the initial open() call, causing
1955 * the terminal attributes to be misconfigured.
1956 */
1957 revoke_ttys();
1958
1959 /* Try to run the rc.shutdown script within a period of time */
1960 runshutdown();
1961
1962 /* Unblock suspend if we blocked it. */
1963 if (!blocked)
1964 sysctlbyname("kern.suspend_blocked", NULL, NULL,
1965 &blocked, sizeof(blocked));
1966
1967 return (state_func_t) death_single;
1968 }
1969
1970 /*
1971 * Do what is necessary to reinitialize single user mode or reboot
1972 * from an incomplete state.
1973 */
1974 static state_func_t
death_single(void)1975 death_single(void)
1976 {
1977 int i;
1978 pid_t pid;
1979 static const int death_sigs[2] = { SIGTERM, SIGKILL };
1980
1981 revoke(_PATH_CONSOLE);
1982
1983 BOOTTRACE("start killing user processes");
1984 for (i = 0; i < 2; ++i) {
1985 if (kill(-1, death_sigs[i]) == -1 && errno == ESRCH)
1986 return (state_func_t) single_user;
1987
1988 clang = false;
1989 alarm(DEATH_WATCH);
1990 do
1991 if ((pid = waitpid(-1, (int *)0, 0)) != -1)
1992 collect_child(pid);
1993 while (!clang && errno != ECHILD);
1994
1995 if (errno == ECHILD)
1996 return (state_func_t) single_user;
1997 }
1998
1999 warning("some processes would not die; ps axl advised");
2000
2001 return (state_func_t) single_user;
2002 }
2003
2004 static void
revoke_ttys(void)2005 revoke_ttys(void)
2006 {
2007 session_t *sp;
2008
2009 for (sp = sessions; sp; sp = sp->se_next) {
2010 sp->se_flags |= SE_SHUTDOWN;
2011 kill(sp->se_process, SIGHUP);
2012 revoke(sp->se_device);
2013 }
2014 }
2015
2016 /*
2017 * Run the system shutdown script.
2018 *
2019 * Exit codes: XXX I should document more
2020 * -2 shutdown script terminated abnormally
2021 * -1 fatal error - can't run script
2022 * 0 good.
2023 * >0 some error (exit code)
2024 */
2025 static int
runshutdown(void)2026 runshutdown(void)
2027 {
2028 pid_t pid, wpid;
2029 int status;
2030 int shutdowntimeout;
2031 size_t len;
2032 char *argv[SCRIPT_ARGV_SIZE];
2033 struct stat sb;
2034
2035 BOOTTRACE("init(8): start rc.shutdown");
2036
2037 /*
2038 * rc.shutdown is optional, so to prevent any unnecessary
2039 * complaints from the shell we simply don't run it if the
2040 * file does not exist. If the stat() here fails for other
2041 * reasons, we'll let the shell complain.
2042 */
2043 if (stat(_PATH_RUNDOWN, &sb) == -1 && errno == ENOENT)
2044 return 0;
2045
2046 if ((pid = fork()) == 0) {
2047 char _reboot[] = "reboot";
2048 char _single[] = "single";
2049 char _path_rundown[] = _PATH_RUNDOWN;
2050
2051 argv[0] = _path_rundown;
2052 argv[1] = Reboot ? _reboot : _single;
2053 argv[2] = NULL;
2054
2055 execute_script(argv);
2056 _exit(1); /* force single user mode */
2057 }
2058
2059 if (pid == -1) {
2060 emergency("can't fork for %s: %m", _PATH_RUNDOWN);
2061 while (waitpid(-1, (int *) 0, WNOHANG) > 0)
2062 continue;
2063 sleep(STALL_TIMEOUT);
2064 return -1;
2065 }
2066
2067 len = sizeof(shutdowntimeout);
2068 if (sysctlbyname("kern.init_shutdown_timeout", &shutdowntimeout, &len,
2069 NULL, 0) == -1 || shutdowntimeout < 2)
2070 shutdowntimeout = DEATH_SCRIPT;
2071 alarm(shutdowntimeout);
2072 clang = false;
2073 /*
2074 * Copied from single_user(). This is a bit paranoid.
2075 * Use the same ALRM handler.
2076 */
2077 do {
2078 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
2079 collect_child(wpid);
2080 if (clang) {
2081 /* we were waiting for the sub-shell */
2082 kill(wpid, SIGTERM);
2083 warning("timeout expired for %s: %m; going to "
2084 "single user mode", _PATH_RUNDOWN);
2085 BOOTTRACE("rc.shutdown's %d sec timeout expired",
2086 shutdowntimeout);
2087 return -1;
2088 }
2089 if (wpid == -1) {
2090 if (errno == EINTR)
2091 continue;
2092 warning("wait for %s failed: %m; going to "
2093 "single user mode", _PATH_RUNDOWN);
2094 return -1;
2095 }
2096 if (wpid == pid && WIFSTOPPED(status)) {
2097 warning("init: %s stopped, restarting\n",
2098 _PATH_RUNDOWN);
2099 kill(pid, SIGCONT);
2100 wpid = -1;
2101 }
2102 } while (wpid != pid && !clang);
2103
2104 /* Turn off the alarm */
2105 alarm(0);
2106
2107 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM &&
2108 requested_transition == catatonia) {
2109 /*
2110 * /etc/rc.shutdown executed /sbin/reboot;
2111 * wait for the end quietly
2112 */
2113 sigset_t s;
2114
2115 sigfillset(&s);
2116 for (;;)
2117 sigsuspend(&s);
2118 }
2119
2120 if (!WIFEXITED(status)) {
2121 warning("%s terminated abnormally, going to "
2122 "single user mode", _PATH_RUNDOWN);
2123 return -2;
2124 }
2125
2126 if ((status = WEXITSTATUS(status)) != 0)
2127 warning("%s returned status %d", _PATH_RUNDOWN, status);
2128
2129 return status;
2130 }
2131
2132 static char *
strk(char * p)2133 strk(char *p)
2134 {
2135 static char *t;
2136 char *q;
2137 int c;
2138
2139 if (p)
2140 t = p;
2141 if (!t)
2142 return 0;
2143
2144 c = *t;
2145 while (c == ' ' || c == '\t' )
2146 c = *++t;
2147 if (!c) {
2148 t = 0;
2149 return 0;
2150 }
2151 q = t;
2152 if (c == '\'') {
2153 c = *++t;
2154 q = t;
2155 while (c && c != '\'')
2156 c = *++t;
2157 if (!c) /* unterminated string */
2158 q = t = 0;
2159 else
2160 *t++ = 0;
2161 } else {
2162 while (c && c != ' ' && c != '\t' )
2163 c = *++t;
2164 *t++ = 0;
2165 if (!c)
2166 t = 0;
2167 }
2168 return q;
2169 }
2170
2171 #ifdef LOGIN_CAP
2172 static void
setprocresources(const char * cname)2173 setprocresources(const char *cname)
2174 {
2175 login_cap_t *lc;
2176 if ((lc = login_getclassbyname(cname, NULL)) != NULL) {
2177 setusercontext(lc, (struct passwd*)NULL, 0,
2178 LOGIN_SETENV |
2179 LOGIN_SETPRIORITY | LOGIN_SETRESOURCES |
2180 LOGIN_SETLOGINCLASS | LOGIN_SETCPUMASK);
2181 login_close(lc);
2182 }
2183 }
2184 #endif
2185
2186 /*
2187 * Run /etc/rc.final to execute scripts after all user processes have been
2188 * terminated.
2189 */
2190 static void
runfinal(void)2191 runfinal(void)
2192 {
2193 struct stat sb;
2194 pid_t other_pid, pid;
2195 sigset_t mask;
2196
2197 /* Avoid any surprises. */
2198 alarm(0);
2199
2200 /* rc.final is optional. */
2201 if (stat(_PATH_RUNFINAL, &sb) == -1 && errno == ENOENT)
2202 return;
2203 if (access(_PATH_RUNFINAL, X_OK) != 0) {
2204 warning("%s exists, but not executable", _PATH_RUNFINAL);
2205 return;
2206 }
2207
2208 pid = fork();
2209 if (pid == 0) {
2210 /*
2211 * Reopen stdin/stdout/stderr so that scripts can write to
2212 * console.
2213 */
2214 close(0);
2215 open(_PATH_DEVNULL, O_RDONLY);
2216 close(1);
2217 close(2);
2218 open_console();
2219 dup2(1, 2);
2220 sigemptyset(&mask);
2221 sigprocmask(SIG_SETMASK, &mask, NULL);
2222 signal(SIGCHLD, SIG_DFL);
2223 execl(_PATH_RUNFINAL, _PATH_RUNFINAL, NULL);
2224 perror("execl(" _PATH_RUNFINAL ") failed");
2225 exit(1);
2226 }
2227
2228 /* Wait for rc.final script to exit */
2229 while ((other_pid = waitpid(-1, NULL, 0)) != pid && other_pid > 0) {
2230 continue;
2231 }
2232 }
2233