Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (8 years ago)
Author:
bruno
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/loginutils/login.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    44 */
    5 
    65#include "libbb.h"
    7 #include <utmp.h>
     6#include <syslog.h>
     7#if ENABLE_FEATURE_UTMP
     8# include <utmp.h> /* USER_PROCESS */
     9#endif
    810#include <sys/resource.h>
    9 #include <syslog.h>
    1011
    1112#if ENABLE_SELINUX
    12 #include <selinux/selinux.h>  /* for is_selinux_enabled()  */
    13 #include <selinux/get_context_list.h> /* for get_default_context() */
    14 #include <selinux/flask.h> /* for security class definitions  */
     13# include <selinux/selinux.h>  /* for is_selinux_enabled()  */
     14# include <selinux/get_context_list.h> /* for get_default_context() */
     15# include <selinux/flask.h> /* for security class definitions  */
    1516#endif
    1617
    1718#if ENABLE_PAM
    1819/* PAM may include <locale.h>. We may need to undefine bbox's stub define: */
    19 #undef setlocale
     20# undef setlocale
    2021/* For some obscure reason, PAM is not in pam/xxx, but in security/xxx.
    2122 * Apparently they like to confuse people. */
    22 #include <security/pam_appl.h>
    23 #include <security/pam_misc.h>
     23# include <security/pam_appl.h>
     24# include <security/pam_misc.h>
    2425static const struct pam_conv conv = {
    2526    misc_conv,
     
    3738static char* short_tty;
    3839
    39 #if ENABLE_FEATURE_UTMP
    40 /* vv  Taken from tinylogin utmp.c  vv */
    41 /*
    42  * read_or_build_utent - see if utmp file is correct for this process
    43  *
    44  *  System V is very picky about the contents of the utmp file
    45  *  and requires that a slot for the current process exist.
    46  *  The utmp file is scanned for an entry with the same process
    47  *  ID.  If no entry exists the process exits with a message.
    48  *
    49  *  The "picky" flag is for network and other logins that may
    50  *  use special flags.  It allows the pid checks to be overridden.
    51  *  This means that getty should never invoke login with any
    52  *  command line flags.
    53  */
    54 
    55 static void read_or_build_utent(struct utmp *utptr, int picky)
    56 {
    57     struct utmp *ut;
    58     pid_t pid = getpid();
    59 
    60     setutent();
    61 
    62     /* First, try to find a valid utmp entry for this process.  */
    63     while ((ut = getutent()))
    64         if (ut->ut_pid == pid && ut->ut_line[0] && ut->ut_id[0] &&
    65         (ut->ut_type == LOGIN_PROCESS || ut->ut_type == USER_PROCESS))
    66             break;
    67 
    68     /* If there is one, just use it, otherwise create a new one.  */
    69     if (ut) {
    70         *utptr = *ut;
    71     } else {
    72         if (picky)
    73             bb_error_msg_and_die("no utmp entry found");
    74 
    75         memset(utptr, 0, sizeof(*utptr));
    76         utptr->ut_type = LOGIN_PROCESS;
    77         utptr->ut_pid = pid;
    78         strncpy(utptr->ut_line, short_tty, sizeof(utptr->ut_line));
    79         /* This one is only 4 chars wide. Try to fit something
    80          * remotely meaningful by skipping "tty"... */
    81         strncpy(utptr->ut_id, short_tty + 3, sizeof(utptr->ut_id));
    82         strncpy(utptr->ut_user, "LOGIN", sizeof(utptr->ut_user));
    83         utptr->ut_time = time(NULL);
    84     }
    85     if (!picky) /* root login */
    86         memset(utptr->ut_host, 0, sizeof(utptr->ut_host));
    87 }
    88 
    89 /*
    90  * write_utent - put a USER_PROCESS entry in the utmp file
    91  *
    92  *  write_utent changes the type of the current utmp entry to
    93  *  USER_PROCESS.  the wtmp file will be updated as well.
    94  */
    95 static void write_utent(struct utmp *utptr, const char *username)
    96 {
    97     utptr->ut_type = USER_PROCESS;
    98     strncpy(utptr->ut_user, username, sizeof(utptr->ut_user));
    99     utptr->ut_time = time(NULL);
    100     /* other fields already filled in by read_or_build_utent above */
    101     setutent();
    102     pututline(utptr);
    103     endutent();
    104 #if ENABLE_FEATURE_WTMP
    105     if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) {
    106         close(creat(bb_path_wtmp_file, 0664));
    107     }
    108     updwtmp(bb_path_wtmp_file, utptr);
    109 #endif
    110 }
    111 #else /* !ENABLE_FEATURE_UTMP */
    112 #define read_or_build_utent(utptr, picky) ((void)0)
    113 #define write_utent(utptr, username) ((void)0)
    114 #endif /* !ENABLE_FEATURE_UTMP */
    115 
    11640#if ENABLE_FEATURE_NOLOGIN
    117 static void die_if_nologin_and_non_root(int amroot)
     41static void die_if_nologin(void)
    11842{
    11943    FILE *fp;
    12044    int c;
    121 
    122     if (access("/etc/nologin", F_OK))
     45    int empty = 1;
     46
     47    fp = fopen_for_read("/etc/nologin");
     48    if (!fp) /* assuming it does not exist */
    12349        return;
    12450
    125     fp = fopen("/etc/nologin", "r");
    126     if (fp) {
    127         while ((c = getc(fp)) != EOF)
    128             putchar((c=='\n') ? '\r' : c);
    129         fflush(stdout);
    130         fclose(fp);
    131     } else
     51    while ((c = getc(fp)) != EOF) {
     52        if (c == '\n')
     53            bb_putchar('\r');
     54        bb_putchar(c);
     55        empty = 0;
     56    }
     57    if (empty)
    13258        puts("\r\nSystem closed for routine maintenance\r");
    133     if (!amroot)
    134         exit(1);
    135     puts("\r\n[Disconnect bypassed -- root login allowed]\r");
     59
     60    fclose(fp);
     61    fflush_all();
     62    /* Users say that they do need this prior to exit: */
     63    tcdrain(STDOUT_FILENO);
     64    exit(EXIT_FAILURE);
    13665}
    13766#else
    138 static ALWAYS_INLINE void die_if_nologin_and_non_root(int amroot) {}
     67# define die_if_nologin() ((void)0)
    13968#endif
    14069
     
    14271static int check_securetty(void)
    14372{
    144     FILE *fp;
    145     int i;
    146     char buf[256];
    147 
    148     fp = fopen("/etc/securetty", "r");
    149     if (!fp) {
    150         /* A missing securetty file is not an error. */
    151         return 1;
    152     }
    153     while (fgets(buf, sizeof(buf)-1, fp)) {
    154         for (i = strlen(buf)-1; i >= 0; --i) {
    155             if (!isspace(buf[i]))
    156                 break;
    157         }
    158         buf[++i] = '\0';
    159         if (!buf[0] || (buf[0] == '#'))
    160             continue;
    161         if (strcmp(buf, short_tty) == 0) {
    162             fclose(fp);
    163             return 1;
    164         }
    165     }
    166     fclose(fp);
    167     return 0;
     73    char *buf = (char*)"/etc/securetty"; /* any non-NULL is ok */
     74    parser_t *parser = config_open2("/etc/securetty", fopen_for_read);
     75    while (config_read(parser, &buf, 1, 1, "# \t", PARSE_NORMAL)) {
     76        if (strcmp(buf, short_tty) == 0)
     77            break;
     78        buf = NULL;
     79    }
     80    config_close(parser);
     81    /* buf != NULL here if config file was not found, empty
     82     * or line was found which equals short_tty */
     83    return buf != NULL;
    16884}
    16985#else
    17086static ALWAYS_INLINE int check_securetty(void) { return 1; }
     87#endif
     88
     89#if ENABLE_SELINUX
     90static void initselinux(char *username, char *full_tty,
     91                        security_context_t *user_sid)
     92{
     93    security_context_t old_tty_sid, new_tty_sid;
     94
     95    if (!is_selinux_enabled())
     96        return;
     97
     98    if (get_default_context(username, NULL, user_sid)) {
     99        bb_error_msg_and_die("can't get SID for %s", username);
     100    }
     101    if (getfilecon(full_tty, &old_tty_sid) < 0) {
     102        bb_perror_msg_and_die("getfilecon(%s) failed", full_tty);
     103    }
     104    if (security_compute_relabel(*user_sid, old_tty_sid,
     105                SECCLASS_CHR_FILE, &new_tty_sid) != 0) {
     106        bb_perror_msg_and_die("security_change_sid(%s) failed", full_tty);
     107    }
     108    if (setfilecon(full_tty, new_tty_sid) != 0) {
     109        bb_perror_msg_and_die("chsid(%s, %s) failed", full_tty, new_tty_sid);
     110    }
     111}
     112#endif
     113
     114#if ENABLE_LOGIN_SCRIPTS
     115static void run_login_script(struct passwd *pw, char *full_tty)
     116{
     117    char *t_argv[2];
     118
     119    t_argv[0] = getenv("LOGIN_PRE_SUID_SCRIPT");
     120    if (t_argv[0]) {
     121        t_argv[1] = NULL;
     122        xsetenv("LOGIN_TTY", full_tty);
     123        xsetenv("LOGIN_USER", pw->pw_name);
     124        xsetenv("LOGIN_UID", utoa(pw->pw_uid));
     125        xsetenv("LOGIN_GID", utoa(pw->pw_gid));
     126        xsetenv("LOGIN_SHELL", pw->pw_shell);
     127        spawn_and_wait(t_argv); /* NOMMU-friendly */
     128        unsetenv("LOGIN_TTY");
     129        unsetenv("LOGIN_USER");
     130        unsetenv("LOGIN_UID");
     131        unsetenv("LOGIN_GID");
     132        unsetenv("LOGIN_SHELL");
     133    }
     134}
     135#else
     136void run_login_script(struct passwd *pw, char *full_tty);
    171137#endif
    172138
     
    181147    do {
    182148        c = getchar();
    183         if (c == EOF) exit(1);
     149        if (c == EOF)
     150            exit(EXIT_FAILURE);
    184151        if (c == '\n') {
    185             if (!--cntdown) exit(1);
     152            if (!--cntdown)
     153                exit(EXIT_FAILURE);
    186154            goto prompt;
    187155        }
    188     } while (isspace(c));
     156    } while (isspace(c)); /* maybe isblank? */
    189157
    190158    *buf++ = c;
    191159    if (!fgets(buf, size_buf-2, stdin))
    192         exit(1);
     160        exit(EXIT_FAILURE);
    193161    if (!strchr(buf, '\n'))
    194         exit(1);
    195     while (isgraph(*buf)) buf++;
     162        exit(EXIT_FAILURE);
     163    while ((unsigned char)*buf > ' ')
     164        buf++;
    196165    *buf = '\0';
    197166}
     
    202171
    203172    fd = open(bb_path_motd_file, O_RDONLY);
    204     if (fd) {
    205         fflush(stdout);
     173    if (fd >= 0) {
     174        fflush_all();
    206175        bb_copyfd_eof(fd, STDOUT_FILENO);
    207176        close(fd);
     
    209178}
    210179
    211 static void alarm_handler(int sig ATTRIBUTE_UNUSED)
     180static void alarm_handler(int sig UNUSED_PARAM)
    212181{
    213182    /* This is the escape hatch!  Poor serial line users and the like
     
    215184     * We don't want to block here */
    216185    ndelay_on(1);
    217     ndelay_on(2);
    218186    printf("\r\nLogin timed out after %d seconds\r\n", TIMEOUT);
    219     exit(EXIT_SUCCESS);
    220 }
    221 
    222 int login_main(int argc, char **argv);
    223 int login_main(int argc, char **argv)
     187    fflush_all();
     188    /* unix API is brain damaged regarding O_NONBLOCK,
     189     * we should undo it, or else we can affect other processes */
     190    ndelay_off(1);
     191    _exit(EXIT_SUCCESS);
     192}
     193
     194int login_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     195int login_main(int argc UNUSED_PARAM, char **argv)
    224196{
    225197    enum {
     
    230202    char *fromhost;
    231203    char username[USERNAME_SIZE];
    232     const char *tmp;
    233     int amroot;
     204    const char *shell;
     205    int run_by_root;
    234206    unsigned opt;
    235207    int count = 0;
    236208    struct passwd *pw;
    237209    char *opt_host = NULL;
    238     char *opt_user = NULL;
    239     char full_tty[TTYNAME_SIZE];
    240     USE_SELINUX(security_context_t user_sid = NULL;)
    241     USE_FEATURE_UTMP(struct utmp utent;)
    242     USE_PAM(pam_handle_t *pamh;)
    243     USE_PAM(int pamret;)
    244     USE_PAM(const char *failed_msg;)
    245 
    246     short_tty = full_tty;
     210    char *opt_user = opt_user; /* for compiler */
     211    char *full_tty;
     212    IF_SELINUX(security_context_t user_sid = NULL;)
     213#if ENABLE_PAM
     214    int pamret;
     215    pam_handle_t *pamh;
     216    const char *pamuser;
     217    const char *failed_msg;
     218    struct passwd pwdstruct;
     219    char pwdbuf[256];
     220#endif
     221
    247222    username[0] = '\0';
    248     amroot = (getuid() == 0);
    249223    signal(SIGALRM, alarm_handler);
    250224    alarm(TIMEOUT);
     225
     226    /* More of suid paranoia if called by non-root: */
     227    /* Clear dangerous stuff, set PATH */
     228    run_by_root = !sanitize_env_if_suid();
    251229
    252230    /* Mandatory paranoia for suid applet:
     
    258236    opt = getopt32(argv, "f:h:p", &opt_user, &opt_host);
    259237    if (opt & LOGIN_OPT_f) {
    260         if (!amroot)
     238        if (!run_by_root)
    261239            bb_error_msg_and_die("-f is for root only");
    262240        safe_strncpy(username, opt_user, sizeof(username));
    263241    }
    264     if (optind < argc) /* user from command line (getty) */
    265         safe_strncpy(username, argv[optind], sizeof(username));
     242    argv += optind;
     243    if (argv[0]) /* user from command line (getty) */
     244        safe_strncpy(username, argv[0], sizeof(username));
    266245
    267246    /* Let's find out and memorize our tty */
    268     if (!isatty(0) || !isatty(1) || !isatty(2))
    269         return EXIT_FAILURE;        /* Must be a terminal */
    270     safe_strncpy(full_tty, "UNKNOWN", sizeof(full_tty));
    271     tmp = ttyname(0);
    272     if (tmp) {
    273         safe_strncpy(full_tty, tmp, sizeof(full_tty));
    274         if (strncmp(full_tty, "/dev/", 5) == 0)
    275             short_tty = full_tty + 5;
    276     }
    277 
    278     read_or_build_utent(&utent, !amroot);
     247    if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO) || !isatty(STDERR_FILENO))
     248        return EXIT_FAILURE;  /* Must be a terminal */
     249    full_tty = xmalloc_ttyname(STDIN_FILENO);
     250    if (!full_tty)
     251        full_tty = xstrdup("UNKNOWN");
     252    short_tty = skip_dev_pfx(full_tty);
    279253
    280254    if (opt_host) {
    281         USE_FEATURE_UTMP(
    282             safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host));
    283         )
    284255        fromhost = xasprintf(" on '%s' from '%s'", short_tty, opt_host);
    285     } else
     256    } else {
    286257        fromhost = xasprintf(" on '%s'", short_tty);
     258    }
    287259
    288260    /* Was breaking "login <username>" from shell command line: */
    289261    /*bb_setpgrp();*/
    290262
    291     openlog(applet_name, LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
     263    openlog(applet_name, LOG_PID | LOG_CONS, LOG_AUTH);
    292264
    293265    while (1) {
     266        /* flush away any type-ahead (as getty does) */
     267        tcflush(0, TCIFLUSH);
     268
    294269        if (!username[0])
    295270            get_username_or_die(username, sizeof(username));
     
    298273        pamret = pam_start("login", username, &conv, &pamh);
    299274        if (pamret != PAM_SUCCESS) {
    300             failed_msg = "pam_start";
     275            failed_msg = "start";
    301276            goto pam_auth_failed;
    302277        }
     
    304279        pamret = pam_set_item(pamh, PAM_TTY, short_tty);
    305280        if (pamret != PAM_SUCCESS) {
    306             failed_msg = "pam_set_item(TTY)";
     281            failed_msg = "set_item(TTY)";
    307282            goto pam_auth_failed;
    308283        }
    309284        pamret = pam_authenticate(pamh, 0);
    310285        if (pamret != PAM_SUCCESS) {
    311             failed_msg = "pam_authenticate";
     286            failed_msg = "authenticate";
    312287            goto pam_auth_failed;
    313288            /* TODO: or just "goto auth_failed"
     
    319294        pamret = pam_acct_mgmt(pamh, 0);
    320295        if (pamret != PAM_SUCCESS) {
    321             failed_msg = "account setup";
     296            failed_msg = "acct_mgmt";
    322297            goto pam_auth_failed;
    323298        }
    324299        /* read user back */
    325         {
    326             const char *pamuser;
    327             /* gcc: "dereferencing type-punned pointer breaks aliasing rules..."
    328              * thus we cast to (void*) */
    329             if (pam_get_item(pamh, PAM_USER, (void*)&pamuser) != PAM_SUCCESS) {
    330                 failed_msg = "pam_get_item(USER)";
    331                 goto pam_auth_failed;
    332             }
    333             safe_strncpy(username, pamuser, sizeof(username));
    334         }
    335         /* If we get here, the user was authenticated, and is
    336          * granted access. */
    337         pw = getpwnam(username);
    338         if (pw)
    339             break;
    340         goto auth_failed;
     300        pamuser = NULL;
     301        /* gcc: "dereferencing type-punned pointer breaks aliasing rules..."
     302         * thus we cast to (void*) */
     303        if (pam_get_item(pamh, PAM_USER, (void*)&pamuser) != PAM_SUCCESS) {
     304            failed_msg = "get_item(USER)";
     305            goto pam_auth_failed;
     306        }
     307        if (!pamuser || !pamuser[0])
     308            goto auth_failed;
     309        safe_strncpy(username, pamuser, sizeof(username));
     310        /* Don't use "pw = getpwnam(username);",
     311         * PAM is said to be capable of destroying static storage
     312         * used by getpwnam(). We are using safe(r) function */
     313        pw = NULL;
     314        getpwnam_r(username, &pwdstruct, pwdbuf, sizeof(pwdbuf), &pw);
     315        if (!pw)
     316            goto auth_failed;
     317        pamret = pam_open_session(pamh, 0);
     318        if (pamret != PAM_SUCCESS) {
     319            failed_msg = "open_session";
     320            goto pam_auth_failed;
     321        }
     322        pamret = pam_setcred(pamh, PAM_ESTABLISH_CRED);
     323        if (pamret != PAM_SUCCESS) {
     324            failed_msg = "setcred";
     325            goto pam_auth_failed;
     326        }
     327        break; /* success, continue login process */
     328
    341329 pam_auth_failed:
    342         bb_error_msg("%s failed: %s (%d)", failed_msg, pam_strerror(pamh, pamret), pamret);
     330        /* syslog, because we don't want potential attacker
     331         * to know _why_ login failed */
     332        syslog(LOG_WARNING, "pam_%s call failed: %s (%d)", failed_msg,
     333                    pam_strerror(pamh, pamret), pamret);
    343334        safe_strncpy(username, "UNKNOWN", sizeof(username));
    344335#else /* not PAM */
     
    374365            syslog(LOG_WARNING, "invalid password for '%s'%s",
    375366                        username, fromhost);
     367
     368            if (ENABLE_FEATURE_CLEAN_UP)
     369                free(fromhost);
     370
    376371            return EXIT_FAILURE;
    377372        }
    378373        username[0] = '\0';
    379     }
     374    } /* while (1) */
    380375
    381376    alarm(0);
    382     die_if_nologin_and_non_root(pw->pw_uid == 0);
    383 
    384     write_utent(&utent, username);
    385 
    386 #if ENABLE_SELINUX
    387     if (is_selinux_enabled()) {
    388         security_context_t old_tty_sid, new_tty_sid;
    389 
    390         if (get_default_context(username, NULL, &user_sid)) {
    391             bb_error_msg_and_die("cannot get SID for %s",
    392                     username);
    393         }
    394         if (getfilecon(full_tty, &old_tty_sid) < 0) {
    395             bb_perror_msg_and_die("getfilecon(%s) failed",
    396                     full_tty);
    397         }
    398         if (security_compute_relabel(user_sid, old_tty_sid,
    399                     SECCLASS_CHR_FILE, &new_tty_sid) != 0) {
    400             bb_perror_msg_and_die("security_change_sid(%s) failed",
    401                     full_tty);
    402         }
    403         if (setfilecon(full_tty, new_tty_sid) != 0) {
    404             bb_perror_msg_and_die("chsid(%s, %s) failed",
    405                     full_tty, new_tty_sid);
    406         }
    407     }
    408 #endif
     377    /* We can ignore /etc/nologin if we are logging in as root,
     378     * it doesn't matter whether we are run by root or not */
     379    if (pw->pw_uid != 0)
     380        die_if_nologin();
     381
     382    IF_SELINUX(initselinux(username, full_tty, &user_sid));
     383
    409384    /* Try these, but don't complain if they fail.
    410385     * _f_chown is safe wrt race t=ttyname(0);...;chown(t); */
     
    412387    fchmod(0, 0600);
    413388
    414     if (ENABLE_LOGIN_SCRIPTS) {
    415         char *t_argv[2];
    416 
    417         t_argv[0] = getenv("LOGIN_PRE_SUID_SCRIPT");
    418         if (t_argv[0]) {
    419             t_argv[1] = NULL;
    420             xsetenv("LOGIN_TTY", full_tty);
    421             xsetenv("LOGIN_USER", pw->pw_name);
    422             xsetenv("LOGIN_UID", utoa(pw->pw_uid));
    423             xsetenv("LOGIN_GID", utoa(pw->pw_gid));
    424             xsetenv("LOGIN_SHELL", pw->pw_shell);
    425             xspawn(t_argv); /* NOMMU-friendly */
    426             /* All variables are unset by setup_environment */
    427             wait(NULL);
    428         }
    429     }
     389    update_utmp(getpid(), USER_PROCESS, short_tty, username, run_by_root ? opt_host : NULL);
     390
     391    /* We trust environment only if we run by root */
     392    if (ENABLE_LOGIN_SCRIPTS && run_by_root)
     393        run_login_script(pw, full_tty);
    430394
    431395    change_identity(pw);
    432     tmp = pw->pw_shell;
    433     if (!tmp || !*tmp)
    434         tmp = DEFAULT_SHELL;
    435     /* setup_environment params: shell, loginshell, changeenv, pw */
    436     setup_environment(tmp, 1, !(opt & LOGIN_OPT_p), pw);
    437     /* FIXME: login shell = 1 -> 3rd parameter is ignored! */
     396    shell = pw->pw_shell;
     397    if (!shell || !shell[0])
     398        shell = DEFAULT_SHELL;
     399    setup_environment(shell,
     400            (!(opt & LOGIN_OPT_p) * SETUP_ENV_CLEARENV) + SETUP_ENV_CHANGEENV,
     401            pw);
    438402
    439403    motd();
     
    441405    if (pw->pw_uid == 0)
    442406        syslog(LOG_INFO, "root login%s", fromhost);
    443 #if ENABLE_SELINUX
     407
     408    if (ENABLE_FEATURE_CLEAN_UP)
     409        free(fromhost);
     410
    444411    /* well, a simple setexeccon() here would do the job as well,
    445412     * but let's play the game for now */
    446     set_current_security_context(user_sid);
    447 #endif
     413    IF_SELINUX(set_current_security_context(user_sid);)
    448414
    449415    // util-linux login also does:
     
    456422    // If this stuff is really needed, add it and explain why!
    457423
    458     /* set signals to defaults */
    459     signal(SIGALRM, SIG_DFL);
     424    /* Set signals to defaults */
     425    /* Non-ignored signals revert to SIG_DFL on exec anyway */
     426    /*signal(SIGALRM, SIG_DFL);*/
     427
    460428    /* Is this correct? This way user can ctrl-c out of /etc/profile,
    461429     * potentially creating security breach (tested with bash 3.0).
     
    463431     * Maybe bash is buggy?
    464432     * Need to find out what standards say about /bin/login -
    465      * should it leave SIGINT etc enabled or disabled? */
     433     * should we leave SIGINT etc enabled or disabled? */
    466434    signal(SIGINT, SIG_DFL);
    467435
    468436    /* Exec login shell with no additional parameters */
    469     run_shell(tmp, 1, NULL, NULL);
     437    run_shell(shell, 1, NULL, NULL);
    470438
    471439    /* return EXIT_FAILURE; - not reached */
Note: See TracChangeset for help on using the changeset viewer.