* remotely meaningful by skipping "tty"... */
strncpy(utptr->ut_id, short_tty + 3, sizeof(utptr->ut_id));
strncpy(utptr->ut_user, "LOGIN", sizeof(utptr->ut_user));
- utptr->ut_time = time(NULL);
+ utptr->ut_tv.tv_sec = time(NULL);
}
if (!picky) /* root login */
memset(utptr->ut_host, 0, sizeof(utptr->ut_host));
{
utptr->ut_type = USER_PROCESS;
strncpy(utptr->ut_user, username, sizeof(utptr->ut_user));
- utptr->ut_time = time(NULL);
+ utptr->ut_tv.tv_sec = time(NULL);
/* other fields already filled in by read_or_build_utent above */
setutent();
pututline(utptr);
#endif /* !ENABLE_FEATURE_UTMP */
#if ENABLE_FEATURE_NOLOGIN
-static void die_if_nologin_and_non_root(int amroot)
+static void die_if_nologin(void)
{
FILE *fp;
int c;
fclose(fp);
} else
puts("\r\nSystem closed for routine maintenance\r");
- if (!amroot)
- exit(1);
- puts("\r\n[Disconnect bypassed -- root login allowed]\r");
+ exit(EXIT_FAILURE);
}
#else
-static ALWAYS_INLINE void die_if_nologin_and_non_root(int amroot) {}
+static ALWAYS_INLINE void die_if_nologin(void) {}
#endif
#if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM
/* skip whitespace */
do {
c = getchar();
- if (c == EOF) exit(1);
+ if (c == EOF) exit(EXIT_FAILURE);
if (c == '\n') {
- if (!--cntdown) exit(1);
+ if (!--cntdown) exit(EXIT_FAILURE);
goto prompt;
}
} while (isspace(c));
*buf++ = c;
if (!fgets(buf, size_buf-2, stdin))
- exit(1);
+ exit(EXIT_FAILURE);
if (!strchr(buf, '\n'))
- exit(1);
+ exit(EXIT_FAILURE);
while (isgraph(*buf)) buf++;
*buf = '\0';
}
}
}
-static void alarm_handler(int sig ATTRIBUTE_UNUSED)
+static void alarm_handler(int sig UNUSED_PARAM)
{
/* This is the escape hatch! Poor serial line users and the like
* arrive here when their connection is broken.
* We don't want to block here */
ndelay_on(1);
- ndelay_on(2);
printf("\r\nLogin timed out after %d seconds\r\n", TIMEOUT);
+ fflush(stdout);
/* unix API is brain damaged regarding O_NONBLOCK,
* we should undo it, or else we can affect other processes */
ndelay_off(1);
- ndelay_off(2);
- exit(EXIT_SUCCESS);
+ _exit(EXIT_SUCCESS);
}
int login_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
-int login_main(int argc, char **argv)
+int login_main(int argc UNUSED_PARAM, char **argv)
{
enum {
LOGIN_OPT_f = (1<<0),
unsigned opt;
int count = 0;
struct passwd *pw;
- char *opt_host = NULL;
- char *opt_user = NULL;
+ char *opt_host = opt_host; /* for compiler */
+ char *opt_user = opt_user; /* for compiler */
char full_tty[TTYNAME_SIZE];
USE_SELINUX(security_context_t user_sid = NULL;)
USE_FEATURE_UTMP(struct utmp utent;)
short_tty = full_tty;
username[0] = '\0';
- amroot = (getuid() == 0);
signal(SIGALRM, alarm_handler);
alarm(TIMEOUT);
+ /* More of suid paranoia if called by non-root */
+ amroot = !sanitize_env_if_suid(); /* Clear dangerous stuff, set PATH */
+
/* Mandatory paranoia for suid applet:
* ensure that fd# 0,1,2 are opened (at least to /dev/null)
* and any extra open fd's are closed.
* (The name of the function is misleading. Not daemonizing here.) */
bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE | DAEMON_CLOSE_EXTRA_FDS, NULL);
- /* More of suid paranoia if called by non-root */
- if (!amroot) {
- /* Clear dangerous stuff, set PATH */
- sanitize_env_for_suid();
- }
opt = getopt32(argv, "f:h:p", &opt_user, &opt_host);
if (opt & LOGIN_OPT_f) {
bb_error_msg_and_die("-f is for root only");
safe_strncpy(username, opt_user, sizeof(username));
}
- if (optind < argc) /* user from command line (getty) */
- safe_strncpy(username, argv[optind], sizeof(username));
+ argv += optind;
+ if (argv[0]) /* user from command line (getty) */
+ safe_strncpy(username, argv[0], sizeof(username));
/* Let's find out and memorize our tty */
if (!isatty(0) || !isatty(1) || !isatty(2))
read_or_build_utent(&utent, !amroot);
- if (opt_host) {
+ if (opt & LOGIN_OPT_h) {
USE_FEATURE_UTMP(
safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host));
)
}
alarm(0);
- die_if_nologin_and_non_root(pw->pw_uid == 0);
+ if (!amroot)
+ die_if_nologin();
write_utent(&utent, username);
xsetenv("LOGIN_UID", utoa(pw->pw_uid));
xsetenv("LOGIN_GID", utoa(pw->pw_gid));
xsetenv("LOGIN_SHELL", pw->pw_shell);
- xspawn(t_argv); /* NOMMU-friendly */
- /* All variables are unset by setup_environment */
- wait(NULL);
+ spawn_and_wait(t_argv); /* NOMMU-friendly */
+ unsetenv("LOGIN_TTY" );
+ unsetenv("LOGIN_USER" );
+ unsetenv("LOGIN_UID" );
+ unsetenv("LOGIN_GID" );
+ unsetenv("LOGIN_SHELL");
}
}
tmp = pw->pw_shell;
if (!tmp || !*tmp)
tmp = DEFAULT_SHELL;
- /* setup_environment params: shell, loginshell, changeenv, pw */
- setup_environment(tmp, 1, !(opt & LOGIN_OPT_p), pw);
- /* FIXME: login shell = 1 -> 3rd parameter is ignored! */
+ /* setup_environment params: shell, clear_env, change_env, pw */
+ setup_environment(tmp, !(opt & LOGIN_OPT_p), 1, pw);
motd();