source: branches/3.2/mindi-busybox/loginutils/sulogin.c @ 3232

Last change on this file since 3232 was 3232, checked in by Bruno Cornec, 7 years ago
  • Update mindi-busybox to 1.21.1
File size: 2.5 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * Mini sulogin implementation for busybox
4 *
5 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
6 */
7
8//usage:#define sulogin_trivial_usage
9//usage:       "[-t N] [TTY]"
10//usage:#define sulogin_full_usage "\n\n"
11//usage:       "Single user login\n"
12//usage:     "\n    -t N    Timeout"
13
14#include "libbb.h"
15#include <syslog.h>
16
17//static void catchalarm(int UNUSED_PARAM junk)
18//{
19//  exit(EXIT_FAILURE);
20//}
21
22
23int sulogin_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
24int sulogin_main(int argc UNUSED_PARAM, char **argv)
25{
26    char *cp;
27    int timeout = 0;
28    struct passwd *pwd;
29    const char *shell;
30#if ENABLE_FEATURE_SHADOWPASSWDS
31    /* Using _r function to avoid pulling in static buffers */
32    char buffer[256];
33    struct spwd spw;
34#endif
35
36    logmode = LOGMODE_BOTH;
37    openlog(applet_name, 0, LOG_AUTH);
38
39    opt_complementary = "t+"; /* -t N */
40    getopt32(argv, "t:", &timeout);
41    argv += optind;
42
43    if (argv[0]) {
44        close(0);
45        close(1);
46        dup(xopen(argv[0], O_RDWR));
47        close(2);
48        dup(0);
49    }
50
51    /* Malicious use like "sulogin /dev/sda"? */
52    if (!isatty(0) || !isatty(1) || !isatty(2)) {
53        logmode = LOGMODE_SYSLOG;
54        bb_error_msg_and_die("not a tty");
55    }
56
57    /* Clear dangerous stuff, set PATH */
58    sanitize_env_if_suid();
59
60    pwd = getpwuid(0);
61    if (!pwd) {
62        goto auth_error;
63    }
64
65#if ENABLE_FEATURE_SHADOWPASSWDS
66    {
67        /* getspnam_r may return 0 yet set result to NULL.
68         * At least glibc 2.4 does this. Be extra paranoid here. */
69        struct spwd *result = NULL;
70        int r = getspnam_r(pwd->pw_name, &spw, buffer, sizeof(buffer), &result);
71        if (r || !result) {
72            goto auth_error;
73        }
74        pwd->pw_passwd = result->sp_pwdp;
75    }
76#endif
77
78    while (1) {
79        char *encrypted;
80        int r;
81
82        /* cp points to a static buffer that is zeroed every time */
83        cp = bb_ask(STDIN_FILENO, timeout,
84                "Give root password for system maintenance\n"
85                "(or type Control-D for normal startup):");
86
87        if (!cp || !*cp) {
88            bb_info_msg("Normal startup");
89            return 0;
90        }
91        encrypted = pw_encrypt(cp, pwd->pw_passwd, 1);
92        r = strcmp(encrypted, pwd->pw_passwd);
93        free(encrypted);
94        if (r == 0) {
95            break;
96        }
97        bb_do_delay(LOGIN_FAIL_DELAY);
98        bb_info_msg("Login incorrect");
99    }
100    memset(cp, 0, strlen(cp));
101//  signal(SIGALRM, SIG_DFL);
102
103    bb_info_msg("System Maintenance Mode");
104
105    IF_SELINUX(renew_current_security_context());
106
107    shell = getenv("SUSHELL");
108    if (!shell)
109        shell = getenv("sushell");
110    if (!shell)
111        shell = pwd->pw_shell;
112
113    /* Exec login shell with no additional parameters. Never returns. */
114    run_shell(shell, 1, NULL, NULL);
115
116 auth_error:
117    bb_error_msg_and_die("no password entry for root");
118}
Note: See TracBrowser for help on using the repository browser.