From a8911e418f7b3693479efac2a2d862fd47ec542b Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Mon, 21 Dec 2015 16:33:34 -0800 Subject: [PATCH 1/2] Ticket #48295 - Entry cache is not rolled back -- Linked Attributes plug-in - wrong behaviour when adding valid and broken links Bug Description: When multiple link attribute values are added or deleted and if some of the op was successfully and one fails, the succeeded operation's managed type appears in the managed entry although all of the link attribute operation were rolled back. The managed type indeed does not exist in the managed entry. That just in the entry cache. Once the server is restarted the changes disappear. Fix Description: If the first link attribute value operation fails, it stops the operation and returns the failure. If the second or the later operation fails, the succeeded operation up to the previous one are reverted. --- ldap/servers/plugins/linkedattrs/linked_attrs.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ldap/servers/plugins/linkedattrs/linked_attrs.c b/ldap/servers/plugins/linkedattrs/linked_attrs.c index 0d07a1f..27af287 100644 --- a/ldap/servers/plugins/linkedattrs/linked_attrs.c +++ b/ldap/servers/plugins/linkedattrs/linked_attrs.c @@ -1474,6 +1474,9 @@ linked_attrs_mod_backpointers(Slapi_PBlock *pb, char *linkdn, char *type, } else if (rc != LDAP_SUCCESS) { char *err_msg = NULL; + slapi_log_error(SLAPI_LOG_FATAL, LINK_PLUGIN_SUBSYSTEM, + "Linked Attrs Plugin: Failed to update link to target entry (%s) error %d", + targetdn, rc); err_msg = PR_smprintf("Linked Attrs Plugin: Failed to update " "link to target entry (%s) error %d", targetdn, rc); @@ -1481,6 +1484,23 @@ linked_attrs_mod_backpointers(Slapi_PBlock *pb, char *linkdn, char *type, slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, err_msg); PR_smprintf_free(err_msg); slapi_sdn_free(&targetsdn); + if (i > 0) { + int j; + Slapi_ValueSet *undoVals = slapi_valueset_new(); + /* undo 0..i-1 */ + j = slapi_valueset_first_value(targetvals, &targetval); + do { + slapi_valueset_add_value(undoVals, targetval); + j = slapi_valueset_next_value(targetvals, j, &targetval); + } while (j < i); + if (LDAP_MOD_DELETE == modop) { + modop = LDAP_MOD_ADD; + } else { + modop = LDAP_MOD_DELETE; + } + rc = linked_attrs_mod_backpointers(pb, linkdn, type, scope, modop, undoVals); + slapi_valueset_free(undoVals); + } rc = LDAP_UNWILLING_TO_PERFORM; break; } -- 2.4.3