[evolution-patches] patch for lots of misc issues in the e-d-s ldap backend



The ChangeLog diff should be explanatory enough - this is the current
state of the ldap backend on my machine, which seems much much happier
than the backend does on other peoples' :)

Chris
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/addressbook/ChangeLog,v
retrieving revision 1.117
diff -u -r1.117 ChangeLog
--- ChangeLog	5 Apr 2004 07:07:59 -0000	1.117
+++ ChangeLog	5 Apr 2004 16:33:16 -0000
@@ -1,3 +1,44 @@
+2004-04-05  Chris Toshok  <toshok ximian com>
+
+	* backends/ldap/e-book-backend-ldap.c (struct
+	_EBookBackendLDAPPrivate): add a mutex around our it_to_op
+	GHashTable.
+	(struct _EBookBackendLDAPCursorPrivate): nuke.
+	(view_destroy): lock around access to id_to_op.
+	(add_to_supported_fields): plug leak (don't strdup the arg to
+	g_hash_table_lookup.)
+	(query_ldap_root_dse): fix c&p bugs with
+	supported_fields/supported_auth_methods.
+	(e_book_backend_ldap_connect): add a check for
+	LDAP_PARTIAL_RESULTS (which is apparently what certain versions of
+	GWIA's ldap returns when we try a root dse query.)  Also, try a v2
+	bind if the v3 bind fails.
+	(ldap_op_add): lock access to id_to_op hash.
+	(ldap_op_finished): same.
+	(create_contact_handler): add more debug spew (additional ldap
+	error info.)
+	(remove_contact_handler): same.
+	(modify_contact_modify_handler): same.
+	(modify_contact_search_handler): same.
+	(get_contact_handler): same.
+	(contact_list_handler): same.
+	(poll_ldap): lock around id_to_op.
+	(ldap_search_handler): add more spew, and just use view instead of
+	search_op->view.
+	(ldap_search_dtor): lock the book view's mutex here, and clear the
+	::search_op g_object_data.
+	(e_book_backend_ldap_search): set the book view's ::search_op.
+	(e_book_backend_ldap_start_book_view): add race detection with
+	::stop here.
+	(e_book_backend_ldap_stop_book_view): same.
+	(e_book_backend_ldap_load_source): make the default for
+	unrecognized ssl type "NO" instead of "WHENEVER".
+	(e_book_backend_ldap_dispose): lock access to id_to_op while we
+	destroy it, and free our mutex.  also free up some additional
+	private data we were leaking before (the ->ldap_host,
+	->ldap_rootdn).
+	(e_book_backend_ldap_init): init the mutex.
+
 2004-04-05  Sivaiah Nallagatla <snallagatla novell com>
 	
 	* e-book-backend-groupwise.c : added code to build groupwise filter from 
Index: backends/ldap/e-book-backend-ldap.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/addressbook/backends/ldap/e-book-backend-ldap.c,v
retrieving revision 1.13
diff -u -r1.13 e-book-backend-ldap.c
--- backends/ldap/e-book-backend-ldap.c	31 Mar 2004 17:18:34 -0000	1.13
+++ backends/ldap/e-book-backend-ldap.c	5 Apr 2004 16:33:17 -0000
@@ -25,6 +25,8 @@
 #undef LDAP_DEBUG
 #endif
 
+#define d(x) x
+
 #if LDAP_VENDOR_VERSION > 20000
 #define OPENLDAP2
 #else
@@ -75,7 +77,6 @@
 static gchar *e_book_backend_ldap_build_query (EBookBackendLDAP *bl, const char *query);
 
 static EBookBackendClass *e_book_backend_ldap_parent_class;
-typedef struct _EBookBackendLDAPCursorPrivate EBookBackendLDAPCursorPrivate;
 typedef struct LDAPOp LDAPOp;
 
 
@@ -112,17 +113,10 @@
 	gboolean evolutionPersonChecked;
 
 	/* our operations */
+	GStaticRecMutex op_hash_mutex;
 	GHashTable *id_to_op;
 	int active_ops;
-	int                   poll_timeout;
-};
-
-struct _EBookBackendLDAPCursorPrivate {
-	EBookBackend *backend;
-	EDataBook    *book;
-
-	GList      *elements;
-	long       num_elements;
+	int poll_timeout;
 };
 
 typedef void (*LDAPOpHandler)(LDAPOp *op, LDAPMessage *res);
@@ -298,6 +292,8 @@
 	EBookBackendLDAP    *bl;
 	EIterator         *iter;
 
+	d(printf ("view_destroy (%p)\n", where_object_was));
+
 	bl = E_BOOK_BACKEND_LDAP(e_data_book_get_backend(book));
 
 	iter = e_list_get_iterator (bl->priv->book_views);
@@ -316,7 +312,9 @@
 			/* and remove us as the view for any other
                            operations that might be using us to spew
                            status messages to the gui */
+			g_static_rec_mutex_lock (&bl->priv->op_hash_mutex);
 			g_hash_table_foreach (bl->priv->id_to_op, (GHFunc)remove_view, view->book_view);
+			g_static_rec_mutex_unlock (&bl->priv->op_hash_mutex);
 
 			/* free up the view structure */
 			g_free (view->search);
@@ -382,7 +380,7 @@
 {
 	int i;
 	for (i = 0; attrs[i]; i ++) {
-		char *query_prop = g_hash_table_lookup (attr_hash, g_strdup (attrs[i]));
+		char *query_prop = g_hash_table_lookup (attr_hash, attrs[i]);
 
 		if (query_prop) {
 			bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup (query_prop));
@@ -525,7 +523,7 @@
 			   (info.ldapai_vendor_version % 10000) / 1000,
 			   info.ldapai_vendor_version % 1000);
 
-		g_message ("extensions present:");
+		g_message ("library extensions present:");
 		/* yuck.  we have to free these? */
 		for (i = 0; info.ldapai_extensions[i]; i++) {
 			char *extension = info.ldapai_extensions[i];
@@ -602,11 +600,11 @@
 		bl->priv->supported_auth_methods = g_list_append (bl->priv->supported_auth_methods, auth_method);
 
 		auth_method = g_strdup_printf ("ldap/simple-email|%s", _("Using Email Address"));
-		bl->priv->supported_fields = g_list_append (bl->priv->supported_auth_methods, auth_method);
+		bl->priv->supported_auth_methods = g_list_append (bl->priv->supported_auth_methods, auth_method);
 
 		for (i = 0; values[i]; i++) {
 			auth_method = g_strdup_printf ("sasl/%s|%s", values[i], values[i]);
-			bl->priv->supported_fields = g_list_append (bl->priv->supported_auth_methods, auth_method);
+			bl->priv->supported_auth_methods = g_list_append (bl->priv->supported_auth_methods, auth_method);
 			g_message ("supported SASL mechanism: %s", values[i]);
 		}
 		ldap_value_free (values);
@@ -637,6 +635,7 @@
 e_book_backend_ldap_connect (EBookBackendLDAP *bl)
 {
 	EBookBackendLDAPPrivate *blpriv = bl->priv;
+	int protocol_version = LDAP_VERSION3;
 
 	/* close connection first if it's open first */
 	if (blpriv->ldap)
@@ -654,7 +653,8 @@
 		int ldap_error;
 
 		if (bl->priv->use_tls != E_BOOK_BACKEND_LDAP_TLS_NO) {
-			int protocol_version = LDAP_VERSION3;
+			int tls_level;
+
 			ldap_error = ldap_set_option (blpriv->ldap, LDAP_OPT_PROTOCOL_VERSION, &protocol_version);
 			if (LDAP_OPT_SUCCESS != ldap_error) {
 				g_warning ("failed to set protocol version to LDAPv3");
@@ -671,7 +671,7 @@
 			}
 
 			if (bl->priv->ldap_port == LDAPS_PORT && bl->priv->use_tls == E_BOOK_BACKEND_LDAP_TLS_ALWAYS) {
-				int tls_level = LDAP_OPT_X_TLS_HARD;
+				tls_level = LDAP_OPT_X_TLS_HARD;
 				ldap_set_option (blpriv->ldap, LDAP_OPT_X_TLS, &tls_level);
 			}
 			else if (bl->priv->use_tls) {
@@ -697,7 +697,23 @@
 		   authenticate_user) if they've selected
 		   authentication */
 		ldap_error = ldap_simple_bind_s (blpriv->ldap, NULL, NULL);
-		if (ldap_error == LDAP_SERVER_DOWN) {
+		if (ldap_error == LDAP_PROTOCOL_ERROR) {
+			g_warning ("failed to bind using v3.  trying v2.");
+			/* server doesn't support v3 binds, so let's
+			   drop it down to v2 and try again. */
+			bl->priv->ldap_v3 = FALSE;
+			
+			protocol_version = LDAP_VERSION2;
+			ldap_set_option (blpriv->ldap, LDAP_OPT_PROTOCOL_VERSION, &protocol_version);
+
+			ldap_error = ldap_simple_bind_s (blpriv->ldap, NULL, NULL);
+		}
+
+		if (ldap_error == LDAP_PROTOCOL_ERROR) {
+			g_warning ("failed to bind using either v3 or v2 binds.");
+			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);
 			return GNOME_Evolution_Addressbook_RepositoryOffline;
@@ -711,8 +727,12 @@
 		/* we can't just check for LDAP_SUCCESS here since in
 		   older servers (namely openldap1.x servers), there's
 		   not a root DSE at all, so the query will fail with
-		   LDAP_NO_SUCH_OBJECT. */
-		if (ldap_error == LDAP_SUCCESS || LDAP_NAME_ERROR (ldap_error)) {
+		   LDAP_NO_SUCH_OBJECT, and GWIA's LDAP server (which
+		   is v2 based and doesn't have a root dse) seems to
+		   fail with LDAP_PARTIAL_RESULTS. */
+		if (ldap_error == LDAP_SUCCESS 
+		    || ldap_error == LDAP_PARTIAL_RESULTS
+		    || LDAP_NAME_ERROR (ldap_error)) {
 			blpriv->connected = TRUE;
 
 			/* check to see if evolutionPerson is supported, if we can (me
@@ -781,6 +801,7 @@
 	op->handler = handler;
 	op->dtor = dtor;
 
+	g_static_rec_mutex_lock (&bl->priv->op_hash_mutex);
 	if (g_hash_table_lookup (bl->priv->id_to_op, &op->id)) {
 		g_warning ("conflicting ldap msgid's");
 	}
@@ -794,6 +815,8 @@
 		bl->priv->poll_timeout = g_timeout_add (LDAP_POLL_INTERVAL,
 							(GSourceFunc) poll_ldap,
 							bl);
+
+	g_static_rec_mutex_unlock (&bl->priv->op_hash_mutex);
 }
 
 static void
@@ -802,6 +825,7 @@
 	EBookBackend *backend = op->backend;
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend);
 
+	g_static_rec_mutex_lock (&bl->priv->op_hash_mutex);
 	g_hash_table_remove (bl->priv->id_to_op, &op->id);
 
 	/* should handle errors here */
@@ -816,6 +840,7 @@
 			g_source_remove (bl->priv->poll_timeout);
 		bl->priv->poll_timeout = -1;
 	}
+	g_static_rec_mutex_unlock (&bl->priv->op_hash_mutex);
 }
 
 static void
@@ -824,12 +849,14 @@
 	EBookBackend *backend = op->backend;
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend);
 
+	g_static_rec_mutex_lock (&bl->priv->op_hash_mutex);
 	g_hash_table_remove (bl->priv->id_to_op, &op->id);
 
 	op->id = msg_id;
 
 	g_hash_table_insert (bl->priv->id_to_op,
 			     &op->id, op);
+	g_static_rec_mutex_unlock (&bl->priv->op_hash_mutex);
 }
 
 static int
@@ -1121,6 +1148,7 @@
 	LDAPCreateOp *create_op = (LDAPCreateOp*)op;
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (op->backend);
 	LDAP *ldap = bl->priv->ldap;
+	char *ldap_error_msg;
 	int ldap_error;
 	int response;
 
@@ -1134,13 +1162,19 @@
 	}
 
 	ldap_parse_result (ldap, res, &ldap_error,
-			   NULL, NULL, NULL, NULL, 0);
+			   NULL, &ldap_error_msg, NULL, NULL, 0);
+	if (ldap_error != LDAP_SUCCESS) {
+		g_warning ("create_contact_handler: %02X (%s), additional info: %s",
+			   ldap_error,
+			   ldap_err2string (ldap_error), ldap_error_msg);
+	}
+	ldap_memfree (ldap_error_msg);
 
 	/* and lastly respond */
 	response = ldap_error_to_response (ldap_error);
 	e_data_book_respond_create (op->book,
-				 response,
-				 create_op->new_contact);
+				    response,
+				    create_op->new_contact);
 
 	ldap_op_finished (op);
 }
@@ -1283,6 +1317,7 @@
 {
 	LDAPRemoveOp *remove_op = (LDAPRemoveOp*)op;
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (op->backend);
+	char *ldap_error_msg;
 	int ldap_error;
 	GList *ids = NULL;
 
@@ -1296,7 +1331,13 @@
 	}
 
 	ldap_parse_result (bl->priv->ldap, res, &ldap_error,
-			   NULL, NULL, NULL, NULL, 0);
+			   NULL, &ldap_error_msg, NULL, NULL, 0);
+	if (ldap_error != LDAP_SUCCESS) {
+		g_warning ("remove_contact_handler: %02X (%s), additional info: %s",
+			   ldap_error,
+			   ldap_err2string (ldap_error), ldap_error_msg);
+	}
+	ldap_memfree (ldap_error_msg);
 
 	ids = g_list_append (ids, remove_op->id);
 	e_data_book_respond_remove_contacts (remove_op->op.book,
@@ -1383,6 +1424,7 @@
 	LDAPModifyOp *modify_op = (LDAPModifyOp*)op;
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (op->backend);
 	LDAP *ldap = bl->priv->ldap;
+	char *ldap_error_msg;
 	int ldap_error;
 
 	if (LDAP_RES_MODIFY != ldap_msgtype (res)) {
@@ -1395,7 +1437,13 @@
 	}
 
 	ldap_parse_result (ldap, res, &ldap_error,
-			   NULL, NULL, NULL, NULL, 0);
+			   NULL, &ldap_error_msg, NULL, NULL, 0);
+	if (ldap_error != LDAP_SUCCESS) {
+		g_warning ("modify_contact_handler: %02X (%s), additional info: %s",
+			   ldap_error,
+			   ldap_err2string (ldap_error), ldap_error_msg);
+	}
+	ldap_memfree (ldap_error_msg);
 
 	/* and lastly respond */
 	e_data_book_respond_modify (op->book,
@@ -1433,6 +1481,7 @@
 								       &modify_op->existing_objectclasses);
 	}
 	else if (msg_type == LDAP_RES_SEARCH_RESULT) {
+		char *ldap_error_msg;
 		int ldap_error;
 		LDAPMod **ldap_mods;
 		GPtrArray *mod_array;
@@ -1443,7 +1492,13 @@
 		/* grab the result code, and set up the actual modify
                    if it was successful */
 		ldap_parse_result (bl->priv->ldap, res, &ldap_error,
-				   NULL, NULL, NULL, NULL, 0);
+				   NULL, &ldap_error_msg, NULL, NULL, 0);
+		if (ldap_error != LDAP_SUCCESS) {
+			g_warning ("modify_contact_search_handler: %02X (%s), additional info: %s",
+				   ldap_error,
+				   ldap_err2string (ldap_error), ldap_error_msg);
+		}
+		ldap_memfree (ldap_error_msg);
 
 		if (ldap_error != LDAP_SUCCESS) {
 			/* more here i'm sure */
@@ -1600,9 +1655,17 @@
 		ldap_op_finished (op);
 	}
 	else if (msg_type == LDAP_RES_SEARCH_RESULT) {
+		char *ldap_error_msg;
 		int ldap_error;
 		ldap_parse_result (bl->priv->ldap, res, &ldap_error,
-				   NULL, NULL, NULL, NULL, 0);
+				   NULL, &ldap_error_msg, NULL, NULL, 0);
+		if (ldap_error != LDAP_SUCCESS) {
+			g_warning ("get_contact_handler: %02X (%s), additional info: %s",
+				   ldap_error,
+				   ldap_err2string (ldap_error), ldap_error_msg);
+		}
+		ldap_memfree (ldap_error_msg);
+
 		e_data_book_respond_get_contact (op->book, ldap_error_to_response (ldap_error), "");
 		ldap_op_finished (op);
 	}
@@ -1692,10 +1755,17 @@
 		}
 	}
 	else if (msg_type == LDAP_RES_SEARCH_RESULT) {
+		char *ldap_error_msg;
 		int ldap_error;
 
 		ldap_parse_result (ldap, res, &ldap_error,
-				   NULL, NULL, NULL, NULL, 0);
+				   NULL, &ldap_error_msg, NULL, NULL, 0);
+		if (ldap_error != LDAP_SUCCESS) {
+			g_warning ("contact_list_handler: %02X (%s), additional info: %s",
+				   ldap_error,
+				   ldap_err2string (ldap_error), ldap_error_msg);
+		}
+		ldap_memfree (ldap_error_msg);
 
 		g_warning ("search returned %d\n", ldap_error);
 
@@ -2623,6 +2693,8 @@
 	LDAPOp op;
 	EDataBookView *view;
 
+	/* used to detect problems with start/stop_book_view racing */
+	gboolean aborted;
 	/* used by search_handler to only send the status messages once */
 	gboolean notified_receiving_results;
 } LDAPSearchOp;
@@ -2739,13 +2811,20 @@
 			int msgid = ldap_msgid (res);
 			LDAPOp *op;
 
+			g_static_rec_mutex_lock (&bl->priv->op_hash_mutex);
 			op = g_hash_table_lookup (bl->priv->id_to_op, &msgid);
 
+			d(printf ("looked up msgid %d, got op %p\n", msgid, op));
+
 			if (op)
 				op->handler (op, res);
 			else
 				g_warning ("unknown operation, msgid = %d", msgid);
 
+			/* XXX should the call to op->handler be
+			   protected by the lock? */
+			g_static_rec_mutex_unlock (&bl->priv->op_hash_mutex);
+
 			ldap_msgfree(res);
 		}
 	}
@@ -2763,6 +2842,8 @@
 	LDAPMessage *e;
 	int msg_type;
 
+	d(printf ("ldap_search_handler (%p)\n", view));
+
 	bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view)), NULL);
 
 	if (!search_op->notified_receiving_results) {
@@ -2785,28 +2866,34 @@
 		}
 	}
 	else if (msg_type == LDAP_RES_SEARCH_RESULT) {
+		char *ldap_error_msg;
 		int ldap_error;
 
 		ldap_parse_result (ldap, res, &ldap_error,
-				   NULL, NULL, NULL, NULL, 0);
-
-		g_warning ("search returned %d\n", ldap_error);
+				   NULL, &ldap_error_msg, NULL, NULL, 0);
+		if (ldap_error != LDAP_SUCCESS) {
+			g_warning ("ldap_search_handler: %02X (%s), additional info: %s",
+				   ldap_error,
+				   ldap_err2string (ldap_error), ldap_error_msg);
+		}
+		ldap_memfree (ldap_error_msg);
 
 		if (ldap_error == LDAP_TIMELIMIT_EXCEEDED)
-			e_data_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_SearchTimeLimitExceeded);
+			e_data_book_view_notify_complete (view, GNOME_Evolution_Addressbook_SearchTimeLimitExceeded);
 		else if (ldap_error == LDAP_SIZELIMIT_EXCEEDED)
-			e_data_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_SearchSizeLimitExceeded);
+			e_data_book_view_notify_complete (view, GNOME_Evolution_Addressbook_SearchSizeLimitExceeded);
 		else if (ldap_error == LDAP_SUCCESS)
-			e_data_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_Success);
+			e_data_book_view_notify_complete (view, GNOME_Evolution_Addressbook_Success);
 		else
-			e_data_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_OtherError);
+			e_data_book_view_notify_complete (view, GNOME_Evolution_Addressbook_OtherError);
 
 		ldap_op_finished (op);
 	}
 	else {
 		g_warning ("unhandled search result type %d returned", msg_type);
-		e_data_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_OtherError);
+		e_data_book_view_notify_complete (view, GNOME_Evolution_Addressbook_OtherError);
 		ldap_op_finished (op);
+
 	}
 
 
@@ -2818,11 +2905,14 @@
 {
 	LDAPSearchOp *search_op = (LDAPSearchOp*) op;
 
-#if notyet
-	/* unhook us from our EBookBackendLDAPBookView */
-	if (search_op->view)
-		search_op->view->search_op = NULL;
-#endif
+	g_mutex_lock (e_data_book_view_get_mutex (search_op->view));
+
+	d(printf ("ldap_search_dtor (%p)\n", search_op->view));
+
+	/* unhook us from our EDataBookView */
+	g_object_set_data (G_OBJECT (search_op->view), "EBookBackendLDAP.BookView::search_op", NULL);
+
+	g_mutex_unlock (e_data_book_view_get_mutex (search_op->view));
 
 	g_free (search_op);
 }
@@ -2871,16 +2961,15 @@
 		else {
 			LDAPSearchOp *op = g_new0 (LDAPSearchOp, 1);
 
-			op->view = view;
+			d(printf ("adding search_op (%p, %d)\n", view, search_msgid));
 
-#if notyet
-			view->search_op = (LDAPOp*)op;
-#endif
+			op->view = view;
 
 			ldap_op_add ((LDAPOp*)op, E_BOOK_BACKEND(bl), book, view,
 				     search_msgid,
 				     ldap_search_handler, ldap_search_dtor);
-			
+
+			g_object_set_data (G_OBJECT (view), "EBookBackendLDAP.BookView::search_op", op);
 		}
 		return;
 	}
@@ -2897,15 +2986,53 @@
 				     EDataBookView *view)
 {
 	EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend);
+	LDAPSearchOp *op;
+
+	d(printf ("start_book_view (%p)\n", view));
+
+	g_mutex_lock (e_data_book_view_get_mutex (view));
+
+	op = g_object_get_data (G_OBJECT (view), "EBookBackendLDAP.BookView::search_op");
 
-	e_book_backend_ldap_search (bl, NULL /* XXX ugh */, view);
+	if (op) {
+		/* the only way op can be set here is if we raced with
+		   stop_book_view and lost.  make sure by checking
+		   op->aborted. */
+		if (!op->aborted) {
+			g_warning ("lost race with stop_book_view, but op->aborted != TRUE");
+		}
+
+		g_free (op);
+		g_object_set_data (G_OBJECT (view), "EBookBackendLDAP.BookView::search_op", NULL);
+	}
+	else {
+		e_book_backend_ldap_search (bl, NULL /* XXX ugh */, view);
+	}
+
+	g_mutex_unlock (e_data_book_view_get_mutex (view));
 }
 
 static void
 e_book_backend_ldap_stop_book_view (EBookBackend  *backend,
 				    EDataBookView *view)
 {
-	/* FIXME we don't stop them... */
+	LDAPSearchOp *op;
+
+	d(printf ("stop_book_view (%p)\n", view));
+
+	g_mutex_lock (e_data_book_view_get_mutex (view));
+
+	op = g_object_get_data (G_OBJECT (view), "EBookBackendLDAP.BookView::search_op");
+	if (op) {
+		ldap_op_finished ((LDAPOp*)op);
+	}
+	else {
+		op = g_new0 (LDAPSearchOp, 1);
+		op->aborted = TRUE;
+		g_object_set_data (G_OBJECT (view), "EBookBackendLDAP.BookView::search_op", op);
+	}
+
+	g_mutex_unlock (e_data_book_view_get_mutex (view));
 }
 
 static void
@@ -3079,7 +3206,7 @@
 			g_warning ("Unhandled value for 'ssl', not using it.");
 	}
 	else
-		bl->priv->use_tls = E_BOOK_BACKEND_LDAP_TLS_WHEN_POSSIBLE;
+		bl->priv->use_tls = E_BOOK_BACKEND_LDAP_TLS_NO;
 
 	str = e_source_get_property (source, "timeout");
 	if (str)
@@ -3162,8 +3289,11 @@
 	bl = E_BOOK_BACKEND_LDAP (object);
 
 	if (bl->priv) {
+		g_static_rec_mutex_lock (&bl->priv->op_hash_mutex);
 		g_hash_table_foreach_remove (bl->priv->id_to_op, (GHRFunc)call_dtor, NULL);
 		g_hash_table_destroy (bl->priv->id_to_op);
+		g_static_rec_mutex_unlock (&bl->priv->op_hash_mutex);
+		g_static_rec_mutex_free (&bl->priv->op_hash_mutex);
 
 		if (bl->priv->poll_timeout != -1) {
 			printf ("removing timeout\n");
@@ -3180,6 +3310,9 @@
 			g_list_free (bl->priv->supported_auth_methods);
 		}
 
+		g_free (bl->priv->ldap_host);
+		g_free (bl->priv->ldap_rootdn);
+		
 		g_free (bl->priv);
 		bl->priv = NULL;
 	}
@@ -3232,6 +3365,8 @@
 	priv->ldap_limit       	     = 100;
 	priv->id_to_op         	     = g_hash_table_new (g_int_hash, g_int_equal);
 	priv->poll_timeout     	     = -1;
+
+	g_static_rec_mutex_init (&priv->op_hash_mutex);
 
 	backend->priv = priv;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]