Blame 0004-Use-GSS-SPNEGO-if-available.patch

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