/* * Makes sure the connection is opened */ gboolean gda_ldap_ensure_bound (GdaLdapConnection *cnc, GError **error) { LdapConnectionData *cdata; cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc)); if (!cdata) return FALSE; else if (cdata->handle) return TRUE; return gda_ldap_rebind (cnc, error); }
static GdaLdapEntry * worker_gdaprov_ldap_describe_entry (WorkerLdapDescrEntryData *data, GError **error) { if (! gda_ldap_ensure_bound (data->cnc, error)) return NULL; gda_ldap_execution_slowdown (data->cnc); int res; LDAPMessage *msg = NULL; const gchar *real_dn; real_dn = data->dn ? data->dn : data->cdata->base_dn; retry: res = ldap_search_ext_s (data->cdata->handle, real_dn, LDAP_SCOPE_BASE, "(objectClass=*)", NULL, 0, NULL, NULL, NULL, -1, &msg); switch (res) { case LDAP_SUCCESS: case LDAP_NO_SUCH_OBJECT: { gint nb_entries; LDAPMessage *ldap_row; char *attr; BerElement* ber; GdaLdapEntry *lentry; GArray *array = NULL; nb_entries = ldap_count_entries (data->cdata->handle, msg); if (nb_entries == 0) { ldap_msgfree (msg); gda_ldap_may_unbind (data->cnc); return NULL; } else if (nb_entries > 1) { g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_INTERNAL_ERROR, _("LDAP server returned more than one entry with DN '%s'"), real_dn); gda_ldap_may_unbind (data->cnc); return NULL; } lentry = g_new0 (GdaLdapEntry, 1); lentry->dn = g_strdup (real_dn); lentry->attributes_hash = g_hash_table_new (g_str_hash, g_str_equal); array = g_array_new (TRUE, FALSE, sizeof (GdaLdapAttribute*)); ldap_row = ldap_first_entry (data->cdata->handle, msg); for (attr = ldap_first_attribute (data->cdata->handle, ldap_row, &ber); attr; attr = ldap_next_attribute (data->cdata->handle, ldap_row, ber)) { BerValue **bvals; GArray *varray = NULL; bvals = ldap_get_values_len (data->cdata->handle, ldap_row, attr); if (bvals) { gint i; for (i = 0; bvals [i]; i++) { if (!varray) varray = g_array_new (TRUE, FALSE, sizeof (GValue *)); GValue *value; GType type; type = gda_ldap_get_g_type (data->cnc, data->cdata, attr, NULL); /*g_print ("Type for attr %s is %s\n", attr, gda_g_type_to_string (type)); */ value = gda_ldap_attr_value_to_g_value (data->cdata, type, bvals[i]); g_array_append_val (varray, value); } ldap_value_free_len (bvals); } if (varray) { GdaLdapAttribute *lattr = NULL; lattr = g_new0 (GdaLdapAttribute, 1); lattr->attr_name = g_strdup (attr); lattr->values = (GValue**) varray->data; lattr->nb_values = varray->len; g_array_free (varray, FALSE); g_array_append_val (array, lattr); g_hash_table_insert (lentry->attributes_hash, lattr->attr_name, lattr); } ldap_memfree (attr); } if (ber) ber_free (ber, 0); ldap_msgfree (msg); if (array) { g_array_sort (array, (GCompareFunc) attr_array_sort_func); lentry->attributes = (GdaLdapAttribute**) array->data; lentry->nb_attributes = array->len; g_array_free (array, FALSE); } gda_ldap_may_unbind (data->cnc); return lentry; } case LDAP_SERVER_DOWN: default: { if (res == LDAP_SERVER_DOWN) { gint i; for (i = 0; i < 5; i++) { if (gda_ldap_rebind (data->cnc, NULL)) goto retry; g_usleep (G_USEC_PER_SEC * 2); } } /* error */ int ldap_errno; ldap_get_option (data->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 (data->cnc); return NULL; } } }