|
|
dc8c34 |
From c77411b9204d7889b7c7811ff453ff5158aa87a0 Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Rich Megginson <rmeggins@redhat.com>
|
|
|
dc8c34 |
Date: Mon, 14 Oct 2013 12:43:51 -0600
|
|
|
dc8c34 |
Subject: [PATCH] Ticket #47559 hung server - related to sasl and initialize
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://fedorahosted.org/389/ticket/47559
|
|
|
dc8c34 |
Reviewed by: ???
|
|
|
dc8c34 |
Branch: master
|
|
|
dc8c34 |
Fix Description: Use a mutex to protect calls to openldap functions that do
|
|
|
dc8c34 |
anything with crypto - bind, unbind, start_tls, other calls.
|
|
|
dc8c34 |
Platforms tested: RHEL6 x86_64
|
|
|
dc8c34 |
Flag Day: no
|
|
|
dc8c34 |
Doc impact: no
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
ldap/servers/slapd/ldaputil.c | 51 +++++++++++++++++++++++++++++++++++++---
|
|
|
dc8c34 |
1 files changed, 47 insertions(+), 4 deletions(-)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/ldaputil.c b/ldap/servers/slapd/ldaputil.c
|
|
|
dc8c34 |
index 331dd71..307a3a5 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/ldaputil.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/ldaputil.c
|
|
|
dc8c34 |
@@ -99,10 +99,16 @@
|
|
|
dc8c34 |
#if !defined(USE_OPENLDAP)
|
|
|
dc8c34 |
#include <ldap_ssl.h>
|
|
|
dc8c34 |
#include <ldappr.h>
|
|
|
dc8c34 |
+#define BIND_LOCK (void)0
|
|
|
dc8c34 |
+#define BIND_UNLOCK (void)0
|
|
|
dc8c34 |
#else
|
|
|
dc8c34 |
/* need mutex around ldap_initialize - see https://fedorahosted.org/389/ticket/348 */
|
|
|
dc8c34 |
static PRCallOnceType ol_init_callOnce = {0,0};
|
|
|
dc8c34 |
static PRLock *ol_init_lock = NULL;
|
|
|
dc8c34 |
+/* need mutex around ldap_sasl_bind - see https://fedorahosted.org/389/ticket/47599 */
|
|
|
dc8c34 |
+static PRLock *ol_bind_lock = NULL;
|
|
|
dc8c34 |
+#define BIND_LOCK PR_Lock(ol_bind_lock)
|
|
|
dc8c34 |
+#define BIND_UNLOCK PR_Unlock(ol_bind_lock)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
static PRStatus
|
|
|
dc8c34 |
internal_ol_init_init(void)
|
|
|
dc8c34 |
@@ -110,12 +116,20 @@ internal_ol_init_init(void)
|
|
|
dc8c34 |
PR_ASSERT(NULL == ol_init_lock);
|
|
|
dc8c34 |
if ((ol_init_lock = PR_NewLock()) == NULL) {
|
|
|
dc8c34 |
PRErrorCode errorCode = PR_GetError();
|
|
|
dc8c34 |
- slapi_log_error(SLAPI_LOG_FATAL, "internal_ol_init_init", "PR_NewLock failed %d:%s\n",
|
|
|
dc8c34 |
+ slapi_log_error(SLAPI_LOG_FATAL, "internal_ol_init_init", "PR_NewLock init_lock failed %d:%s\n",
|
|
|
dc8c34 |
errorCode, slapd_pr_strerror(errorCode));
|
|
|
dc8c34 |
return PR_FAILURE;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- return PR_SUCCESS;
|
|
|
dc8c34 |
+ PR_ASSERT(NULL == ol_bind_lock);
|
|
|
dc8c34 |
+ if ((ol_bind_lock = PR_NewLock()) == NULL) {
|
|
|
dc8c34 |
+ PRErrorCode errorCode = PR_GetError();
|
|
|
dc8c34 |
+ slapi_log_error(SLAPI_LOG_FATAL, "internal_ol_init_init", "PR_NewLock bind_lock failed %d:%s\n",
|
|
|
dc8c34 |
+ errorCode, slapd_pr_strerror(errorCode));
|
|
|
dc8c34 |
+ return PR_FAILURE;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ return PR_SUCCESS;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
#endif
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -145,7 +159,16 @@ void
|
|
|
dc8c34 |
slapi_ldap_unbind( LDAP *ld )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
if ( ld != NULL ) {
|
|
|
dc8c34 |
+#if defined(USE_OPENLDAP)
|
|
|
dc8c34 |
+ if (PR_SUCCESS != PR_CallOnce(&ol_init_callOnce, internal_ol_init_init)) {
|
|
|
dc8c34 |
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_unbind",
|
|
|
dc8c34 |
+ "Could not perform internal ol_init init\n");
|
|
|
dc8c34 |
+ return;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+#endif
|
|
|
dc8c34 |
+ BIND_LOCK;
|
|
|
dc8c34 |
ldap_unbind_ext( ld, NULL, NULL );
|
|
|
dc8c34 |
+ BIND_UNLOCK;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -1024,11 +1047,22 @@ slapi_ldap_bind(
|
|
|
dc8c34 |
ldap_controls_free(clientctrls);
|
|
|
dc8c34 |
ldap_set_option(ld, LDAP_OPT_CLIENT_CONTROLS, NULL);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+#if defined(USE_OPENLDAP)
|
|
|
dc8c34 |
+ if (PR_SUCCESS != PR_CallOnce(&ol_init_callOnce, internal_ol_init_init)) {
|
|
|
dc8c34 |
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
|
|
|
dc8c34 |
+ "Could not perform internal ol_init init\n");
|
|
|
dc8c34 |
+ rc = -1;
|
|
|
dc8c34 |
+ goto done;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+#endif
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
if ((secure > 0) && mech && !strcmp(mech, LDAP_SASL_EXTERNAL)) {
|
|
|
dc8c34 |
#if defined(USE_OPENLDAP)
|
|
|
dc8c34 |
/* we already set up a tls context in slapi_ldap_init_ext() - this will
|
|
|
dc8c34 |
free those old settings and context and create a new one */
|
|
|
dc8c34 |
+ PR_Lock(ol_bind_lock);
|
|
|
dc8c34 |
rc = setup_ol_tls_conn(ld, 1);
|
|
|
dc8c34 |
+ PR_Unlock(ol_bind_lock);
|
|
|
dc8c34 |
#else
|
|
|
dc8c34 |
/* SSL connections will use the server's security context
|
|
|
dc8c34 |
and cert for client auth */
|
|
|
dc8c34 |
@@ -1053,7 +1087,9 @@ slapi_ldap_bind(
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if (secure == 2) { /* send start tls */
|
|
|
dc8c34 |
+ BIND_LOCK;
|
|
|
dc8c34 |
rc = ldap_start_tls_s(ld, NULL /* serverctrls?? */, NULL);
|
|
|
dc8c34 |
+ BIND_UNLOCK;
|
|
|
dc8c34 |
if (LDAP_SUCCESS != rc) {
|
|
|
dc8c34 |
slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
|
|
|
dc8c34 |
"Error: could not send startTLS request: "
|
|
|
dc8c34 |
@@ -1075,8 +1111,11 @@ slapi_ldap_bind(
|
|
|
dc8c34 |
"attempting %s bind with id [%s] creds [%s]\n",
|
|
|
dc8c34 |
mech ? mech : "SIMPLE",
|
|
|
dc8c34 |
bindid, creds);
|
|
|
dc8c34 |
- if ((rc = ldap_sasl_bind(ld, bindid, mech, &bvcreds, serverctrls,
|
|
|
dc8c34 |
- NULL /* clientctrls */, &mymsgid))) {
|
|
|
dc8c34 |
+ BIND_LOCK;
|
|
|
dc8c34 |
+ rc = ldap_sasl_bind(ld, bindid, mech, &bvcreds, serverctrls,
|
|
|
dc8c34 |
+ NULL /* clientctrls */, &mymsgid);
|
|
|
dc8c34 |
+ BIND_UNLOCK;
|
|
|
dc8c34 |
+ if (rc) {
|
|
|
dc8c34 |
slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
|
|
|
dc8c34 |
"Error: could not send bind request for id "
|
|
|
dc8c34 |
"[%s] mech [%s]: error %d (%s) %d (%s) %d (%s)\n",
|
|
|
dc8c34 |
@@ -1091,7 +1130,9 @@ slapi_ldap_bind(
|
|
|
dc8c34 |
if (msgidp) { /* let caller process result */
|
|
|
dc8c34 |
*msgidp = mymsgid;
|
|
|
dc8c34 |
} else { /* process results */
|
|
|
dc8c34 |
+ BIND_LOCK;
|
|
|
dc8c34 |
rc = ldap_result(ld, mymsgid, LDAP_MSG_ALL, timeout, &result);
|
|
|
dc8c34 |
+ BIND_UNLOCK;
|
|
|
dc8c34 |
if (-1 == rc) { /* error */
|
|
|
dc8c34 |
rc = slapi_ldap_get_lderrno(ld, NULL, NULL);
|
|
|
dc8c34 |
slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
|
|
|
dc8c34 |
@@ -1156,9 +1197,11 @@ slapi_ldap_bind(
|
|
|
dc8c34 |
ldap_set_option(ld, LDAP_OPT_X_SASL_SSF_MAX, &max_ssf);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
#endif
|
|
|
dc8c34 |
+ BIND_LOCK;
|
|
|
dc8c34 |
rc = slapd_ldap_sasl_interactive_bind(ld, bindid, creds, mech,
|
|
|
dc8c34 |
serverctrls, returnedctrls,
|
|
|
dc8c34 |
msgidp);
|
|
|
dc8c34 |
+ BIND_UNLOCK;
|
|
|
dc8c34 |
if (LDAP_SUCCESS != rc) {
|
|
|
dc8c34 |
slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
|
|
|
dc8c34 |
"Error: could not perform interactive bind for id "
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
1.7.1
|
|
|
dc8c34 |
|