login: fix PAM login (was unable to complete Kerberos login)

This commit is contained in:
Denis Vlasenko 2007-11-07 00:23:47 +00:00
parent cb12cb2407
commit a29a5e40ae

View File

@ -243,9 +243,14 @@ int login_main(int argc, char **argv)
char full_tty[TTYNAME_SIZE]; char full_tty[TTYNAME_SIZE];
USE_SELINUX(security_context_t user_sid = NULL;) USE_SELINUX(security_context_t user_sid = NULL;)
USE_FEATURE_UTMP(struct utmp utent;) USE_FEATURE_UTMP(struct utmp utent;)
USE_PAM(pam_handle_t *pamh;) #if ENABLE_PAM
USE_PAM(int pamret;) int pamret;
USE_PAM(const char *failed_msg;) pam_handle_t *pamh;
const char *pamuser;
const char *failed_msg;
struct passwd pwdstruct;
char pwdbuf[256];
#endif
short_tty = full_tty; short_tty = full_tty;
username[0] = '\0'; username[0] = '\0';
@ -306,18 +311,18 @@ int login_main(int argc, char **argv)
#if ENABLE_PAM #if ENABLE_PAM
pamret = pam_start("login", username, &conv, &pamh); pamret = pam_start("login", username, &conv, &pamh);
if (pamret != PAM_SUCCESS) { if (pamret != PAM_SUCCESS) {
failed_msg = "pam_start"; failed_msg = "start";
goto pam_auth_failed; goto pam_auth_failed;
} }
/* set TTY (so things like securetty work) */ /* set TTY (so things like securetty work) */
pamret = pam_set_item(pamh, PAM_TTY, short_tty); pamret = pam_set_item(pamh, PAM_TTY, short_tty);
if (pamret != PAM_SUCCESS) { if (pamret != PAM_SUCCESS) {
failed_msg = "pam_set_item(TTY)"; failed_msg = "set_item(TTY)";
goto pam_auth_failed; goto pam_auth_failed;
} }
pamret = pam_authenticate(pamh, 0); pamret = pam_authenticate(pamh, 0);
if (pamret != PAM_SUCCESS) { if (pamret != PAM_SUCCESS) {
failed_msg = "pam_authenticate"; failed_msg = "authenticate";
goto pam_auth_failed; goto pam_auth_failed;
/* TODO: or just "goto auth_failed" /* TODO: or just "goto auth_failed"
* since user seems to enter wrong password * since user seems to enter wrong password
@ -327,28 +332,42 @@ int login_main(int argc, char **argv)
/* check that the account is healthy */ /* check that the account is healthy */
pamret = pam_acct_mgmt(pamh, 0); pamret = pam_acct_mgmt(pamh, 0);
if (pamret != PAM_SUCCESS) { if (pamret != PAM_SUCCESS) {
failed_msg = "account setup"; failed_msg = "acct_mgmt";
goto pam_auth_failed; goto pam_auth_failed;
} }
/* read user back */ /* read user back */
{ pamuser = NULL;
const char *pamuser;
/* gcc: "dereferencing type-punned pointer breaks aliasing rules..." /* gcc: "dereferencing type-punned pointer breaks aliasing rules..."
* thus we cast to (void*) */ * thus we cast to (void*) */
if (pam_get_item(pamh, PAM_USER, (void*)&pamuser) != PAM_SUCCESS) { if (pam_get_item(pamh, PAM_USER, (void*)&pamuser) != PAM_SUCCESS) {
failed_msg = "pam_get_item(USER)"; failed_msg = "get_item(USER)";
goto pam_auth_failed; goto pam_auth_failed;
} }
safe_strncpy(username, pamuser, sizeof(username)); if (!pamuser || !pamuser[0])
}
/* If we get here, the user was authenticated, and is
* granted access. */
pw = getpwnam(username);
if (pw)
break;
goto auth_failed; goto auth_failed;
safe_strncpy(username, pamuser, sizeof(username));
/* Don't use "pw = getpwnam(username);",
* PAM is said to be capable of destroying static storage
* used by getpwnam(). We are using safe(r) function */
pw = NULL;
getpwnam_r(username, &pwdstruct, pwdbuf, sizeof(pwdbuf), &pw);
if (!pw)
goto auth_failed;
pamret = pam_open_session(pamh, 0);
if (pamret != PAM_SUCCESS) {
failed_msg = "open_session";
goto pam_auth_failed;
}
pamret = pam_setcred(pamh, PAM_ESTABLISH_CRED);
if (pamret != PAM_SUCCESS) {
failed_msg = "setcred";
goto pam_auth_failed;
}
break; /* success, continue login process */
pam_auth_failed: pam_auth_failed:
bb_error_msg("%s failed: %s (%d)", failed_msg, pam_strerror(pamh, pamret), pamret); bb_error_msg("pam_%s call failed: %s (%d)", failed_msg,
pam_strerror(pamh, pamret), pamret);
safe_strncpy(username, "UNKNOWN", sizeof(username)); safe_strncpy(username, "UNKNOWN", sizeof(username));
#else /* not PAM */ #else /* not PAM */
pw = getpwnam(username); pw = getpwnam(username);