svn commit: trunk/busybox/loginutils

vda at busybox.net vda at busybox.net
Tue Nov 6 16:23:47 PST 2007


Author: vda
Date: 2007-11-06 16:23:47 -0800 (Tue, 06 Nov 2007)
New Revision: 20377

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



Modified:
   trunk/busybox/loginutils/login.c


Changeset:
Modified: trunk/busybox/loginutils/login.c
===================================================================
--- trunk/busybox/loginutils/login.c	2007-11-06 11:34:03 UTC (rev 20376)
+++ trunk/busybox/loginutils/login.c	2007-11-07 00:23:47 UTC (rev 20377)
@@ -243,9 +243,14 @@
 	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;)
+#if ENABLE_PAM
+	int pamret;
+	pam_handle_t *pamh;
+	const char *pamuser;
+	const char *failed_msg;
+	struct passwd pwdstruct;
+	char pwdbuf[256];
+#endif
 
 	short_tty = full_tty;
 	username[0] = '\0';
@@ -306,18 +311,18 @@
 #if ENABLE_PAM
 		pamret = pam_start("login", username, &conv, &pamh);
 		if (pamret != PAM_SUCCESS) {
-			failed_msg = "pam_start";
+			failed_msg = "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)";
+			failed_msg = "set_item(TTY)";
 			goto pam_auth_failed;
 		}
 		pamret = pam_authenticate(pamh, 0);
 		if (pamret != PAM_SUCCESS) {
-			failed_msg = "pam_authenticate";
+			failed_msg = "authenticate";
 			goto pam_auth_failed;
 			/* TODO: or just "goto auth_failed"
 			 * since user seems to enter wrong password
@@ -327,28 +332,42 @@
 		/* check that the account is healthy */
 		pamret = pam_acct_mgmt(pamh, 0);
 		if (pamret != PAM_SUCCESS) {
-			failed_msg = "account setup";
+			failed_msg = "acct_mgmt";
 			goto pam_auth_failed;
 		}
 		/* read user back */
-		{
-			const char *pamuser;
-			/* gcc: "dereferencing type-punned pointer breaks aliasing rules..."
-			 * thus we cast to (void*) */
-			if (pam_get_item(pamh, PAM_USER, (void*)&pamuser) != PAM_SUCCESS) {
-				failed_msg = "pam_get_item(USER)";
-				goto pam_auth_failed;
-			}
-			safe_strncpy(username, pamuser, sizeof(username));
+		pamuser = NULL;
+		/* gcc: "dereferencing type-punned pointer breaks aliasing rules..."
+		 * thus we cast to (void*) */
+		if (pam_get_item(pamh, PAM_USER, (void*)&pamuser) != PAM_SUCCESS) {
+			failed_msg = "get_item(USER)";
+			goto pam_auth_failed;
 		}
-		/* If we get here, the user was authenticated, and is
-		 * granted access. */
-		pw = getpwnam(username);
-		if (pw)
-			break;
-		goto auth_failed;
+		if (!pamuser || !pamuser[0])
+			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:
-		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));
 #else /* not PAM */
 		pw = getpwnam(username);



More information about the busybox-cvs mailing list