From: <svn...@op...> - 2009-04-01 21:56:47
|
Author: scriptor Date: Wed Apr 1 23:56:44 2009 New Revision: 5510 URL: http://www.opensync.org/changeset/5510 Log: Checking for the presence of the keyattribute is something different from making sure, that the most-left part of an LDAP DN is actually present as an LDAP attribute, and that the values of both are really identical. Otherwise: "Naming violation". New function: ldap_plugin_assure_attribute() Tiny changes with some comments. Modified: plugins/ldap-sync/src/ldap_connect.c plugins/ldap-sync/src/ldap_plugin.c plugins/ldap-sync/src/ldap_plugin.h Modified: plugins/ldap-sync/src/ldap_connect.c ============================================================================== --- plugins/ldap-sync/src/ldap_connect.c Wed Apr 1 20:15:48 2009 (r5509) +++ plugins/ldap-sync/src/ldap_connect.c Wed Apr 1 23:56:44 2009 (r5510) @@ -3719,8 +3719,12 @@ /*****************************/ // Rewrite the check_entry object - if (!ldap_plugin_rewrite_ldap_entry(check_entry, modifications, error)) { - goto error; + if (modifications) { + if (!ldap_plugin_rewrite_ldap_entry(check_entry, modifications, error)) { + goto error; + } + } else { + osync_trace(TRACE_INTERNAL, "%s:%i:%s(): No modification could be found. Nothing to do, therefore.", __FILE__, __LINE__, __func__); } @@ -3733,11 +3737,11 @@ #ifdef DEBUG_change_type_modified - ldap_plugin_printf( "\n\n----------\n%s:%i:%s(): \nModified version of check_entry:", __FILE__, __LINE__, __func__); + ldap_plugin_printf( "\n\n----------\n%s:%i:%s(): \nModified version of check_entry:", __FILE__, __LINE__, __func__); - // TODO - ldap_plugin_dump_ldap_attributes(check_entry); - ldap_plugin_printf("----------\n\n"); + // TODO + ldap_plugin_dump_ldap_attributes(check_entry); + ldap_plugin_printf("----------\n\n"); #endif @@ -3764,12 +3768,185 @@ } +/** + * @brief This function checks an LDAP entry for the presence of a + * particular LDAP attribute. If not found, it supplements + * the LDAP entry accordingly. + * + * @param entry The LDAP entry to be checked. + * @param attribute The LDAP attribute which is required to be present. + * @param value The value of the required LDAP attribute. + * + * @param error The libopensync error pointer. + */ + +osync_bool ldap_plugin_assure_attribute(ldap_entry *entry, const char *ldap_attribute, const char *value, OSyncError **error) +{ + int i = 0; + osync_bool found_attribute = FALSE; + + + osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, entry, ldap_attribute, error); + + + if (entry == NULL) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: entry = NULL.", __FILE__, __LINE__); + goto error; + } + + if (entry->id == NULL) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: entry->id = NULL.", __FILE__, __LINE__); + goto error; + } + + if (entry->id[0] == 0) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: entry->id[0] = 0.", __FILE__, __LINE__); + goto error; + } + + if (entry->mods == NULL) { + osync_trace(TRACE_INTERNAL, "%s:%i: WARNING: entry->mods = NULL. Strange, but not really a problem.", __FILE__, __LINE__); + goto out; + } + + if (ldap_attribute == NULL) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_attribute = NULL.", __FILE__, __LINE__); + goto error; + } + -osync_bool ldap_plugin_check_for_keyattribute(sink_environment *sinkenv, ldap_entry *entry, OSyncError **error) + // Search the array of mods for ldap_attribute + for (i = 0; entry->mods[i]; i++) { + LDAPMod *mod = entry->mods[i]; + + if (mod) { + if (mod->mod_type) { + if (!strcmp(mod->mod_type, ldap_attribute)) { + osync_trace(TRACE_INTERNAL, "%s(): OK. Attribute \"%s\" found.", __func__, ldap_attribute); + found_attribute = TRUE; + } + } + } + } // for (i = 0; entry->mods[i]; i++) + + + // Supplement it, if necessary + if (!found_attribute) { + GList *new_set_of_mods = NULL; +#ifndef CALL_ABORT + int j = 0; +#endif + + + osync_trace(TRACE_INTERNAL, "%s:%i: WARNING: Attribute \"%s\" could not be found.", __FILE__, __LINE__, ldap_attribute); + osync_trace(TRACE_INTERNAL, "This happened with:"); + osync_trace(TRACE_INTERNAL, "entry->dn = \"%s\"", entry->dn); + osync_trace(TRACE_INTERNAL, "entry->id = \"%s\"", entry->id); + // ldap_plugin_dump_ldap_attributes(entry); + osync_trace(TRACE_INTERNAL, "-------------"); + +#ifdef CALL_ABORT + osync_trace(TRACE_ERROR, "%s:%i: Calling abort();\n", __FILE__, __LINE__); + ldap_plugin_printf("%s:%i: Calling abort();\n", __FILE__, __LINE__); + fprintf(stderr, "%s:%i: Calling abort();\n\n", __FILE__, __LINE__); + fflush(stderr); + abort(); + +#else + osync_trace(TRACE_INTERNAL, "%s:%i: Trying to add missing LDAP attribute.", __FILE__, __LINE__); + + // Copy old mods into new_set_of_mods + for (j = 0 ; entry->mods[j] ; j++ ) { + if (entry->mods[j]->mod_type) { + if (entry->mods[j]->mod_bvalues) { + if (entry->mods[j]->mod_values[0]) { + if (entry->mods[j]->mod_bvalues[0]->bv_val) { + new_set_of_mods = ldap_plugin_append_ldapmod(new_set_of_mods, entry->mods[j]->mod_type, entry->mods[j]->mod_bvalues[0]->bv_val); + } else { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: mod_bvalues[0]->bv_val = NULL with j = %i", __FILE__, __LINE__, j); + } + } else { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: mod_bvalues[0] = NULL with j = %i", __FILE__, __LINE__, j); + } + } else { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: mod_bvalues = NULL with j = %i", __FILE__, __LINE__, j); + } + } else { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: mod_type = NULL with j = %i", __FILE__, __LINE__, j); + } + } + + + // Add missing attribute + new_set_of_mods = ldap_plugin_append_ldapmod(new_set_of_mods, (char *)ldap_attribute, (char *)value); + + + // Rewrite the LDAP entry + ldap_plugin_rewrite_ldap_entry(entry, new_set_of_mods, error); + if (osync_error_is_set(error)) { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: ldap_plugin_rewrite_ldap_entry() has failed.", __FILE__, __LINE__); + goto error; + } + +#endif + + } // if (!found_attribute) + + +out: + osync_trace(TRACE_EXIT, "%s: found_attribute = %s", __func__, found_attribute ? "TRUE" : "FALSE"); + return TRUE; + + +error: + if (!osync_error_is_set(error)) + osync_error_set(error, OSYNC_ERROR_GENERIC, "Unknown reason.\n"); + + osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); + osync_error_unref(error); + + return FALSE; +} + + + + + + +/** + * @brief This function checks whether the sinkenv->keyattr is present in the + * LDAP entry. + * + * This is important for two reasons: + * - The hashtable and the whole synchronization process requires + * the key attribute, as it is the identifier that matters. + * - The LDAP server requires the most-left part of the DN + * be present in the LDAP entry. + * Example: + * dn: ou=addressbook,dc=example,dc=com + * ou: addressbook MUST be present in the LDAP entry. + * Otherwise: Naming violation. + * + * Note: This function MUST NOT be called for subentries and + * sub-subentries. + * + * @param sinkenv The sink specific environment. + * @param entry The LDAP entry to be checked + * @param check_key_attribute Whether or not the presence of the key attribute + * should be checked. As it seems, entrymods that + * are to be sent to ldap_modify_ext_s() should + * set FALSE here. + * @param error The libopensync error pointer. + * + * @returns TRUE on success, FALSE in case of any error + */ + +osync_bool ldap_plugin_check_for_keyattribute(sink_environment *sinkenv, ldap_entry *entry, osync_bool check_key_attribute, OSyncError **error) { int i = 0; - osync_bool found_name = FALSE, found_value = FALSE; + osync_bool dn_attribute_found = FALSE, identical = FALSE; + gchar **required = NULL; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, sinkenv, entry, error); @@ -3812,51 +3989,117 @@ } - for (i = 0; entry->mods[i]; i++) { - LDAPMod *mod = entry->mods[i]; - if (mod) { - if (mod->mod_type) { - if (!strcmp(mod->mod_type, sinkenv->keyattr)) { - osync_trace(TRACE_INTERNAL, "%s(): OK. Keyattribute \"%s\" found.", __func__, sinkenv->keyattr); - found_name = TRUE; - - if (mod->mod_bvalues) { - if (mod->mod_bvalues[0]) { - if (mod->mod_bvalues[0]->bv_val) { - if (!strcmp(mod->mod_bvalues[0]->bv_val, entry->id)) { - osync_trace(TRACE_INTERNAL, "%s(): OK. Value of keyattribute is identical to the identifier: \"%s\".", __func__, entry->id); - found_value = TRUE; - } else { - osync_trace(TRACE_ERROR, "%s:%i: WARNING: Value of keyattribute \"%s\" conflicts with identifier \"%s\". Trying to enforce correct one.", __FILE__, __LINE__, mod->mod_bvalues[0]->bv_val, entry->id); - g_free(mod->mod_bvalues[0]->bv_val); - mod->mod_bvalues[0]->bv_val = g_strdup(entry->id); - mod->mod_bvalues[0]->bv_len = strlen(entry->id); - // What about the hash value? + + // Check for keyattribute + if (check_key_attribute) { + if (g_str_has_prefix(entry->dn, sinkenv->keyattr)) { + osync_trace(TRACE_INTERNAL, "%s:%i: Checking for presence of keyattribute for \"dn: %s\"", __FILE__, __LINE__, entry->dn); + + + if (!ldap_plugin_assure_attribute(entry, sinkenv->keyattr, entry->id, error)) { + if (!osync_error_is_set(error)) + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_plugin_assure_attribute.\n", __FILE__, __LINE__); + + goto error; + } + } else { + osync_trace(TRACE_INTERNAL, "%s:%i: This must be a subentry: \"dn: %s\". Therefore NOT checking for presence of keyattribute. Only checking for consistency.", __FILE__, __LINE__, entry->dn); + } + } + + + + + // Check for identity between DN prefix and corresponding LDAP attribute + required = g_strsplit(entry->dn, "=", 10); + + + if (required) { + if (required[0]) { + osync_trace(TRACE_INTERNAL, "%s:%i: required = \"%s\"", __FILE__, __LINE__, required[0]); + + for (i = 0; entry->mods[i]; i++) { + LDAPMod *mod = entry->mods[i]; + + if (mod) { + if (mod->mod_type) { + if (!strcmp(mod->mod_type, required[0])) { + osync_trace(TRACE_INTERNAL, "%s(): OK. First element of DN \"%s\" has been found.", __func__, required[0]); + dn_attribute_found = TRUE; + + if (mod->mod_bvalues) { + if (mod->mod_bvalues[0]) { + if (mod->mod_bvalues[0]->bv_val) { + if (!strcmp(mod->mod_bvalues[0]->bv_val, entry->id)) { + osync_trace(TRACE_INTERNAL, "%s(): OK. Value of keyattribute is identical to the identifier: \"%s\".", __func__, entry->id); + identical = TRUE; + } else { + osync_trace(TRACE_ERROR, "%s:%i: WARNING: Value of keyattribute \"%s\" conflicts with identifier \"%s\". Trying to enforce correct one.", __FILE__, __LINE__, mod->mod_bvalues[0]->bv_val, entry->id); + g_free(mod->mod_bvalues[0]->bv_val); + mod->mod_bvalues[0]->bv_val = g_strdup(entry->id); + mod->mod_bvalues[0]->bv_len = strlen(entry->id); + + // What about the hash value? + } + } } } + + break; } } + } + } // for (i = 0; entry->mods[i]; i++) + + + if (check_key_attribute) { + if (dn_attribute_found == FALSE) { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: required LDAP attribute \"%s\" could not be found.", __FILE__, __LINE__, required[0]); + osync_trace(TRACE_ERROR, "%s:%i: ERROR: This happened with entry->id = \"%s\", entry->dn = \"%s\":", __FILE__, __LINE__, entry->id, entry->dn); + ldap_plugin_dump_ldap_attributes(entry); + ldap_plugin_printf("-----------------\n"); + + +#ifdef CALL_ABORT + osync_trace(TRACE_ERROR, "%s:%i: Calling abort();\n", __FILE__, __LINE__); + ldap_plugin_printf("%s:%i: Calling abort();\n", __FILE__, __LINE__); + fprintf(stderr, "%s:%i: Calling abort();\n\n", __FILE__, __LINE__); + fflush(stderr); + abort(); + +#else + if (!ldap_plugin_assure_attribute(entry, required[0], entry->id, error)) { + if (!osync_error_is_set(error)) + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_plugin_assure_attribute.\n", __FILE__, __LINE__); + + goto error; + } +#endif - break; } } + + + } else { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: required[0] = NULL.", __FILE__, __LINE__); + goto error; } - } - if (!found_name) { - osync_trace(TRACE_ERROR, "%s:%i: WARNING: Keyattribute \"%s\" could not be found.", __FILE__, __LINE__, sinkenv->keyattr); - ldap_plugin_printf("This happened with:"); - ldap_plugin_dump_ldap_attributes(entry); - ldap_plugin_printf("-------------"); + g_strfreev(required); + required = NULL; + + } else { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: required = NULL.", __FILE__, __LINE__); + goto error; } out: - osync_trace(TRACE_EXIT, "%s: found_name = %s, found_value = %s", __func__, found_name ? "TRUE" : "FALSE", found_value ? "TRUE" : "FALSE"); + osync_trace(TRACE_EXIT, "%s: dn_attribute_found = %s, identical = %s", __func__, dn_attribute_found ? "TRUE" : "FALSE", identical ? "TRUE" : "FALSE"); return TRUE; error: @@ -3871,9 +4114,6 @@ - - - /** Modified: plugins/ldap-sync/src/ldap_plugin.c ============================================================================== --- plugins/ldap-sync/src/ldap_plugin.c Wed Apr 1 20:15:48 2009 (r5509) +++ plugins/ldap-sync/src/ldap_plugin.c Wed Apr 1 23:56:44 2009 (r5510) @@ -225,9 +225,6 @@ - - - /** * @brief Since changeset r5277 gaining "sink_environment *sinkenv" * has changed: It cannot be got from a library call, any more. @@ -1090,6 +1087,123 @@ + + + +/** + * + @brief Adds one "attribute name - value" pair in form of an LDAPMod to a GList + @details ldap.h + 697 union mod_vals_u { + 698 char **modv_strvals; + 699 struct berval **modv_bvals; + 700 } mod_vals; + 701 define mod_values mod_vals.modv_strvals + 702 define mod_bvalues mod_vals.modv_bvals + + @details lber.h + 208 typedef struct berval { + 209 ber_len_t bv_len; + 210 char *bv_val; + 211 } BerValue; + + @param list A list of LDAPMod's or NULL. + @param ldapattr The attribute name out of which the LDAPMod will be built + @param value The attribute value out of which the LDAPMod will be built + @returns A list of LDAPMod's + */ + +GList *ldap_plugin_append_ldapmod(GList *list, gchar *ldapattr, gchar *value) +{ + osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, list, ldapattr, value); + + + + if (ldapattr == NULL) { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: ldapattr = NULL. Returning.\n", __FILE__, __LINE__); + goto out; + } + + + if (ldapattr[0] == 0) { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: ldapattr[0] = 0. Returning.\n", __FILE__, __LINE__); + goto out; + } + + + if (value == NULL) { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: value = NULL. Returning.\n", __FILE__, __LINE__); + goto out; + } + + + + + + LDAPMod *mod = (LDAPMod*)g_malloc0(sizeof(LDAPMod)); + mod->mod_type = g_strdup(ldapattr); + mod->mod_op = LDAP_MOD_BVALUES; // Do not forget this! + mod->mod_bvalues = (struct berval **)g_malloc0(2 * sizeof(struct berval *)); + if (mod->mod_bvalues) { + mod->mod_bvalues[1] = NULL; // terminating NULL + mod->mod_bvalues[0] = (struct berval *)g_malloc0(sizeof(struct berval)); + if (mod->mod_bvalues[0]) { + int check = 0; + + mod->mod_bvalues[0]->bv_val = g_strdup(value); + mod->mod_bvalues[0]->bv_len = strlen(value); + if (mod->mod_bvalues[0]->bv_val == NULL) { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: bv_val = NULL.\n", __FILE__, __LINE__); + } else { + if (mod->mod_bvalues[0]->bv_val[0] == 0) { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: mod->mod_bvalues[0] is 0.\n", __FILE__, __LINE__); + } else { + check = check + 1; + } + } + + if (mod->mod_bvalues[0]->bv_len == 0) { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: bv_len = 0.\n", __FILE__, __LINE__); + } else { + check = check + 1; + } + + } else { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: mod->mod_bvalues[0] = NULL. Calling abort().", __FILE__, __LINE__); + ldap_plugin_printf("%s:%i: ERROR: mod->mod_bvalues[0] = NULL. Calling abort().", __FILE__, __LINE__); + abort(); + } + + + + } else { + ldap_plugin_printf("%s:%i: ERROR: mod->mod_bvalues = NULL. malloc problem. Exiting.", __FILE__, __LINE__); + exit(1); + } + + + + list = g_list_append(list, mod); + + if (list == NULL) { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: list = NULL. \n", __FILE__, __LINE__); + } + + +out: + osync_trace(TRACE_EXIT, "%s(): list = %p", __func__, list); + return list; +} + + + + + + + + + + /** * @brief This function is just a dummy function, not a real validator * for the plugin-internal XML format. @@ -2930,7 +3044,7 @@ // Workaround for buggy peers, that send an identifier which differs // from what has been stored as value for the key attribute. - if (!ldap_plugin_check_for_keyattribute(sinkenv, entry, error)) { + if (!ldap_plugin_check_for_keyattribute(sinkenv, entry, TRUE, error)) { if (!osync_error_is_set(error)) osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_plugin_check_for_keyattribute() has failed."); @@ -3200,7 +3314,7 @@ // Make sure that the key attribute is present in the LDAP entry. // And that its value is identical to the one that builds // the identifier. - if (!ldap_plugin_check_for_keyattribute(sinkenv, entry, error)) { + if (!ldap_plugin_check_for_keyattribute(sinkenv, entry, TRUE, error)) { if (!osync_error_is_set(error)) osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_plugin_check_for_keyattribute() has failed."); @@ -3283,7 +3397,7 @@ // Make sure that the key attribute is present in the LDAP entry. // And that its value is identical to the one that builds // the identifier. - if (!ldap_plugin_check_for_keyattribute(sinkenv, entry, error)) { + if (!ldap_plugin_check_for_keyattribute(sinkenv, entry, FALSE, error)) { if (!osync_error_is_set(error)) osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_plugin_check_for_keyattribute() has failed."); Modified: plugins/ldap-sync/src/ldap_plugin.h ============================================================================== --- plugins/ldap-sync/src/ldap_plugin.h Wed Apr 1 20:15:48 2009 (r5509) +++ plugins/ldap-sync/src/ldap_plugin.h Wed Apr 1 23:56:44 2009 (r5510) @@ -71,6 +71,7 @@ #include "config.h" +#if 0 /** * @headerfile "/usr/local/include/valgrind/valgrind.h" * @headerfile "/usr/local/include/valgrind/memcheck.h" @@ -78,7 +79,6 @@ * use of certain VALGRIND macros to check addressability * and definedness of a variable. */ -#if 0 #include "/usr/local/include/valgrind/valgrind.h" #include "/usr/local/include/valgrind/memcheck.h" #endif @@ -90,19 +90,19 @@ ///< function names of this plugin keep being ///< visible in backtraces when running ///< valgrind ... --leak-check=full -#undef DISABLE_SET_SLOWSYNC 1 ///< Defining this disables all of the code - ///< that deals with setting slowsync based - ///< on any anchor or database setting. -#undef NO_OUTPUT_TO_SCREEN 1 ///< Calls to ldap_plugin_printf() print a - ///< message by default BOTH to the trace files - ///< AND to the screen. However, defining this - ///< makes this function abstain from printing - ///< anything to the screen. -#undef CALL_ABORT 1 ///< Defining this lets certain code call "abort()" rather - ///< than "goto error". The code fragments that make - ///< use of this define are known to detect error - ///< conditions in libopensync. So they are almost - ///< scheduled for debugging. +// define DISABLE_SET_SLOWSYNC 1 ///< Defining this disables all of the code + ///< that deals with setting slowsync based + ///< on any anchor or database setting. +// define NO_OUTPUT_TO_SCREEN 1 ///< Calls to ldap_plugin_printf() print a + ///< message by default BOTH to the trace files + ///< AND to the screen. However, defining this + ///< makes this function abstain from printing + ///< anything to the screen. +// define CALL_ABORT 1 ///< Defining this lets certain code call "abort()" rather + ///< than "goto error". The code fragments that make + ///< use of this define are known to detect error + ///< conditions in libopensync. So they are almost + ///< scheduled for debugging. #define DEBUG_auth 1 #define DEBUG_configuration 1 @@ -393,10 +393,12 @@ // ldap_connect.c: void ldap_plugin_add_uid_to_list(const char *uid, const char *hash, void *userdata); +GList *ldap_plugin_append_ldapmod(GList *list, gchar *ldapattr, gchar *value); +osync_bool ldap_plugin_assure_attribute(ldap_entry *entry, const char *attribute, const char *value, OSyncError **error); char *ldap_plugin_build_actual_hash(OSyncContext *ctx, sink_environment *sinkenv, const char *base, const char *filter, LDAPMessage *all_entries, OSyncError **error); osync_bool ldap_plugin_call_ldap_search(OSyncContext *ctx, const LDAP *ldap_handle, const char *searchbase, const char *filter, const int scope, const int kind_of_attributes, const sink_environment *sinkenv, LDAPMessage **results, OSyncError **error); osync_bool ldap_plugin_check_contact_format_support(OSyncContext *ctx, sink_environment *sinkenv, OSyncError **error); -osync_bool ldap_plugin_check_for_keyattribute(sink_environment *sinkenv, ldap_entry *entry, OSyncError **error); +osync_bool ldap_plugin_check_for_keyattribute(sink_environment *sinkenv, ldap_entry *entry, osync_bool check_key_attribute, OSyncError **error); osync_bool ldap_plugin_check_ldap_schema_support(OSyncContext *ctx, sink_environment *sinkenv, const char *ldap_schema, osync_bool *result, OSyncError **error); osync_bool ldap_plugin_check_modify_on_attr_vals (OSyncContext *ctx, struct berval **oldvals, struct berval **newvals, osync_bool *modification, OSyncError **error); void ldap_plugin_connect(OSyncObjTypeSink *sink, OSyncPluginInfo *info, OSyncContext *ctx, void *userdata); |