source: branches/2.2.9/mindi-busybox/loginutils/sulogin.c @ 2142

Last change on this file since 2142 was 1765, checked in by bruno, 12 years ago

Update to busybox 1.7.2

File size: 2.4 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 tarball for details.
6 */
7
8#include <syslog.h>
9
10#include "libbb.h"
11
12static const char *const forbid[] = {
13    "ENV",
14    "BASH_ENV",
15    "HOME",
16    "IFS",
17    "PATH",
18    "SHELL",
19    "LD_LIBRARY_PATH",
20    "LD_PRELOAD",
21    "LD_TRACE_LOADED_OBJECTS",
22    "LD_BIND_NOW",
23    "LD_AOUT_LIBRARY_PATH",
24    "LD_AOUT_PRELOAD",
25    "LD_NOWARN",
26    "LD_KEEPDIR",
27    (char *) 0
28};
29
30
31static void catchalarm(int ATTRIBUTE_UNUSED junk)
32{
33    exit(EXIT_FAILURE);
34}
35
36
37int sulogin_main(int argc, char **argv);
38int sulogin_main(int argc, char **argv)
39{
40    char *cp;
41    int timeout = 0;
42    char *timeout_arg;
43    const char *const *p;
44    struct passwd *pwd;
45    const char *shell;
46#if ENABLE_FEATURE_SHADOWPASSWDS
47    /* Using _r function to avoid pulling in static buffers */
48    char buffer[256];
49    struct spwd spw;
50    struct spwd *result;
51#endif
52
53    logmode = LOGMODE_BOTH;
54    openlog(applet_name, 0, LOG_AUTH);
55
56    if (getopt32(argv, "t:", &timeout_arg)) {
57        timeout = xatoi_u(timeout_arg);
58    }
59
60    if (argv[optind]) {
61        close(0);
62        close(1);
63        dup(xopen(argv[optind], O_RDWR));
64        close(2);
65        dup(0);
66    }
67
68    if (!isatty(0) || !isatty(1) || !isatty(2)) {
69        logmode = LOGMODE_SYSLOG;
70        bb_error_msg_and_die("not a tty");
71    }
72
73    /* Clear out anything dangerous from the environment */
74    for (p = forbid; *p; p++)
75        unsetenv(*p);
76
77    signal(SIGALRM, catchalarm);
78
79    pwd = getpwuid(0);
80    if (!pwd) {
81        goto auth_error;
82    }
83
84#if ENABLE_FEATURE_SHADOWPASSWDS
85    if (getspnam_r(pwd->pw_name, &spw, buffer, sizeof(buffer), &result)) {
86        goto auth_error;
87    }
88    pwd->pw_passwd = spw.sp_pwdp;
89#endif
90
91    while (1) {
92        /* cp points to a static buffer that is zeroed every time */
93        cp = bb_askpass(timeout,
94                "Give root password for system maintenance\n"
95                "(or type Control-D for normal startup):");
96
97        if (!cp || !*cp) {
98            bb_info_msg("Normal startup");
99            return 0;
100        }
101        if (strcmp(pw_encrypt(cp, pwd->pw_passwd), pwd->pw_passwd) == 0) {
102            break;
103        }
104        bb_do_delay(FAIL_DELAY);
105        bb_error_msg("login incorrect");
106    }
107    memset(cp, 0, strlen(cp));
108    signal(SIGALRM, SIG_DFL);
109
110    bb_info_msg("System Maintenance Mode");
111
112    USE_SELINUX(renew_current_security_context());
113
114    shell = getenv("SUSHELL");
115    if (!shell) shell = getenv("sushell");
116    if (!shell) {
117        shell = "/bin/sh";
118        if (pwd->pw_shell[0])
119            shell = pwd->pw_shell;
120    }
121    run_shell(shell, 1, 0, 0);
122    /* never returns */
123
124auth_error:
125    bb_error_msg_and_die("no password entry for 'root'");
126}
Note: See TracBrowser for help on using the repository browser.