[libgda] LDAP provider: close connection when not used



commit 59ca7a63003acee283db7f2bd192c43f082b2281
Author: Vivien Malerba <malerba gnome-db org>
Date:   Sat Apr 28 19:18:22 2012 +0200

    LDAP provider: close connection when not used
    
    to avoid keeping an opened connection to the server if not
    necessary

 providers/ldap/gda-ldap-provider.c       |   45 +++++++++++++++--
 providers/ldap/gda-ldap-util.c           |   35 ++++++++++--
 providers/ldap/gda-ldap.h                |    6 ++-
 providers/ldap/gdaprov-data-model-ldap.c |   83 +++++++++++++++++++++++++----
 4 files changed, 146 insertions(+), 23 deletions(-)
---
diff --git a/providers/ldap/gda-ldap-provider.c b/providers/ldap/gda-ldap-provider.c
index 416f8f9..fe8c09c 100644
--- a/providers/ldap/gda-ldap-provider.c
+++ b/providers/ldap/gda-ldap-provider.c
@@ -501,6 +501,7 @@ gda_ldap_provider_open_connection (GdaServerProvider *provider, GdaConnection *c
         }
 
 	cdata = g_new0 (LdapConnectionData, 1);
+	cdata->keep_bound_count = 0;
 	cdata->handle = ld;
 	cdata->url = url;
 	cdata->time_limit = 0;
@@ -590,16 +591,46 @@ gda_ldap_provider_open_connection (GdaServerProvider *provider, GdaConnection *c
                 return FALSE;
         }
 
+	gda_ldap_may_unbind (cdata);
 	return TRUE;
 }
 
 /*
+ * Unbinds the connection if possible (i.e. if cdata->keep_bound_count is 0)
+ * This allows to avoid keeping the connection to the LDAP server if unused
+ */
+void
+gda_ldap_may_unbind (LdapConnectionData *cdata)
+{
+	if (!cdata || (cdata->keep_bound_count > 0))
+		return;
+	if (cdata->handle) {
+                ldap_unbind_ext (cdata->handle, NULL, NULL);
+		cdata->handle = NULL;
+	}
+}
+
+/*
+ * Makes sure the connection is opened
+ */
+gboolean
+gda_ldap_ensure_bound (LdapConnectionData *cdata, GError **error)
+{
+	if (!cdata)
+		return FALSE;
+	else if (cdata->handle)
+		return TRUE;
+
+	return gda_ldap_rebind (cdata, error);
+}
+
+/*
  * Reopens a connection after the server has closed it (possibly because of a timeout)
  *
  * If it fails, then @cdata is left unchanged, otherwise it is modified to be useable again.
  */
 gboolean
-gda_ldap_silently_rebind (LdapConnectionData *cdata)
+gda_ldap_rebind (LdapConnectionData *cdata, GError **error)
 {
 	if (!cdata)
 		return FALSE;
@@ -608,8 +639,11 @@ gda_ldap_silently_rebind (LdapConnectionData *cdata)
 	LDAP *ld;
 	int res;
 	res = ldap_initialize (&ld, cdata->url);
-	if (res != LDAP_SUCCESS)
+	if (res != LDAP_SUCCESS) {
+		g_set_error (error, GDA_CONNECTION_ERROR, GDA_CONNECTION_OPEN_ERROR,
+			     "%s", ldap_err2string (res));
 		return FALSE;
+	}
 
 	/* set protocol version to 3 by default */
 	int version = LDAP_VERSION3;
@@ -620,6 +654,8 @@ gda_ldap_silently_rebind (LdapConnectionData *cdata)
 			res = ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version);
 		}
 		if (res != LDAP_SUCCESS) {
+			g_set_error (error, GDA_CONNECTION_ERROR, GDA_CONNECTION_OPEN_ERROR,
+				     "%s", ldap_err2string (res));
 			ldap_unbind_ext (ld, NULL, NULL);
 			return FALSE;
 		}
@@ -634,6 +670,8 @@ gda_ldap_silently_rebind (LdapConnectionData *cdata)
         cred.bv_val = pwd && *pwd ? (char *) pwd : NULL;
 	res = ldap_sasl_bind_s (ld, cdata->user, NULL, &cred, NULL, NULL, NULL);
 	if (res != LDAP_SUCCESS) {
+		g_set_error (error, GDA_CONNECTION_ERROR, GDA_CONNECTION_OPEN_ERROR,
+			     "%s", ldap_err2string (res));
 		ldap_unbind_ext (ld, NULL, NULL);
                 return FALSE;
 	}
@@ -700,8 +738,7 @@ gda_ldap_provider_get_database (GdaServerProvider *provider, GdaConnection *cnc)
         cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc));
         if (!cdata)
                 return NULL;
-        TO_IMPLEMENT;
-        return NULL;
+        return cdata->base_dn;
 }
 
 /*
diff --git a/providers/ldap/gda-ldap-util.c b/providers/ldap/gda-ldap-util.c
index 1fd722d..229864c 100644
--- a/providers/ldap/gda-ldap-util.c
+++ b/providers/ldap/gda-ldap-util.c
@@ -556,13 +556,17 @@ gdaprov_ldap_get_class_info (GdaLdapConnection *cnc, const gchar *classname)
 	char *schema_attrs[] = {"objectClasses", NULL};
 	
 	/* look for subschema */
+	if (! gda_ldap_ensure_bound (cdata, NULL))
+		return NULL;
 	res = ldap_search_ext_s (cdata->handle, "", LDAP_SCOPE_BASE,
 				 "(objectclass=*)",
 				 subschemasubentry, 0,
 				 NULL, NULL, NULL, 0,
 				 &msg);
-	if (res != LDAP_SUCCESS)
+	if (res != LDAP_SUCCESS) {
+		gda_ldap_may_unbind (cdata);
 		return NULL;
+	}
 
 	if ((entry = ldap_first_entry (cdata->handle, msg))) {
 		char *attr;
@@ -580,8 +584,10 @@ gdaprov_ldap_get_class_info (GdaLdapConnection *cnc, const gchar *classname)
 	}
 	ldap_msgfree (msg);
 
-	if (! subschema)
+	if (! subschema) {
+		gda_ldap_may_unbind (cdata);
 		return NULL;
+	}
 
 	/* look for attributeTypes */
 	res = ldap_search_ext_s (cdata->handle, subschema, LDAP_SCOPE_BASE,
@@ -590,8 +596,10 @@ gdaprov_ldap_get_class_info (GdaLdapConnection *cnc, const gchar *classname)
 				 NULL, NULL, NULL, 0,
 				 &msg);
 	g_free (subschema);
-	if (res != LDAP_SUCCESS)
+	if (res != LDAP_SUCCESS) {
+		gda_ldap_may_unbind (cdata);
 		return NULL;
+	}
 
 	GHashTable *h_refs;
 	h_refs = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_strfreev);
@@ -716,6 +724,7 @@ gdaprov_ldap_get_class_info (GdaLdapConnection *cnc, const gchar *classname)
 	g_hash_table_destroy (h_refs);
 
 	retval = g_hash_table_lookup (cdata->classes_hash, classname);
+	gda_ldap_may_unbind (cdata);
 	return retval;
 }
 
@@ -1199,6 +1208,10 @@ gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **e
         if (!cdata)
                 return NULL;
 
+
+	if (! gda_ldap_ensure_bound (cdata, error))
+		return NULL;
+
 	int res;
 	LDAPMessage *msg = NULL;
 	const gchar *real_dn;
@@ -1221,6 +1234,7 @@ gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **e
 		nb_entries = ldap_count_entries (cdata->handle, msg);
 		if (nb_entries == 0) {
 			ldap_msgfree (msg);
+			gda_ldap_may_unbind (cdata);
 			return NULL;
 		}
 		else if (nb_entries > 1) {
@@ -1228,6 +1242,7 @@ gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **e
 				     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
 				     _("LDAP server returned more than one entry with DN '%s'"),
 				     real_dn);
+			gda_ldap_may_unbind (cdata);
 			return NULL;
 		}
 
@@ -1278,12 +1293,13 @@ gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **e
 			lentry->nb_attributes = array->len;
 			g_array_free (array, FALSE);
 		}
+		gda_ldap_may_unbind (cdata);
 		return lentry;
 	}
 	case LDAP_SERVER_DOWN: {
 		gint i;
 		for (i = 0; i < 5; i++) {
-			if (gda_ldap_silently_rebind (cdata))
+			if (gda_ldap_rebind (cdata, NULL))
 				goto retry;
 			g_usleep (G_USEC_PER_SEC * 2);
 		}
@@ -1294,6 +1310,7 @@ gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **e
 		ldap_get_option (cdata->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
 		g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_OTHER_ERROR,
 			     "%s", ldap_err2string(ldap_errno));
+		gda_ldap_may_unbind (cdata);
 		return NULL;
 	}
 	}
@@ -1309,7 +1326,8 @@ entry_array_sort_func (gconstpointer a, gconstpointer b)
 }
 
 GdaLdapEntry **
-gdaprov_ldap_get_entry_children (GdaLdapConnection *cnc, const gchar *dn, gchar **attributes, GError **error)
+gdaprov_ldap_get_entry_children (GdaLdapConnection *cnc, const gchar *dn, gchar **attributes,
+				 GError **error)
 {
 	LdapConnectionData *cdata;
 	g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), NULL);
@@ -1319,6 +1337,9 @@ gdaprov_ldap_get_entry_children (GdaLdapConnection *cnc, const gchar *dn, gchar
         if (!cdata)
                 return NULL;
 
+	if (! gda_ldap_ensure_bound (cdata, error))
+		return NULL;
+
 	int res;
 	LDAPMessage *msg = NULL;
  retry:
@@ -1414,6 +1435,7 @@ gdaprov_ldap_get_entry_children (GdaLdapConnection *cnc, const gchar *dn, gchar
 			g_array_append_val (children, lentry);
 		}
 		ldap_msgfree (msg);
+		gda_ldap_may_unbind (cdata);
 		if (children) {
 			g_array_sort (children, (GCompareFunc) entry_array_sort_func);
 			return (GdaLdapEntry**) g_array_free (children, FALSE);
@@ -1424,7 +1446,7 @@ gdaprov_ldap_get_entry_children (GdaLdapConnection *cnc, const gchar *dn, gchar
 	case LDAP_SERVER_DOWN: {
 		gint i;
 		for (i = 0; i < 5; i++) {
-			if (gda_ldap_silently_rebind (cdata))
+			if (gda_ldap_rebind (cdata, NULL))
 				goto retry;
 			g_usleep (G_USEC_PER_SEC * 2);
 		}
@@ -1435,6 +1457,7 @@ gdaprov_ldap_get_entry_children (GdaLdapConnection *cnc, const gchar *dn, gchar
 		ldap_get_option (cdata->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
 		g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_OTHER_ERROR,
 			     "%s", ldap_err2string(ldap_errno));
+		gda_ldap_may_unbind (cdata);
 		return NULL;
 	}
 	}
diff --git a/providers/ldap/gda-ldap.h b/providers/ldap/gda-ldap.h
index bbd4388..baff245 100644
--- a/providers/ldap/gda-ldap.h
+++ b/providers/ldap/gda-ldap.h
@@ -36,7 +36,9 @@
  * Provider's specific connection data
  */
 typedef struct {
+	guint         keep_bound_count; /* set to >0 if connection must remain opened */
 	LDAP         *handle;
+
 	gchar        *base_dn;
 	gchar        *server_version;
 	gchar        *url;
@@ -53,6 +55,8 @@ typedef struct {
 	GHashTable   *classes_hash; /* key = class name, value = a #LdapClass */
 } LdapConnectionData;
 
-gboolean gda_ldap_silently_rebind (LdapConnectionData *cdata);
+void     gda_ldap_may_unbind (LdapConnectionData *cdata);
+gboolean gda_ldap_ensure_bound (LdapConnectionData *cdata, GError **error);
+gboolean gda_ldap_rebind (LdapConnectionData *cdata, GError **error);
 
 #endif
diff --git a/providers/ldap/gdaprov-data-model-ldap.c b/providers/ldap/gdaprov-data-model-ldap.c
index acaca76..05c98f4 100644
--- a/providers/ldap/gdaprov-data-model-ldap.c
+++ b/providers/ldap/gdaprov-data-model-ldap.c
@@ -64,7 +64,7 @@ struct _LdapPart {
 #define LDAP_PART(x) ((LdapPart*)(x))
 
 static LdapPart *ldap_part_new (LdapPart *parent, const gchar *base_dn, GdaLdapSearchScope scope);
-static void ldap_part_free (LdapPart *part);
+static void ldap_part_free (LdapPart *part, LdapConnectionData *cdata);
 static gboolean ldap_part_split (LdapPart *part, GdaDataModelLdap *model, gboolean *out_error);
 static LdapPart *ldap_part_next (LdapPart *part, gboolean executed);
 #ifdef GDA_DEBUG_SUBSEARCHES
@@ -267,7 +267,7 @@ gda_data_model_ldap_class_init (GdaDataModelLdapClass *klass)
 }
 
 static void
-gda_data_model_ldap_dispose (GObject * object)
+gda_data_model_ldap_dispose (GObject *object)
 {
 	GdaDataModelLdap *model = (GdaDataModelLdap *) object;
 
@@ -295,8 +295,11 @@ gda_data_model_ldap_dispose (GObject * object)
 		if (model->priv->column_mv_actions)
 			g_array_free (model->priv->column_mv_actions, TRUE);
 
-		if (model->priv->top_exec)
-			ldap_part_free (model->priv->top_exec);
+		if (model->priv->top_exec) {
+			LdapConnectionData *cdata;
+			cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (model->priv->cnc));
+			ldap_part_free (model->priv->top_exec, cdata);
+		}
 
 		g_free (model->priv->base_dn);
 		g_free (model->priv->filter);
@@ -701,6 +704,9 @@ update_iter_from_ldap_row (GdaDataModelLdap *imodel, GdaDataModelIter *iter)
 	cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (imodel->priv->cnc));
 	g_return_if_fail (cdata);
 
+	/* LDAP connection must have been kept opened */
+	g_assert (cdata->handle);
+
 	g_object_get (G_OBJECT (iter), "update-model", &update_model, NULL);
 	g_object_set (G_OBJECT (iter), "update-model", FALSE, NULL);
 		
@@ -933,6 +939,12 @@ execute_ldap_search (GdaDataModelLdap *model)
 	cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (model->priv->cnc));
 	g_return_if_fail (cdata);
 
+	GError *e = NULL;
+	if (! gda_ldap_ensure_bound (cdata, &e)) {
+		add_exception (model, e);
+		return;
+	}
+
 	g_assert (model->priv->current_exec);
 	g_assert (! model->priv->current_exec->executed);
 
@@ -997,6 +1009,10 @@ execute_ldap_search (GdaDataModelLdap *model)
 		/* all Ok */
 		model->priv->current_exec->ldap_msg = msg;
 		model->priv->current_exec->nb_entries = ldap_count_entries (cdata->handle, msg);
+
+		/* keep the connection opened for this LdapPart */
+		cdata->keep_bound_count ++;
+
 #ifdef GDA_DEBUG_SUBSEARCHES
 		g_print ("model->priv->current_exec->nb_entries = %d\n",
 			 model->priv->current_exec->nb_entries);
@@ -1038,13 +1054,16 @@ execute_ldap_search (GdaDataModelLdap *model)
 			model->priv->truncated = TRUE;
 			model->priv->current_exec->ldap_msg = msg;
 			model->priv->current_exec->nb_entries = ldap_count_entries (cdata->handle, msg);
+
+			/* keep the connection opened for this LdapPart */
+			cdata->keep_bound_count ++;
 		}
 		break;
 	}
 	case LDAP_SERVER_DOWN: {
 		gint i;
 		for (i = 0; i < 5; i++) {
-			if (gda_ldap_silently_rebind (cdata))
+			if (gda_ldap_rebind (cdata, NULL))
 				goto retry;
 			g_usleep (G_USEC_PER_SEC * 2);
 		}
@@ -1057,6 +1076,7 @@ execute_ldap_search (GdaDataModelLdap *model)
 		g_set_error (&e, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_OTHER_ERROR,
 			     "%s", ldap_err2string (ldap_errno));
 		add_exception (model, e);
+		gda_ldap_may_unbind (cdata);
 		return;
 	}
 	}
@@ -1073,6 +1093,7 @@ execute_ldap_search (GdaDataModelLdap *model)
 				model->priv->n_rows += iter->nb_entries;
 		}
 	}
+
 #ifdef GDA_DEBUG_NO
 	gint tmpnb = 0;
 	if (model->priv->top_exec->ldap_msg)
@@ -1105,7 +1126,7 @@ gda_data_model_ldap_iter_next (GdaDataModel *model, GdaDataModelIter *iter)
 	}
 
 	cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (imodel->priv->cnc));
-	if (!cdata) {
+	if (!cdata || ! gda_ldap_ensure_bound (cdata, NULL)) {
 		/* error */
 		gda_data_model_iter_invalidate_contents (iter);
 		return FALSE;
@@ -1129,6 +1150,7 @@ gda_data_model_ldap_iter_next (GdaDataModel *model, GdaDataModelIter *iter)
 		if (! cpart->ldap_msg) {
 			/* error somewhere */
 			gda_data_model_iter_invalidate_contents (iter);
+			gda_ldap_may_unbind (cdata);
 			return FALSE;
 		}
 
@@ -1152,9 +1174,17 @@ gda_data_model_ldap_iter_next (GdaDataModel *model, GdaDataModelIter *iter)
 			update_iter_from_ldap_row (imodel, iter);
 			break;
 		}
-		else
+		else {
 			/* nothing more for this part, switch to the next one */
+			ldap_msgfree (imodel->priv->current_exec->ldap_msg);
+			imodel->priv->current_exec->ldap_msg = NULL;
+
+			g_assert (cdata->keep_bound_count > 0);
+			cdata->keep_bound_count --;
+			gda_ldap_may_unbind (cdata);
+
 			imodel->priv->current_exec = ldap_part_next (cpart, FALSE);
+		}
 	}
 
 	if (!imodel->priv->current_exec) {
@@ -1169,9 +1199,11 @@ gda_data_model_ldap_iter_next (GdaDataModel *model, GdaDataModelIter *iter)
 			add_exception (imodel, e);
 		}
 		g_signal_emit_by_name (iter, "end-of-data");
+		gda_ldap_may_unbind (cdata);
                 return FALSE;
 	}
 
+	gda_ldap_may_unbind (cdata);
 	return TRUE;
 }
 
@@ -1235,16 +1267,23 @@ ldap_part_new (LdapPart *parent, const gchar *base_dn, GdaLdapSearchScope scope)
 }
 
 static void
-ldap_part_free (LdapPart *part)
+ldap_part_free (LdapPart *part, LdapConnectionData *cdata)
 {
 	g_assert (part);
 	g_free (part->base_dn);
 	if (part->children) {
-		g_slist_foreach (part->children, (GFunc) ldap_part_free, NULL);
+		g_slist_foreach (part->children, (GFunc) ldap_part_free, cdata);
 		g_slist_free (part->children);
 	}
-	if (part->ldap_msg)
+	if (part->ldap_msg) {
 		ldap_msgfree (part->ldap_msg);
+
+		/* Release the connection being opened for this LdapPart */
+		g_assert (cdata);
+		g_assert (cdata->keep_bound_count > 0);
+		cdata->keep_bound_count --;
+		gda_ldap_may_unbind (cdata);
+	}
 	g_free (part);
 }
 
@@ -1334,7 +1373,9 @@ ldap_part_split (LdapPart *part, GdaDataModelLdap *model, gboolean *out_error)
 		}
 		if (!sub) {
 			/* error */
-			g_slist_foreach (part->children, (GFunc) ldap_part_free, NULL);
+			LdapConnectionData *cdata;
+			cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (model->priv->cnc));
+			g_slist_foreach (part->children, (GFunc) ldap_part_free, cdata);
 			g_slist_free (part->children);
 			part->children = NULL;
 			break;
@@ -1529,6 +1570,9 @@ gdaprov_ldap_modify (GdaLdapConnection *cnc, GdaLdapModificationType modtype,
 	cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc));
 	g_return_val_if_fail (cdata, FALSE);
 
+	if (! gda_ldap_ensure_bound (cdata, error))
+		return FALSE;
+
 	/* checks */
 	if ((modtype != GDA_LDAP_MODIFICATION_INSERT) &&
 	    (modtype != GDA_LDAP_MODIFICATION_ATTR_ADD) &&
@@ -1536,36 +1580,43 @@ gdaprov_ldap_modify (GdaLdapConnection *cnc, GdaLdapModificationType modtype,
 	    (modtype != GDA_LDAP_MODIFICATION_ATTR_REPL) &&
 	    (modtype != GDA_LDAP_MODIFICATION_ATTR_DIFF)) {
 		g_warning (_("Unknown GdaLdapModificationType %d"), modtype);
+		gda_ldap_may_unbind (cdata);
 		return FALSE;
 	}
 
 	if (((modtype == GDA_LDAP_MODIFICATION_DELETE) || (modtype == GDA_LDAP_MODIFICATION_INSERT)) &&
 	    !entry) {
 		g_warning ("%s", _("No GdaLdapEntry specified"));
+		gda_ldap_may_unbind (cdata);
 		return FALSE;
 	}
 
 	if ((modtype == GDA_LDAP_MODIFICATION_ATTR_ADD) && !entry) {
 		g_warning ("%s", _("No GdaLdapEntry specified to define attributes to add"));
+		gda_ldap_may_unbind (cdata);
 		return FALSE;
 	}
 
 	if ((modtype == GDA_LDAP_MODIFICATION_ATTR_DEL) && !entry) {
 		g_warning ("%s", _("No GdaLdapEntry specified to define attributes to remove"));
+		gda_ldap_may_unbind (cdata);
 		return FALSE;
 	}
 
 	if ((modtype == GDA_LDAP_MODIFICATION_ATTR_REPL) && !entry) {
 		g_warning ("%s", _("No GdaLdapEntry specified to define attributes to replace"));
+		gda_ldap_may_unbind (cdata);
 		return FALSE;
 	}
 
 	if ((modtype == GDA_LDAP_MODIFICATION_ATTR_DIFF) && (!entry || !ref_entry)) {
 		g_warning ("%s", _("No GdaLdapEntry specified to compare attributes"));
+		gda_ldap_may_unbind (cdata);
 		return FALSE;
 	}
 	if ((modtype == GDA_LDAP_MODIFICATION_ATTR_DIFF) && strcmp (entry->dn, ref_entry->dn)) {
 		g_warning ("%s", _("GdaLdapEntry specified to compare have different DN"));
+		gda_ldap_may_unbind (cdata);
 		return FALSE;
 	}
 
@@ -1575,10 +1626,13 @@ gdaprov_ldap_modify (GdaLdapConnection *cnc, GdaLdapModificationType modtype,
 		if (res != LDAP_SUCCESS) {
 			g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_OTHER_ERROR,
 				     "%s", ldap_err2string (res));
+			gda_ldap_may_unbind (cdata);
 			return FALSE;
 		}
-		else
+		else {
+			gda_ldap_may_unbind (cdata);
 			return TRUE;
+		}
 	}
 
 	/* build array of modifications to perform */
@@ -1679,6 +1733,7 @@ gdaprov_ldap_modify (GdaLdapConnection *cnc, GdaLdapModificationType modtype,
 	}
 	g_array_free (mods_array, TRUE);
 
+	gda_ldap_may_unbind (cdata);
 	return retval;
 }
 
@@ -1711,6 +1766,9 @@ gdaprov_ldap_rename_entry (GdaLdapConnection *cnc, const gchar *current_dn, cons
 	cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc));
 	g_return_val_if_fail (cdata, FALSE);
 
+	if (! gda_ldap_ensure_bound (cdata, error))
+		return FALSE;
+
 	gchar **carray, **narray;
 	int res;
 	gboolean retval = TRUE;
@@ -1734,5 +1792,6 @@ gdaprov_ldap_rename_entry (GdaLdapConnection *cnc, const gchar *current_dn, cons
 		retval = FALSE;
 	}
 
+	gda_ldap_may_unbind (cdata);
 	return retval;
 }



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