Ticket #47367 - (phase 1) ldapdelete returns non-leaf entry error while trying to remove a leaf entry
Bug description: Replication conflict confuses the numsubordinate count,
which leaves an entry that cannot be deleted even its subordinate entries
are all removed.
Fix description:
[urp.c] 1) get_dn_plus_uniqueid: a logic to create a conflict DN had a bug.
It used to call slapi_sdn_get_rdn to get the rdn. The function slapi_sdn_
get_rdn blindly returned the "dn" field without checking whether the field
is NULL or not. Instead, this patch changes the interface of the helper
function get_dn_plus_uniqueid and use the original Slapi_DN with slapi_sdn_
get_dn, then generates the conflict DN "nsuniqueid=...+ <RDN>,<PARENT>".
2) The urp calling timing was moved from SLAPI_PLUGIN_BE_TXN_PRE_* to
SLAPI_PLUGIN_BE_PRE_*. (Note: SLAPI_PLUGIN_BE_PRE_* is also in the
backend transaction.) This is necessary since urp needs to be done
prior to parent checking.
[ldbm_add.c] Moved SLAPI_PLUGIN_BE_PRE_ADD_FN inside of the transaction.
Other operations are already calling SLAPI_PLUGIN_BE_PRE function at the
timing.
[ldbm_delete.c] There is a case a parent of a delete-candidate entry runs
into a conflict and multiple parent entries exist. Once it occurs, a
parent entry found by the parent dn string may not be the entry which
manages the numsubordinate count the delete-candidate entry belonging to.
It confuses the numsubordinate counts and leaves an entry which cannot be
deleted due to the numsubordinate count mismatch. This patch retrieves
parent entry by parent id if it is available.
[ldbm_entryrdn.c] When traversing the DIT, a special treatment is needed
for a tombstone entry. I.e, 2 RDNs (nsuniqueid=..., <RDN>) is treated as
one RDN. It should decrement the index (rdnidx) one more to point to the
right position of the RDN array in Slapi_RDN.
[ldbm_search.c] When checking the scope of an entry in ldbm_back_next_
search_entry_ext, a tombstone entry was not properly examined. This patch
introduces a new slapi api slapi_sdn_scope_test_ext.
[dn.c] In slapi_sdn_get_rdn, use slapi_sdn_get_dn to get the dn value of
Slapi_DN. It was one cause of the problem in get_dn_plus_uniqueid (urp.c).
This patch adds slapi_sdn_scope_test_ext, which takes flags to indicates
the first argument dn is a tombstone sdn. Also, this patch replaces
"malloc + strcpy + strcat" with slapi_ch_smprintf to improve the
readability of the code.
[rdn.c] This patch replaces "malloc + strcpy + strcat" with slapi_create_
dn_string to normalize the newly added rdn and improve the readability of
the code.
Reviewed by Rich (Thanks!!)
https://fedorahosted.org/389/ticket/47367
(cherry picked from commit 2f4f74b3d38eeb38f0794dfb2e880a95e7e9bd49)
(cherry picked from commit 690d58ba5870e7f0dd3ad6593c92a86771fc54d5)