1 /* vi: set sw=4 ts=4: */
3 * Mini sulogin implementation for busybox
5 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
7 //config:config SULOGIN
8 //config: bool "sulogin (18 kb)"
10 //config: select FEATURE_SYSLOG
12 //config: sulogin is invoked when the system goes into single user
13 //config: mode (this is done through an entry in inittab).
15 //applet:IF_SULOGIN(APPLET_NOEXEC(sulogin, sulogin, BB_DIR_SBIN, BB_SUID_DROP, sulogin))
17 //kbuild:lib-$(CONFIG_SULOGIN) += sulogin.o
19 //usage:#define sulogin_trivial_usage
20 //usage: "[-t N] [TTY]"
21 //usage:#define sulogin_full_usage "\n\n"
22 //usage: "Single user login\n"
23 //usage: "\n -p Start a login shell"
24 //usage: "\n -t SEC Timeout"
29 int sulogin_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
30 int sulogin_main(int argc UNUSED_PARAM
, char **argv
)
38 /* Note: sulogin is not a suid app. It is meant to be run by init
39 * for single user / emergency mode. init starts it as root.
40 * Normal users (potentially malicious ones) can only run it under
41 * their UID, therefore no paranoia here is warranted:
42 * $LD_LIBRARY_PATH in env, TTY = /dev/sda
43 * are no more dangerous here than in e.g. cp applet.
46 logmode
= LOGMODE_BOTH
;
47 openlog(applet_name
, 0, LOG_AUTH
);
49 opts
= getopt32(argv
, "pt:+", &timeout
);
55 dup(xopen(argv
[0], O_RDWR
));
62 bb_simple_error_msg_and_die("no password entry for root");
68 r
= ask_and_check_password_extended(pwd
, timeout
,
69 "Give root password for maintenance\n"
70 "(or type Ctrl-D to continue): "
73 /* ^D, ^C, timeout, or read error */
74 /* util-linux 2.36.1 compat: no message */
75 /*bb_simple_info_msg("normal startup");*/
81 pause_after_failed_login();
82 bb_simple_info_msg("Login incorrect");
85 /* util-linux 2.36.1 compat: no message */
86 /*bb_simple_info_msg("starting shell for system maintenance");*/
88 IF_SELINUX(renew_current_security_context());
90 shell
= getenv("SUSHELL");
92 shell
= getenv("sushell");
94 shell
= pwd
->pw_shell
;
96 /* util-linux 2.36.1 compat: cd to root's HOME, set a few envvars */
97 setup_environment(shell
, 0
98 + SETUP_ENV_CHANGEENV_LOGNAME
101 // no SETUP_ENV_CLEARENV
102 // SETUP_ENV_CHANGEENV_LOGNAME - set HOME, SHELL, USER,and LOGNAME
103 // SETUP_ENV_CHDIR - cd to $HOME
105 /* util-linux 2.36.1 compat: steal ctty if we don't have it yet
106 * (yes, util-linux uses force=1) */
107 tsid
= tcgetsid(STDIN_FILENO
);
108 if (tsid
< 0 || getpid() != tsid
) {
109 if (ioctl(STDIN_FILENO
, TIOCSCTTY
, /*force:*/ (long)1) != 0) {
110 // bb_perror_msg("TIOCSCTTY1 tsid:%d", tsid);
112 // bb_error_msg("done setsid()");
113 /* If it still does not work, ignore */
114 if (ioctl(STDIN_FILENO
, TIOCSCTTY
, /*force:*/ (long)1) != 0) {
115 // bb_perror_msg("TIOCSCTTY2 tsid:%d", tsid);
122 * Note: login does this (should we do it too?):
124 /*signal(SIGINT, SIG_DFL);*/
126 /* Exec shell with no additional parameters. Never returns. */
127 exec_shell(shell
, /* -p? then shell is login:*/(opts
& 1), NULL
);