check_schema_support (EBookBackendLDAP *bl)
{
	const gchar *attrs[2];
	LDAPMessage *resp;
	struct timeval timeout;
	gchar *lst;

	g_rec_mutex_lock (&eds_ldap_handler_lock);
	if (!bl->priv->ldap) {
		g_rec_mutex_unlock (&eds_ldap_handler_lock);
		return;
	}

	if (!bl->priv->schema_dn) {
		g_rec_mutex_unlock (&eds_ldap_handler_lock);
		return;
	}

	bl->priv->evolutionPersonChecked = TRUE;

	attrs[0] = "objectClasses";
	attrs[1] = NULL;

	timeout.tv_sec = 30;
	timeout.tv_usec = 0;

	if (ldap_search_ext_s (bl->priv->ldap, bl->priv->schema_dn, LDAP_SCOPE_BASE,
			       "(objectClass=subschema)", (gchar **) attrs, 0,
			       NULL, NULL, &timeout, LDAP_NO_LIMIT, &resp) == LDAP_SUCCESS) {
		gchar **values;

		values = ldap_get_values (bl->priv->ldap, resp, "objectClasses");
		g_rec_mutex_unlock (&eds_ldap_handler_lock);

		if (values) {
			gint i;
			for (i = 0; values[i]; i++) {
				gint j;
				gint code;
				const gchar *err;
				LDAPObjectClass *oc = ldap_str2objectclass (values[i], &code, &err, 0);

				if (!oc)
					continue;

				for (j = 0; oc->oc_names[j]; j++)
					if (!g_ascii_strcasecmp (oc->oc_names[j], EVOLUTIONPERSON)) {
						if (enable_debug)
							g_print ("support found on ldap server for objectclass evolutionPerson\n");
						bl->priv->evolutionPersonSupported = TRUE;

						add_oc_attributes_to_supported_fields (bl, oc);
					}
					else if (!g_ascii_strcasecmp (oc->oc_names[j], CALENTRY)) {
						if (enable_debug)
							g_print ("support found on ldap server for objectclass calEntry\n");
						bl->priv->calEntrySupported = TRUE;
						add_oc_attributes_to_supported_fields (bl, oc);
					}
					else if (!g_ascii_strcasecmp (oc->oc_names[j], INETORGPERSON)
						 || !g_ascii_strcasecmp (oc->oc_names[j], ORGANIZATIONALPERSON)
						 || !g_ascii_strcasecmp (oc->oc_names[j], PERSON)
						 || !g_ascii_strcasecmp (oc->oc_names[j], GROUPOFNAMES)) {
						add_oc_attributes_to_supported_fields (bl, oc);
					}

				ldap_objectclass_free (oc);
			}

			ldap_value_free (values);
		}
		else {
			/* the reason for this is so that if the user
			 * ends up authenticating to the ldap server,
			 * we will requery for the subschema values.
			 * This makes it a bit more robust in the face
			 * of draconian acl's that keep subschema
			 * reads from working until the user is
			 * authed. */
			if (e_book_backend_is_readonly (E_BOOK_BACKEND (bl))) {
				g_warning ("subschema read returned nothing before successful auth");
				bl->priv->evolutionPersonChecked = FALSE;
			}
			else {
				g_warning ("subschema read returned nothing after successful auth");
			}
		}

		ldap_msgfree (resp);
	}
	else {
		g_rec_mutex_unlock (&eds_ldap_handler_lock);
	}

	lst = e_data_book_string_slist_to_comma_string (bl->priv->supported_fields);
	e_book_backend_notify_property_changed (E_BOOK_BACKEND (bl), BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS, lst);
	g_free (lst);
}
check_schema_support (EBookBackendLDAP *bl)
{
	const gchar *attrs[2];
	LDAPMessage *resp;
	struct timeval timeout;
	gchar *lst;

	g_rec_mutex_lock (&eds_ldap_handler_lock);
	if (!bl->priv->ldap) {
		g_rec_mutex_unlock (&eds_ldap_handler_lock);
		return;
	}

	if (!bl->priv->schema_dn) {
		g_rec_mutex_unlock (&eds_ldap_handler_lock);
		return;
	}

	bl->priv->evolutionPersonChecked = TRUE;

	attrs[0] = "objectClasses";
	attrs[1] = NULL;

	timeout.tv_sec = 30;
	timeout.tv_usec = 0;

	if (ldap_search_ext_s (bl->priv->ldap, bl->priv->schema_dn, LDAP_SCOPE_BASE,
			       "(objectClass=subschema)", (gchar **) attrs, 0,
			       NULL, NULL, &timeout, LDAP_NO_LIMIT, &resp) == LDAP_SUCCESS) {
		gchar **values;

		values = ldap_get_values (bl->priv->ldap, resp, "objectClasses");
		g_rec_mutex_unlock (&eds_ldap_handler_lock);

		if (values) {
			gint i;
			for (i = 0; values[i]; i++) {
				gint j;
				gint code;
				const gchar *err;
				LDAPObjectClass *oc = ldap_str2objectclass (values[i], &code, &err, 0);

				if (!oc)
					continue;

				for (j = 0; oc->oc_names[j]; j++)
					if (!g_ascii_strcasecmp (oc->oc_names[j], EVOLUTIONPERSON)) {
						if (enable_debug)
							g_print ("support found on ldap server for objectclass evolutionPerson\n");
						bl->priv->evolutionPersonSupported = TRUE;

						add_oc_attributes_to_supported_fields (bl, oc);
					}
					else if (!g_ascii_strcasecmp (oc->oc_names[j], CALENTRY)) {
						if (enable_debug)
							g_print ("support found on ldap server for objectclass calEntry\n");
						bl->priv->calEntrySupported = TRUE;
						add_oc_attributes_to_supported_fields (bl, oc);
					}
					else if (!g_ascii_strcasecmp (oc->oc_names[j], INETORGPERSON)
						 || !g_ascii_strcasecmp (oc->oc_names[j], ORGANIZATIONALPERSON)
						 || !g_ascii_strcasecmp (oc->oc_names[j], PERSON)
						 || !g_ascii_strcasecmp (oc->oc_names[j], GROUPOFNAMES)) {
						add_oc_attributes_to_supported_fields (bl, oc);
					}

				ldap_objectclass_free (oc);
			}

			ldap_value_free (values);
		}
		else {
			 
			if (e_book_backend_is_readonly (E_BOOK_BACKEND (bl))) {
				g_warning ("subschema read returned nothing before successful auth");
				bl->priv->evolutionPersonChecked = FALSE;
			}
			else {
				g_warning ("subschema read returned nothing after successful auth");
			}
		}

		ldap_msgfree (resp);
	}
	else {
		g_rec_mutex_unlock (&eds_ldap_handler_lock);
	}

	lst = e_data_book_string_slist_to_comma_string (bl->priv->supported_fields);
	e_book_backend_notify_property_changed (E_BOOK_BACKEND (bl), BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS, lst);
	g_free (lst);
}