Blame SOURCES/0001-Use-GSS-SPNEGO-if-available.patch

463fb6
From a4c35124b5c83603333ee7518d0783ff708e86df Mon Sep 17 00:00:00 2001
463fb6
From: Sumit Bose <sbose@redhat.com>
463fb6
Date: Fri, 11 Oct 2019 16:39:25 +0200
463fb6
Subject: [PATCH 1/2] Use GSS-SPNEGO if available
463fb6
463fb6
Currently adcli uses the GSSAPI SASL mechanism for LDAP authentication
463fb6
and to establish encryption. While this works in general it does not
463fb6
handle some of the more advanced features which can be required by AD
463fb6
DCs.
463fb6
463fb6
The GSS-SPNEGO mechanism can handle them and is used with this patch by
463fb6
adcli if the AD DC indicates that it supports it.
463fb6
463fb6
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1762420
463fb6
---
463fb6
 library/adconn.c | 35 ++++++++++++++++++++++++++++++++++-
463fb6
 library/adconn.h |  3 +++
463fb6
 2 files changed, 37 insertions(+), 1 deletion(-)
463fb6
463fb6
diff --git a/library/adconn.c b/library/adconn.c
463fb6
index f6c23d3..a3f4548 100644
463fb6
--- a/library/adconn.c
463fb6
+++ b/library/adconn.c
463fb6
@@ -77,6 +77,7 @@ struct _adcli_conn_ctx {
463fb6
 	char *default_naming_context;
463fb6
 	char *configuration_naming_context;
463fb6
 	char **supported_capabilities;
463fb6
+	char **supported_sasl_mechs;
463fb6
 
463fb6
 	/* Connect state */
463fb6
 	LDAP *ldap;
463fb6
@@ -845,6 +846,7 @@ connect_and_lookup_naming (adcli_conn *conn,
463fb6
 		"defaultNamingContext",
463fb6
 		"configurationNamingContext",
463fb6
 		"supportedCapabilities",
463fb6
+		"supportedSASLMechanisms",
463fb6
 		NULL
463fb6
 	};
463fb6
 
463fb6
@@ -897,6 +899,11 @@ connect_and_lookup_naming (adcli_conn *conn,
463fb6
 		                                                         "supportedCapabilities");
463fb6
 	}
463fb6
 
463fb6
+	if (conn->supported_sasl_mechs == NULL) {
463fb6
+		conn->supported_sasl_mechs = _adcli_ldap_parse_values (ldap, results,
463fb6
+		                                                       "supportedSASLMechanisms");
463fb6
+	}
463fb6
+
463fb6
 	ldap_msgfree (results);
463fb6
 
463fb6
 	if (conn->default_naming_context == NULL) {
463fb6
@@ -1022,6 +1029,7 @@ authenticate_to_directory (adcli_conn *conn)
463fb6
 	OM_uint32 minor;
463fb6
 	ber_len_t ssf;
463fb6
 	int ret;
463fb6
+	const char *mech = "GSSAPI";
463fb6
 
463fb6
 	if (conn->ldap_authenticated)
463fb6
 		return ADCLI_SUCCESS;
463fb6
@@ -1038,7 +1046,11 @@ authenticate_to_directory (adcli_conn *conn)
463fb6
 	ret = ldap_set_option (conn->ldap, LDAP_OPT_X_SASL_SSF_MIN, &ssf;;
463fb6
 	return_unexpected_if_fail (ret == 0);
463fb6
 
463fb6
-	ret = ldap_sasl_interactive_bind_s (conn->ldap, NULL, "GSSAPI", NULL, NULL,
463fb6
+	if (adcli_conn_server_has_sasl_mech (conn, "GSS-SPNEGO")) {
463fb6
+		mech =  "GSS-SPNEGO";
463fb6
+	}
463fb6
+
463fb6
+	ret = ldap_sasl_interactive_bind_s (conn->ldap, NULL, mech, NULL, NULL,
463fb6
 	                                    LDAP_SASL_QUIET, sasl_interact, NULL);
463fb6
 
463fb6
 	/* Clear the credential cache GSSAPI to use (for this thread) */
463fb6
@@ -1231,6 +1243,7 @@ conn_free (adcli_conn *conn)
463fb6
 	free (conn->default_naming_context);
463fb6
 	free (conn->configuration_naming_context);
463fb6
 	_adcli_strv_free (conn->supported_capabilities);
463fb6
+	_adcli_strv_free (conn->supported_sasl_mechs);
463fb6
 
463fb6
 	free (conn->computer_name);
463fb6
 	free (conn->host_fqdn);
463fb6
@@ -1593,6 +1606,26 @@ adcli_conn_server_has_capability (adcli_conn *conn,
463fb6
 	return 0;
463fb6
 }
463fb6
 
463fb6
+bool
463fb6
+adcli_conn_server_has_sasl_mech (adcli_conn *conn,
463fb6
+                                 const char *mech)
463fb6
+{
463fb6
+	int i;
463fb6
+
463fb6
+	return_val_if_fail (conn != NULL, false);
463fb6
+	return_val_if_fail (mech != NULL, false);
463fb6
+
463fb6
+	if (!conn->supported_sasl_mechs)
463fb6
+		return false;
463fb6
+
463fb6
+	for (i = 0; conn->supported_sasl_mechs[i] != NULL; i++) {
463fb6
+		if (strcasecmp (mech, conn->supported_sasl_mechs[i]) == 0)
463fb6
+			return true;
463fb6
+	}
463fb6
+
463fb6
+	return false;
463fb6
+}
463fb6
+
463fb6
 bool adcli_conn_is_writeable (adcli_conn *conn)
463fb6
 {
463fb6
 	disco_dance_if_necessary (conn);
463fb6
diff --git a/library/adconn.h b/library/adconn.h
463fb6
index 13cfd32..8e88045 100644
463fb6
--- a/library/adconn.h
463fb6
+++ b/library/adconn.h
463fb6
@@ -146,6 +146,9 @@ void                adcli_conn_set_krb5_conf_dir     (adcli_conn *conn,
463fb6
 int                 adcli_conn_server_has_capability (adcli_conn *conn,
463fb6
                                                       const char *capability);
463fb6
 
463fb6
+bool                adcli_conn_server_has_sasl_mech  (adcli_conn *conn,
463fb6
+                                                      const char *mech);
463fb6
+
463fb6
 bool                adcli_conn_is_writeable          (adcli_conn *conn);
463fb6
 
463fb6
 #endif /* ADCONN_H_ */
463fb6
-- 
463fb6
2.21.1
463fb6