|
From: <svn...@op...> - 2010-01-05 21:09:12
|
Author: scriptor Date: Tue Jan 5 22:08:57 2010 New Revision: 5977 URL: http://www.opensync.org/changeset/5977 Log: The schema discovery must be performed in two steps rather than just one: 1. Which entry carries the schemata? This is answered by the "subschemaSubentry". 2. Which schemata are available? This is answered by the entry returned in 1. Modified: plugins/ldap-sync/src/ldap_connect.c Modified: plugins/ldap-sync/src/ldap_connect.c ============================================================================== --- plugins/ldap-sync/src/ldap_connect.c Tue Jan 5 19:55:20 2010 (r5976) +++ plugins/ldap-sync/src/ldap_connect.c Tue Jan 5 22:08:57 2010 (r5977) @@ -1169,9 +1169,10 @@ */ osync_bool ldap_plugin_check_ldap_schema_support(OSyncContext *ctx, sink_environment *sinkenv, const char *ldap_schema, osync_bool *result, OSyncError **error) { - LDAPMessage *res = NULL, *res2 = NULL; + LDAPMessage *res = NULL, *res2 = NULL, *res3 = NULL, *res4 = NULL; int i = 0; - struct berval **ber = NULL; + struct berval **ber = NULL, **ber2 = NULL; + char *search_base = NULL; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %p)", __func__, (void *)ctx, (void *)sinkenv, (void *)ldap_schema, (void *)result, (void *)error); @@ -1207,8 +1208,56 @@ *result = FALSE; + // Get the relevant search_base. It may differ from server to server. + if (!ldap_plugin_call_ldap_search(ctx, sinkenv->ld, "", "(objectClass=*)", LDAP_SCOPE_BASE, OPERATIONAL_ATTRIBUTES, sinkenv, TRUE, &res3, error)) { + if (!osync_error_is_set(error)) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_plugin_call_ldap_search() has failed.\n", __FILE__, __LINE__); + } + + goto error; + } + + + // subschemaSubentry MUST be present. So it is legitimate, when we error out + // here. + if (res3 == NULL) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_plugin_call_ldap_search() must have failed.\n", __FILE__, __LINE__); + ldap_plugin_dump_ldap_error_message(sinkenv, __FILE__, __LINE__, "", "", "ldap_plugin_call_ldap_search()"); + + goto error; + } + + + res4 = ldap_first_entry(sinkenv->ld, res3); + if (res4) { + ber2 = ldap_get_values_len(sinkenv->ld, res4, "subschemaSubentry"); + if (ber2) { + while (ber2[i]) { + if (ber2[i]->bv_val) { + search_base = g_strdup(ber2[i]->bv_val); + break; + } + + i++; + } + } + } + + + + + + + // We haven't found the real search_base. So let's assume, it is + // "cn=Subschema". + if (search_base == NULL) { + osync_trace(TRACE_INTERNAL, "%s:%i: WARNING: search_base = NULL. Setting it to \"cn=Subschema\".", __FILE__, __LINE__); + search_base = g_strdup("cn=Subschema"); + } + + // Look for all the LDAP subschemata (as used by slapd from openldap): - if (!ldap_plugin_call_ldap_search(ctx, sinkenv->ld, "cn=Subschema", "(objectClass=subschema)", LDAP_SCOPE_BASE, OBJECTCLASSES, sinkenv, TRUE, &res, error)) { + if (!ldap_plugin_call_ldap_search(ctx, sinkenv->ld, search_base, "(objectClass=subschema)", LDAP_SCOPE_BASE, OBJECTCLASSES, sinkenv, TRUE, &res, error)) { if (!osync_error_is_set(error)) { osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_plugin_call_ldap_search() has failed.\n", __FILE__, __LINE__); } @@ -1219,7 +1268,7 @@ if (res == NULL) { osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_plugin_call_ldap_search() must have failed.\n", __FILE__, __LINE__); - ldap_plugin_dump_ldap_error_message(sinkenv, __FILE__, __LINE__, "cn=Subschema", "(objectClass=subschema)", "ldap_plugin_call_ldap_search()"); + ldap_plugin_dump_ldap_error_message(sinkenv, __FILE__, __LINE__, search_base, "(objectClass=subschema)", "ldap_plugin_call_ldap_search()"); goto error; } @@ -1228,17 +1277,12 @@ res2 = ldap_first_entry(sinkenv->ld, res); if (!res2) { /* No objectClass entries found */ -/* - osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: Could not find any objectClass entry while searching for LDAP subschemata.", __FILE__, __LINE__); - goto error; -*/ - if (res) ldap_msgfree(res); // Look for all the LDAP schemata (as used by ns-slapd from the // fedora directory server): - if (!ldap_plugin_call_ldap_search(ctx, sinkenv->ld, "cn=schema", "(objectClass=subschema)", LDAP_SCOPE_BASE, OBJECTCLASSES, sinkenv, TRUE, &res, error)) { + if (!ldap_plugin_call_ldap_search(ctx, sinkenv->ld, search_base, "(objectClass=subschema)", LDAP_SCOPE_BASE, OBJECTCLASSES, sinkenv, TRUE, &res, error)) { if (!osync_error_is_set(error)) { osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_plugin_call_ldap_search() has failed.\n", __FILE__, __LINE__); } @@ -1248,7 +1292,7 @@ if (res == NULL) { osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_plugin_call_ldap_search() must have failed.\n", __FILE__, __LINE__); - ldap_plugin_dump_ldap_error_message(sinkenv, __FILE__, __LINE__, "cn=schema", "(objectClass=subschema)", "ldap_plugin_call_ldap_search()"); + ldap_plugin_dump_ldap_error_message(sinkenv, __FILE__, __LINE__, search_base, "(objectClass=subschema)", "ldap_plugin_call_ldap_search()"); goto error; } @@ -1287,6 +1331,8 @@ if (res) ldap_msgfree(res); + if (search_base) + g_free(search_base); osync_trace(TRACE_EXIT, "%s", __func__); @@ -1300,6 +1346,9 @@ if (res) ldap_msgfree(res); + if (search_base) + g_free(search_base); + if (!osync_error_is_set(error)) osync_error_set(error, OSYNC_ERROR_GENERIC, "Unknown reason.\n"); @@ -1501,7 +1550,11 @@ * sub: the current location in the DIT and all of its children * * - * @param kind_of_attributes For example, whether user attributes or control attributes are to be shown. + * @param kind_of_attributes For example, whether user attributes or + * operational attributes are to be shown. + * ldap_plugin.h defines 3 types: USER_ATTRIBUTES, + * OPERATIONAL_ATTRIBUTES and OBJECTCLASSES. + * * @param sinkenv The object type specific environment * @param results This function fills this struct with the search result. * @param ignore_no_such_object This variable tells this function whether |