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

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