From 05fc9bf65371477778fe48933aeb66dead0d3bfe Mon Sep 17 00:00:00 2001
From: Quanah Gibson-Mount <quanah@openldap.org>
Date: Thu, 11 Jun 2009 23:48:11 +0000
Subject: [PATCH] ITS#6167

---
 CHANGES                             |  1 +
 servers/slapd/back-ldap/back-ldap.h |  3 +++
 servers/slapd/back-ldap/bind.c      | 13 +++++++++++--
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/CHANGES b/CHANGES
index b8b820d7e9..b6bc31a5c3 100644
--- a/CHANGES
+++ b/CHANGES
@@ -31,6 +31,7 @@ OpenLDAP 2.4.17 Engineering
 	Fixed slapd-hdb freeing of already freed entries (ITS#6074)
 	Fixed slapd-hdb entryinfo cleanup (ITS#6088)
 	Fixed slapd-hdb dncache lockups (ITS#6095)
+	Fixed slapd-ldap deadlock with non-responsive TLS URIs (ITS#6167)
 	Fixed slapd-relay to return failure on failure (ITS#5328)
 	Fixed slapd-sql with BACKSQL_ARBITRARY_KEY defined (ITS#6100)
 	Fixed slapo-dds entry expiration (ITS#6169)
diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h
index 54e55ce633..7069245701 100644
--- a/servers/slapd/back-ldap/back-ldap.h
+++ b/servers/slapd/back-ldap/back-ldap.h
@@ -245,6 +245,9 @@ typedef struct ldapinfo_t {
 	 * to be checked for the presence of a certain item */
 	BerVarray		li_bvuri;
 	ldap_pvt_thread_mutex_t	li_uri_mutex;
+	/* hack because when TLS is used we need to lock and let 
+	 * the li_urllist_f function to know it's locked */
+	int			li_uri_mutex_do_not_lock;
 
 	LDAP_REBIND_PROC	*li_rebind_f;
 	LDAP_URLLIST_PROC	*li_urllist_f;
diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c
index 9691f11f6d..2521b3fbf8 100644
--- a/servers/slapd/back-ldap/bind.c
+++ b/servers/slapd/back-ldap/bind.c
@@ -691,8 +691,11 @@ ldap_back_prepare_conn( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_
 	}
 
 	ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
+	assert( li->li_uri_mutex_do_not_lock == 0 );
+	li->li_uri_mutex_do_not_lock = 1;
 	rs->sr_err = ldap_back_start_tls( ld, op->o_protocol, &is_tls,
 			li->li_uri, li->li_flags, li->li_nretries, &rs->sr_text );
+	li->li_uri_mutex_do_not_lock = 0;
 	ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
 		ldap_unbind_ext( ld, NULL, NULL );
@@ -1581,13 +1584,19 @@ ldap_back_default_urllist(
 	*urllist = *url;
 	*url = NULL;
 
-	ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
+	if ( !li->li_uri_mutex_do_not_lock ) {
+		ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
+	}
+
 	if ( li->li_uri ) {
 		ch_free( li->li_uri );
 	}
 
 	ldap_get_option( ld, LDAP_OPT_URI, (void *)&li->li_uri );
-	ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex );
+
+	if ( !li->li_uri_mutex_do_not_lock ) {
+		ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex );
+	}
 
 	return LDAP_SUCCESS;
 }
-- 
GitLab