init.c revision 1.108 1 /* $NetBSD: init.c,v 1.108 2020/06/22 07:50:53 msaitoh Exp $ */
2
3 /*-
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Donn Seeley at Berkeley Software Design, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #include <sys/cdefs.h>
36 #ifndef lint
37 __COPYRIGHT("@(#) Copyright (c) 1991, 1993\
38 The Regents of the University of California. All rights reserved.");
39 #endif /* not lint */
40
41 #ifndef lint
42 #if 0
43 static char sccsid[] = "@(#)init.c 8.2 (Berkeley) 4/28/95";
44 #else
45 __RCSID("$NetBSD: init.c,v 1.108 2020/06/22 07:50:53 msaitoh Exp $");
46 #endif
47 #endif /* not lint */
48
49 #include <sys/param.h>
50 #include <sys/sysctl.h>
51 #include <sys/wait.h>
52 #include <sys/mman.h>
53 #include <sys/stat.h>
54 #include <sys/mount.h>
55 #include <machine/cpu.h>
56
57 #include <db.h>
58 #include <errno.h>
59 #include <fcntl.h>
60 #include <signal.h>
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <string.h>
64 #include <syslog.h>
65 #include <time.h>
66 #include <ttyent.h>
67 #include <unistd.h>
68 #include <util.h>
69 #include <paths.h>
70 #include <err.h>
71 #ifdef SUPPORT_UTMP
72 #include <utmp.h>
73 #endif
74 #ifdef SUPPORT_UTMPX
75 #include <utmpx.h>
76 #endif
77
78 #include <stdarg.h>
79
80 #ifdef SECURE
81 #include <pwd.h>
82 #endif
83
84 #include "pathnames.h"
85
86 #define XSTR(x) #x
87 #define STR(x) XSTR(x)
88
89 /*
90 * Sleep times; used to prevent thrashing.
91 */
92 #define GETTY_SPACING 5 /* N secs minimum getty spacing */
93 #define GETTY_SLEEP 30 /* sleep N secs after spacing problem */
94 #define WINDOW_WAIT 3 /* wait N secs after starting window */
95 #define STALL_TIMEOUT 30 /* wait N secs after warning */
96 #define DEATH_WATCH 10 /* wait N secs for procs to die */
97
98 static const struct timespec dtrtime = {.tv_sec = 0, .tv_nsec = 250000};
99
100 #if defined(RESCUEDIR)
101 #define INIT_BSHELL RESCUEDIR "/sh"
102 #define INIT_MOUNT_MFS RESCUEDIR "/mount_mfs"
103 #define INIT_PATH RESCUEDIR ":" _PATH_STDPATH
104 #else
105 #define INIT_BSHELL _PATH_BSHELL
106 #define INIT_MOUNT_MFS "/sbin/mount_mfs"
107 #define INIT_PATH _PATH_STDPATH
108 #endif
109
110 static void handle(sig_t, ...);
111 static void delset(sigset_t *, ...);
112
113 static void stall(const char *, ...) __sysloglike(1, 2);
114 static void warning(const char *, ...) __sysloglike(1, 2);
115 static void emergency(const char *, ...) __sysloglike(1, 2);
116 __dead static void disaster(int);
117 static void badsys(int);
118
119 /*
120 * We really need a recursive typedef...
121 * The following at least guarantees that the return type of (*state_t)()
122 * is sufficiently wide to hold a function pointer.
123 */
124 typedef long (*state_func_t)(void);
125 typedef state_func_t (*state_t)(void);
126
127 #define DEATH 'd'
128 #define SINGLE_USER 's'
129 #define RUNCOM 'r'
130 #define READ_TTYS 't'
131 #define MULTI_USER 'm'
132 #define CLEAN_TTYS 'T'
133 #define CATATONIA 'c'
134
135 static state_func_t single_user(void);
136 #ifndef LETS_GET_SMALL
137 static state_func_t runcom(void);
138 static state_func_t read_ttys(void);
139 static state_func_t multi_user(void);
140 static state_func_t clean_ttys(void);
141 static state_func_t catatonia(void);
142 static state_func_t death(void);
143 #endif
144
145 static enum { AUTOBOOT, FASTBOOT } runcom_mode = AUTOBOOT;
146
147 static void transition(state_t);
148 static void setctty(const char *);
149
150 typedef struct init_session {
151 int se_index; /* index of entry in ttys file */
152 pid_t se_process; /* controlling process */
153 struct timeval se_started; /* used to avoid thrashing */
154 int se_flags; /* status of session */
155 #define SE_SHUTDOWN 0x1 /* session won't be restarted */
156 #define SE_PRESENT 0x2 /* session is in /etc/ttys */
157 char *se_device; /* filename of port */
158 char *se_getty; /* what to run on that port */
159 char **se_getty_argv; /* pre-parsed argument array */
160 char *se_window; /* window system (started only once) */
161 char **se_window_argv; /* pre-parsed argument array */
162 struct init_session *se_prev;
163 struct init_session *se_next;
164 } session_t;
165
166 static void collect_child(pid_t, int);
167 static int clang;
168 static void transition_handler(int);
169 static void alrm_handler(int);
170 static int has_securelevel(void);
171 static int securelevel_present;
172
173 #ifndef LETS_GET_SMALL
174 static int do_setttyent(void);
175 static void start_window_system(session_t *);
176 static char **construct_argv(char *);
177 static int setupargv(session_t *, struct ttyent *);
178 static pid_t start_getty(session_t *);
179 static void free_session(session_t *);
180 static session_t *new_session(session_t *, int, struct ttyent *);
181 static session_t *sessions;
182 static void setsecuritylevel(int);
183 static int getsecuritylevel(void);
184 static int start_session_db(void);
185 static void add_session(session_t *);
186 static void del_session(session_t *);
187 static session_t *find_session(pid_t);
188 static DB *session_db;
189 static state_t requested_transition = runcom;
190
191 static void clear_session_logs(session_t *, int);
192 static state_func_t runetcrc(int);
193 #ifdef SUPPORT_UTMPX
194 static struct timeval boot_time;
195 static state_t current_state = death;
196 static void session_utmpx(const session_t *, int);
197 static void make_utmpx(const char *, const char *, int, pid_t,
198 const struct timeval *, int);
199 static char get_runlevel(const state_t);
200 static void utmpx_set_runlevel(char, char);
201 #endif
202
203 #ifdef CHROOT
204 static int did_multiuser_chroot = 0;
205 static char rootdir[PATH_MAX];
206 static int shouldchroot(void);
207 static int createsysctlnode(void);
208 #endif /* CHROOT */
209
210 #else /* LETS_GET_SMALL */
211 static state_t requested_transition = single_user;
212 #endif /* !LETS_GET_SMALL */
213
214 #ifdef MFS_DEV_IF_NO_CONSOLE
215
216 static int mfs_dev(void);
217
218 #endif
219
220 /*
221 * The mother of all processes.
222 */
223 int
224 main(int argc, char **argv)
225 {
226 struct sigaction sa;
227 sigset_t mask;
228 #ifndef LETS_GET_SMALL
229 int c;
230
231 #ifdef SUPPORT_UTMPX
232 (void)gettimeofday(&boot_time, NULL);
233 #endif /* SUPPORT_UTMPX */
234
235 /* Dispose of random users. */
236 if (getuid() != 0) {
237 errno = EPERM;
238 err(1, NULL);
239 }
240
241 /* System V users like to reexec init. */
242 if (getpid() != 1)
243 errx(1, "already running");
244 #endif
245
246 /*
247 * Create an initial session.
248 */
249 if (setsid() < 0)
250 warn("initial setsid() failed");
251
252 /*
253 * Establish an initial user so that programs running
254 * single user do not freak out and die (like passwd).
255 */
256 if (setlogin("root") < 0)
257 warn("setlogin() failed");
258
259
260 #ifdef MFS_DEV_IF_NO_CONSOLE
261 if (mfs_dev() == -1)
262 requested_transition = single_user;
263 #endif
264
265 #ifndef LETS_GET_SMALL
266 /*
267 * Note that this does NOT open a file...
268 * Does 'init' deserve its own facility number?
269 */
270 openlog("init", LOG_CONS, LOG_AUTH);
271 #endif /* LETS_GET_SMALL */
272
273
274 #ifndef LETS_GET_SMALL
275 /*
276 * This code assumes that we always get arguments through flags,
277 * never through bits set in some random machine register.
278 */
279 while ((c = getopt(argc, argv, "sf")) != -1)
280 switch (c) {
281 case 's':
282 requested_transition = single_user;
283 break;
284 case 'f':
285 runcom_mode = FASTBOOT;
286 break;
287 default:
288 warning("unrecognized flag `%c'", c);
289 break;
290 }
291
292 if (optind != argc)
293 warning("ignoring excess arguments");
294 #else /* LETS_GET_SMALL */
295 requested_transition = single_user;
296 #endif /* LETS_GET_SMALL */
297
298 /*
299 * We catch or block signals rather than ignore them,
300 * so that they get reset on exec.
301 */
302 handle(badsys, SIGSYS, 0);
303 handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV,
304 SIGBUS, SIGXCPU, SIGXFSZ, 0);
305 handle(transition_handler, SIGHUP, SIGTERM, SIGTSTP, 0);
306 handle(alrm_handler, SIGALRM, 0);
307 (void)sigfillset(&mask);
308 delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS,
309 SIGXCPU, SIGXFSZ, SIGHUP, SIGTERM, SIGTSTP, SIGALRM, 0);
310 (void)sigprocmask(SIG_SETMASK, &mask, NULL);
311 (void)sigemptyset(&sa.sa_mask);
312 sa.sa_flags = 0;
313 sa.sa_handler = SIG_IGN;
314 (void)sigaction(SIGTTIN, &sa, NULL);
315 (void)sigaction(SIGTTOU, &sa, NULL);
316
317 /*
318 * Paranoia.
319 */
320 (void)close(0);
321 (void)close(1);
322 (void)close(2);
323
324 #if !defined(LETS_GET_SMALL) && defined(CHROOT)
325 /* Create "init.root" sysctl node. */
326 (void)createsysctlnode();
327 #endif /* !LETS_GET_SMALL && CHROOT*/
328
329 /*
330 * Securelevel might not be supported by the kernel. Query for it, and
331 * set a variable indicating whether we should attempt anything with it
332 * or not.
333 */
334 securelevel_present = has_securelevel();
335
336 /*
337 * Start the state machine.
338 */
339 transition(requested_transition);
340
341 /*
342 * Should never reach here.
343 */
344 return 1;
345 }
346
347 /*
348 * Associate a function with a signal handler.
349 */
350 static void
351 handle(sig_t handler, ...)
352 {
353 int sig;
354 struct sigaction sa;
355 sigset_t mask_everything;
356 va_list ap;
357
358 va_start(ap, handler);
359
360 sa.sa_handler = handler;
361 (void)sigfillset(&mask_everything);
362
363 while ((sig = va_arg(ap, int)) != 0) {
364 sa.sa_mask = mask_everything;
365 /* XXX SA_RESTART? */
366 sa.sa_flags = sig == SIGCHLD ? SA_NOCLDSTOP : 0;
367 (void)sigaction(sig, &sa, NULL);
368 }
369 va_end(ap);
370 }
371
372 /*
373 * Delete a set of signals from a mask.
374 */
375 static void
376 delset(sigset_t *maskp, ...)
377 {
378 int sig;
379 va_list ap;
380
381 va_start(ap, maskp);
382
383 while ((sig = va_arg(ap, int)) != 0)
384 (void)sigdelset(maskp, sig);
385 va_end(ap);
386 }
387
388 #if 0 /* Enable to get error messages from init ! */
389 #define vsyslog(level, fmt, ap) print_console(level, fmt, ap)
390 #define closelog()
391
392 static void
393 print_console(int level, const char *message, va_list ap)
394 {
395 /*
396 * XXX: syslog seems to just plain not work in console-only
397 * XXX: situation... that should be fixed. Let's leave this
398 * XXX: note + code here in case someone gets in trouble and
399 * XXX: wants to debug. -- Jachym Holecek <freza (at) liberouter.org>
400 */
401 char errbuf[1024];
402 int fd, len;
403
404 /* We can't do anything on errors, anyway... */
405 fd = open(_PATH_CONSOLE, O_WRONLY);
406 if (fd == -1)
407 return ;
408
409 /* %m will get lost... */
410 len = vsnprintf(errbuf, sizeof(errbuf), message, ap);
411 (void)write(fd, (void *)errbuf, len);
412 (void)close(fd);
413 }
414 #endif
415
416 /*
417 * Log a message and sleep for a while (to give someone an opportunity
418 * to read it and to save log or hardcopy output if the problem is chronic).
419 * NB: should send a message to the session logger to avoid blocking.
420 */
421 static void
422 stall(const char *message, ...)
423 {
424 va_list ap;
425
426 va_start(ap, message);
427 vsyslog(LOG_ALERT, message, ap);
428 va_end(ap);
429 closelog();
430 (void)sleep(STALL_TIMEOUT);
431 }
432
433 /*
434 * Like stall(), but doesn't sleep.
435 * If cpp had variadic macros, the two functions could be #defines for another.
436 * NB: should send a message to the session logger to avoid blocking.
437 */
438 static void
439 warning(const char *message, ...)
440 {
441 va_list ap;
442
443 va_start(ap, message);
444 vsyslog(LOG_ALERT, message, ap);
445 va_end(ap);
446 closelog();
447 }
448
449 /*
450 * Log an emergency message.
451 * NB: should send a message to the session logger to avoid blocking.
452 */
453 static void
454 emergency(const char *message, ...)
455 {
456 va_list ap;
457
458 va_start(ap, message);
459 vsyslog(LOG_EMERG, message, ap);
460 va_end(ap);
461 closelog();
462 }
463
464 /*
465 * Catch a SIGSYS signal.
466 *
467 * These may arise if a system does not support sysctl.
468 * We tolerate up to 25 of these, then throw in the towel.
469 */
470 static void
471 badsys(int sig)
472 {
473 static int badcount = 0;
474
475 if (badcount++ < 25)
476 return;
477 disaster(sig);
478 }
479
480 /*
481 * Catch an unexpected signal.
482 */
483 static void
484 disaster(int sig)
485 {
486
487 emergency("fatal signal: %s", strsignal(sig));
488 (void)sleep(STALL_TIMEOUT);
489 _exit(sig); /* reboot */
490 }
491
492 /*
493 * Check if securelevel is present.
494 */
495 static int
496 has_securelevel(void)
497 {
498 #ifdef KERN_SECURELVL
499 int name[2], curlevel;
500 size_t len;
501
502 name[0] = CTL_KERN;
503 name[1] = KERN_SECURELVL;
504 len = sizeof curlevel;
505 if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) {
506 /* If it doesn't exist, it's okay. */
507 if (errno == ENOENT)
508 return 0;
509 }
510 return 1;
511 #else
512 return 0;
513 #endif
514 }
515
516 /*
517 * Get the security level of the kernel.
518 */
519 static int
520 getsecuritylevel(void)
521 {
522 #ifdef KERN_SECURELVL
523 int name[2], curlevel;
524 size_t len;
525
526 if (!securelevel_present)
527 return -1;
528
529 name[0] = CTL_KERN;
530 name[1] = KERN_SECURELVL;
531 len = sizeof curlevel;
532 if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) {
533 emergency("cannot get kernel security level: %m");
534 return -1;
535 }
536 return curlevel;
537 #else
538 return -1;
539 #endif
540 }
541
542 /*
543 * Set the security level of the kernel.
544 */
545 static void
546 setsecuritylevel(int newlevel)
547 {
548 #ifdef KERN_SECURELVL
549 int name[2], curlevel;
550
551 if (!securelevel_present)
552 return;
553
554 curlevel = getsecuritylevel();
555 if (newlevel == curlevel)
556 return;
557 name[0] = CTL_KERN;
558 name[1] = KERN_SECURELVL;
559 if (sysctl(name, 2, NULL, NULL, &newlevel, sizeof newlevel) == -1) {
560 emergency("cannot change kernel security level from"
561 " %d to %d: %m", 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
576 transition(state_t s)
577 {
578
579 if (s == NULL)
580 return;
581 for (;;) {
582 #ifdef SUPPORT_UTMPX
583 #ifndef LETS_GET_SMALL
584 utmpx_set_runlevel(get_runlevel(current_state),
585 get_runlevel(s));
586 current_state = s;
587 #endif
588 #endif
589 s = (state_t)(*s)();
590 }
591 }
592
593 #ifndef LETS_GET_SMALL
594 /*
595 * Close out the accounting files for a login session.
596 * NB: should send a message to the session logger to avoid blocking.
597 */
598 static void
599 clear_session_logs(session_t *sp, int status)
600 {
601 #if defined(SUPPORT_UTMP) || defined(SUPPORT_UTMPX)
602 char *line = sp->se_device + sizeof(_PATH_DEV) - 1;
603 #endif
604
605 #ifdef SUPPORT_UTMPX
606 if (logoutx(line, status, DEAD_PROCESS))
607 logwtmpx(line, "", "", status, DEAD_PROCESS);
608 #endif
609 #ifdef SUPPORT_UTMP
610 if (logout(line))
611 logwtmp(line, "", "");
612 #endif
613 }
614 #endif
615
616 /*
617 * Start a session and allocate a controlling terminal.
618 * Only called by children of init after forking.
619 */
620 static void
621 setctty(const char *name)
622 {
623 int fd;
624
625 (void)revoke(name);
626 (void)nanosleep(&dtrtime, NULL); /* leave DTR low for a bit */
627 if ((fd = open(name, O_RDWR)) == -1) {
628 stall("can't open %s: %m", name);
629 _exit(1);
630 }
631 if (login_tty(fd) == -1) {
632 stall("can't get %s for controlling terminal: %m", name);
633 _exit(2);
634 }
635 }
636
637 /*
638 * Bring the system up single user.
639 */
640 static state_func_t
641 single_user(void)
642 {
643 pid_t pid, wpid;
644 int status;
645 int from_securitylevel;
646 sigset_t mask;
647 struct sigaction sa, satstp, sahup;
648 #ifdef ALTSHELL
649 const char *shell = INIT_BSHELL;
650 #endif
651 const char *argv[2];
652 #ifdef SECURE
653 struct ttyent *typ;
654 struct passwd *pp;
655 char *clear, *password;
656 #endif
657 #ifdef ALTSHELL
658 char altshell[128];
659 #endif /* ALTSHELL */
660
661 #if !defined(LETS_GET_SMALL) && defined(CHROOT)
662 /* Clear previous idea, just in case. */
663 did_multiuser_chroot = 0;
664 #endif /* !LETS_GET_SMALL && CHROOT */
665
666 /*
667 * If the kernel is in secure mode, downgrade it to insecure mode.
668 */
669 from_securitylevel = getsecuritylevel();
670 if (from_securitylevel > 0)
671 setsecuritylevel(0);
672
673 (void)sigemptyset(&sa.sa_mask);
674 sa.sa_flags = 0;
675 sa.sa_handler = SIG_IGN;
676 (void)sigaction(SIGTSTP, &sa, &satstp);
677 (void)sigaction(SIGHUP, &sa, &sahup);
678 if ((pid = fork()) == 0) {
679 /*
680 * Start the single user session.
681 */
682 if (access(_PATH_CONSTTY, F_OK) == 0)
683 setctty(_PATH_CONSTTY);
684 else
685 setctty(_PATH_CONSOLE);
686
687 #ifdef SECURE
688 /*
689 * Check the root password.
690 * We don't care if the console is 'on' by default;
691 * it's the only tty that can be 'off' and 'secure'.
692 */
693 typ = getttynam("console");
694 pp = getpwnam("root");
695 if (typ && (from_securitylevel >=2 || (typ->ty_status
696 & TTY_SECURE) == 0) && pp && *pp->pw_passwd != '\0') {
697 (void)fprintf(stderr,
698 "Enter root password, or ^D to go multi-user\n");
699 for (;;) {
700 clear = getpass("Password:");
701 if (clear == 0 || *clear == '\0')
702 _exit(0);
703 password = crypt(clear, pp->pw_passwd);
704 (void)memset(clear, 0, _PASSWORD_LEN);
705 if (strcmp(password, pp->pw_passwd) == 0)
706 break;
707 warning("single-user login failed");
708 }
709 }
710 (void)endttyent();
711 endpwent();
712 #endif /* SECURE */
713
714 #ifdef ALTSHELL
715 (void)fprintf(stderr,
716 "Enter pathname of shell or RETURN for %s: ", shell);
717 if (fgets(altshell, sizeof(altshell), stdin) == NULL) {
718 altshell[0] = '\0';
719 } else {
720 /* nuke \n */
721 char *p;
722
723 if ((p = strchr(altshell, '\n')) != NULL)
724 *p = '\0';
725 }
726
727 if (altshell[0])
728 shell = altshell;
729 #endif /* ALTSHELL */
730
731 /*
732 * Unblock signals.
733 * We catch all the interesting ones,
734 * and those are reset to SIG_DFL on exec.
735 */
736 (void)sigemptyset(&mask);
737 (void)sigprocmask(SIG_SETMASK, &mask, NULL);
738
739 /*
740 * Fire off a shell.
741 * If the default one doesn't work, try the Bourne shell.
742 */
743 argv[0] = "-sh";
744 argv[1] = 0;
745 (void)setenv("PATH", INIT_PATH, 1);
746 #ifdef ALTSHELL
747 if (altshell[0])
748 argv[0] = altshell;
749 (void)execv(shell, __UNCONST(argv));
750 emergency("can't exec `%s' for single user: %m", shell);
751 argv[0] = "-sh";
752 #endif /* ALTSHELL */
753 (void)execv(INIT_BSHELL, __UNCONST(argv));
754 emergency("can't exec `%s' for single user: %m", INIT_BSHELL);
755 (void)sleep(STALL_TIMEOUT);
756 _exit(3);
757 }
758
759 if (pid == -1) {
760 /*
761 * We are seriously hosed. Do our best.
762 */
763 emergency("can't fork single-user shell: %m, trying again");
764 while (waitpid(-1, NULL, WNOHANG) > 0)
765 continue;
766 (void)sigaction(SIGTSTP, &satstp, NULL);
767 (void)sigaction(SIGHUP, &sahup, NULL);
768 return (state_func_t)single_user;
769 }
770
771 requested_transition = 0;
772 do {
773 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
774 collect_child(wpid, status);
775 if (wpid == -1) {
776 if (errno == EINTR)
777 continue;
778 warning("wait for single-user shell failed: %m; "
779 "restarting");
780 return (state_func_t)single_user;
781 }
782 if (wpid == pid && WIFSTOPPED(status)) {
783 warning("shell stopped, restarting");
784 (void)kill(pid, SIGCONT);
785 wpid = -1;
786 }
787 } while (wpid != pid && !requested_transition);
788
789 if (requested_transition) {
790 (void)sigaction(SIGTSTP, &satstp, NULL);
791 (void)sigaction(SIGHUP, &sahup, NULL);
792 return (state_func_t)requested_transition;
793 }
794
795 if (WIFSIGNALED(status)) {
796 if (WTERMSIG(status) == SIGKILL) {
797 /* executed /sbin/reboot; wait for the end quietly */
798 sigset_t s;
799
800 (void)sigfillset(&s);
801 for (;;)
802 (void)sigsuspend(&s);
803 } else {
804 warning("single user shell terminated (%x), restarting",
805 status);
806 (void)sigaction(SIGTSTP, &satstp, NULL);
807 (void)sigaction(SIGHUP, &sahup, NULL);
808 return (state_func_t)single_user;
809 }
810 }
811
812 runcom_mode = FASTBOOT;
813 (void)sigaction(SIGTSTP, &satstp, NULL);
814 (void)sigaction(SIGHUP, &sahup, NULL);
815 #ifndef LETS_GET_SMALL
816 return (state_func_t)runcom;
817 #else /* LETS_GET_SMALL */
818 return (state_func_t)single_user;
819 #endif /* LETS_GET_SMALL */
820 }
821
822 #ifndef LETS_GET_SMALL
823
824 /* ARGSUSED */
825 static state_func_t
826 runetcrc(int trychroot)
827 {
828 pid_t pid, wpid;
829 int status;
830 const char *argv[4];
831 struct sigaction sa;
832
833 switch ((pid = fork())) {
834 case 0:
835 (void)sigemptyset(&sa.sa_mask);
836 sa.sa_flags = 0;
837 sa.sa_handler = SIG_IGN;
838 (void)sigaction(SIGTSTP, &sa, NULL);
839 (void)sigaction(SIGHUP, &sa, NULL);
840
841 setctty(_PATH_CONSOLE);
842
843 argv[0] = "sh";
844 argv[1] = _PATH_RUNCOM;
845 argv[2] = (runcom_mode == AUTOBOOT ? "autoboot" : 0);
846 argv[3] = 0;
847
848 (void)sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);
849
850 #ifdef CHROOT
851 if (trychroot)
852 if (chroot(rootdir) != 0) {
853 warning("failed to chroot to `%s': %m",
854 rootdir);
855 _exit(4); /* force single user mode */
856 }
857 #endif /* CHROOT */
858
859 (void)execv(INIT_BSHELL, __UNCONST(argv));
860 stall("can't exec `%s' for `%s': %m", INIT_BSHELL, _PATH_RUNCOM);
861 _exit(5); /* force single user mode */
862 /*NOTREACHED*/
863 case -1:
864 emergency("can't fork for `%s' on `%s': %m", INIT_BSHELL,
865 _PATH_RUNCOM);
866 while (waitpid(-1, NULL, WNOHANG) > 0)
867 continue;
868 (void)sleep(STALL_TIMEOUT);
869 return (state_func_t)single_user;
870 default:
871 break;
872 }
873
874 /*
875 * Copied from single_user(). This is a bit paranoid.
876 */
877 do {
878 if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
879 collect_child(wpid, status);
880 if (wpid == -1) {
881 if (errno == EINTR)
882 continue;
883 warning("wait for `%s' on `%s' failed: %m; going to "
884 "single user mode", INIT_BSHELL, _PATH_RUNCOM);
885 return (state_func_t)single_user;
886 }
887 if (wpid == pid && WIFSTOPPED(status)) {
888 warning("`%s' on `%s' stopped, restarting",
889 INIT_BSHELL, _PATH_RUNCOM);
890 (void)kill(pid, SIGCONT);
891 wpid = -1;
892 }
893 } while (wpid != pid);
894
895 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM &&
896 requested_transition == catatonia) {
897 /* /etc/rc executed /sbin/reboot; wait for the end quietly */
898 sigset_t s;
899
900 (void)sigfillset(&s);
901 for (;;)
902 (void)sigsuspend(&s);
903 }
904
905 if (!WIFEXITED(status)) {
906 warning("`%s' on `%s' terminated abnormally, going to "
907 "single user mode", INIT_BSHELL, _PATH_RUNCOM);
908 return (state_func_t)single_user;
909 }
910
911 if (WEXITSTATUS(status))
912 return (state_func_t)single_user;
913
914 return (state_func_t)read_ttys;
915 }
916
917 /*
918 * Run the system startup script.
919 */
920 static state_func_t
921 runcom(void)
922 {
923 state_func_t next_step;
924
925 /* Run /etc/rc and choose next state depending on the result. */
926 next_step = runetcrc(0);
927 if (next_step != (state_func_t)read_ttys)
928 return (state_func_t)next_step;
929
930 #ifdef CHROOT
931 /*
932 * If init.root sysctl does not point to "/", we'll chroot and run
933 * The Real(tm) /etc/rc now. Global variable rootdir will tell us
934 * where to go.
935 */
936 if (shouldchroot()) {
937 next_step = runetcrc(1);
938 if (next_step != (state_func_t)read_ttys)
939 return (state_func_t)next_step;
940
941 did_multiuser_chroot = 1;
942 } else {
943 did_multiuser_chroot = 0;
944 }
945 #endif /* CHROOT */
946
947 /*
948 * Regardless of whether in chroot or not, we booted successfully.
949 * It's time to spawn gettys (ie. next_step's value at this point).
950 */
951 runcom_mode = AUTOBOOT; /* the default */
952 /* NB: should send a message to the session logger to avoid blocking. */
953 #ifdef SUPPORT_UTMPX
954 logwtmpx("~", "reboot", "", 0, INIT_PROCESS);
955 #endif
956 #ifdef SUPPORT_UTMP
957 logwtmp("~", "reboot", "");
958 #endif
959 return (state_func_t)read_ttys;
960 }
961
962 /*
963 * Open the session database.
964 *
965 * NB: We could pass in the size here; is it necessary?
966 */
967 static int
968 start_session_db(void)
969 {
970
971 if (session_db && (*session_db->close)(session_db))
972 emergency("session database close: %m");
973 if ((session_db = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL)) == 0) {
974 emergency("session database open: %m");
975 return 1;
976 }
977 return 0;
978
979 }
980
981 /*
982 * Add a new login session.
983 */
984 static void
985 add_session(session_t *sp)
986 {
987 DBT key;
988 DBT data;
989
990 if (session_db == NULL)
991 return;
992
993 key.data = &sp->se_process;
994 key.size = sizeof sp->se_process;
995 data.data = &sp;
996 data.size = sizeof sp;
997
998 if ((*session_db->put)(session_db, &key, &data, 0))
999 emergency("insert %d: %m", sp->se_process);
1000 #ifdef SUPPORT_UTMPX
1001 session_utmpx(sp, 1);
1002 #endif
1003 }
1004
1005 /*
1006 * Delete an old login session.
1007 */
1008 static void
1009 del_session(session_t *sp)
1010 {
1011 DBT key;
1012
1013 key.data = &sp->se_process;
1014 key.size = sizeof sp->se_process;
1015
1016 if ((*session_db->del)(session_db, &key, 0))
1017 emergency("delete %d: %m", sp->se_process);
1018 #ifdef SUPPORT_UTMPX
1019 session_utmpx(sp, 0);
1020 #endif
1021 }
1022
1023 /*
1024 * Look up a login session by pid.
1025 */
1026 static session_t *
1027 find_session(pid_t pid)
1028 {
1029 DBT key;
1030 DBT data;
1031 session_t *ret;
1032
1033 if (session_db == NULL)
1034 return NULL;
1035
1036 key.data = &pid;
1037 key.size = sizeof pid;
1038 if ((*session_db->get)(session_db, &key, &data, 0) != 0)
1039 return 0;
1040 (void)memmove(&ret, data.data, sizeof(ret));
1041 return ret;
1042 }
1043
1044 /*
1045 * Construct an argument vector from a command line.
1046 */
1047 static char **
1048 construct_argv(char *command)
1049 {
1050 int argc = 0;
1051 char **argv = malloc(((strlen(command) + 1) / 2 + 1) * sizeof (char *));
1052 static const char separators[] = " \t";
1053
1054 if (argv == NULL)
1055 return NULL;
1056
1057 if ((argv[argc++] = strtok(command, separators)) == 0) {
1058 free(argv);
1059 return NULL;
1060 }
1061 while ((argv[argc++] = strtok(NULL, separators)) != NULL)
1062 continue;
1063 return argv;
1064 }
1065
1066 /*
1067 * Deallocate a session descriptor.
1068 */
1069 static void
1070 free_session(session_t *sp)
1071 {
1072
1073 free(sp->se_device);
1074 if (sp->se_getty) {
1075 free(sp->se_getty);
1076 free(sp->se_getty_argv);
1077 }
1078 if (sp->se_window) {
1079 free(sp->se_window);
1080 free(sp->se_window_argv);
1081 }
1082 free(sp);
1083 }
1084
1085 /*
1086 * Allocate a new session descriptor.
1087 */
1088 static session_t *
1089 new_session(session_t *sprev, int session_index, struct ttyent *typ)
1090 {
1091 session_t *sp;
1092
1093 if ((typ->ty_status & TTY_ON) == 0 || typ->ty_name == NULL ||
1094 typ->ty_getty == NULL)
1095 return NULL;
1096
1097 sp = malloc(sizeof (session_t));
1098 if (sp == NULL)
1099 return NULL;
1100 (void)memset(sp, 0, sizeof *sp);
1101
1102 sp->se_flags = SE_PRESENT;
1103 sp->se_index = session_index;
1104
1105 (void)asprintf(&sp->se_device, "%s%s", _PATH_DEV, typ->ty_name);
1106 if (!sp->se_device) {
1107 free(sp);
1108 return NULL;
1109 }
1110
1111 if (setupargv(sp, typ) == 0) {
1112 free_session(sp);
1113 return NULL;
1114 }
1115
1116 sp->se_next = NULL;
1117 if (sprev == NULL) {
1118 sessions = sp;
1119 sp->se_prev = NULL;
1120 } else {
1121 sprev->se_next = sp;
1122 sp->se_prev = sprev;
1123 }
1124
1125 return sp;
1126 }
1127
1128 /*
1129 * Calculate getty and if useful window argv vectors.
1130 */
1131 static int
1132 setupargv(session_t *sp, struct ttyent *typ)
1133 {
1134
1135 if (sp->se_getty) {
1136 free(sp->se_getty);
1137 free(sp->se_getty_argv);
1138 }
1139 (void)asprintf(&sp->se_getty, "%s %s", typ->ty_getty, typ->ty_name);
1140 if (!sp->se_getty)
1141 return 0;
1142 sp->se_getty_argv = construct_argv(sp->se_getty);
1143 if (sp->se_getty_argv == NULL) {
1144 warning("can't parse getty for port `%s'", sp->se_device);
1145 free(sp->se_getty);
1146 sp->se_getty = NULL;
1147 return 0;
1148 }
1149 if (typ->ty_window) {
1150 if (sp->se_window)
1151 free(sp->se_window);
1152 sp->se_window = strdup(typ->ty_window);
1153 sp->se_window_argv = construct_argv(sp->se_window);
1154 if (sp->se_window_argv == NULL) {
1155 warning("can't parse window for port `%s'",
1156 sp->se_device);
1157 free(sp->se_window);
1158 sp->se_window = NULL;
1159 return 0;
1160 }
1161 }
1162 return 1;
1163 }
1164
1165 /*
1166 * Walk the list of ttys and create sessions for each active line.
1167 */
1168 static state_func_t
1169 read_ttys(void)
1170 {
1171 int session_index = 0;
1172 session_t *sp, *snext;
1173 struct ttyent *typ;
1174
1175 #ifdef SUPPORT_UTMPX
1176 if (sessions == NULL) {
1177 struct stat st;
1178
1179 make_utmpx("", BOOT_MSG, BOOT_TIME, 0, &boot_time, 0);
1180
1181 /*
1182 * If wtmpx is not empty, pick the down time from there
1183 */
1184 if (stat(_PATH_WTMPX, &st) != -1 && st.st_size != 0) {
1185 struct timeval down_time;
1186
1187 TIMESPEC_TO_TIMEVAL(&down_time,
1188 st.st_atime > st.st_mtime ?
1189 &st.st_atimespec : &st.st_mtimespec);
1190 make_utmpx("", DOWN_MSG, DOWN_TIME, 0, &down_time, 0);
1191 }
1192 }
1193 #endif
1194 /*
1195 * Destroy any previous session state.
1196 * There shouldn't be any, but just in case...
1197 */
1198 for (sp = sessions; sp; sp = snext) {
1199 #ifndef LETS_GET_SMALL
1200 if (sp->se_process)
1201 clear_session_logs(sp, 0);
1202 #endif
1203 snext = sp->se_next;
1204 free_session(sp);
1205 }
1206 sessions = NULL;
1207
1208 if (start_session_db()) {
1209 warning("start_session_db failed, death");
1210 #ifdef CHROOT
1211 /* If /etc/rc ran in chroot, we want to kill any survivors. */
1212 if (did_multiuser_chroot)
1213 return (state_func_t)death;
1214 else
1215 #endif /* CHROOT */
1216 return (state_func_t)single_user;
1217 }
1218
1219 (void)do_setttyent();
1220
1221 /*
1222 * Allocate a session entry for each active port.
1223 * Note that sp starts at 0.
1224 */
1225 while ((typ = getttyent()) != NULL)
1226 if ((snext = new_session(sp, ++session_index, typ)) != NULL)
1227 sp = snext;
1228 (void)endttyent();
1229
1230 return (state_func_t)multi_user;
1231 }
1232
1233 /*
1234 * Start a window system running.
1235 */
1236 static void
1237 start_window_system(session_t *sp)
1238 {
1239 pid_t pid;
1240 sigset_t mask;
1241
1242 if ((pid = fork()) == -1) {
1243 emergency("can't fork for window system on port `%s': %m",
1244 sp->se_device);
1245 /* hope that getty fails and we can try again */
1246 return;
1247 }
1248
1249 if (pid)
1250 return;
1251
1252 (void)sigemptyset(&mask);
1253 (void)sigprocmask(SIG_SETMASK, &mask, NULL);
1254
1255 if (setsid() < 0)
1256 emergency("setsid failed (window): %m");
1257
1258 (void)execv(sp->se_window_argv[0], sp->se_window_argv);
1259 stall("can't exec window system `%s' for port `%s': %m",
1260 sp->se_window_argv[0], sp->se_device);
1261 _exit(6);
1262 }
1263
1264 /*
1265 * Start a login session running.
1266 */
1267 static pid_t
1268 start_getty(session_t *sp)
1269 {
1270 pid_t pid;
1271 sigset_t mask;
1272 time_t current_time = time(NULL);
1273
1274 /*
1275 * fork(), not vfork() -- we can't afford to block.
1276 */
1277 if ((pid = fork()) == -1) {
1278 emergency("can't fork for getty on port `%s': %m",
1279 sp->se_device);
1280 return -1;
1281 }
1282
1283 if (pid)
1284 return pid;
1285
1286 #ifdef CHROOT
1287 /* If /etc/rc did proceed inside chroot, we have to try as well. */
1288 if (did_multiuser_chroot)
1289 if (chroot(rootdir) != 0) {
1290 stall("can't chroot getty `%s' inside `%s': %m",
1291 sp->se_getty_argv[0], rootdir);
1292 _exit(7);
1293 }
1294 #endif /* CHROOT */
1295
1296 if (current_time > sp->se_started.tv_sec &&
1297 current_time - sp->se_started.tv_sec < GETTY_SPACING) {
1298 warning("getty repeating too quickly on port `%s', sleeping",
1299 sp->se_device);
1300 (void)sleep(GETTY_SLEEP);
1301 }
1302
1303 if (sp->se_window) {
1304 start_window_system(sp);
1305 (void)sleep(WINDOW_WAIT);
1306 }
1307
1308 (void)sigemptyset(&mask);
1309 (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
1310
1311 (void)execv(sp->se_getty_argv[0], sp->se_getty_argv);
1312 stall("can't exec getty `%s' for port `%s': %m",
1313 sp->se_getty_argv[0], sp->se_device);
1314 _exit(8);
1315 /*NOTREACHED*/
1316 }
1317 #ifdef SUPPORT_UTMPX
1318 static void
1319 session_utmpx(const session_t *sp, int add)
1320 {
1321 const char *name = sp->se_getty ? sp->se_getty :
1322 (sp->se_window ? sp->se_window : "");
1323 const char *line = sp->se_device + sizeof(_PATH_DEV) - 1;
1324
1325 make_utmpx(name, line, add ? LOGIN_PROCESS : DEAD_PROCESS,
1326 sp->se_process, &sp->se_started, sp->se_index);
1327 }
1328
1329 static void
1330 make_utmpx(const char *name, const char *line, int type, pid_t pid,
1331 const struct timeval *tv, int session)
1332 {
1333 struct utmpx ut;
1334 const char *eline;
1335
1336 (void)memset(&ut, 0, sizeof(ut));
1337 (void)strlcpy(ut.ut_name, name, sizeof(ut.ut_name));
1338 ut.ut_type = type;
1339 (void)strlcpy(ut.ut_line, line, sizeof(ut.ut_line));
1340 ut.ut_pid = pid;
1341 if (tv)
1342 ut.ut_tv = *tv;
1343 else
1344 (void)gettimeofday(&ut.ut_tv, NULL);
1345 ut.ut_session = session;
1346
1347 eline = line + strlen(line);
1348 if ((size_t)(eline - line) >= sizeof(ut.ut_id))
1349 line = eline - sizeof(ut.ut_id);
1350 (void)strncpy(ut.ut_id, line, sizeof(ut.ut_id));
1351
1352 if (pututxline(&ut) == NULL)
1353 warning("can't add utmpx record for `%s': %m", ut.ut_line);
1354 endutxent();
1355 }
1356
1357 static char
1358 get_runlevel(const state_t s)
1359 {
1360 if (s == (state_t)single_user)
1361 return SINGLE_USER;
1362 if (s == (state_t)runcom)
1363 return RUNCOM;
1364 if (s == (state_t)read_ttys)
1365 return READ_TTYS;
1366 if (s == (state_t)multi_user)
1367 return MULTI_USER;
1368 if (s == (state_t)clean_ttys)
1369 return CLEAN_TTYS;
1370 if (s == (state_t)catatonia)
1371 return CATATONIA;
1372 return DEATH;
1373 }
1374
1375 static void
1376 utmpx_set_runlevel(char old, char new)
1377 {
1378 struct utmpx ut;
1379
1380 /*
1381 * Don't record any transitions until we did the first transition
1382 * to read ttys, which is when we are guaranteed to have a read-write
1383 * /var. Perhaps use a different variable for this?
1384 */
1385 if (sessions == NULL)
1386 return;
1387
1388 (void)memset(&ut, 0, sizeof(ut));
1389 (void)snprintf(ut.ut_line, sizeof(ut.ut_line), RUNLVL_MSG, new);
1390 ut.ut_type = RUN_LVL;
1391 (void)gettimeofday(&ut.ut_tv, NULL);
1392 ut.ut_exit.e_exit = old;
1393 ut.ut_exit.e_termination = new;
1394 if (pututxline(&ut) == NULL)
1395 warning("can't add utmpx record for `runlevel': %m");
1396 endutxent();
1397 }
1398 #endif /* SUPPORT_UTMPX */
1399
1400 #endif /* LETS_GET_SMALL */
1401
1402 /*
1403 * Collect exit status for a child.
1404 * If an exiting login, start a new login running.
1405 */
1406 static void
1407 collect_child(pid_t pid, int status)
1408 {
1409 #ifndef LETS_GET_SMALL
1410 session_t *sp, *sprev, *snext;
1411
1412 if (! sessions)
1413 return;
1414
1415 if ((sp = find_session(pid)) == NULL)
1416 return;
1417
1418 clear_session_logs(sp, status);
1419 del_session(sp);
1420 sp->se_process = 0;
1421
1422 if (sp->se_flags & SE_SHUTDOWN) {
1423 if ((sprev = sp->se_prev) != NULL)
1424 sprev->se_next = sp->se_next;
1425 else
1426 sessions = sp->se_next;
1427 if ((snext = sp->se_next) != NULL)
1428 snext->se_prev = sp->se_prev;
1429 free_session(sp);
1430 return;
1431 }
1432
1433 if ((pid = start_getty(sp)) == -1) {
1434 /* serious trouble */
1435 requested_transition = clean_ttys;
1436 return;
1437 }
1438
1439 sp->se_process = pid;
1440 (void)gettimeofday(&sp->se_started, NULL);
1441 add_session(sp);
1442 #endif /* LETS_GET_SMALL */
1443 }
1444
1445 /*
1446 * Catch a signal and request a state transition.
1447 */
1448 static void
1449 transition_handler(int sig)
1450 {
1451
1452 switch (sig) {
1453 #ifndef LETS_GET_SMALL
1454 case SIGHUP:
1455 requested_transition = clean_ttys;
1456 break;
1457 case SIGTERM:
1458 requested_transition = death;
1459 break;
1460 case SIGTSTP:
1461 requested_transition = catatonia;
1462 break;
1463 #endif /* LETS_GET_SMALL */
1464 default:
1465 requested_transition = 0;
1466 break;
1467 }
1468 }
1469
1470 #ifndef LETS_GET_SMALL
1471 /*
1472 * Take the system multiuser.
1473 */
1474 static state_func_t
1475 multi_user(void)
1476 {
1477 pid_t pid;
1478 int status;
1479 session_t *sp;
1480
1481 requested_transition = 0;
1482
1483 /*
1484 * If the administrator has not set the security level to -1
1485 * to indicate that the kernel should not run multiuser in secure
1486 * mode, and the run script has not set a higher level of security
1487 * than level 1, then put the kernel into secure mode.
1488 */
1489 if (getsecuritylevel() == 0)
1490 setsecuritylevel(1);
1491
1492 for (sp = sessions; sp; sp = sp->se_next) {
1493 if (sp->se_process)
1494 continue;
1495 if ((pid = start_getty(sp)) == -1) {
1496 /* serious trouble */
1497 requested_transition = clean_ttys;
1498 break;
1499 }
1500 sp->se_process = pid;
1501 (void)gettimeofday(&sp->se_started, NULL);
1502 add_session(sp);
1503 }
1504
1505 while (!requested_transition)
1506 if ((pid = waitpid(-1, &status, 0)) != -1)
1507 collect_child(pid, status);
1508
1509 return (state_func_t)requested_transition;
1510 }
1511
1512 /*
1513 * This is an n-squared algorithm. We hope it isn't run often...
1514 */
1515 static state_func_t
1516 clean_ttys(void)
1517 {
1518 session_t *sp, *sprev;
1519 struct ttyent *typ;
1520 int session_index = 0;
1521 int devlen;
1522
1523 for (sp = sessions; sp; sp = sp->se_next)
1524 sp->se_flags &= ~SE_PRESENT;
1525
1526 (void)do_setttyent();
1527
1528 devlen = sizeof(_PATH_DEV) - 1;
1529 while ((typ = getttyent()) != NULL) {
1530 ++session_index;
1531
1532 for (sprev = 0, sp = sessions; sp; sprev = sp, sp = sp->se_next)
1533 if (strcmp(typ->ty_name, sp->se_device + devlen) == 0)
1534 break;
1535
1536 if (sp) {
1537 sp->se_flags |= SE_PRESENT;
1538 if (sp->se_index != session_index) {
1539 warning("port `%s' changed utmp index from "
1540 "%d to %d", sp->se_device, sp->se_index,
1541 session_index);
1542 sp->se_index = session_index;
1543 }
1544 if ((typ->ty_status & TTY_ON) == 0 ||
1545 typ->ty_getty == 0) {
1546 sp->se_flags |= SE_SHUTDOWN;
1547 if (sp->se_process != 0)
1548 (void)kill(sp->se_process, SIGHUP);
1549 continue;
1550 }
1551 sp->se_flags &= ~SE_SHUTDOWN;
1552 if (setupargv(sp, typ) == 0) {
1553 warning("can't parse getty for port `%s'",
1554 sp->se_device);
1555 sp->se_flags |= SE_SHUTDOWN;
1556 if (sp->se_process != 0)
1557 (void)kill(sp->se_process, SIGHUP);
1558 }
1559 continue;
1560 }
1561
1562 (void)new_session(sprev, session_index, typ);
1563 }
1564
1565 (void)endttyent();
1566
1567 for (sp = sessions; sp; sp = sp->se_next)
1568 if ((sp->se_flags & SE_PRESENT) == 0) {
1569 sp->se_flags |= SE_SHUTDOWN;
1570 if (sp->se_process != 0)
1571 (void)kill(sp->se_process, SIGHUP);
1572 }
1573
1574 return (state_func_t)multi_user;
1575 }
1576
1577 /*
1578 * Block further logins.
1579 */
1580 static state_func_t
1581 catatonia(void)
1582 {
1583 session_t *sp;
1584
1585 for (sp = sessions; sp; sp = sp->se_next)
1586 sp->se_flags |= SE_SHUTDOWN;
1587
1588 return (state_func_t)multi_user;
1589 }
1590 #endif /* LETS_GET_SMALL */
1591
1592 /*
1593 * Note SIGALRM.
1594 */
1595 static void
1596 /*ARGSUSED*/
1597 alrm_handler(int sig)
1598 {
1599
1600 clang = 1;
1601 }
1602
1603 #ifndef LETS_GET_SMALL
1604 /*
1605 * Bring the system down to single user.
1606 */
1607 static state_func_t
1608 death(void)
1609 {
1610 session_t *sp;
1611 int i, status;
1612 pid_t pid;
1613 static const int death_sigs[3] = { SIGHUP, SIGTERM, SIGKILL };
1614
1615 for (sp = sessions; sp; sp = sp->se_next)
1616 sp->se_flags |= SE_SHUTDOWN;
1617
1618 /* NB: should send a message to the session logger to avoid blocking. */
1619 #ifdef SUPPORT_UTMPX
1620 logwtmpx("~", "shutdown", "", 0, INIT_PROCESS);
1621 #endif
1622 #ifdef SUPPORT_UTMP
1623 logwtmp("~", "shutdown", "");
1624 #endif
1625
1626 for (i = 0; i < 3; ++i) {
1627 if (kill(-1, death_sigs[i]) == -1 && errno == ESRCH)
1628 return (state_func_t)single_user;
1629
1630 clang = 0;
1631 (void)alarm(DEATH_WATCH);
1632 do
1633 if ((pid = waitpid(-1, &status, 0)) != -1)
1634 collect_child(pid, status);
1635 while (clang == 0 && errno != ECHILD);
1636
1637 if (errno == ECHILD)
1638 return (state_func_t)single_user;
1639 }
1640
1641 warning("some processes would not die; ps axl advised");
1642
1643 return (state_func_t)single_user;
1644 }
1645 #endif /* LETS_GET_SMALL */
1646
1647 #ifdef MFS_DEV_IF_NO_CONSOLE
1648
1649 static int
1650 mfs_dev(void)
1651 {
1652 /*
1653 * We cannot print errors so we bail out silently...
1654 */
1655 pid_t pid;
1656 int status;
1657
1658 /* If we have /dev/console, assume all is OK */
1659 if (access(_PATH_CONSOLE, F_OK) == 0)
1660 return 0;
1661
1662 #if 0 /* Useful for testing MAKEDEV */
1663 /* Mount an mfs over /mnt so we can create a console entry */
1664 switch ((pid = fork())) {
1665 case 0:
1666 (void)execl(INIT_MOUNT_MFS, "mount_mfs",
1667 "-b", "4096", "-f", "512",
1668 "-s", 64, "-n", 10,
1669 "-p", "0755",
1670 "swap", "/mnt", NULL);
1671 _exit(9);
1672 /*NOTREACHED*/
1673
1674 case -1:
1675 return(-1);
1676
1677 default:
1678 if (waitpid(pid, &status, 0) == -1)
1679 return(-1);
1680 if (status != 0)
1681 return(-1);
1682 break;
1683 }
1684
1685 {
1686 dev_t dev;
1687 #ifdef CPU_CONSDEV
1688 static int name[2] = { CTL_MACHDEP, CPU_CONSDEV };
1689 size_t olen;
1690 olen = sizeof(dev);
1691 if (sysctl(name, sizeof(name) / sizeof(name[0]), &dev, &olen,
1692 NULL, 0) == -1)
1693 #endif
1694 dev = makedev(0, 0);
1695
1696 /* Make a console for us, so we can see things happening */
1697 if (mknod("/mnt/console", 0666 | S_IFCHR, dev) == -1)
1698 return(-1);
1699 (void)freopen("/mnt/console", "a", stderr);
1700 }
1701
1702 #endif
1703
1704 /* Run the makedev script to create devices */
1705 switch ((pid = fork())) {
1706 case 0:
1707 (void)dup2(2, 1); /* Give the script stdout */
1708 if (chdir("/dev") == 0)
1709 (void)execl(INIT_BSHELL, "sh",
1710 access("./MAKEDEV", X_OK) == 0
1711 ? "./MAKEDEV" : "/etc/MAKEDEV",
1712 "-MM", "init", NULL);
1713 _exit(10);
1714 /* NOTREACHED */
1715
1716 case -1:
1717 break;
1718
1719 default:
1720 if (waitpid(pid, &status, 0) == -1)
1721 break;
1722 if (status != 0)
1723 warn("MAKEDEV exit status %d", status);
1724 /*
1725 * If /dev/console got created, then return 0
1726 * regardless of MAKEDEV exit status.
1727 */
1728 if (access(_PATH_CONSOLE, F_OK) == 0)
1729 return 0;
1730 _exit(11);
1731 }
1732 warn("Unable to run MAKEDEV");
1733 _exit(12);
1734 }
1735 #endif
1736
1737 #ifndef LETS_GET_SMALL
1738 static int
1739 do_setttyent(void)
1740 {
1741 (void)endttyent();
1742 #ifdef CHROOT
1743 if (did_multiuser_chroot) {
1744 char path[PATH_MAX];
1745
1746 (void)snprintf(path, sizeof(path), "%s/%s", rootdir, _PATH_TTYS);
1747
1748 return setttyentpath(path);
1749 } else
1750 #endif /* CHROOT */
1751 return setttyent();
1752 }
1753 #endif
1754
1755 #if !defined(LETS_GET_SMALL) && defined(CHROOT)
1756
1757 static int
1758 createsysctlnode(void)
1759 {
1760 struct sysctlnode node;
1761 int mib[2];
1762 size_t len;
1763
1764 /*
1765 * Create top-level dynamic sysctl node. Its child nodes will only
1766 * be readable by the superuser, since regular mortals should not
1767 * care ("Sssh, it's a secret!").
1768 */
1769 len = sizeof(struct sysctlnode);
1770 mib[0] = CTL_CREATE;
1771
1772 (void)memset(&node, 0, len);
1773 node.sysctl_flags = SYSCTL_VERSION | CTLFLAG_READWRITE |
1774 CTLFLAG_PRIVATE | CTLTYPE_NODE;
1775 node.sysctl_num = CTL_CREATE;
1776 (void)snprintf(node.sysctl_name, SYSCTL_NAMELEN, "init");
1777 if (sysctl(&mib[0], 1, &node, &len, &node, len) == -1) {
1778 warning("could not create init node: %m");
1779 return -1;
1780 }
1781
1782 /*
1783 * Create second level dynamic node capable of holding pathname.
1784 * Provide "/" as the default value.
1785 */
1786 len = sizeof(struct sysctlnode);
1787 mib[0] = node.sysctl_num;
1788 mib[1] = CTL_CREATE;
1789
1790 (void)memset(&node, 0, len);
1791 node.sysctl_flags = SYSCTL_VERSION | CTLFLAG_READWRITE |
1792 CTLTYPE_STRING | CTLFLAG_OWNDATA;
1793 node.sysctl_size = _POSIX_PATH_MAX;
1794 node.sysctl_data = __UNCONST("/");
1795 node.sysctl_num = CTL_CREATE;
1796 (void)snprintf(node.sysctl_name, SYSCTL_NAMELEN, "root");
1797 if (sysctl(&mib[0], 2, NULL, NULL, &node, len) == -1) {
1798 warning("could not create init.root node: %m");
1799 return -1;
1800 }
1801
1802 return 0;
1803 }
1804
1805 static int
1806 shouldchroot(void)
1807 {
1808 struct sysctlnode node;
1809 size_t len, cnt;
1810 int mib;
1811
1812 len = sizeof(struct sysctlnode);
1813
1814 if (sysctlbyname("init.root", rootdir, &len, NULL, 0) == -1) {
1815 warning("could not read init.root: %m");
1816
1817 /* Child killed our node. Recreate it. */
1818 if (errno == ENOENT) {
1819 /* Destroy whatever is left, recreate from scratch. */
1820 if (sysctlnametomib("init", &mib, &cnt) != -1) {
1821 (void)memset(&node, 0, sizeof(node));
1822 node.sysctl_flags = SYSCTL_VERSION;
1823 node.sysctl_num = mib;
1824 mib = CTL_DESTROY;
1825
1826 (void)sysctl(&mib, 1, NULL, NULL, &node,
1827 sizeof(node));
1828 }
1829
1830 (void)createsysctlnode();
1831 }
1832
1833 /* We certainly won't chroot. */
1834 return 0;
1835 }
1836
1837 if (rootdir[len] != '\0' || strlen(rootdir) != len - 1) {
1838 warning("init.root is not a string");
1839 return 0;
1840 }
1841
1842 if (strcmp(rootdir, "/") == 0)
1843 return 0;
1844
1845 return 1;
1846 }
1847
1848 #endif /* !LETS_GET_SMALL && CHROOT */
1849