int sync_refresh_update_content(Slapi_PBlock *pb, Sync_Cookie *client_cookie, Sync_Cookie *server_cookie) { Slapi_PBlock *seq_pb; char *filter; Sync_CallBackData cb_data; int rc; int chg_count = server_cookie->cookie_change_info - client_cookie->cookie_change_info + 1; cb_data.cb_updates = (Sync_UpdateNode *)slapi_ch_calloc(chg_count, sizeof(Sync_UpdateNode)); seq_pb = slapi_pblock_new(); slapi_pblock_init(seq_pb); cb_data.orig_pb = pb; cb_data.change_start = client_cookie->cookie_change_info; filter = slapi_ch_smprintf("(&(changenumber>=%lu)(changenumber<=%lu))", client_cookie->cookie_change_info, server_cookie->cookie_change_info); slapi_search_internal_set_pb( seq_pb, CL_SRCH_BASE, LDAP_SCOPE_ONE, filter, NULL, 0, NULL, NULL, plugin_get_default_component_id(), 0); rc = slapi_search_internal_callback_pb ( seq_pb, &cb_data, NULL, sync_read_entry_from_changelog, NULL); slapi_pblock_destroy(seq_pb); /* Now send the deleted entries in a sync info message * and the modified entries as single entries */ sync_send_deleted_entries(pb, cb_data.cb_updates, chg_count, server_cookie); sync_send_modified_entries(pb, cb_data.cb_updates, chg_count); sync_free_update_nodes(&cb_data.cb_updates, chg_count); slapi_ch_free((void **)&filter); return (rc); }
static int _do_modify(Slapi_PBlock *mod_pb, Slapi_DN *entrySDN, LDAPMod **mods) { int rc = 0; slapi_pblock_init(mod_pb); if(allow_repl){ /* Must set as a replicated operation */ slapi_modify_internal_set_pb_ext(mod_pb, entrySDN, mods, NULL, NULL, referint_plugin_identity, OP_FLAG_REPLICATED); } else { slapi_modify_internal_set_pb_ext(mod_pb, entrySDN, mods, NULL, NULL, referint_plugin_identity, 0); } slapi_modify_internal_pb(mod_pb); slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); return rc; }
int update_integrity(char **argv, Slapi_DN *origSDN, char *newrDN, Slapi_DN *newsuperior, int logChanges) { Slapi_PBlock *search_result_pb = NULL; Slapi_PBlock *mod_pb = slapi_pblock_new(); Slapi_Entry **search_entries = NULL; Slapi_DN *sdn = NULL; Slapi_Attr *attr = NULL; void *node = NULL; const char *origDN = slapi_sdn_get_dn(origSDN); const char *search_base = NULL; char *attrName = NULL; char *filter = NULL; char *attrs[2]; int search_result; int nval = 0; int i, j; int rc; if ( argv == NULL ){ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "referint_postop required config file arguments missing\n" ); rc = -1; goto free_and_return; } /* * For now, just putting attributes to keep integrity on in conf file, * until resolve the other timing mode issue */ search_result_pb = slapi_pblock_new(); /* Search each namingContext in turn */ for ( sdn = slapi_get_first_suffix( &node, 0 ); sdn != NULL; sdn = slapi_get_next_suffix( &node, 0 )) { Slapi_Backend *be = slapi_be_select(sdn); search_base = slapi_sdn_get_dn( sdn ); for(i = 3; argv[i] != NULL; i++){ filter = slapi_filter_sprintf("(%s=*%s%s)", argv[i], ESC_NEXT_VAL, origDN); if ( filter ) { /* Need only the current attribute and its subtypes */ attrs[0] = argv[i]; attrs[1] = NULL; /* Use new search API */ slapi_pblock_init(search_result_pb); slapi_pblock_set(search_result_pb, SLAPI_BACKEND, be); slapi_search_internal_set_pb(search_result_pb, search_base, LDAP_SCOPE_SUBTREE, filter, attrs, 0 /* attrs only */, NULL, NULL, referint_plugin_identity, 0); slapi_search_internal_pb(search_result_pb); slapi_pblock_get( search_result_pb, SLAPI_PLUGIN_INTOP_RESULT, &search_result); /* if search successfull then do integrity update */ if(search_result == LDAP_SUCCESS) { slapi_pblock_get(search_result_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &search_entries); for(j = 0; search_entries[j] != NULL; j++){ attr = NULL; attrName = NULL; /* * Loop over all the attributes of the entry and search * for the integrity attribute and its subtypes */ for (slapi_entry_first_attr(search_entries[j], &attr); attr; slapi_entry_next_attr(search_entries[j], attr, &attr)) { /* * Take into account only the subtypes of the attribute * in argv[i] having the necessary value - origDN */ slapi_attr_get_type(attr, &attrName); if (slapi_attr_type_cmp(argv[i], attrName, SLAPI_TYPE_CMP_SUBTYPE) == 0) { nval = 0; slapi_attr_get_numvalues(attr, &nval); /* * We want to reduce the "modify" call as much as * possible. But if an entry contains 1000s of * attributes which need to be updated by the * referint plugin (e.g., a group containing 1000s * of members), we want to avoid to allocate too * many mods * in one "modify" call. * This is a compromise: If an attribute type has * more than 128 values, we update the attribute * value one by one. Otherwise, update all values * in one "modify" call. */ if (nval > 128) { rc = _update_one_per_mod( slapi_entry_get_sdn(search_entries[j]), attr, attrName, origSDN, newrDN, slapi_sdn_get_dn(newsuperior), mod_pb); } else { rc = _update_all_per_mod( slapi_entry_get_sdn(search_entries[j]), attr, attrName, origSDN, newrDN, slapi_sdn_get_dn(newsuperior), mod_pb); } /* Should we stop if one modify returns an error? */ } } } } else { if (isFatalSearchError(search_result)){ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "update_integrity search (base=%s filter=%s) returned " "error %d\n", search_base, filter, search_result); rc = -1; goto free_and_return; } } slapi_ch_free_string(&filter); } slapi_free_search_results_internal(search_result_pb); } } /* if got here, then everything good rc = 0 */ rc = 0; free_and_return: /* free filter and search_results_pb */ slapi_ch_free_string(&filter); slapi_pblock_destroy(mod_pb); if (search_result_pb) { slapi_free_search_results_internal(search_result_pb); slapi_pblock_destroy(search_result_pb); } return(rc); }
static int linked_attrs_add_backlinks_callback(Slapi_Entry *e, void *callback_data) { int rc = 0; char *linkdn = slapi_entry_get_dn(e); struct configEntry *config = (struct configEntry *)callback_data; Slapi_PBlock *pb = slapi_pblock_new(); int i = 0; char **targets = NULL; char *val[2]; LDAPMod mod; LDAPMod *mods[2]; /* Setup the modify operation. Only the target will * change, so we only need to do this once. */ val[0] = linkdn; val[1] = 0; mod.mod_op = LDAP_MOD_ADD; mod.mod_type = config->managedtype; mod.mod_values = val; mods[0] = &mod; mods[1] = 0; targets = slapi_entry_attr_get_charray(e, config->linktype); for (i = 0; targets && targets[i]; ++i) { char *targetdn = (char *)targets[i]; int perform_update = 0; Slapi_DN *targetsdn = NULL; if (slapi_is_shutting_down()) { rc = -1; goto done; } targetsdn = slapi_sdn_new_normdn_byref(targetdn); if (config->scope) { /* Check if the target is within the scope. */ perform_update = slapi_dn_issuffix(targetdn, config->scope); } else { /* Find out the root suffix that the linkdn is in * and see if the target is in the same backend. */ Slapi_Backend *be = NULL; Slapi_DN *linksdn = slapi_sdn_new_normdn_byref(linkdn); if ((be = slapi_be_select(linksdn))) { perform_update = slapi_sdn_issuffix(targetsdn, slapi_be_getsuffix(be, 0)); } slapi_sdn_free(&linksdn); } if (perform_update) { slapi_log_error(SLAPI_LOG_PLUGIN, LINK_PLUGIN_SUBSYSTEM, "Adding backpointer (%s) in entry (%s)\n", linkdn, targetdn); /* Perform the modify operation. */ slapi_modify_internal_set_pb_ext(pb, targetsdn, mods, 0, 0, linked_attrs_get_plugin_id(), 0); slapi_modify_internal_pb(pb); /* Initialize the pblock so we can reuse it. */ slapi_pblock_init(pb); } slapi_sdn_free(&targetsdn); } done: slapi_ch_array_free(targets); slapi_pblock_destroy(pb); return rc; }
static void linked_attrs_fixup_links(struct configEntry *config) { Slapi_PBlock *pb = slapi_pblock_new(); char *del_filter = NULL; char *add_filter = NULL; del_filter = slapi_ch_smprintf("%s=*", config->managedtype); add_filter = slapi_ch_smprintf("%s=*", config->linktype); /* Lock the attribute pair. */ slapi_lock_mutex(config->lock); if (config->scope) { /* Find all entries with the managed type present * within the scope and remove the managed type. */ slapi_search_internal_set_pb(pb, config->scope, LDAP_SCOPE_SUBTREE, del_filter, 0, 0, 0, 0, linked_attrs_get_plugin_id(), 0); slapi_search_internal_callback_pb(pb, config->managedtype, 0, linked_attrs_remove_backlinks_callback, 0); /* Clean out pblock for reuse. */ slapi_pblock_init(pb); /* Find all entries with the link type present within the * scope and add backlinks to the entries they point to. */ slapi_search_internal_set_pb(pb, config->scope, LDAP_SCOPE_SUBTREE, add_filter, 0, 0, 0, 0, linked_attrs_get_plugin_id(), 0); slapi_search_internal_callback_pb(pb, config, 0, linked_attrs_add_backlinks_callback, 0); } else { /* Loop through all non-private backend suffixes and * remove the managed type from any entry that has it. * We then find any entry with the linktype present and * generate the proper backlinks. */ void *node = NULL; Slapi_DN * suffix = slapi_get_first_suffix (&node, 0); while (suffix) { slapi_search_internal_set_pb(pb, slapi_sdn_get_dn(suffix), LDAP_SCOPE_SUBTREE, del_filter, 0, 0, 0, 0, linked_attrs_get_plugin_id(), 0); slapi_search_internal_callback_pb(pb, config->managedtype, 0, linked_attrs_remove_backlinks_callback, 0); /* Clean out pblock for reuse. */ slapi_pblock_init(pb); slapi_search_internal_set_pb(pb, slapi_sdn_get_dn(suffix), LDAP_SCOPE_SUBTREE, add_filter, 0, 0, 0, 0, linked_attrs_get_plugin_id(), 0); slapi_search_internal_callback_pb(pb, config, 0, linked_attrs_add_backlinks_callback, 0); /* Clean out pblock for reuse. */ slapi_pblock_init(pb); suffix = slapi_get_next_suffix (&node, 0); } } /* Unlock the attribute pair. */ slapi_unlock_mutex(config->lock); slapi_ch_free_string(&del_filter); slapi_ch_free_string(&add_filter); slapi_pblock_destroy(pb); }