Index: addressbook/ChangeLog
===================================================================
--- addressbook/ChangeLog	(revision 8557)
+++ addressbook/ChangeLog	(working copy)
@@ -1,3 +1,11 @@
+2008-03-06  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #303067
+
+	* backends/ldap/e-book-backend-ldap.c:
+	Guard access to priv->ldap with priv->ldap_lock mutex.
+	Also do not use local copy of priv->ldap when reconnect can change it.
+
 2008-02-28  Milan Crha  <mcrha@redhat.com>
 
 	** Fix for bug #519214
Index: addressbook/backends/ldap/e-book-backend-ldap.c
===================================================================
--- addressbook/backends/ldap/e-book-backend-ldap.c	(revision 8557)
+++ addressbook/backends/ldap/e-book-backend-ldap.c	(working copy)
@@ -146,6 +146,8 @@ struct _EBookBackendLDAPPrivate {
 	EBookBackendLDAPUseTLS use_tls;
 
 	LDAP     *ldap;
+	/* every access to 'ldap' should be guarded with this lock */
+	GMutex *ldap_lock;
 
 	GList    *supported_fields;
 	GList    *supported_auth_methods;
@@ -191,8 +193,6 @@ struct LDAPOp {
 	int            id;   /* the ldap msg id */
 };
 
-static GStaticRecMutex eds_ldap_handler_lock = G_STATIC_REC_MUTEX_INIT;
-
 static void     ldap_op_add (LDAPOp *op, EBookBackend *backend, EDataBook *book,
 			     EDataBookView *view, int opid, int msgid, LDAPOpHandler handler, LDAPOpDtor dtor);
 static void     ldap_op_finished (LDAPOp *op);
@@ -535,13 +535,14 @@ check_schema_support (EBookBackendLDAP *
 {
 	char *attrs[2];
 	LDAPMessage *resp;
-	LDAP *ldap;
 	struct timeval timeout;
 
-	ldap = bl->priv->ldap;
-	if (!ldap) {
+	g_mutex_lock (bl->priv->ldap_lock);
+	if (!bl->priv->ldap) {
+		g_mutex_unlock (bl->priv->ldap_lock);
 		return;
 	}
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	if (!bl->priv->schema_dn)
 		return;
@@ -554,14 +555,14 @@ check_schema_support (EBookBackendLDAP *
 	timeout.tv_sec = 30;
 	timeout.tv_usec = 0;
 
-	g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-	if (ldap_search_ext_s (ldap, bl->priv->schema_dn, LDAP_SCOPE_BASE,
+	g_mutex_lock (bl->priv->ldap_lock);
+	if (ldap_search_ext_s (bl->priv->ldap, bl->priv->schema_dn, LDAP_SCOPE_BASE,
 			       "(objectClass=subschema)", attrs, 0,
 			       NULL, NULL, &timeout, LDAP_NO_LIMIT, &resp) == LDAP_SUCCESS) {
 		char **values;
 
-		values = ldap_get_values (ldap, resp, "objectClasses");
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+		values = ldap_get_values (bl->priv->ldap, resp, "objectClasses");
+		g_mutex_unlock (bl->priv->ldap_lock);
 
 		if (values) {
 			int i;
@@ -618,7 +619,7 @@ check_schema_support (EBookBackendLDAP *
 		ldap_msgfree (resp);
 	}
 	else {
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+		g_mutex_unlock (bl->priv->ldap_lock);
 	}
 }
 
@@ -668,20 +669,18 @@ static int
 query_ldap_root_dse (EBookBackendLDAP *bl)
 {
 #define MAX_DSE_ATTRS 20
-	LDAP *ldap;
 	LDAPMessage *resp;
 	int ldap_error = LDAP_OTHER;
 	char *attrs[MAX_DSE_ATTRS], **values;
 	int i = 0;
 	struct timeval timeout;
 
-	g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-	ldap = bl->priv->ldap;
-	if (!ldap) {
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+	g_mutex_lock (bl->priv->ldap_lock);
+	if (!bl->priv->ldap) {
+		g_mutex_unlock (bl->priv->ldap_lock);
 		return ldap_error;
 	}
-	g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	attrs[i++] = "supportedControl";
 	attrs[i++] = "supportedExtension";
@@ -695,29 +694,29 @@ query_ldap_root_dse (EBookBackendLDAP *b
 	timeout.tv_sec = 30;
 	timeout.tv_usec = 0;
 
-	g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-	ldap_error = ldap_search_ext_s (ldap,
+	g_mutex_lock (bl->priv->ldap_lock);
+	ldap_error = ldap_search_ext_s (bl->priv->ldap,
 					LDAP_ROOT_DSE, LDAP_SCOPE_BASE,
 					"(objectclass=*)",
 					attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, &resp);
-	g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+	g_mutex_unlock (bl->priv->ldap_lock);
 	if (ldap_error != LDAP_SUCCESS) {
 		g_warning ("could not perform query on Root DSE (ldap_error 0x%02x)", ldap_error);
 		return ldap_error;
 	}
 
-	g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-	values = ldap_get_values (ldap, resp, "supportedControl");
-	g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+	g_mutex_lock (bl->priv->ldap_lock);
+	values = ldap_get_values (bl->priv->ldap, resp, "supportedControl");
+	g_mutex_unlock (bl->priv->ldap_lock);
 	if (values) {
 		for (i = 0; values[i]; i++)
 			g_message ("supported server control: %s", values[i]);
 		ldap_value_free (values);
 	}
 
-	g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-	values = ldap_get_values (ldap, resp, "supportedExtension");
-	g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+	g_mutex_lock (bl->priv->ldap_lock);
+	values = ldap_get_values (bl->priv->ldap, resp, "supportedExtension");
+	g_mutex_unlock (bl->priv->ldap_lock);
 	if (values) {
 		for (i = 0; values[i]; i++) {
 			g_message ("supported server extension: %s", values[i]);
@@ -728,9 +727,9 @@ query_ldap_root_dse (EBookBackendLDAP *b
 		ldap_value_free (values);
 	}
 
-	g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-	values = ldap_get_values (ldap, resp, "supportedSASLMechanisms");
-	g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+	g_mutex_lock (bl->priv->ldap_lock);
+	values = ldap_get_values (bl->priv->ldap, resp, "supportedSASLMechanisms");
+	g_mutex_unlock (bl->priv->ldap_lock);
 	if (values) {
 		char *auth_method;
 		if (bl->priv->supported_auth_methods) {
@@ -753,14 +752,14 @@ query_ldap_root_dse (EBookBackendLDAP *b
 		ldap_value_free (values);
 	}
 
-	g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-	values = ldap_get_values (ldap, resp, "subschemaSubentry");
-	g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+	g_mutex_lock (bl->priv->ldap_lock);
+	values = ldap_get_values (bl->priv->ldap, resp, "subschemaSubentry");
+	g_mutex_unlock (bl->priv->ldap_lock);
 	if (!values || !values[0]) {
 		if (values) ldap_value_free (values);
-		g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-		values = ldap_get_values (ldap, resp, "schemaNamingContext");
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+		g_mutex_lock (bl->priv->ldap_lock);
+		values = ldap_get_values (bl->priv->ldap, resp, "schemaNamingContext");
+		g_mutex_unlock (bl->priv->ldap_lock);
 	}
 	if (values && values[0]) {
 		g_free (bl->priv->schema_dn);
@@ -794,7 +793,7 @@ e_book_backend_ldap_connect (EBookBacken
 	}
 
 	/* close connection first if it's open first */
-	g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+	g_mutex_lock (bl->priv->ldap_lock);
 	if (blpriv->ldap) {
 		ldap_unbind (blpriv->ldap);
 	}
@@ -834,7 +833,7 @@ e_book_backend_ldap_connect (EBookBacken
 				g_message ("TLS not available (fatal version), v3 protocol could not be established (ldap_error 0x%02x)", ldap_error);
 				ldap_unbind (blpriv->ldap);
 				blpriv->ldap = NULL;
-				g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+				g_mutex_unlock (bl->priv->ldap_lock);
 				return GNOME_Evolution_Addressbook_TLSNotAvailable;
 			}
 
@@ -880,7 +879,7 @@ e_book_backend_ldap_connect (EBookBacken
 						g_message ("TLS not available (fatal version), (ldap_error 0x%02x)", ldap_error);
 						ldap_unbind (blpriv->ldap);
 						blpriv->ldap = NULL;
-						g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+						g_mutex_unlock (bl->priv->ldap_lock);
 						return GNOME_Evolution_Addressbook_TLSNotAvailable;
 					}
 					else {
@@ -911,21 +910,21 @@ e_book_backend_ldap_connect (EBookBacken
 
 		if (ldap_error == LDAP_PROTOCOL_ERROR) {
 			g_warning ("failed to bind using either v3 or v2 binds.");
-			g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+			g_mutex_unlock (bl->priv->ldap_lock);
 			return GNOME_Evolution_Addressbook_OtherError;
 		}
 		else if (ldap_error == LDAP_SERVER_DOWN) {
 			/* we only want this to be fatal if the server is down. */
 			g_warning ("failed to bind anonymously while connecting (ldap_error 0x%02x)", ldap_error);
-			g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+			g_mutex_unlock (bl->priv->ldap_lock);
 			return GNOME_Evolution_Addressbook_RepositoryOffline;
 		} else if (ldap_error == LDAP_INVALID_CREDENTIALS) {
 			g_warning ("Invalid credentials while connecting (ldap_error 0x%02x)", ldap_error);
-			g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+			g_mutex_unlock (bl->priv->ldap_lock);
 			return (GNOME_Evolution_Addressbook_AuthenticationFailed);
 		}
 
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+		g_mutex_unlock (bl->priv->ldap_lock);
 		ldap_error = query_ldap_root_dse (bl);
 		/* query_ldap_root_dse will cause the actual
 		   connect(), so any tcpip problems will show up
@@ -964,7 +963,7 @@ e_book_backend_ldap_connect (EBookBacken
 			g_warning ("Failed to perform root dse query anonymously, (ldap_error 0x%02x)", ldap_error);
 	}
 	else {
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+		g_mutex_unlock (bl->priv->ldap_lock);
 	}
 
 	g_warning ("e_book_backend_ldap_connect failed for "
@@ -987,11 +986,14 @@ e_book_backend_ldap_reconnect (EBookBack
 		g_get_current_time (&start);
 	}
 
+	g_mutex_lock (bl->priv->ldap_lock);
 	if (!bl->priv->ldap) {
+		g_mutex_unlock (bl->priv->ldap_lock);
 		if (enable_debug)
 			printf ("e_book_backend_ldap_reconnect ... ldap handler is NULL\n");
 		return FALSE;
 	}
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	/* we need to reconnect if we were previously connected */
 	if (bl->priv->connected && ldap_status == LDAP_SERVER_DOWN) {
@@ -1012,11 +1014,11 @@ e_book_backend_ldap_reconnect (EBookBack
 		}
 
 		if (bl->priv->auth_dn) {
-			g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+			g_mutex_lock (bl->priv->ldap_lock);
 			ldap_error = ldap_simple_bind_s(bl->priv->ldap,
 							bl->priv->auth_dn,
 							bl->priv->auth_passwd);
-			g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+			g_mutex_unlock (bl->priv->ldap_lock);
 		}
 		if (book_view)
 			book_view_notify_status (book_view, "");
@@ -1082,10 +1084,10 @@ ldap_op_finished (LDAPOp *op)
 	g_hash_table_remove (bl->priv->id_to_op, &op->id);
 
 	/* should handle errors here */
-	g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+	g_mutex_lock (bl->priv->ldap_lock);
 	if (bl->priv->ldap)
 		ldap_abandon (bl->priv->ldap, op->id);
-	g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	if (op->dtor)
 		op->dtor (op);
@@ -1425,13 +1427,13 @@ create_contact_handler (LDAPOp *op, LDAP
 {
 	LDAPCreateOp *create_op = (LDAPCreateOp*)op;
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (op->backend);
-	LDAP *ldap;
 	char *ldap_error_msg;
 	int ldap_error;
 	int response;
 
-	ldap = bl->priv->ldap;
-	if (!ldap) {
+	g_mutex_lock (bl->priv->ldap_lock);
+	if (!bl->priv->ldap) {
+		g_mutex_unlock (bl->priv->ldap_lock);
 		e_data_book_respond_create (op->book,
 					    op->opid,
 					    GNOME_Evolution_Addressbook_OtherError,
@@ -1439,6 +1441,7 @@ create_contact_handler (LDAPOp *op, LDAP
 		ldap_op_finished (op);
 		return;
 	}
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	if (LDAP_RES_ADD != ldap_msgtype (res)) {
 		g_warning ("incorrect msg type %d passed to create_contact_handler", ldap_msgtype (res));
@@ -1450,10 +1453,10 @@ create_contact_handler (LDAPOp *op, LDAP
 		return;
 	}
 
-	g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-	ldap_parse_result (ldap, res, &ldap_error,
+	g_mutex_lock (bl->priv->ldap_lock);
+	ldap_parse_result (bl->priv->ldap, res, &ldap_error,
 			   NULL, &ldap_error_msg, NULL, NULL, 0);
-	g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+	g_mutex_unlock (bl->priv->ldap_lock);
 	if (ldap_error != LDAP_SUCCESS) {
 		g_warning ("create_contact_handler: %02X (%s), additional info: %s",
 			   ldap_error,
@@ -1498,8 +1501,6 @@ e_book_backend_ldap_create_contact (EBoo
 	int err;
 	GPtrArray *mod_array;
 	LDAPMod **ldap_mods;
-	LDAP *ldap;
-
 
 	switch (bl->priv->mode) {
 
@@ -1508,13 +1509,13 @@ e_book_backend_ldap_create_contact (EBoo
 		return;
 	case GNOME_Evolution_Addressbook_MODE_REMOTE :
 
-		g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+		g_mutex_lock (bl->priv->ldap_lock);
 		if (!bl->priv->ldap) {
-			g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+			g_mutex_unlock (bl->priv->ldap_lock);
 			e_data_book_respond_create (book, opid, GNOME_Evolution_Addressbook_OtherError, NULL);
 			return;
 		}
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+		g_mutex_unlock (bl->priv->ldap_lock);
 
 		book_view = find_book_view (bl);
 
@@ -1592,14 +1593,12 @@ e_book_backend_ldap_create_contact (EBoo
 
 		ldap_mods = (LDAPMod**)mod_array->pdata;
 
-		ldap = bl->priv->ldap;
-
 		do {
 			book_view_notify_status (book_view, _("Adding contact to LDAP server..."));
-			g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-			err = ldap_add_ext (ldap, create_op->dn, ldap_mods,
+			g_mutex_lock (bl->priv->ldap_lock);
+			err = ldap_add_ext (bl->priv->ldap, create_op->dn, ldap_mods,
 					    NULL, NULL, &create_contact_msgid);
-			g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+			g_mutex_unlock (bl->priv->ldap_lock);
 
 		} while (e_book_backend_ldap_reconnect (bl, book_view, err));
 
@@ -1639,11 +1638,14 @@ remove_contact_handler (LDAPOp *op, LDAP
 	int ldap_error;
 	GList *ids = NULL;
 
+	g_mutex_lock (bl->priv->ldap_lock);
 	if (!bl->priv->ldap) {
+		g_mutex_unlock (bl->priv->ldap_lock);
 		e_data_book_respond_remove_contacts (op->book, op->opid, GNOME_Evolution_Addressbook_OtherError, NULL);
 		ldap_op_finished (op);
 		return;
 	}
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	if (LDAP_RES_DELETE != ldap_msgtype (res)) {
 		g_warning ("incorrect msg type %d passed to remove_contact_handler", ldap_msgtype (res));
@@ -1655,10 +1657,10 @@ remove_contact_handler (LDAPOp *op, LDAP
 		return;
 	}
 
-	g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+	g_mutex_lock (bl->priv->ldap_lock);
 	ldap_parse_result (bl->priv->ldap, res, &ldap_error,
 			   NULL, &ldap_error_msg, NULL, NULL, 0);
-	g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+	g_mutex_unlock (bl->priv->ldap_lock);
 	if (ldap_error != LDAP_SUCCESS) {
 		g_warning ("remove_contact_handler: %02X (%s), additional info: %s",
 			   ldap_error,
@@ -1707,11 +1709,14 @@ e_book_backend_ldap_remove_contacts (EBo
 		g_free (remove_op);
 		return;
 	case GNOME_Evolution_Addressbook_MODE_REMOTE :
+		g_mutex_lock (bl->priv->ldap_lock);
 		if (!bl->priv->ldap) {
+			g_mutex_unlock (bl->priv->ldap_lock);
 			e_data_book_respond_remove_contacts (book, opid, GNOME_Evolution_Addressbook_OtherError, NULL);
 			g_free (remove_op);
 			return;
 		}
+		g_mutex_unlock (bl->priv->ldap_lock);
 
 		book_view = find_book_view (bl);
 
@@ -1725,11 +1730,11 @@ e_book_backend_ldap_remove_contacts (EBo
 		do {
 			book_view_notify_status (book_view, _("Removing contact from LDAP server..."));
 
-			g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+			g_mutex_lock (bl->priv->ldap_lock);
 			ldap_error = ldap_delete_ext (bl->priv->ldap,
 						      remove_op->id,
 						      NULL, NULL, &remove_msgid);
-			g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+			g_mutex_unlock (bl->priv->ldap_lock);
 		} while (e_book_backend_ldap_reconnect (bl, book_view, ldap_error));
 
 		if (ldap_error != LDAP_SUCCESS) {
@@ -1775,12 +1780,12 @@ modify_contact_modify_handler (LDAPOp *o
 {
 	LDAPModifyOp *modify_op = (LDAPModifyOp*)op;
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (op->backend);
-	LDAP *ldap;
 	char *ldap_error_msg;
 	int ldap_error;
 
-	ldap = bl->priv->ldap;
-	if (!ldap) {
+	g_mutex_lock (bl->priv->ldap_lock);
+	if (!bl->priv->ldap) {
+		g_mutex_unlock (bl->priv->ldap_lock);
 		e_data_book_respond_modify (op->book,
 					    op->opid,
 					    GNOME_Evolution_Addressbook_OtherError,
@@ -1788,6 +1793,7 @@ modify_contact_modify_handler (LDAPOp *o
 		ldap_op_finished (op);
 		return;
 	}
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	if (LDAP_RES_MODIFY != ldap_msgtype (res)) {
 		g_warning ("incorrect msg type %d passed to modify_contact_handler", ldap_msgtype (res));
@@ -1799,10 +1805,10 @@ modify_contact_modify_handler (LDAPOp *o
 		return;
 	}
 
-	g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-	ldap_parse_result (ldap, res, &ldap_error,
+	g_mutex_lock (bl->priv->ldap_lock);
+	ldap_parse_result (bl->priv->ldap, res, &ldap_error,
 			   NULL, &ldap_error_msg, NULL, NULL, 0);
-	g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+	g_mutex_unlock (bl->priv->ldap_lock);
 	if (ldap_error != LDAP_SUCCESS) {
 		g_warning ("modify_contact_handler: %02X (%s), additional info: %s",
 			   ldap_error,
@@ -1826,16 +1832,17 @@ modify_contact_search_handler (LDAPOp *o
 {
 	LDAPModifyOp *modify_op = (LDAPModifyOp*)op;
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (op->backend);
-	LDAP *ldap;
 	int msg_type;
 
-	ldap = bl->priv->ldap;
-	if (!ldap) {
+	g_mutex_lock (bl->priv->ldap_lock);
+	if (!bl->priv->ldap) {
+		g_mutex_unlock (bl->priv->ldap_lock);
 		e_data_book_respond_modify (op->book, op->opid,
 					    GNOME_Evolution_Addressbook_OtherError, NULL);
 		ldap_op_finished (op);
 		return;
 	}
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	/* if it's successful, we should get called with a
 	   RES_SEARCH_ENTRY and a RES_SEARCH_RESULT.  if it's
@@ -1843,7 +1850,11 @@ modify_contact_search_handler (LDAPOp *o
 
 	msg_type = ldap_msgtype (res);
 	if (msg_type == LDAP_RES_SEARCH_ENTRY) {
-		LDAPMessage *e = ldap_first_entry(ldap, res);
+		LDAPMessage *e;
+
+		g_mutex_lock (bl->priv->ldap_lock);
+		e = ldap_first_entry (bl->priv->ldap, res);
+		g_mutex_unlock (bl->priv->ldap_lock);
 
 		if (!e) {
 			g_warning ("uh, this shouldn't happen");
@@ -1869,10 +1880,10 @@ modify_contact_search_handler (LDAPOp *o
 
 		/* grab the result code, and set up the actual modify
                    if it was successful */
-		g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+		g_mutex_lock (bl->priv->ldap_lock);
 		ldap_parse_result (bl->priv->ldap, res, &ldap_error,
 				   NULL, &ldap_error_msg, NULL, NULL, 0);
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+		g_mutex_unlock (bl->priv->ldap_lock);
 		if (ldap_error != LDAP_SUCCESS) {
 			g_warning ("modify_contact_search_handler: %02X (%s), additional info: %s",
 				   ldap_error,
@@ -1944,10 +1955,10 @@ modify_contact_search_handler (LDAPOp *o
 			}
 #endif
 			/* actually perform the ldap modify */
-			g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-			ldap_error = ldap_modify_ext (ldap, modify_op->id, ldap_mods,
+			g_mutex_lock (bl->priv->ldap_lock);
+			ldap_error = ldap_modify_ext (bl->priv->ldap, modify_op->id, ldap_mods,
 						      NULL, NULL, &modify_contact_msgid);
-			g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+			g_mutex_unlock (bl->priv->ldap_lock);
 
 			if (ldap_error == LDAP_SUCCESS) {
 				op->handler = modify_contact_modify_handler;
@@ -2002,7 +2013,6 @@ e_book_backend_ldap_modify_contact (EBoo
 	LDAPModifyOp *modify_op = g_new0 (LDAPModifyOp, 1);
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend);
 	int ldap_error;
-	LDAP *ldap;
 	int modify_contact_msgid;
 	EDataBookView *book_view;
 
@@ -2013,11 +2023,14 @@ e_book_backend_ldap_modify_contact (EBoo
 		e_data_book_respond_modify(book, opid, GNOME_Evolution_Addressbook_RepositoryOffline, NULL);
 		return;
 	case GNOME_Evolution_Addressbook_MODE_REMOTE :
+		g_mutex_lock (bl->priv->ldap_lock);
 		if (!bl->priv->ldap) {
+			g_mutex_unlock (bl->priv->ldap_lock);
 			e_data_book_respond_modify (book, opid, GNOME_Evolution_Addressbook_OtherError, NULL);
 			g_free (modify_op);
 			return;
 		}
+		g_mutex_unlock (bl->priv->ldap_lock);
 
 		book_view = find_book_view (bl);
 
@@ -2025,19 +2038,17 @@ e_book_backend_ldap_modify_contact (EBoo
 		modify_op->contact = e_contact_new_from_vcard (vcard);
 		modify_op->id = e_contact_get_const (modify_op->contact, E_CONTACT_UID);
 
-		ldap = bl->priv->ldap;
-
 		do {
 			book_view_notify_status (book_view, _("Modifying contact from LDAP server..."));
 
-			g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-			ldap_error = ldap_search_ext (ldap, modify_op->id,
+			g_mutex_lock (bl->priv->ldap_lock);
+			ldap_error = ldap_search_ext (bl->priv->ldap, modify_op->id,
 						      LDAP_SCOPE_BASE,
 						      "(objectclass=*)",
 						      NULL, 0, NULL, NULL,
 						      NULL, /* XXX timeout */
 						      1, &modify_contact_msgid);
-			g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+			g_mutex_unlock (bl->priv->ldap_lock);
 
 		} while (e_book_backend_ldap_reconnect (bl, book_view, ldap_error));
 
@@ -2075,20 +2086,27 @@ get_contact_handler (LDAPOp *op, LDAPMes
 		g_get_current_time (&start);
 	}
 
+	g_mutex_lock (bl->priv->ldap_lock);
 	if (!bl->priv->ldap) {
+		g_mutex_unlock (bl->priv->ldap_lock);
 		e_data_book_respond_get_contact (op->book, op->opid, GNOME_Evolution_Addressbook_OtherError, "");
 		ldap_op_finished (op);
 		if (enable_debug)
 			printf ("get_contact_handler... ldap handler is NULL \n");
 		return;
 	}
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	/* the msg_type will be either SEARCH_ENTRY (if we're
 	   successful) or SEARCH_RESULT (if we're not), so we finish
 	   the op after either */
 	msg_type = ldap_msgtype (res);
 	if (msg_type == LDAP_RES_SEARCH_ENTRY) {
-		LDAPMessage *e = ldap_first_entry (bl->priv->ldap, res);
+		LDAPMessage *e;
+
+		g_mutex_lock (bl->priv->ldap_lock);
+		e = ldap_first_entry (bl->priv->ldap, res);
+		g_mutex_unlock (bl->priv->ldap_lock);
 
 		EContact *contact;
 		char *vcard;
@@ -2126,10 +2144,10 @@ get_contact_handler (LDAPOp *op, LDAPMes
 		char *ldap_error_msg;
 		int ldap_error;
 
-		g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+		g_mutex_lock (bl->priv->ldap_lock);
 		ldap_parse_result (bl->priv->ldap, res, &ldap_error,
 				   NULL, &ldap_error_msg, NULL, NULL, 0);
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+		g_mutex_unlock (bl->priv->ldap_lock);
 		if (ldap_error != LDAP_SUCCESS) {
 			g_warning ("get_contact_handler: %02X (%s), additional info: %s",
 				   ldap_error,
@@ -2170,7 +2188,6 @@ e_book_backend_ldap_get_contact (EBookBa
 {
 	LDAPGetContactOp *get_contact_op;
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend);
-	LDAP *ldap;
 	int get_contact_msgid;
 	EDataBookView *book_view;
 	int ldap_error;
@@ -2209,27 +2226,29 @@ e_book_backend_ldap_get_contact (EBookBa
 			printf("e_book_backend_ldap_get_contact ... \n");
 			g_get_current_time (&start);
 		}
-		ldap = bl->priv->ldap;
 
-		if (!ldap) {
+		g_mutex_lock (bl->priv->ldap_lock);
+		if (!bl->priv->ldap) {
+			g_mutex_unlock (bl->priv->ldap_lock);
 			e_data_book_respond_get_contact (book, opid, GNOME_Evolution_Addressbook_OtherError, "");
 			if (enable_debug)
 				printf("e_book_backend_ldap_get_contact ... ldap handler is NULL\n");
 			return;
 		}
+		g_mutex_unlock (bl->priv->ldap_lock);
 
 		get_contact_op = g_new0 (LDAPGetContactOp, 1);
 		book_view = find_book_view (bl);
 
 		do {
-			g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-			ldap_error = ldap_search_ext (ldap, id,
+			g_mutex_lock (bl->priv->ldap_lock);
+			ldap_error = ldap_search_ext (bl->priv->ldap, id,
 						      LDAP_SCOPE_BASE,
 						      "(objectclass=*)",
 						      NULL, 0, NULL, NULL,
 						      NULL, /* XXX timeout */
 						      1, &get_contact_msgid);
-			g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+			g_mutex_unlock (bl->priv->ldap_lock);
 		} while (e_book_backend_ldap_reconnect (bl, book_view, ldap_error));
 
 		if (ldap_error == LDAP_SUCCESS) {
@@ -2267,7 +2286,6 @@ contact_list_handler (LDAPOp *op, LDAPMe
 {
 	LDAPGetContactListOp *contact_list_op = (LDAPGetContactListOp*)op;
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (op->backend);
-	LDAP *ldap;
 	LDAPMessage *e;
 	int msg_type;
 	GTimeVal start, end;
@@ -2277,18 +2295,23 @@ contact_list_handler (LDAPOp *op, LDAPMe
 		printf ("contact_list_handler ...\n");
 		g_get_current_time (&start);
 	}
-	ldap = bl->priv->ldap;
-	if (!ldap) {
+
+	g_mutex_lock (bl->priv->ldap_lock);
+	if (!bl->priv->ldap) {
+		g_mutex_unlock (bl->priv->ldap_lock);
 		e_data_book_respond_get_contact_list (op->book, op->opid, GNOME_Evolution_Addressbook_OtherError, NULL);
 		ldap_op_finished (op);
 		if (enable_debug)
 			printf ("contact_list_handler ... ldap handler is NULL \n");
 		return;
 	}
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	msg_type = ldap_msgtype (res);
 	if (msg_type == LDAP_RES_SEARCH_ENTRY) {
-		e = ldap_first_entry (ldap, res);
+		g_mutex_lock (bl->priv->ldap_lock);
+		e = ldap_first_entry (bl->priv->ldap, res);
+		g_mutex_unlock (bl->priv->ldap_lock);
 
 		while (NULL != e) {
 			EContact *contact;
@@ -2305,17 +2328,19 @@ contact_list_handler (LDAPOp *op, LDAPMe
 
 			g_object_unref (contact);
 
-			e = ldap_next_entry(ldap, e);
+			g_mutex_lock (bl->priv->ldap_lock);
+			e = ldap_next_entry (bl->priv->ldap, e);
+			g_mutex_unlock (bl->priv->ldap_lock);
 		}
 	}
 	else if (msg_type == LDAP_RES_SEARCH_RESULT) {
 		char *ldap_error_msg;
 		int ldap_error;
 
-		g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-		ldap_parse_result (ldap, res, &ldap_error,
+		g_mutex_lock (bl->priv->ldap_lock);
+		ldap_parse_result (bl->priv->ldap, res, &ldap_error,
 				   NULL, &ldap_error_msg, NULL, NULL, 0);
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+		g_mutex_unlock (bl->priv->ldap_lock);
 		if (ldap_error != LDAP_SUCCESS) {
 			g_warning ("contact_list_handler: %02X (%s), additional info: %s",
 				   ldap_error,
@@ -2382,7 +2407,6 @@ e_book_backend_ldap_get_contact_list (EB
 {
 	LDAPGetContactListOp *contact_list_op;
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend);
-	LDAP *ldap;
 	int contact_list_msgid;
 	EDataBookView *book_view;
 	int ldap_error;
@@ -2422,14 +2446,15 @@ e_book_backend_ldap_get_contact_list (EB
 		return;
 
 	case GNOME_Evolution_Addressbook_MODE_REMOTE:
-		ldap = bl->priv->ldap;
-
-		if (!ldap) {
+		g_mutex_lock (bl->priv->ldap_lock);
+		if (!bl->priv->ldap) {
+			g_mutex_unlock (bl->priv->ldap_lock);
 			e_data_book_respond_get_contact_list (book, opid, GNOME_Evolution_Addressbook_OtherError, NULL);
 			if (enable_debug)
 				printf ("e_book_backend_ldap_get_contact_list... ldap handler is NULL\n");
 			return;
 		}
+		g_mutex_unlock (bl->priv->ldap_lock);
 
 		contact_list_op = g_new0 (LDAPGetContactListOp, 1);
 		book_view = find_book_view (bl);
@@ -2439,15 +2464,15 @@ e_book_backend_ldap_get_contact_list (EB
 		printf ("getting contact list with filter: %s\n", ldap_query);
 
 		do {
-			g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-			ldap_error = ldap_search_ext (ldap,
+			g_mutex_lock (bl->priv->ldap_lock);
+			ldap_error = ldap_search_ext (bl->priv->ldap,
 						      bl->priv->ldap_rootdn,
 						      bl->priv->ldap_scope,
 						      ldap_query,
 						      NULL, 0, NULL, NULL,
 						      NULL, /* XXX timeout */
 						      LDAP_NO_LIMIT, &contact_list_msgid);
-			g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+			g_mutex_unlock (bl->priv->ldap_lock);
 		} while (e_book_backend_ldap_reconnect (bl, book_view, ldap_error));
 
 		g_free (ldap_query);
@@ -3790,22 +3815,27 @@ build_contact_from_entry (EBookBackendLD
 	char *dn;
 	char *attr;
 	BerElement *ber = NULL;
-	LDAP *ldap;
 
-	ldap = bl->priv->ldap;
-	dn = ldap_get_dn (ldap, e);
+	g_mutex_lock (bl->priv->ldap_lock);
+	dn = ldap_get_dn (bl->priv->ldap, e);
+	g_mutex_unlock (bl->priv->ldap_lock);
 	e_contact_set (contact, E_CONTACT_UID, dn);
 	ldap_memfree (dn);
 
-	for (attr = ldap_first_attribute (ldap, e, &ber); attr;
-	     attr = ldap_next_attribute (ldap, e, ber)) {
+	g_mutex_lock (bl->priv->ldap_lock);
+	for (attr = ldap_first_attribute (bl->priv->ldap, e, &ber); attr;
+	     attr = ldap_next_attribute (bl->priv->ldap, e, ber)) {
 		int i;
 		struct prop_info *info = NULL;
 		char **values;
 
+		g_mutex_unlock (bl->priv->ldap_lock);
+
 		printf ("attr = %s \n", attr);
 		if (!g_ascii_strcasecmp (attr, "objectclass")) {
-			values = ldap_get_values (ldap, e, attr);
+			g_mutex_lock (bl->priv->ldap_lock);
+			values = ldap_get_values (bl->priv->ldap, e, attr);
+			g_mutex_unlock (bl->priv->ldap_lock);
 			for (i = 0; values[i]; i ++) {
 				printf ("value = %s\n", values[i]);
 				if (!g_ascii_strcasecmp (values[i], "groupOfNames")) {
@@ -3827,11 +3857,17 @@ build_contact_from_entry (EBookBackendLD
 			printf ("info = %p\n", info);
 
 			if (info) {
-				if (info->prop_type & PROP_WRITE_ONLY)
+				if (info->prop_type & PROP_WRITE_ONLY) {
+					g_mutex_lock (bl->priv->ldap_lock);
 					continue;
+				}
 
 				if (info->prop_type & PROP_TYPE_BINARY) {
-					struct berval **ber_values = ldap_get_values_len (ldap, e, attr);
+					struct berval **ber_values;
+
+					g_mutex_lock (bl->priv->ldap_lock);
+					ber_values = ldap_get_values_len (bl->priv->ldap, e, attr);
+					g_mutex_unlock (bl->priv->ldap_lock);
 
 					if (ber_values) {
 						info->binary_populate_contact_func (contact, ber_values);
@@ -3840,7 +3876,9 @@ build_contact_from_entry (EBookBackendLD
 					}
 				}
 				else {
-					values = ldap_get_values (ldap, e, attr);
+					g_mutex_lock (bl->priv->ldap_lock);
+					values = ldap_get_values (bl->priv->ldap, e, attr);
+					g_mutex_unlock (bl->priv->ldap_lock);
 
 					if (values) {
 						if (info->prop_type & PROP_TYPE_STRING) {
@@ -3882,6 +3920,7 @@ build_contact_from_entry (EBookBackendLD
 								/* set base to DN and scope to base */
 								printf ("value (dn) = %s \n", values [j]);
 								do {
+									g_mutex_lock (bl->priv->ldap_lock);
 									if ((ldap_error = ldap_search_ext_s (bl->priv->ldap,
 						    						        values[j],
 						    						        LDAP_SCOPE_BASE,
@@ -3893,8 +3932,8 @@ build_contact_from_entry (EBookBackendLD
 												        view_limit,
 											    	        &result)) == LDAP_SUCCESS) {
 										/* find the e-mail ids of members */
-										cn_values = ldap_get_values (ldap, result, "cn");
-										email_values = ldap_get_values (ldap, result, "mail");
+										cn_values = ldap_get_values (bl->priv->ldap, result, "cn");
+										email_values = ldap_get_values (bl->priv->ldap, result, "mail");
 
 										if (email_values) {
 											printf ("email = %s \n", email_values[0]);
@@ -3911,6 +3950,7 @@ build_contact_from_entry (EBookBackendLD
 											ldap_value_free (cn_values);
 										}
 									}
+									g_mutex_unlock (bl->priv->ldap_lock);
 								}
 								while (e_book_backend_ldap_reconnect (bl, book_view, ldap_error));
 
@@ -3936,7 +3976,9 @@ build_contact_from_entry (EBookBackendLD
 		}
 
 		ldap_memfree (attr);
+		g_mutex_lock (bl->priv->ldap_lock);
 	}
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	if (ber)
 		ber_free (ber, 0);
@@ -3947,17 +3989,18 @@ build_contact_from_entry (EBookBackendLD
 static gboolean
 poll_ldap (EBookBackendLDAP *bl)
 {
-	LDAP           *ldap;
 	int            rc;
 	LDAPMessage    *res;
 	struct timeval timeout;
 	const char *ldap_timeout_string;
 
-	ldap = bl->priv->ldap;
-	if (!ldap) {
+	g_mutex_lock (bl->priv->ldap_lock);
+	if (!bl->priv->ldap) {
+		g_mutex_unlock (bl->priv->ldap_lock);
 		bl->priv->poll_timeout = -1;
 		return FALSE;
 	}
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	if (!bl->priv->active_ops) {
 		g_warning ("poll_ldap being called for backend with no active operations");
@@ -3973,7 +4016,9 @@ poll_ldap (EBookBackendLDAP *bl)
 	else
 		timeout.tv_usec = LDAP_RESULT_TIMEOUT_MILLIS * 1000;
 
-	rc = ldap_result (ldap, LDAP_RES_ANY, 0, &timeout, &res);
+	g_mutex_lock (bl->priv->ldap_lock);
+	rc = ldap_result (bl->priv->ldap, LDAP_RES_ANY, 0, &timeout, &res);
+	g_mutex_unlock (bl->priv->ldap_lock);
 	if (rc != 0) {/* rc == 0 means timeout exceeded */
 		if (rc == -1) {
 			EDataBookView *book_view = find_book_view (bl);
@@ -4016,7 +4061,6 @@ ldap_search_handler (LDAPOp *op, LDAPMes
 	LDAPSearchOp *search_op = (LDAPSearchOp*)op;
 	EDataBookView *view = search_op->view;
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (op->backend);
-	LDAP *ldap;
 	LDAPMessage *e;
 	int msg_type;
 	GTimeVal start, end;
@@ -4026,14 +4070,16 @@ ldap_search_handler (LDAPOp *op, LDAPMes
 	if (enable_debug)
 		g_get_current_time(&start);
 
-	ldap = bl->priv->ldap;
-	if (!ldap) {
+	g_mutex_lock (bl->priv->ldap_lock);
+	if (!bl->priv->ldap) {
+		g_mutex_unlock (bl->priv->ldap_lock);
 		e_data_book_view_notify_complete (view, GNOME_Evolution_Addressbook_OtherError);
 		ldap_op_finished (op);
 		if (enable_debug)
 			printf ("ldap_search_handler... ldap handler is NULL \n");
 		return;
 	}
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	if (!search_op->notified_receiving_results) {
 		search_op->notified_receiving_results = TRUE;
@@ -4042,7 +4088,9 @@ ldap_search_handler (LDAPOp *op, LDAPMes
 
 	msg_type = ldap_msgtype (res);
 	if (msg_type == LDAP_RES_SEARCH_ENTRY) {
-		e = ldap_first_entry (ldap, res);
+		g_mutex_lock (bl->priv->ldap_lock);
+		e = ldap_first_entry (bl->priv->ldap, res);
+		g_mutex_unlock (bl->priv->ldap_lock);
 
 		while (NULL != e) {
 			EContact *contact = build_contact_from_entry (bl, e, NULL);
@@ -4050,17 +4098,19 @@ ldap_search_handler (LDAPOp *op, LDAPMes
 			e_data_book_view_notify_update (view, contact);
 			g_object_unref (contact);
 
-			e = ldap_next_entry(ldap, e);
+			g_mutex_lock (bl->priv->ldap_lock);
+			e = ldap_next_entry(bl->priv->ldap, e);
+			g_mutex_unlock (bl->priv->ldap_lock);
 		}
 	}
 	else if (msg_type == LDAP_RES_SEARCH_RESULT) {
 		char *ldap_error_msg;
 		int ldap_error;
 
-		g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-		ldap_parse_result (ldap, res, &ldap_error,
+		g_mutex_lock (bl->priv->ldap_lock);
+		ldap_parse_result (bl->priv->ldap, res, &ldap_error,
 				   NULL, &ldap_error_msg, NULL, NULL, 0);
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+		g_mutex_unlock (bl->priv->ldap_lock);
 		if (ldap_error != LDAP_SUCCESS) {
 			g_warning ("ldap_search_handler: %02X (%s), additional info: %s",
 				   ldap_error,
@@ -4150,12 +4200,14 @@ e_book_backend_ldap_search (EBookBackend
 	case GNOME_Evolution_Addressbook_MODE_REMOTE :
 		ldap_query = e_book_backend_ldap_build_query (bl, e_data_book_view_get_card_query (view));
 
+		g_mutex_lock (bl->priv->ldap_lock);
 		if (ldap_query != NULL && bl->priv->ldap) {
-			LDAP *ldap;
 			int ldap_err;
 			int search_msgid;
 			int view_limit;
 
+			g_mutex_unlock (bl->priv->ldap_lock);
+
 			view_limit = e_data_book_view_get_max_results (view);
 			if (view_limit == -1 || view_limit > bl->priv->ldap_limit)
 				view_limit = bl->priv->ldap_limit;
@@ -4163,12 +4215,11 @@ e_book_backend_ldap_search (EBookBackend
 			printf ("searching server using filter: %s (expecting max %d results)\n", ldap_query,
 				view_limit);
 
-			ldap = bl->priv->ldap;
-
 			do {
 				book_view_notify_status (view, _("Searching..."));
 
-				ldap_err = ldap_search_ext (ldap, bl->priv->ldap_rootdn,
+				g_mutex_lock (bl->priv->ldap_lock);
+				ldap_err = ldap_search_ext (bl->priv->ldap, bl->priv->ldap_rootdn,
 							    bl->priv->ldap_scope,
 							    ldap_query,
 							    NULL, 0,
@@ -4176,6 +4227,7 @@ e_book_backend_ldap_search (EBookBackend
 							    NULL, /* XXX */
 							    NULL, /* XXX timeout */
 							    view_limit, &search_msgid);
+				g_mutex_unlock (bl->priv->ldap_lock);
 			} while (e_book_backend_ldap_reconnect (bl, view, ldap_err));
 
 			g_free (ldap_query);
@@ -4215,6 +4267,7 @@ e_book_backend_ldap_search (EBookBackend
 			return;
 		}
 		else {
+			g_mutex_unlock (bl->priv->ldap_lock);
 			/*
 			e_data_book_view_notify_complete (view,
 							  GNOME_Evolution_Addressbook_InvalidQuery);
@@ -4276,7 +4329,6 @@ generate_cache_handler (LDAPOp *op, LDAP
 {
 	LDAPGetContactListOp *contact_list_op = (LDAPGetContactListOp *) op;
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (op->backend);
-	LDAP *ldap;
 	LDAPMessage *e;
 	gint msg_type;
 	EDataBookView *book_view;
@@ -4287,30 +4339,33 @@ generate_cache_handler (LDAPOp *op, LDAP
 		printf ("generate_cache_handler ... \n");
 		g_get_current_time (&start);
 	}
-	ldap = bl->priv->ldap;
-	if (!ldap) {
+
+	g_mutex_lock (bl->priv->ldap_lock);
+	if (!bl->priv->ldap) {
+		g_mutex_unlock (bl->priv->ldap_lock);
 		ldap_op_finished (op);
 		if (enable_debug)
 			printf ("generate_cache_handler ... ldap handler is NULL \n");
 		return;
 	}
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	book_view = find_book_view (bl);
 
 	msg_type = ldap_msgtype (res);
 	if (msg_type == LDAP_RES_SEARCH_ENTRY) {
-		g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-		e = ldap_first_entry(ldap, res);
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+		g_mutex_lock (bl->priv->ldap_lock);
+		e = ldap_first_entry (bl->priv->ldap, res);
+		g_mutex_unlock (bl->priv->ldap_lock);
 
 		while (e != NULL) {
 			EContact *contact = build_contact_from_entry (bl, e, NULL);
 
 			contact_list_op->contacts = g_list_prepend (contact_list_op->contacts, contact);
 
-			g_static_rec_mutex_lock (&eds_ldap_handler_lock);
-			e = ldap_next_entry(ldap, e);
-			g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+			g_mutex_lock (bl->priv->ldap_lock);
+			e = ldap_next_entry (bl->priv->ldap, e);
+			g_mutex_unlock (bl->priv->ldap_lock);
 		}
 	} else {
 		GList *l;
@@ -4380,17 +4435,21 @@ generate_cache (EBookBackendLDAP *book_b
 
 	priv = book_backend_ldap->priv;
 
+	g_mutex_lock (priv->ldap_lock);
 	if (!priv->ldap) {
+		g_mutex_unlock (priv->ldap_lock);
 		g_free (contact_list_op);
 		if (enable_debug)
 			printf ("generating offline cache failed ... ldap handler is NULL\n");
 		return;
 	}
+	g_mutex_unlock (priv->ldap_lock);
 
 	ldap_query = e_book_backend_ldap_build_query (book_backend_ldap,
 						      "(beginswith \"file_as\" \"\")");
 
 	do {
+		g_mutex_lock (priv->ldap_lock);
 		ldap_error = ldap_search_ext (priv->ldap,
 					      priv->ldap_rootdn,
 					      priv->ldap_scope,
@@ -4398,6 +4457,7 @@ generate_cache (EBookBackendLDAP *book_b
 					      NULL, 0, NULL, NULL,
 					      NULL, /* XXX timeout */
 					      LDAP_NO_LIMIT, &contact_list_msgid);
+		g_mutex_unlock (priv->ldap_lock);
 	} while (e_book_backend_ldap_reconnect (book_backend_ldap, NULL, ldap_error));
 
 	g_free (ldap_query);
@@ -4443,7 +4503,9 @@ e_book_backend_ldap_authenticate_user (E
 		return;
 	}
 
+	g_mutex_lock (bl->priv->ldap_lock);
 	if (!bl->priv->connected || !bl->priv->ldap) {
+		g_mutex_unlock (bl->priv->ldap_lock);
 
 		status = e_book_backend_ldap_connect (bl);
 		if (status != GNOME_Evolution_Addressbook_Success) {
@@ -4451,8 +4513,8 @@ e_book_backend_ldap_authenticate_user (E
 							       opid, status);
 			return ;
 		}
-
 	}
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	if (!g_ascii_strncasecmp (auth_method, LDAP_SIMPLE_PREFIX, strlen (LDAP_SIMPLE_PREFIX))) {
 
@@ -4460,21 +4522,21 @@ e_book_backend_ldap_authenticate_user (E
 			LDAPMessage    *res, *e;
 			char *query = g_strdup_printf ("(mail=%s)", user);
 
-			g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+			g_mutex_lock (bl->priv->ldap_lock);
 			ldap_error = ldap_search_s (bl->priv->ldap,
 						    bl->priv->ldap_rootdn,
 						    bl->priv->ldap_scope,
 						    query,
 						    NULL, 0, &res);
-			g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+			g_mutex_unlock (bl->priv->ldap_lock);
 			g_free (query);
 
 			if (ldap_error == LDAP_SUCCESS) {
 				char *entry_dn;
 
-				g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+				g_mutex_lock (bl->priv->ldap_lock);
 				e = ldap_first_entry (bl->priv->ldap, res);
-				g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+				g_mutex_unlock (bl->priv->ldap_lock);
 				if (!e) {
 					g_warning ("Failed to get the DN for %s", user);
 					ldap_msgfree (res);
@@ -4484,9 +4546,9 @@ e_book_backend_ldap_authenticate_user (E
 					return;
 				}
 
-				g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+				g_mutex_lock (bl->priv->ldap_lock);
 				entry_dn = ldap_get_dn (bl->priv->ldap, e);
-				g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+				g_mutex_unlock (bl->priv->ldap_lock);
 				dn = g_strdup(entry_dn);
 
 				ldap_memfree (entry_dn);
@@ -4505,11 +4567,11 @@ e_book_backend_ldap_authenticate_user (E
 
 		/* now authenticate against the DN we were either supplied or queried for */
 		printf ("simple auth as %s\n", dn);
-		g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+		g_mutex_lock (bl->priv->ldap_lock);
 		ldap_error = ldap_simple_bind_s(bl->priv->ldap,
 						dn,
 						passwd);
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+		g_mutex_unlock (bl->priv->ldap_lock);
 		/* Some ldap servers are returning (ex active directory ones) LDAP_SERVER_DOWN
 		 * when we try to do an ldap operation  after being  idle
 		 * for some time. This error is handled by poll_ldap in case of search operations
@@ -4532,7 +4594,7 @@ e_book_backend_ldap_authenticate_user (E
 #ifdef ENABLE_SASL_BINDS
 	else if (!g_ascii_strncasecmp (auth_method, SASL_PREFIX, strlen (SASL_PREFIX))) {
 		g_print ("sasl bind (mech = %s) as %s", auth_method + strlen (SASL_PREFIX), user);
-		g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+		g_mutex_lock (bl->priv->ldap_lock);
 		ldap_error = ldap_sasl_bind_s (bl->priv->ldap,
 					       NULL,
 					       auth_method + strlen (SASL_PREFIX),
@@ -4540,7 +4602,7 @@ e_book_backend_ldap_authenticate_user (E
 					       NULL,
 					       NULL,
 					       NULL);
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+		g_mutex_unlock (bl->priv->ldap_lock);
 
 		if (ldap_error == LDAP_NOT_SUPPORTED)
 			e_data_book_respond_authenticate_user (book,
@@ -4646,10 +4708,10 @@ ldap_cancel_op(void *key, void *value, v
 	LDAPOp *op = value;
 
 	/* ignore errors, its only best effort? */
-	g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+	g_mutex_lock (bl->priv->ldap_lock);
 	if (bl->priv->ldap)
 		ldap_abandon (bl->priv->ldap, op->id);
-	g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+	g_mutex_unlock (bl->priv->ldap_lock);
 }
 
 static GNOME_Evolution_Addressbook_CallStatus
@@ -4856,10 +4918,12 @@ e_book_backend_ldap_set_mode (EBookBacke
 		e_book_backend_notify_connection_status (backend, FALSE);
 
 #if 0
+		g_mutex_lock (bl->priv->ldap_lock);
 		if (bl->priv->ldap) {
 			ldap_unbind (bl->priv->ldap);
 			bl->priv->ldap = NULL;
 		}
+		g_mutex_unlock (bl->priv->ldap_lock);
 #endif
 
 		bl->priv->connected = FALSE;
@@ -4927,10 +4991,10 @@ call_dtor (int msgid, LDAPOp *op, gpoint
 
 	bl = E_BOOK_BACKEND_LDAP (op->backend);
 
-	g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+	g_mutex_lock (bl->priv->ldap_lock);
 	if (bl->priv->ldap)
 		ldap_abandon (bl->priv->ldap, op->id);
-	g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+	g_mutex_unlock (bl->priv->ldap_lock);
 
 	op->dtor (op);
 
@@ -4951,10 +5015,11 @@ e_book_backend_ldap_dispose (GObject *ob
 		g_static_rec_mutex_unlock (&bl->priv->op_hash_mutex);
 		g_static_rec_mutex_free (&bl->priv->op_hash_mutex);
 
-		g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+		g_mutex_lock (bl->priv->ldap_lock);
 		if (bl->priv->ldap)
 			ldap_unbind (bl->priv->ldap);
-		g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+		g_mutex_unlock (bl->priv->ldap_lock);
+		g_mutex_free (bl->priv->ldap_lock);
 
 		if (bl->priv->poll_timeout != -1) {
 			g_source_remove (bl->priv->poll_timeout);
@@ -5045,6 +5110,7 @@ e_book_backend_ldap_init (EBookBackendLD
 	priv->reserved2 	     = NULL;
 	priv->reserved3 	     = NULL;
 	priv->reserved4 	     = NULL;
+	priv->ldap_lock		     = g_mutex_new ();
 	g_static_rec_mutex_init (&priv->op_hash_mutex);
 
 	backend->priv = priv;
