[evolution-data-server] Bug #665381 - LDAP backend crash when query_ldap_root_dse() fails
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug #665381 - LDAP backend crash when query_ldap_root_dse() fails
- Date: Fri, 20 Apr 2012 08:33:44 +0000 (UTC)
commit 3f820b76ee39aff977a2c6bb93ba01021e19e0ce
Author: Milan Crha <mcrha redhat com>
Date: Fri Apr 20 10:33:21 2012 +0200
Bug #665381 - LDAP backend crash when query_ldap_root_dse() fails
addressbook/backends/ldap/e-book-backend-ldap.c | 93 ++++++++++++++--------
libedataserverui/e-client-utils.c | 7 ++
2 files changed, 66 insertions(+), 34 deletions(-)
---
diff --git a/addressbook/backends/ldap/e-book-backend-ldap.c b/addressbook/backends/ldap/e-book-backend-ldap.c
index 7e7548a..bf8478e 100644
--- a/addressbook/backends/ldap/e-book-backend-ldap.c
+++ b/addressbook/backends/ldap/e-book-backend-ldap.c
@@ -833,8 +833,8 @@ query_ldap_root_dse (EBookBackendLDAP *bl)
return LDAP_SUCCESS;
}
-static GError *
-e_book_backend_ldap_connect (EBookBackendLDAP *bl)
+static gboolean
+e_book_backend_ldap_connect (EBookBackendLDAP *bl, GError **error)
{
EBookBackendLDAPPrivate *blpriv = bl->priv;
gint protocol_version = LDAP_VERSION3;
@@ -891,7 +891,8 @@ e_book_backend_ldap_connect (EBookBackendLDAP *bl)
ldap_unbind (blpriv->ldap);
blpriv->ldap = NULL;
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
- return EDB_ERROR (TLS_NOT_AVAILABLE);
+ g_propagate_error (error, EDB_ERROR (TLS_NOT_AVAILABLE));
+ return FALSE;
}
if (bl->priv->ldap_port == LDAPS_PORT && bl->priv->use_tls == E_BOOK_BACKEND_LDAP_TLS_ALWAYS) {
@@ -941,7 +942,8 @@ e_book_backend_ldap_connect (EBookBackendLDAP *bl)
ldap_unbind (blpriv->ldap);
blpriv->ldap = NULL;
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
- return EDB_ERROR (TLS_NOT_AVAILABLE);
+ g_propagate_error (error, EDB_ERROR (TLS_NOT_AVAILABLE));
+ return FALSE;
}
else {
g_message ("TLS not available (ldap_error 0x%02x)", ldap_error);
@@ -970,18 +972,33 @@ e_book_backend_ldap_connect (EBookBackendLDAP *bl)
if (ldap_error == LDAP_PROTOCOL_ERROR) {
g_warning ("failed to bind using either v3 or v2 binds.");
+ if (blpriv->ldap) {
+ ldap_unbind (blpriv->ldap);
+ blpriv->ldap = NULL;
+ }
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
- return e_data_book_create_error (E_DATA_BOOK_STATUS_OTHER_ERROR, "Failed to bind using either v3 or v2 binds");
+ g_propagate_error (error, e_data_book_create_error (E_DATA_BOOK_STATUS_OTHER_ERROR, "Failed to bind using either v3 or v2 binds"));
+ return FALSE;
}
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);
+ if (blpriv->ldap) {
+ ldap_unbind (blpriv->ldap);
+ blpriv->ldap = NULL;
+ }
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
- return EDB_ERROR (REPOSITORY_OFFLINE);
+ g_propagate_error (error, EDB_ERROR (REPOSITORY_OFFLINE));
+ return FALSE;
} else if (ldap_error == LDAP_INVALID_CREDENTIALS) {
g_warning ("Invalid credentials while connecting (ldap_error 0x%02x)", ldap_error);
+ if (blpriv->ldap) {
+ ldap_unbind (blpriv->ldap);
+ blpriv->ldap = NULL;
+ }
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
- return EDB_ERROR (AUTHENTICATION_FAILED);
+ g_propagate_error (error, EDB_ERROR (AUTHENTICATION_FAILED));
+ return FALSE;
}
if (ldap_error == LDAP_INSUFFICIENT_ACCESS)
@@ -1018,17 +1035,28 @@ e_book_backend_ldap_connect (EBookBackendLDAP *bl)
printf("e_book_backend_ldap_connect took %ld.%03ld seconds\n",
diff / 1000,diff % 1000);
}
- return EDB_ERROR (SUCCESS);
+ return TRUE;
} else if (ldap_error == LDAP_UNWILLING_TO_PERFORM) {
- e_book_backend_notify_auth_required (E_BOOK_BACKEND (bl), TRUE, NULL);
+ if (blpriv->ldap) {
+ ldap_unbind (blpriv->ldap);
+ blpriv->ldap = NULL;
+ }
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
- return EDB_ERROR (SUCCESS);
+ g_propagate_error (error, EDB_ERROR (AUTHENTICATION_FAILED));
+ return FALSE;
} else {
+ if (blpriv->ldap) {
+ ldap_unbind (blpriv->ldap);
+ blpriv->ldap = NULL;
+ }
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
g_warning ("Failed to perform root dse query anonymously, (ldap_error 0x%02x)", ldap_error);
}
- }
- else {
+ } else {
+ if (blpriv->ldap) {
+ ldap_unbind (blpriv->ldap);
+ blpriv->ldap = NULL;
+ }
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
}
@@ -1038,7 +1066,8 @@ e_book_backend_ldap_connect (EBookBackendLDAP *bl)
blpriv->ldap_port,
blpriv->ldap_rootdn ? blpriv->ldap_rootdn : "");
blpriv->connected = FALSE;
- return EDB_ERROR (REPOSITORY_OFFLINE);
+ g_propagate_error (error, EDB_ERROR (REPOSITORY_OFFLINE));
+ return FALSE;
}
static gboolean
@@ -1065,18 +1094,16 @@ e_book_backend_ldap_reconnect (EBookBackendLDAP *bl,
/* we need to reconnect if we were previously connected */
if (bl->priv->connected && ldap_status == LDAP_SERVER_DOWN) {
- GError *error;
+ GError *error = NULL;
gint ldap_error = LDAP_SUCCESS;
book_view_notify_status (bl, book_view, _("Reconnecting to LDAP server..."));
- error = e_book_backend_ldap_connect (bl);
-
- if (error) {
+ if (!e_book_backend_ldap_connect (bl, &error)) {
book_view_notify_status (bl, book_view, "");
if (enable_debug)
printf ("e_book_backend_ldap_reconnect ... failed (server down?)\n");
- g_error_free (error);
+ g_clear_error (&error);
return FALSE;
}
@@ -5194,13 +5221,13 @@ e_book_backend_ldap_authenticate_user (EBookBackend *backend,
printf ("simple auth as %s\n", dn);
g_static_rec_mutex_lock (&eds_ldap_handler_lock);
if (!bl->priv->connected || !bl->priv->ldap) {
- GError *error;
+ GError *error = NULL;
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
- error = e_book_backend_ldap_connect (bl);
- if (error) {
- e_book_backend_notify_opened (backend, error);
+ if (!e_book_backend_ldap_connect (bl, &error)) {
+ if (error)
+ e_book_backend_notify_opened (backend, error);
return;
}
}
@@ -5229,13 +5256,13 @@ e_book_backend_ldap_authenticate_user (EBookBackend *backend,
g_print ("sasl bind (mech = %s) as %s", auth_method + strlen (SASL_PREFIX), user);
g_static_rec_mutex_lock (&eds_ldap_handler_lock);
if (!bl->priv->connected || !bl->priv->ldap) {
- GError *error;
+ GError *error = NULL;
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
- error = e_book_backend_ldap_connect (bl);
- if (error) {
- e_book_backend_notify_opened (backend, error);
+ if (!e_book_backend_ldap_connect (bl)) {
+ if (error)
+ e_book_backend_notify_opened (backend, error);
return;
}
}
@@ -5325,7 +5352,7 @@ e_book_backend_ldap_open (EBookBackend *backend,
const gchar *str;
const gchar *offline;
gchar *filename;
- GError *err;
+ GError *err = NULL;
gboolean auth_required;
g_assert (bl->priv->connected == FALSE);
@@ -5440,8 +5467,7 @@ e_book_backend_ldap_open (EBookBackend *backend,
}
/* Online */
- err = e_book_backend_ldap_connect (bl);
- if (err) {
+ if (!e_book_backend_ldap_connect (bl, &err)) {
if (enable_debug)
printf ("%s ... failed to connect to server \n", G_STRFUNC);
e_book_backend_respond_opened (backend, book, opid, err);
@@ -5615,13 +5641,12 @@ e_book_backend_ldap_notify_online_cb (EBookBackend *backend,
e_book_backend_notify_online (backend, TRUE);
if (e_book_backend_is_opened (backend)) {
- GError *error;
+ GError *error = NULL;
- error = e_book_backend_ldap_connect (bl);
- e_book_backend_notify_auth_required (backend, TRUE, NULL);
+ if (e_book_backend_ldap_connect (bl, &error))
+ e_book_backend_notify_auth_required (backend, TRUE, NULL);
- if (error)
- g_error_free (error);
+ g_clear_error (&error);
#if 0
start_views (backend);
#endif
diff --git a/libedataserverui/e-client-utils.c b/libedataserverui/e-client-utils.c
index 3784535..0fb44ae 100644
--- a/libedataserverui/e-client-utils.c
+++ b/libedataserverui/e-client-utils.c
@@ -479,6 +479,7 @@ client_utils_open_new_done (EClientUtilsAsyncOpData *async_data)
}
static gboolean client_utils_retry_open_timeout_cb (gpointer user_data);
+static void client_utils_opened_cb (EClient *client, const GError *error, EClientUtilsAsyncOpData *async_data);
static void
finish_or_retry_open (EClientUtilsAsyncOpData *async_data,
@@ -487,6 +488,9 @@ finish_or_retry_open (EClientUtilsAsyncOpData *async_data,
g_return_if_fail (async_data != NULL);
if (async_data->auth_handler && error && g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_AUTHENTICATION_FAILED)) {
+ /* reconnect to the signal */
+ g_signal_connect (async_data->client, "opened", G_CALLBACK (client_utils_opened_cb), async_data);
+
if (async_data->used_credentials) {
const gchar *prompt_key;
@@ -579,6 +583,9 @@ client_utils_retry_open_timeout_cb (gpointer user_data)
g_signal_handlers_disconnect_matched (async_data->cancellable, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, async_data);
+ /* reconnect to the signal */
+ g_signal_connect (async_data->client, "opened", G_CALLBACK (client_utils_opened_cb), async_data);
+
e_client_open (async_data->client, async_data->only_if_exists, async_data->cancellable, client_utils_open_new_async_cb, async_data);
async_data->retry_open_id = 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]