| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693 |
- /** BEGIN COPYRIGHT BLOCK
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- *
- * License: GPL (version 3 or any later version).
- * See LICENSE for details.
- * END COPYRIGHT BLOCK **/
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include "retrocl.h"
- static int
- entry2reple(Slapi_Entry *e, Slapi_Entry *oe, int optype);
- static int
- mods2reple(Slapi_Entry *e, LDAPMod **ldm);
- static int
- modrdn2reple(Slapi_Entry *e, const char *newrdn, int deloldrdn, LDAPMod **ldm, const char *newsup);
- /******************************/
- const char *attr_changenumber = "changenumber";
- const char *attr_targetdn = "targetdn";
- const char *attr_changetype = "changetype";
- const char *attr_newrdn = "newrdn";
- const char *attr_deleteoldrdn = "deleteoldrdn";
- const char *attr_changes = "changes";
- const char *attr_newsuperior = "newsuperior";
- const char *attr_changetime = "changetime";
- const char *attr_objectclass = "objectclass";
- const char *attr_nsuniqueid = "nsuniqueid";
- const char *attr_isreplicated = "isreplicated";
- /*
- * Function: make_changes_string
- *
- * Returns:
- *
- * Arguments:
- *
- * Description:
- * loop through the LDAPMod struct and construct the changes attribute/
- *
- */
- static lenstr *
- make_changes_string(LDAPMod **ldm, const char **includeattrs)
- {
- lenstr *l;
- int i, j, len;
- int skip;
- l = lenstr_new();
- for (i = 0; ldm[i] != NULL; i++) {
- /* If a list of explicit attributes was given, only add those */
- if (NULL != includeattrs) {
- skip = 1;
- for (j = 0; includeattrs[j] != NULL; j++) {
- if (strcasecmp(includeattrs[j], ldm[i]->mod_type) == 0) {
- skip = 0;
- break;
- }
- }
- if (skip) {
- continue;
- }
- }
- if (SLAPD_UNHASHED_PW_NOLOG == slapi_config_get_unhashed_pw_switch()) {
- if (0 == strcasecmp(ldm[i]->mod_type, PSEUDO_ATTR_UNHASHEDUSERPASSWORD)) {
- /* If nsslapd-unhashed-pw-switch == nolog, skip writing it to cl. */
- continue;
- }
- }
- switch (ldm[i]->mod_op & ~LDAP_MOD_BVALUES) {
- case LDAP_MOD_ADD:
- addlenstr(l, "add: ");
- addlenstr(l, ldm[i]->mod_type);
- addlenstr(l, "\n");
- break;
- case LDAP_MOD_DELETE:
- addlenstr(l, "delete: ");
- addlenstr(l, ldm[i]->mod_type);
- addlenstr(l, "\n");
- break;
- case LDAP_MOD_REPLACE:
- addlenstr(l, "replace: ");
- addlenstr(l, ldm[i]->mod_type);
- addlenstr(l, "\n");
- break;
- }
- for (j = 0; ldm[i]->mod_bvalues != NULL &&
- ldm[i]->mod_bvalues[j] != NULL;
- j++) {
- char *buf = NULL;
- char *bufp = NULL;
- len = strlen(ldm[i]->mod_type);
- len = LDIF_SIZE_NEEDED(len,
- ldm[i]->mod_bvalues[j]->bv_len) +
- 1;
- buf = slapi_ch_malloc(len);
- bufp = buf;
- slapi_ldif_put_type_and_value_with_options(&bufp, ldm[i]->mod_type,
- ldm[i]->mod_bvalues[j]->bv_val,
- ldm[i]->mod_bvalues[j]->bv_len, 0);
- *bufp = '\0';
- addlenstr(l, buf);
- slapi_ch_free_string(&buf);
- }
- addlenstr(l, "-\n");
- }
- return l;
- }
- /*
- * Function: write_replog_db
- * Arguments: be - backend to which this change is being applied
- * optype - type of LDAP operation being logged
- * dn - distinguished name of entry being changed
- * log_m - pointer to the actual change operation on a modify
- * flag - only used by modrdn operations - value of deleteoldrdn
- * curtime - the current time
- * Returns: error code
- * Description: Given a change, construct an entry which is to be added to the
- * changelog database.
- */
- static int
- write_replog_db(
- Slapi_PBlock *pb,
- int optype,
- char *dn,
- LDAPMod **log_m,
- int flag,
- time_t curtime,
- Slapi_Entry *log_e,
- Slapi_Entry *post_entry,
- const char *newrdn,
- LDAPMod **modrdn_mods,
- const char *newsuperior)
- {
- Slapi_PBlock *newPb = NULL;
- changeNumber changenum;
- struct berval *vals[2];
- struct berval val;
- Slapi_Entry *e;
- char chnobuf[22] = {0};
- char *edn;
- int extensibleObject = 0;
- int err = 0;
- int ret = LDAP_SUCCESS;
- int i;
- if (!dn) {
- slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "write_replog_db: NULL dn\n");
- return ret;
- }
- if (post_entry) {
- if (!retrocl_entry_in_scope(log_e) && !retrocl_entry_in_scope(post_entry)) {
- /* modrdn: entry not in scope, just return... */
- return ret;
- }
- } else {
- if (!retrocl_entry_in_scope(log_e)) {
- /* entry not in scope, just return... */
- return ret;
- }
- }
- PR_Lock(retrocl_internal_lock);
- changenum = retrocl_assign_changenumber();
- PR_ASSERT(changenum > 0UL);
- slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME,
- "write_replog_db: write change record %lu for dn: \"%s\"\n",
- changenum, dn);
- /* Construct the dn of this change record */
- edn = slapi_ch_smprintf("%s=%lu,%s", attr_changenumber, changenum, RETROCL_CHANGELOG_DN);
- /*
- * Create the entry struct, and fill in fields common to all types
- * of change records.
- */
- vals[0] = &val;
- vals[1] = NULL;
- e = slapi_entry_alloc();
- slapi_entry_set_dn(e, slapi_ch_strdup(edn));
- /* Set the objectclass attribute */
- val.bv_val = "top";
- val.bv_len = 3;
- slapi_entry_add_values(e, "objectclass", vals);
- val.bv_val = "changelogentry";
- val.bv_len = 14;
- slapi_entry_add_values(e, "objectclass", vals);
- for (i = 0; i < retrocl_nattributes; i++) {
- char *attributeName = retrocl_attributes[i];
- char *attributeAlias = retrocl_aliases[i];
- if (attributeAlias == NULL) {
- attributeAlias = attributeName;
- }
- if (strcasecmp(attributeName, attr_nsuniqueid) == 0) {
- Slapi_Entry *entry = NULL;
- const char *uniqueId = NULL;
- slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &entry);
- if (entry == NULL) {
- slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &entry);
- }
- if (entry == NULL)
- continue;
- uniqueId = slapi_entry_get_uniqueid(entry);
- slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME,
- "write_replog_db: add %s: \"%s\"\n", attributeAlias, uniqueId);
- val.bv_val = (char *)uniqueId;
- val.bv_len = strlen(uniqueId);
- slapi_entry_add_values(e, attributeAlias, vals);
- extensibleObject = 1;
- } else if (strcasecmp(attributeName, attr_isreplicated) == 0) {
- int isReplicated = 0;
- char *attributeValue = NULL;
- slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &isReplicated);
- attributeValue = isReplicated ? "TRUE" : "FALSE";
- slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME,
- "write_replog_db: add %s: \"%s\"\n", attributeAlias, attributeValue);
- val.bv_val = attributeValue;
- val.bv_len = strlen(attributeValue);
- slapi_entry_add_values(e, attributeAlias, vals);
- extensibleObject = 1;
- } else {
- Slapi_Entry *entry = NULL;
- Slapi_ValueSet *valueSet = NULL;
- int type_name_disposition = 0;
- char *actual_type_name = NULL;
- int flags = 0;
- int buffer_flags = 0;
- slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &entry);
- if (entry != NULL) {
- slapi_vattr_values_get(entry, attributeName, &valueSet,
- &type_name_disposition, &actual_type_name, flags, &buffer_flags);
- }
- if (valueSet == NULL) {
- slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &entry);
- if (entry != NULL) {
- slapi_vattr_values_get(entry, attributeName, &valueSet,
- &type_name_disposition, &actual_type_name, flags, &buffer_flags);
- }
- }
- if (valueSet == NULL)
- continue;
- slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME,
- "write_replog_db: add %s\n", attributeAlias);
- slapi_entry_add_valueset(e, attributeAlias, valueSet);
- slapi_vattr_values_free(&valueSet, &actual_type_name, buffer_flags);
- extensibleObject = 1;
- }
- }
- if (extensibleObject) {
- val.bv_val = "extensibleObject";
- val.bv_len = 16;
- slapi_entry_add_values(e, "objectclass", vals);
- }
- /* Set the changeNumber attribute */
- sprintf(chnobuf, "%lu", changenum);
- val.bv_val = chnobuf;
- val.bv_len = strlen(chnobuf);
- slapi_entry_add_values(e, attr_changenumber, vals);
- /* Set the targetentrydn attribute */
- val.bv_val = dn;
- val.bv_len = strlen(dn);
- slapi_entry_add_values(e, attr_targetdn, vals);
- /* Set the changeTime attribute */
- val.bv_val = format_genTime(curtime);
- val.bv_len = strlen(val.bv_val);
- slapi_entry_add_values(e, attr_changetime, vals);
- slapi_ch_free((void **)&val.bv_val);
- /*
- * Finish constructing the entry. How to do it depends on the type
- * of modification being logged.
- */
- switch (optype) {
- case OP_ADD:
- if (entry2reple(e, log_e, OP_ADD) != 0) {
- err = SLAPI_PLUGIN_FAILURE;
- }
- break;
- case OP_MODIFY:
- if (mods2reple(e, log_m) != 0) {
- err = SLAPI_PLUGIN_FAILURE;
- }
- break;
- case OP_MODRDN:
- if (modrdn2reple(e, newrdn, flag, modrdn_mods, newsuperior) != 0) {
- err = SLAPI_PLUGIN_FAILURE;
- }
- break;
- case OP_DELETE:
- if (retrocl_log_deleted) {
- /* we have to log the full entry */
- if (entry2reple(e, log_e, OP_DELETE) != 0) {
- err = SLAPI_PLUGIN_FAILURE;
- }
- } else {
- /* Set the changetype attribute */
- val.bv_val = "delete";
- val.bv_len = 6;
- slapi_entry_add_values(e, attr_changetype, vals);
- }
- break;
- default:
- slapi_log_err(SLAPI_LOG_ERR, RETROCL_PLUGIN_NAME,
- "write_replog_db - Unknown LDAP operation type %d.\n", optype);
- err = SLAPI_PLUGIN_FAILURE;
- }
- /* Call the repl backend to add this entry */
- if (0 == err) {
- newPb = slapi_pblock_new();
- slapi_add_entry_internal_set_pb(newPb, e, NULL /* controls */,
- g_plg_identity[PLUGIN_RETROCL],
- /* dont leave entry in cache if main oparation is aborted */
- SLAPI_OP_FLAG_NEVER_CACHE);
- slapi_add_internal_pb(newPb);
- slapi_pblock_get(newPb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
- slapi_pblock_destroy(newPb);
- if (0 != ret) {
- slapi_log_err(SLAPI_LOG_ERR, RETROCL_PLUGIN_NAME,
- "write_replog_db - An error occured while adding change "
- "number %lu, dn = %s: %s. \n",
- changenum, edn, ldap_err2string(ret));
- retrocl_release_changenumber();
- } else {
- /* Tell the change numbering system this one's committed to disk */
- retrocl_commit_changenumber();
- }
- } else {
- slapi_log_err(SLAPI_LOG_ERR, RETROCL_PLUGIN_NAME,
- "write_replog_db - An error occurred while constructing "
- "change record number %ld.\n",
- changenum);
- retrocl_release_changenumber();
- ret = err;
- }
- PR_Unlock(retrocl_internal_lock);
- if (NULL != edn) {
- slapi_ch_free((void **)&edn);
- }
- return ret;
- }
- /*
- * Function: entry2reple
- * Arguments: e - a partially-constructed Slapi_Entry structure
- * oe - the original entry (an entry being added by a client).
- * Returns: 0 on success.
- * Description: Given an Slapi_Entry struct, construct a changelog entry which will be
- * added to the replication database. It is assumed that e points
- * to an entry obtained from slapi_entry_alloc().
- */
- static int
- entry2reple(Slapi_Entry *e, Slapi_Entry *oe, int optype)
- {
- char *p, *estr;
- struct berval *vals[2];
- struct berval val;
- int len;
- vals[0] = &val;
- vals[1] = NULL;
- /* Set the changetype attribute */
- if (optype == OP_ADD) {
- val.bv_val = "add";
- val.bv_len = 3;
- } else if (optype == OP_DELETE) {
- val.bv_val = "delete";
- val.bv_len = 6;
- } else {
- return (1);
- }
- slapi_entry_add_values(e, attr_changetype, vals);
- estr = slapi_entry2str(oe, &len);
- p = estr;
- /* Skip over the dn: line */
- while ((p = strchr(p, '\n')) != NULL) {
- p++;
- if (!ldap_utf8isspace(p)) {
- break;
- }
- }
- val.bv_val = p;
- val.bv_len = len - (p - estr); /* length + terminating \0 */
- slapi_entry_add_values(e, attr_changes, vals);
- slapi_ch_free_string(&estr);
- return 0;
- }
- /*
- * Function: mods2reple
- * Arguments: e - a partially-constructed Slapi_Entry structure
- * ldm - an array of pointers to LDAPMod structures describing the
- * change applied.
- * Returns: 0 on success.
- * Description: Given a pointer to an LDAPMod struct and a dn, construct
- * a new entry which will be added to the replication database.
- * It is assumed that e points to an entry obtained from
- * slapi_entry_alloc().
- */
- static int
- mods2reple(Slapi_Entry *e, LDAPMod **ldm)
- {
- struct berval val;
- struct berval *vals[2];
- lenstr *l;
- vals[0] = &val;
- vals[1] = NULL;
- /* Set the changetype attribute */
- val.bv_val = "modify";
- val.bv_len = 6;
- slapi_entry_add_values(e, "changetype", vals);
- if (NULL != ldm) {
- l = make_changes_string(ldm, NULL);
- if (NULL != l) {
- val.bv_val = l->ls_buf;
- val.bv_len = l->ls_len + 1; /* string + terminating \0 */
- slapi_entry_add_values(e, attr_changes, vals);
- lenstr_free(&l);
- }
- }
- return 0;
- }
- /*
- * Function: modrdn2reple
- * Arguments: e - a partially-constructed Slapi_Entry structure
- * newrdn - the new relative distinguished name for the entry
- * deloldrdn - the "deleteoldrdn" flag provided by the client
- * ldm - any modifications applied as a side-effect of the modrdn
- * Returns: 0 on success
- * Description: Given a dn, a new rdn, and a deleteoldrdn flag, construct
- * a new entry which will be added to the replication database reflecting a
- * completed modrdn operation. The entry has the same form as above.
- * It is assumed that e points to an entry obtained from slapi_entry_alloc().
- */
- static int
- modrdn2reple(
- Slapi_Entry *e,
- const char *newrdn,
- int deloldrdn,
- LDAPMod **ldm,
- const char *newsuperior)
- {
- struct berval val;
- struct berval *vals[2];
- lenstr *l;
- static const char *lastmodattrs[] = {"modifiersname", "modifytimestamp",
- "creatorsname", "createtimestamp",
- NULL};
- vals[0] = &val;
- vals[1] = NULL;
- val.bv_val = "modrdn";
- val.bv_len = 6;
- slapi_entry_add_values(e, attr_changetype, vals);
- if (newrdn) {
- val.bv_val = (char *)newrdn; /* cast away const */
- val.bv_len = strlen(newrdn);
- slapi_entry_add_values(e, attr_newrdn, vals);
- }
- if (deloldrdn == 0) {
- val.bv_val = "FALSE";
- val.bv_len = 5;
- } else {
- val.bv_val = "TRUE";
- val.bv_len = 4;
- }
- slapi_entry_add_values(e, attr_deleteoldrdn, vals);
- if (newsuperior) {
- val.bv_val = (char *)newsuperior; /* cast away const */
- val.bv_len = strlen(newsuperior);
- slapi_entry_add_values(e, attr_newsuperior, vals);
- }
- if (NULL != ldm) {
- l = make_changes_string(ldm, lastmodattrs);
- if (NULL != l) {
- if (l->ls_len) {
- val.bv_val = l->ls_buf;
- val.bv_len = l->ls_len;
- slapi_entry_add_values(e, attr_changes, vals);
- }
- lenstr_free(&l);
- }
- }
- return 0;
- }
- /*
- * Function: retrocl_postob
- *
- * Returns: 0 on success
- *
- * Arguments: pblock, optype (add, del, modify etc)
- *
- * Description: called from retrocl.c op-specific plugins.
- *
- * Please be aware that operation threads may be scheduled out between their
- * being performed inside of the LDBM database and the changelog plugin
- * running. For example, suppose MA and MB are two modify operations on the
- * same entry. MA may be performed on the LDBM database, and then block
- * before the changelog runs. MB then runs against the LDBM database and then
- * is written to the changelog. MA starts running. In the changelog, MB will
- * appear to have been performed before MA, but in the LDBM database the
- * opposite will have occured.
- *
- *
- */
- int
- retrocl_postob(Slapi_PBlock *pb, int optype)
- {
- char *dn;
- LDAPMod **log_m = NULL;
- int flag = 0;
- Slapi_Entry *entry = NULL;
- Slapi_Entry *post_entry = NULL;
- Slapi_Operation *op = NULL;
- LDAPMod **modrdn_mods = NULL;
- char *newrdn = NULL;
- Slapi_DN *newsuperior = NULL;
- Slapi_Backend *be = NULL;
- time_t curtime;
- int rc = SLAPI_PLUGIN_SUCCESS;
- /*
- * Check to see if the change was made to the replication backend db.
- * If so, don't try to log it to the db (otherwise, we'd get in a loop).
- */
- (void)slapi_pblock_get(pb, SLAPI_BACKEND, &be);
- if (be == NULL) {
- slapi_log_err(SLAPI_LOG_ERR, RETROCL_PLUGIN_NAME, "retrocl_postob - Backend is not set\n");
- return SLAPI_PLUGIN_FAILURE;
- }
- if (slapi_be_logchanges(be) == 0) {
- slapi_log_err(SLAPI_LOG_TRACE, RETROCL_PLUGIN_NAME, "retrocl_postob - Not applying change if not logging\n");
- return SLAPI_PLUGIN_SUCCESS;
- }
- if (retrocl_be_changelog == NULL || be == retrocl_be_changelog) {
- slapi_log_err(SLAPI_LOG_TRACE, RETROCL_PLUGIN_NAME, "retrocl_postob - Not applying change if no/cl be\n");
- return SLAPI_PLUGIN_SUCCESS;
- }
- slapi_pblock_get(pb, SLAPI_RESULT_CODE, &rc);
- if (rc != LDAP_SUCCESS) {
- slapi_log_err(SLAPI_LOG_TRACE, RETROCL_PLUGIN_NAME, "retrocl_postob - Not applying change if op failed %d\n", rc);
- /* this could also mean that the changenumber is no longer correct
- * set a flag to check at next assignment
- */
- retrocl_set_check_changenumber();
- return SLAPI_PLUGIN_SUCCESS;
- }
- if (slapi_op_abandoned(pb)) {
- slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "retrocl_postob - Not applying change if op abandoned\n");
- return SLAPI_PLUGIN_SUCCESS;
- }
- curtime = slapi_current_utc_time();
- (void)slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &dn);
- /* change number could be retrieved from Operation extension stored in
- * the pblock, or else it needs to be made dynamically. */
- /* get the operation extension and retrieve the change number */
- slapi_pblock_get(pb, SLAPI_OPERATION, &op);
- if (op == NULL) {
- slapi_log_err(SLAPI_LOG_TRACE, RETROCL_PLUGIN_NAME, "retrocl_postob - Not applying change if no op\n");
- return SLAPI_PLUGIN_SUCCESS;
- }
- if (operation_is_flag_set(op, OP_FLAG_TOMBSTONE_ENTRY)) {
- slapi_log_err(SLAPI_LOG_TRACE, RETROCL_PLUGIN_NAME, "retrocl_postob - Not applying change for nsTombstone entries\n");
- return SLAPI_PLUGIN_SUCCESS;
- }
- /*
- * Start by grabbing the preop entry, ADD will replace it as needed. Getting the entry
- * allows up to perform scoping in write_replog_db() for all op types.
- */
- (void)slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &entry);
- switch (optype) {
- case OP_MODIFY:
- (void)slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &log_m);
- break;
- case OP_ADD:
- /*
- * For adds, we want the unnormalized dn, so we can preserve
- * spacing, case, when replicating it.
- */
- (void)slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &entry);
- if (NULL != entry) {
- dn = slapi_entry_get_dn(entry);
- }
- break;
- case OP_DELETE:
- if (retrocl_log_deleted)
- (void)slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &entry);
- break;
- case OP_MODRDN:
- /* newrdn is used just for logging; no need to be normalized */
- (void)slapi_pblock_get(pb, SLAPI_MODRDN_NEWRDN, &newrdn);
- (void)slapi_pblock_get(pb, SLAPI_MODRDN_DELOLDRDN, &flag);
- (void)slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &modrdn_mods);
- (void)slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &newsuperior);
- (void)slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &post_entry);
- break;
- }
- /* check if we should log change to retro changelog, and
- * if so, do it here */
- if ((rc = write_replog_db(pb, optype, dn, log_m, flag, curtime, entry,
- post_entry, newrdn, modrdn_mods, slapi_sdn_get_dn(newsuperior)))) {
- slapi_log_err(SLAPI_LOG_ERR, RETROCL_PLUGIN_NAME,
- "retrocl_postob - Operation failure [%d]\n", rc);
- if (rc < 0) {
- rc = LDAP_OPERATIONS_ERROR;
- }
- slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
- rc = SLAPI_PLUGIN_FAILURE;
- }
- return rc;
- }
|