[Midnightbsd-cvs] src [7152] trunk/lib/libpam/modules: fix compatibility with kerberos heimdal 1.5.2

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Jul 25 23:07:42 EDT 2015


Revision: 7152
          http://svnweb.midnightbsd.org/src/?rev=7152
Author:   laffer1
Date:     2015-07-25 23:07:40 -0400 (Sat, 25 Jul 2015)
Log Message:
-----------
fix compatibility with kerberos heimdal 1.5.2

Modified Paths:
--------------
    trunk/lib/libpam/modules/pam_krb5/pam_krb5.c
    trunk/lib/libpam/modules/pam_ksu/pam_ksu.c

Modified: trunk/lib/libpam/modules/pam_krb5/pam_krb5.c
===================================================================
--- trunk/lib/libpam/modules/pam_krb5/pam_krb5.c	2015-07-26 00:58:07 UTC (rev 7151)
+++ trunk/lib/libpam/modules/pam_krb5/pam_krb5.c	2015-07-26 03:07:40 UTC (rev 7152)
@@ -91,7 +91,15 @@
 #define PAM_OPT_NO_CCACHE	"no_ccache"
 #define PAM_OPT_NO_USER_CHECK	"no_user_check"
 #define PAM_OPT_REUSE_CCACHE	"reuse_ccache"
+#define PAM_OPT_NO_USER_CHECK	"no_user_check"
 
+#define	PAM_LOG_KRB5_ERR(ctx, rv, fmt, ...)				\
+	do {								\
+		const char *krb5msg = krb5_get_error_message(ctx, rv);	\
+		PAM_LOG(fmt ": %s", ##__VA_ARGS__, krb5msg);		\
+		krb5_free_error_message(ctx, krb5msg);			\
+	} while (0)
+
 /*
  * authentication management
  */
@@ -104,7 +112,7 @@
 	krb5_creds creds;
 	krb5_principal princ;
 	krb5_ccache ccache;
-	krb5_get_init_creds_opt opts;
+	krb5_get_init_creds_opt *opts;
 	struct passwd *pwd;
 	int retval;
 	const void *ccache_data;
@@ -139,13 +147,6 @@
 
 	PAM_LOG("Context initialised");
 
-	krb5_get_init_creds_opt_init(&opts);
-
-	if (openpam_get_option(pamh, PAM_OPT_FORWARDABLE))
-		krb5_get_init_creds_opt_set_forwardable(&opts, 1);
-
-	PAM_LOG("Credentials initialised");
-
 	krbret = krb5_cc_register(pam_context, &krb5_mcc_ops, FALSE);
 	if (krbret != 0 && krbret != KRB5_CC_TYPE_EXISTS) {
 		PAM_VERBOSE_ERROR("Kerberos 5 error");
@@ -166,8 +167,7 @@
 	krbret = krb5_parse_name(pam_context, principal, &princ);
 	free(principal);
 	if (krbret != 0) {
-		PAM_LOG("Error krb5_parse_name(): %s",
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret, "Error krb5_parse_name()");
 		PAM_VERBOSE_ERROR("Kerberos 5 error");
 		retval = PAM_SERVICE_ERR;
 		goto cleanup3;
@@ -179,8 +179,8 @@
 	princ_name = NULL;
 	krbret = krb5_unparse_name(pam_context, princ, &princ_name);
 	if (krbret != 0) {
-		PAM_LOG("Error krb5_unparse_name(): %s",
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_unparse_name()");
 		PAM_VERBOSE_ERROR("Kerberos 5 error");
 		retval = PAM_SERVICE_ERR;
 		goto cleanup2;
@@ -206,8 +206,8 @@
 			    sizeof(luser), luser);
 			if (krbret != 0) {
 				PAM_VERBOSE_ERROR("Kerberos 5 error");
-				PAM_LOG("Error krb5_aname_to_localname(): %s",
-				    krb5_get_err_text(pam_context, krbret));
+				PAM_LOG_KRB5_ERR(pam_context, krbret,
+				    "Error krb5_aname_to_localname()");
 				retval = PAM_USER_UNKNOWN;
 				goto cleanup2;
 			}
@@ -219,23 +219,41 @@
 			PAM_LOG("PAM_USER Redone");
 		}
 
-		pwd = getpwnam(user);
-		if (pwd == NULL) {
-			retval = PAM_USER_UNKNOWN;
-			goto cleanup2;
+		if (!openpam_get_option(pamh, PAM_OPT_NO_USER_CHECK)) {
+			pwd = getpwnam(user);
+			if (pwd == NULL) {
+				retval = PAM_USER_UNKNOWN;
+				goto cleanup2;
+			}
 		}
 
 		PAM_LOG("Done getpwnam()");
 	}
 
+	/* Initialize credentials request options. */
+	krbret = krb5_get_init_creds_opt_alloc(pam_context, &opts);
+	if (krbret != 0) {
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_get_init_creds_opt_alloc()");
+		PAM_VERBOSE_ERROR("Kerberos 5 error");
+		retval = PAM_SERVICE_ERR;
+		goto cleanup2;
+	}
+
+	if (openpam_get_option(pamh, PAM_OPT_FORWARDABLE))
+		krb5_get_init_creds_opt_set_forwardable(opts, 1);
+
+	PAM_LOG("Credential options initialised");
+
 	/* Get a TGT */
 	memset(&creds, 0, sizeof(krb5_creds));
 	krbret = krb5_get_init_creds_password(pam_context, &creds, princ,
-	    pass, NULL, pamh, 0, NULL, &opts);
+	    pass, NULL, pamh, 0, NULL, opts);
+	krb5_get_init_creds_opt_free(pam_context, opts);
 	if (krbret != 0) {
 		PAM_VERBOSE_ERROR("Kerberos 5 error");
-		PAM_LOG("Error krb5_get_init_creds_password(): %s",
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_get_init_creds_password()");
 		retval = PAM_AUTH_ERR;
 		goto cleanup2;
 	}
@@ -243,11 +261,11 @@
 	PAM_LOG("Got TGT");
 
 	/* Generate a temporary cache */
-	krbret = krb5_cc_gen_new(pam_context, &krb5_mcc_ops, &ccache);
+	krbret = krb5_cc_new_unique(pam_context, krb5_cc_type_memory, NULL, &ccache);
 	if (krbret != 0) {
 		PAM_VERBOSE_ERROR("Kerberos 5 error");
-		PAM_LOG("Error krb5_cc_gen_new(): %s",
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_cc_new_unique()");
 		retval = PAM_SERVICE_ERR;
 		goto cleanup;
 	}
@@ -254,8 +272,8 @@
 	krbret = krb5_cc_initialize(pam_context, ccache, princ);
 	if (krbret != 0) {
 		PAM_VERBOSE_ERROR("Kerberos 5 error");
-		PAM_LOG("Error krb5_cc_initialize(): %s",
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_cc_initialize()");
 		retval = PAM_SERVICE_ERR;
 		goto cleanup;
 	}
@@ -262,8 +280,8 @@
 	krbret = krb5_cc_store_cred(pam_context, ccache, &creds);
 	if (krbret != 0) {
 		PAM_VERBOSE_ERROR("Kerberos 5 error");
-		PAM_LOG("Error krb5_cc_store_cred(): %s",
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_cc_store_cred()");
 		krb5_cc_destroy(pam_context, ccache);
 		retval = PAM_SERVICE_ERR;
 		goto cleanup;
@@ -320,11 +338,11 @@
 	PAM_LOG("Done cleanup");
 cleanup2:
 	krb5_free_principal(pam_context, princ);
-	PAM_LOG("Done cleanup2");
-cleanup3:
 	if (princ_name)
 		free(princ_name);
+	PAM_LOG("Done cleanup2");
 
+cleanup3:
 	krb5_free_context(pam_context);
 
 	PAM_LOG("Done cleanup3");
@@ -406,8 +424,8 @@
 	}
 	krbret = krb5_cc_resolve(pam_context, cache_data, &ccache_temp);
 	if (krbret != 0) {
-		PAM_LOG("Error krb5_cc_resolve(\"%s\"): %s", (const char *)cache_data,
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_cc_resolve(\"%s\")", (const char *)cache_data);
 		retval = PAM_SERVICE_ERR;
 		goto cleanup3;
 	}
@@ -479,22 +497,21 @@
 	/* Initialize the new ccache */
 	krbret = krb5_cc_get_principal(pam_context, ccache_temp, &princ);
 	if (krbret != 0) {
-		PAM_LOG("Error krb5_cc_get_principal(): %s",
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_cc_get_principal()");
 		retval = PAM_SERVICE_ERR;
 		goto cleanup3;
 	}
 	krbret = krb5_cc_resolve(pam_context, cache_name, &ccache_perm);
 	if (krbret != 0) {
-		PAM_LOG("Error krb5_cc_resolve(): %s",
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret, "Error krb5_cc_resolve()");
 		retval = PAM_SERVICE_ERR;
 		goto cleanup2;
 	}
 	krbret = krb5_cc_initialize(pam_context, ccache_perm, princ);
 	if (krbret != 0) {
-		PAM_LOG("Error krb5_cc_initialize(): %s",
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_cc_initialize()");
 		retval = PAM_SERVICE_ERR;
 		goto cleanup2;
 	}
@@ -504,8 +521,8 @@
 	/* Prepare for iteration over creds */
 	krbret = krb5_cc_start_seq_get(pam_context, ccache_temp, &cursor);
 	if (krbret != 0) {
-		PAM_LOG("Error krb5_cc_start_seq_get(): %s",
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_cc_start_seq_get()");
 		krb5_cc_destroy(pam_context, ccache_perm);
 		retval = PAM_SERVICE_ERR;
 		goto cleanup2;
@@ -518,8 +535,8 @@
 				&cursor, &creds) == 0)) {
 		krbret = krb5_cc_store_cred(pam_context, ccache_perm, &creds);
 		if (krbret != 0) {
-			PAM_LOG("Error krb5_cc_store_cred(): %s",
-			    krb5_get_err_text(pam_context, krbret));
+			PAM_LOG_KRB5_ERR(pam_context, krbret,
+			    "Error krb5_cc_store_cred()");
 			krb5_cc_destroy(pam_context, ccache_perm);
 			krb5_free_cred_contents(pam_context, &creds);
 			retval = PAM_SERVICE_ERR;
@@ -620,8 +637,8 @@
 
 	krbret = krb5_cc_resolve(pam_context, (const char *)ccache_name, &ccache);
 	if (krbret != 0) {
-		PAM_LOG("Error krb5_cc_resolve(\"%s\"): %s", (const char *)ccache_name,
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_cc_resolve(\"%s\")", (const char *)ccache_name);
 		krb5_free_context(pam_context);
 		return (PAM_PERM_DENIED);
 	}
@@ -631,9 +648,9 @@
 
 	krbret = krb5_cc_get_principal(pam_context, ccache, &princ);
 	if (krbret != 0) {
-		PAM_LOG("Error krb5_cc_get_principal(): %s",
-		    krb5_get_err_text(pam_context, krbret));
-		retval = PAM_PERM_DENIED;;
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_cc_get_principal()");
+		retval = PAM_PERM_DENIED;
 		goto cleanup;
 	}
 
@@ -666,7 +683,7 @@
 	krb5_context pam_context;
 	krb5_creds creds;
 	krb5_principal princ;
-	krb5_get_init_creds_opt opts;
+	krb5_get_init_creds_opt *opts;
 	krb5_data result_code_string, result_string;
 	int result_code, retval;
 	const char *pass;
@@ -690,15 +707,11 @@
 
 	PAM_LOG("Context initialised");
 
-	krb5_get_init_creds_opt_init(&opts);
-
-	PAM_LOG("Credentials options initialised");
-
 	/* Get principal name */
 	krbret = krb5_parse_name(pam_context, (const char *)user, &princ);
 	if (krbret != 0) {
-		PAM_LOG("Error krb5_parse_name(): %s",
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_parse_name()");
 		retval = PAM_USER_UNKNOWN;
 		goto cleanup3;
 	}
@@ -707,8 +720,8 @@
 	princ_name = NULL;
 	krbret = krb5_unparse_name(pam_context, princ, &princ_name);
 	if (krbret != 0) {
-		PAM_LOG("Error krb5_unparse_name(): %s",
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_unparse_name()");
 		retval = PAM_SERVICE_ERR;
 		goto cleanup2;
 	}
@@ -722,12 +735,25 @@
 
 	PAM_LOG("Got password");
 
+	/* Initialize credentials request options. */
+	krbret = krb5_get_init_creds_opt_alloc(pam_context, &opts);
+	if (krbret != 0) {
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_get_init_creds_opt_alloc()");
+		PAM_VERBOSE_ERROR("Kerberos 5 error");
+		retval = PAM_SERVICE_ERR;
+		goto cleanup2;
+	}
+
+	PAM_LOG("Credentials options initialised");
+
 	memset(&creds, 0, sizeof(krb5_creds));
 	krbret = krb5_get_init_creds_password(pam_context, &creds, princ,
-	    pass, NULL, pamh, 0, "kadmin/changepw", &opts);
+	    pass, NULL, pamh, 0, "kadmin/changepw", opts);
+	krb5_get_init_creds_opt_free(pam_context, opts);
 	if (krbret != 0) {
-		PAM_LOG("Error krb5_get_init_creds_password(): %s",
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_get_init_creds_password()");
 		retval = PAM_AUTH_ERR;
 		goto cleanup2;
 	}
@@ -752,12 +778,12 @@
 		retval = PAM_BUF_ERR;
 		goto cleanup;
 	}
-	krbret = krb5_change_password(pam_context, &creds, passdup,
+	krbret = krb5_set_password(pam_context, &creds, passdup, NULL,
 	    &result_code, &result_code_string, &result_string);
 	free(passdup);
 	if (krbret != 0) {
-		PAM_LOG("Error krb5_change_password(): %s",
-		    krb5_get_err_text(pam_context, krbret));
+		PAM_LOG_KRB5_ERR(pam_context, krbret,
+		    "Error krb5_change_password()");
 		retval = PAM_AUTHTOK_ERR;
 		goto cleanup;
 	}
@@ -779,11 +805,11 @@
 	PAM_LOG("Done cleanup");
 cleanup2:
 	krb5_free_principal(pam_context, princ);
-	PAM_LOG("Done cleanup2");
-cleanup3:
 	if (princ_name)
 		free(princ_name);
+	PAM_LOG("Done cleanup2");
 
+cleanup3:
 	krb5_free_context(pam_context);
 
 	PAM_LOG("Done cleanup3");
@@ -840,11 +866,14 @@
 		retval = krb5_sname_to_principal(context, NULL, *service,
 		    KRB5_NT_SRV_HST, &princ);
 		if (retval != 0) {
-			if (debug)
+			if (debug) {
+				const char *msg = krb5_get_error_message(
+				    context, retval);
 				syslog(LOG_DEBUG,
 				    "pam_krb5: verify_krb_v5_tgt(): %s: %s",
-				    "krb5_sname_to_principal()",
-				    krb5_get_err_text(context, retval));
+				    "krb5_sname_to_principal()", msg);
+				krb5_free_error_message(context, msg);
+			}
 			return -1;
 		}
 
@@ -866,11 +895,14 @@
 	}
 	if (retval != 0) {	/* failed to find key */
 		/* Keytab or service key does not exist */
-		if (debug)
+		if (debug) {
+			const char *msg = krb5_get_error_message(context,
+			    retval);
 			syslog(LOG_DEBUG,
 			    "pam_krb5: verify_krb_v5_tgt(): %s: %s",
-			    "krb5_kt_read_service_key()",
-			    krb5_get_err_text(context, retval));
+			    "krb5_kt_read_service_key()", msg);
+			krb5_free_error_message(context, msg);
+		}
 		retval = 0;
 		goto cleanup;
 	}
@@ -886,11 +918,14 @@
 		auth_context = NULL;	/* setup for rd_req */
 	}
 	if (retval) {
-		if (debug)
+		if (debug) {
+			const char *msg = krb5_get_error_message(context,
+			    retval);
 			syslog(LOG_DEBUG,
 			    "pam_krb5: verify_krb_v5_tgt(): %s: %s",
-			    "krb5_mk_req()",
-			    krb5_get_err_text(context, retval));
+			    "krb5_mk_req()", msg);
+			krb5_free_error_message(context, msg);
+		}
 		retval = -1;
 		goto cleanup;
 	}
@@ -899,11 +934,14 @@
 	retval = krb5_rd_req(context, &auth_context, &packet, princ, NULL,
 	    NULL, NULL);
 	if (retval) {
-		if (debug)
+		if (debug) {
+			const char *msg = krb5_get_error_message(context,
+			    retval);
 			syslog(LOG_DEBUG,
 			    "pam_krb5: verify_krb_v5_tgt(): %s: %s",
-			    "krb5_rd_req()",
-			    krb5_get_err_text(context, retval));
+			    "krb5_rd_req()", msg);
+			krb5_free_error_message(context, msg);
+		}
 		retval = -1;
 	}
 	else

Modified: trunk/lib/libpam/modules/pam_ksu/pam_ksu.c
===================================================================
--- trunk/lib/libpam/modules/pam_ksu/pam_ksu.c	2015-07-26 00:58:07 UTC (rev 7151)
+++ trunk/lib/libpam/modules/pam_ksu/pam_ksu.c	2015-07-26 03:07:40 UTC (rev 7152)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libpam/modules/pam_ksu/pam_ksu.c,v 1.5 2004/02/10 10:13:21 des Exp $");
+__FBSDID("$FreeBSD: stable/10/lib/libpam/modules/pam_ksu/pam_ksu.c 233302 2012-03-22 11:18:14Z stas $");
 
 #include <sys/param.h>
 #include <errno.h>
@@ -70,8 +70,9 @@
 	PAM_LOG("Got ruser: %s", (const char *)ruser);
 	rv = krb5_init_context(&context);
 	if (rv != 0) {
-		PAM_LOG("krb5_init_context failed: %s",
-			krb5_get_err_text(context, rv));
+		const char *msg = krb5_get_error_message(context, rv);
+		PAM_LOG("krb5_init_context failed: %s", msg);
+		krb5_free_error_message(context, msg);
 		return (PAM_SERVICE_ERR);
 	}
 	rv = get_su_principal(context, user, ruser, &su_principal_name, &su_principal);
@@ -112,7 +113,7 @@
     krb5_principal su_principal)
 {
 	krb5_creds	 creds;
-	krb5_get_init_creds_opt gic_opt;
+	krb5_get_init_creds_opt *gic_opt;
 	krb5_verify_init_creds_opt vic_opt;
 	const char	*pass;
 	char		*prompt;
@@ -120,7 +121,6 @@
 	int		 pamret;
 
 	prompt = NULL;
-	krb5_get_init_creds_opt_init(&gic_opt);
 	krb5_verify_init_creds_opt_init(&vic_opt);
 	if (su_principal_name != NULL)
 		(void)asprintf(&prompt, "Password for %s:", su_principal_name);
@@ -133,11 +133,20 @@
 	free(prompt);
 	if (pamret != PAM_SUCCESS)
 		return (pamret);
+	rv = krb5_get_init_creds_opt_alloc(context, &gic_opt);
+	if (rv != 0) {
+		const char *msg = krb5_get_error_message(context, rv);
+		PAM_LOG("krb5_get_init_creds_opt_alloc: %s", msg);
+		krb5_free_error_message(context, msg);
+		return (PAM_AUTH_ERR);
+	}
 	rv = krb5_get_init_creds_password(context, &creds, su_principal,
-	    pass, NULL, NULL, 0, NULL, &gic_opt);
+	    pass, NULL, NULL, 0, NULL, gic_opt);
+	krb5_get_init_creds_opt_free(context, gic_opt);
 	if (rv != 0) {
-		PAM_LOG("krb5_get_init_creds_password: %s",
-			krb5_get_err_text(context, rv));
+		const char *msg = krb5_get_error_message(context, rv);
+		PAM_LOG("krb5_get_init_creds_password: %s", msg);
+		krb5_free_error_message(context, msg);
 		return (PAM_AUTH_ERR);
 	}
 	krb5_verify_init_creds_opt_set_ap_req_nofail(&vic_opt, 1);
@@ -145,8 +154,9 @@
 	    &vic_opt);
 	krb5_free_cred_contents(context, &creds);
 	if (rv != 0) {
-		PAM_LOG("krb5_verify_init_creds: %s",
-		       krb5_get_err_text(context, rv));
+		const char *msg = krb5_get_error_message(context, rv);
+		PAM_LOG("krb5_verify_init_creds: %s", msg);
+		krb5_free_error_message(context, msg);
 		return (PAM_AUTH_ERR);
 	}
 	return (PAM_SUCCESS);
@@ -220,8 +230,9 @@
 	rv = krb5_unparse_name(context, default_principal, &principal_name);
 	krb5_free_principal(context, default_principal);
 	if (rv != 0) {
-		PAM_LOG("krb5_unparse_name: %s",
-		    krb5_get_err_text(context, rv));
+		const char *msg = krb5_get_error_message(context, rv);
+		PAM_LOG("krb5_unparse_name: %s", msg);
+		krb5_free_error_message(context, msg);
 		return (rv);
 	}
 	PAM_LOG("Default principal name: %s", principal_name);
@@ -243,8 +254,9 @@
 		return (errno);
 	rv = krb5_parse_name(context, *su_principal_name, &default_principal);
 	if (rv != 0) {
-		PAM_LOG("krb5_parse_name `%s': %s", *su_principal_name,
-		    krb5_get_err_text(context, rv));
+		const char *msg = krb5_get_error_message(context, rv);
+		PAM_LOG("krb5_parse_name `%s': %s", *su_principal_name, msg);
+		krb5_free_error_message(context, msg);
 		free(*su_principal_name);
 		return (rv);
 	}



More information about the Midnightbsd-cvs mailing list