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