login: optional support for PAM
This commit is contained in:
parent
18f2a6bc5e
commit
d6e81c7762
@ -60,18 +60,20 @@ LDFLAGS += -static
|
||||
endif
|
||||
|
||||
BBOX_LIB_LIST = m crypt
|
||||
|
||||
ifeq ($(CONFIG_PAM),y)
|
||||
BBOX_LIB_LIST += pam pam_misc
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SELINUX),y)
|
||||
#LDLIBS += -lselinux -lsepol
|
||||
BBOX_LIB_LIST += selinux sepol
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_EFENCE),y)
|
||||
#LDLIBS += -lefence
|
||||
BBOX_LIB_LIST += efence
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_DMALLOC),y)
|
||||
#LDLIBS += -ldmalloc
|
||||
BBOX_LIB_LIST += dmalloc
|
||||
endif
|
||||
|
||||
|
@ -128,6 +128,13 @@ config LOGIN
|
||||
Note that Busybox binary must be setuid root for this applet to
|
||||
work properly.
|
||||
|
||||
config PAM
|
||||
bool "Support for PAM (Pluggable Authentication Modules)"
|
||||
default n
|
||||
depends on LOGIN
|
||||
help
|
||||
Use PAM in login(1) instead of direct access to password database.
|
||||
|
||||
config LOGIN_SCRIPTS
|
||||
bool "Support for login scripts"
|
||||
depends on LOGIN
|
||||
|
@ -14,6 +14,15 @@
|
||||
#include <selinux/flask.h> /* for security class definitions */
|
||||
#endif
|
||||
|
||||
#if ENABLE_PAM
|
||||
#include <pam/pam_appl.h>
|
||||
#include <pam/pam_misc.h>
|
||||
static const struct pam_conv conv = {
|
||||
misc_conv,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
enum {
|
||||
TIMEOUT = 60,
|
||||
EMPTY_USERNAME_COUNT = 10,
|
||||
@ -125,7 +134,7 @@ static void die_if_nologin_and_non_root(int amroot)
|
||||
static ALWAYS_INLINE void die_if_nologin_and_non_root(int amroot) {}
|
||||
#endif
|
||||
|
||||
#if ENABLE_FEATURE_SECURETTY
|
||||
#if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM
|
||||
static int check_securetty(void)
|
||||
{
|
||||
FILE *fp;
|
||||
@ -214,7 +223,7 @@ int login_main(int argc, char **argv)
|
||||
LOGIN_OPT_h = (1<<1),
|
||||
LOGIN_OPT_p = (1<<2),
|
||||
};
|
||||
char fromhost[512];
|
||||
char *fromhost;
|
||||
char username[USERNAME_SIZE];
|
||||
const char *tmp;
|
||||
int amroot;
|
||||
@ -226,6 +235,9 @@ int login_main(int argc, char **argv)
|
||||
char full_tty[TTYNAME_SIZE];
|
||||
USE_SELINUX(security_context_t user_sid = NULL;)
|
||||
USE_FEATURE_UTMP(struct utmp utent;)
|
||||
USE_PAM(pam_handle_t *pamh;)
|
||||
USE_PAM(int pamret;)
|
||||
USE_PAM(const char *failed_msg;)
|
||||
|
||||
short_tty = full_tty;
|
||||
username[0] = '\0';
|
||||
@ -265,13 +277,12 @@ int login_main(int argc, char **argv)
|
||||
USE_FEATURE_UTMP(
|
||||
safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host));
|
||||
)
|
||||
snprintf(fromhost, sizeof(fromhost)-1, " on '%.100s' from "
|
||||
"'%.200s'", short_tty, opt_host);
|
||||
fromhost = xasprintf(" on '%s' from '%s'", short_tty, opt_host);
|
||||
} else
|
||||
snprintf(fromhost, sizeof(fromhost)-1, " on '%.100s'", short_tty);
|
||||
fromhost = xasprintf(" on '%s'", short_tty);
|
||||
|
||||
// Was breaking "login <username>" from shell command line:
|
||||
// bb_setpgrp();
|
||||
/* Was breaking "login <username>" from shell command line: */
|
||||
/*bb_setpgrp();*/
|
||||
|
||||
openlog(applet_name, LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
|
||||
|
||||
@ -279,6 +290,46 @@ int login_main(int argc, char **argv)
|
||||
if (!username[0])
|
||||
get_username_or_die(username, sizeof(username));
|
||||
|
||||
#if ENABLE_PAM
|
||||
pamret = pam_start("login", username, &conv, &pamh);
|
||||
if (pamret != PAM_SUCCESS) {
|
||||
failed_msg = "pam_start";
|
||||
goto pam_auth_failed;
|
||||
}
|
||||
/* set TTY (so things like securetty work) */
|
||||
pamret = pam_set_item(pamh, PAM_TTY, short_tty);
|
||||
if (pamret != PAM_SUCCESS) {
|
||||
failed_msg = "pam_set_item(TTY)";
|
||||
goto pam_auth_failed;
|
||||
}
|
||||
pamret = pam_authenticate(pamh, 0);
|
||||
if (pamret == PAM_SUCCESS) {
|
||||
char *pamuser;
|
||||
/* check that the account is healthy. */
|
||||
pamret = pam_acct_mgmt(pamh, 0);
|
||||
if (pamret != PAM_SUCCESS) {
|
||||
failed_msg = "account setup";
|
||||
goto pam_auth_failed;
|
||||
}
|
||||
/* read user back */
|
||||
/* gcc: "dereferencing type-punned pointer breaks aliasing rules..."
|
||||
* thus we use double cast */
|
||||
if (pam_get_item(pamh, PAM_USER, (const void **)(void*)&pamuser) != PAM_SUCCESS) {
|
||||
failed_msg = "pam_get_item(USER)";
|
||||
goto pam_auth_failed;
|
||||
}
|
||||
safe_strncpy(username, pamuser, sizeof(username));
|
||||
}
|
||||
/* If we get here, the user was authenticated, and is
|
||||
* granted access. */
|
||||
pw = getpwnam(username);
|
||||
if (pw)
|
||||
break;
|
||||
goto auth_failed;
|
||||
pam_auth_failed:
|
||||
bb_error_msg("%s failed: %s", failed_msg, pam_strerror(pamh, pamret));
|
||||
safe_strncpy(username, "UNKNOWN", sizeof(username));
|
||||
#else /* not PAM */
|
||||
pw = getpwnam(username);
|
||||
if (!pw) {
|
||||
strcpy(username, "UNKNOWN");
|
||||
@ -301,6 +352,7 @@ int login_main(int argc, char **argv)
|
||||
/* authorization takes place here */
|
||||
if (correct_password(pw))
|
||||
break;
|
||||
#endif /* ENABLE_PAM */
|
||||
auth_failed:
|
||||
opt &= ~LOGIN_OPT_f;
|
||||
bb_do_delay(FAIL_DELAY);
|
||||
|
Loading…
Reference in New Issue
Block a user