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

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