#include "busybox.h"
#ifdef CONFIG_SELINUX
-#include <flask_util.h>
-#include <get_sid_list.h>
-#include <proc_secure.h>
-#include <fs_secure.h>
+#include <selinux/selinux.h> /* for is_selinux_enabled() */
+#include <selinux/get_context_list.h> /* for get_default_context() */
+#include <selinux/flask.h> /* for security class definitions */
+#include <errno.h>
#endif
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
// import from utmp.c
static void checkutmp(int picky);
static void setutmp(const char *name, const char *line);
/* Stuff global to this file */
-struct utmp utent;
+static struct utmp utent;
#endif
// login defines
static void motd ( void );
-static void alarm_handler ( int sig )
+static void alarm_handler ( int sig ATTRIBUTE_UNUSED)
{
fprintf (stderr, "\nLogin timed out after %d seconds.\n", TIMEOUT );
exit ( EXIT_SUCCESS );
}
-extern int login_main(int argc, char **argv)
+int login_main(int argc, char **argv)
{
char tty[BUFSIZ];
char full_tty[200];
char *opt_host = 0;
int alarmstarted = 0;
#ifdef CONFIG_SELINUX
- int flask_enabled = is_flask_enabled();
- security_id_t sid = 0, old_tty_sid, new_tty_sid;
+ security_context_t user_sid = NULL;
#endif
username[0]=0;
if ( optarg != argv[optind-1] )
bb_show_usage( );
- if ( !amroot ) /* Auth bypass only if real UID is zero */
+ if ( !amroot ) /* Auth bypass only if real UID is zero */
bb_error_msg_and_die ( "-f permission denied" );
safe_strncpy(username, optarg, USERNAME_SIZE);
if ( !isatty ( 0 ) || !isatty ( 1 ) || !isatty ( 2 ))
return EXIT_FAILURE; /* Must be a terminal */
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
checkutmp ( !amroot );
#endif
else
safe_strncpy ( tty, "UNKNOWN", sizeof( tty ));
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
if ( amroot )
memset ( utent.ut_host, 0, sizeof utent.ut_host );
#endif
if ( opt_host ) {
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
safe_strncpy ( utent.ut_host, opt_host, sizeof( utent. ut_host ));
#endif
snprintf ( fromhost, sizeof( fromhost ) - 1, " on `%.100s' from `%.200s'", tty, opt_host );
if ( !failed)
break;
- { // delay next try
- time_t start, now;
-
- time ( &start );
- now = start;
- while ( difftime ( now, start ) < FAIL_DELAY) {
- sleep ( FAIL_DELAY );
- time ( &now );
- }
- }
-
+ bb_do_delay(FAIL_DELAY);
puts("Login incorrect");
username[0] = 0;
if ( ++count == 3 ) {
if ( check_nologin ( pw-> pw_uid == 0 ))
return EXIT_FAILURE;
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
setutmp ( username, tty );
#endif
+
+ if ( *tty != '/' )
+ snprintf ( full_tty, sizeof( full_tty ) - 1, "/dev/%s", tty);
+ else
+ safe_strncpy ( full_tty, tty, sizeof( full_tty ) - 1 );
+
#ifdef CONFIG_SELINUX
- if (flask_enabled)
+ if (is_selinux_enabled())
{
- struct stat st;
+ security_context_t old_tty_sid, new_tty_sid;
- if (get_default_sid(username, 0, &sid))
+ if (get_default_context(username, NULL, &user_sid))
{
fprintf(stderr, "Unable to get SID for %s\n", username);
exit(1);
}
- if (stat_secure(tty, &st, &old_tty_sid))
+ if (getfilecon(full_tty, &old_tty_sid) < 0)
{
- fprintf(stderr, "stat_secure(%.100s) failed: %.100s\n", tty, strerror(errno));
+ fprintf(stderr, "getfilecon(%.100s) failed: %.100s\n", full_tty, strerror(errno));
return EXIT_FAILURE;
}
- if (security_change_sid (sid, old_tty_sid, SECCLASS_CHR_FILE, &new_tty_sid) != 0)
+ if (security_compute_relabel(user_sid, old_tty_sid, SECCLASS_CHR_FILE, &new_tty_sid) != 0)
{
- fprintf(stderr, "security_change_sid(%.100s) failed: %.100s\n", tty, strerror(errno));
+ fprintf(stderr, "security_change_sid(%.100s) failed: %.100s\n", full_tty, strerror(errno));
return EXIT_FAILURE;
}
- if(chsid(tty, new_tty_sid) != 0)
+ if(setfilecon(full_tty, new_tty_sid) != 0)
{
- fprintf(stderr, "chsid(%.100s, %d) failed: %.100s\n", tty, new_tty_sid, strerror(errno));
+ fprintf(stderr, "chsid(%.100s, %s) failed: %.100s\n", full_tty, new_tty_sid, strerror(errno));
return EXIT_FAILURE;
}
}
- else
- sid = 0;
#endif
-
- if ( *tty != '/' )
- snprintf ( full_tty, sizeof( full_tty ) - 1, "/dev/%s", tty);
- else
- safe_strncpy ( full_tty, tty, sizeof( full_tty ) - 1 );
-
if ( !is_my_tty ( full_tty ))
syslog ( LOG_ERR, "unable to determine TTY name, got %s\n", full_tty );
if ( pw-> pw_uid == 0 )
syslog ( LOG_INFO, "root login %s\n", fromhost );
- run_shell ( tmp, 1, 0, 0
#ifdef CONFIG_SELINUX
- , sid
+ /* well, a simple setexeccon() here would do the job as well,
+ * but let's play the game for now */
+ set_current_security_context(user_sid);
#endif
- ); /* exec the shell finally. */
+ run_shell ( tmp, 1, 0, 0); /* exec the shell finally. */
return EXIT_FAILURE;
}
}
-static void motd ( )
+static void motd (void)
{
FILE *fp;
register int c;
}
-#ifdef CONFIG_FEATURE_U_W_TMP
+#ifdef CONFIG_FEATURE_UTMP
// vv Taken from tinylogin utmp.c vv
#define NO_UTENT \
if (ut) {
utent = *ut;
} else {
+ time_t t_tmp;
+
if (picky) {
puts(NO_UTENT);
exit(1);
/* XXX - assumes /dev/tty?? */
strncpy(utent.ut_id, utent.ut_line + 3, sizeof utent.ut_id);
strncpy(utent.ut_user, "LOGIN", sizeof utent.ut_user);
- time(&utent.ut_time);
+ t_tmp = (time_t)utent.ut_time;
+ time(&t_tmp);
}
}
* USER_PROCESS. the wtmp file will be updated as well.
*/
-static void setutmp(const char *name, const char *line)
+static void setutmp(const char *name, const char *line ATTRIBUTE_UNUSED)
{
+ time_t t_tmp = (time_t)utent.ut_time;
+
utent.ut_type = USER_PROCESS;
strncpy(utent.ut_user, name, sizeof utent.ut_user);
- time(&utent.ut_time);
+ time(&t_tmp);
/* other fields already filled in by checkutmp above */
setutent();
pututline(&utent);
endutent();
+#ifdef CONFIG_FEATURE_WTMP
if (access(_PATH_WTMP, R_OK|W_OK) == -1) {
- creat(_PATH_WTMP, O_RDWR);
+ close(creat(_PATH_WTMP, 0664));
}
updwtmp(_PATH_WTMP, &utent);
+#endif
}
-#endif /* CONFIG_FEATURE_U_W_TMP */
+#endif /* CONFIG_FEATURE_UTMP */