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

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