1 /* vi: set sw=4 ts=4: */
3 * Mini sulogin implementation for busybox
5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
11 //static void catchalarm(int UNUSED_PARAM junk)
13 // exit(EXIT_FAILURE);
17 int sulogin_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
18 int sulogin_main(int argc UNUSED_PARAM, char **argv)
24 #if ENABLE_FEATURE_SHADOWPASSWDS
25 /* Using _r function to avoid pulling in static buffers */
30 logmode = LOGMODE_BOTH;
31 openlog(applet_name, 0, LOG_AUTH);
33 opt_complementary = "t+"; /* -t N */
34 getopt32(argv, "t:", &timeout);
40 dup(xopen(argv[0], O_RDWR));
45 /* Malicious use like "sulogin /dev/sda"? */
46 if (!isatty(0) || !isatty(1) || !isatty(2)) {
47 logmode = LOGMODE_SYSLOG;
48 bb_error_msg_and_die("not a tty");
51 /* Clear dangerous stuff, set PATH */
52 sanitize_env_if_suid();
54 // bb_ask() already handles this
55 // signal(SIGALRM, catchalarm);
62 #if ENABLE_FEATURE_SHADOWPASSWDS
64 /* getspnam_r may return 0 yet set result to NULL.
65 * At least glibc 2.4 does this. Be extra paranoid here. */
66 struct spwd *result = NULL;
67 int r = getspnam_r(pwd->pw_name, &spw, buffer, sizeof(buffer), &result);
71 pwd->pw_passwd = result->sp_pwdp;
79 /* cp points to a static buffer that is zeroed every time */
80 cp = bb_ask(STDIN_FILENO, timeout,
81 "Give root password for system maintenance\n"
82 "(or type Control-D for normal startup):");
85 bb_info_msg("Normal startup");
88 encrypted = pw_encrypt(cp, pwd->pw_passwd, 1);
89 r = strcmp(encrypted, pwd->pw_passwd);
94 bb_do_delay(FAIL_DELAY);
95 bb_error_msg("login incorrect");
97 memset(cp, 0, strlen(cp));
98 // signal(SIGALRM, SIG_DFL);
100 bb_info_msg("System Maintenance Mode");
102 IF_SELINUX(renew_current_security_context());
104 shell = getenv("SUSHELL");
106 shell = getenv("sushell");
109 if (pwd->pw_shell[0])
110 shell = pwd->pw_shell;
112 /* Exec login shell with no additional parameters. Never returns. */
113 run_shell(shell, 1, NULL, NULL);
116 bb_error_msg_and_die("no password entry for root");