Blob Blame Raw
From 2648c806841f09fe2ff130691b4a605feef7eb9b Mon Sep 17 00:00:00 2001
From: Noriko Hosoi <nhosoi@redhat.com>
Date: Thu, 26 Sep 2013 09:18:11 -0700
Subject: [PATCH 18/28] Ticket #47523 - Set up replcation/agreement before initializing the sub suffix, the sub suffix is not found by ldapsearch

Bug description: If a replication is configured against a backend
before initializing the backend with a suffix entry, an RUV entry
is inserted first with the entryid 1. The RUV entry's entryrdn is
added to the entryrdn index with a suffix entry which is a parent
entry of the RUV entry having a temporary entryid 0, which was to
be replaced with the real entryid when the real suffix entry is
added.  But the replacement code was not executed.

Fix description: When a real suffix is added to the entryrdn index,
it returns DB_KEYEXIST, which used to be ignored by resetting 0
(== SUCCESS).  This patch returns DB_KEYEXIST to the caller and let
_entryrdn_insert_key use the info to replace the temporary entryid
with the real one.  The error code is ignored by the other callers.

https://fedorahosted.org/389/ticket/47523

Reviewed by nkinder (Thanks!).
(cherry picked from commit e6eab21920a0374eb356da3d1f041312c6857ecd)
(cherry picked from commit 6b35dc7b04da023cc14045cc6dd1f5e304cf265f)
---
 ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c |   39 ++++++++++++++------------
 1 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
index 22940cc..d381166 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
@@ -748,7 +748,7 @@ entryrdn_rename_subtree(backend *be,
         renamedata.data = (void *)newelem;
         renamedata.flags = DB_DBT_USERMEM;
         rc = _entryrdn_put_data(cursor, &key, &renamedata, RDN_INDEX_SELF, db_txn);
-        if (rc) {
+        if (rc && (DB_KEYEXIST != rc)) { /* failed && ignore already exists */
             slapi_log_error(ENTRYRDN_LOGLEVEL(rc), ENTRYRDN_TAG,
                                 "entryrdn_rename_subtree: Adding %s failed; "
                                 "%s(%d)\n", keybuf, dblayer_strerror(rc), rc);
@@ -769,7 +769,7 @@ entryrdn_rename_subtree(backend *be,
                 renamedata.flags = DB_DBT_USERMEM;
                 rc = _entryrdn_put_data(cursor, &key,
                                         &renamedata, RDN_INDEX_CHILD, db_txn);
-                if (rc) {
+                if (rc && (DB_KEYEXIST != rc)) { /* failed && ignore already exists */
                     goto bail;
                 }
             }
@@ -814,7 +814,7 @@ entryrdn_rename_subtree(backend *be,
             renamedata.data = (void *)newsupelem;
         }
         rc = _entryrdn_put_data(cursor, &key, &renamedata, RDN_INDEX_PARENT, db_txn);
-        if (rc) {
+        if (rc && (DB_KEYEXIST != rc)) { /* failed && ignore already exists */
             slapi_log_error(ENTRYRDN_LOGLEVEL(rc), ENTRYRDN_TAG,
                                              "entryrdn_rename_subtree: Adding "
                                              "%s failed; %s(%d)\n",
@@ -849,7 +849,7 @@ entryrdn_rename_subtree(backend *be,
             renamedata.data = (void *)newelem;
             renamedata.flags = DB_DBT_USERMEM;
             rc = _entryrdn_put_data(cursor, &key, &renamedata, RDN_INDEX_SELF, db_txn);
-            if (rc) {
+            if (rc && (DB_KEYEXIST != rc)) { /* failed && ignore already exists */
                 slapi_log_error(ENTRYRDN_LOGLEVEL(rc), ENTRYRDN_TAG,
                                   "entryrdn_rename_subtree: Adding %s failed; "
                                   "%s(%d)\n", keybuf, dblayer_strerror(rc), rc);
@@ -902,7 +902,7 @@ entryrdn_rename_subtree(backend *be,
             renamedata.flags = DB_DBT_USERMEM;
         }
         rc = _entryrdn_put_data(cursor, &key, &renamedata, RDN_INDEX_CHILD, db_txn);
-        if (rc) {
+        if (rc && (DB_KEYEXIST != rc)) { /* failed && ignore already exists */
             goto bail;
         }
     }
@@ -1955,12 +1955,11 @@ _entryrdn_put_data(DBC *cursor, DBT *key, DBT *data, char type, DB_TXN *db_txn)
         rc = cursor->c_put(cursor, key, data, DB_NODUPDATA);
         if (rc) {
             if (DB_KEYEXIST == rc) {
-                /* this is okay */
+                /* this is okay, but need to return DB_KEYEXIST to caller */
                 slapi_log_error(SLAPI_LOG_BACKLDBM, ENTRYRDN_TAG,
                                 "_entryrdn_put_data: The same key (%s) and the "
                                 "data exists in index\n",
                                 (char *)key->data);
-                rc = 0;
                 break;
             } else {
                 char *keyword = NULL;
@@ -2109,7 +2108,7 @@ _entryrdn_insert_key_elems(backend *be,
     /* adding RDN to the child key */
     rc = _entryrdn_put_data(cursor, key, &adddata, RDN_INDEX_CHILD, db_txn);
     keybuf = key->data;
-    if (rc) { /* failed */
+    if (rc && (DB_KEYEXIST != rc)) { /* failed && ignore already exists */
         goto bail;
     }
 
@@ -2125,7 +2124,7 @@ _entryrdn_insert_key_elems(backend *be,
     key->flags = DB_DBT_USERMEM;    
 
     rc = _entryrdn_put_data(cursor, key, &adddata, RDN_INDEX_SELF, db_txn);
-    if (rc) { /* failed */
+    if (rc && (DB_KEYEXIST != rc)) { /* failed && ignore already exists */
         goto bail;
     }
 
@@ -2145,6 +2144,9 @@ _entryrdn_insert_key_elems(backend *be,
     adddata.flags = DB_DBT_USERMEM;
     /* adding RDN to the self key */
     rc = _entryrdn_put_data(cursor, key, &adddata, RDN_INDEX_PARENT, db_txn);
+    if (DB_KEYEXIST == rc) { /* failed && ignore already exists */
+        rc = 0;
+    }
     /* Succeeded or failed, it's done. */
 bail:
     slapi_ch_free_string(&keybuf);
@@ -2268,7 +2270,7 @@ _entryrdn_replace_suffix_id(DBC *cursor, DBT *key, DBT *adddata,
             /* Add it back */
             rc = _entryrdn_put_data(cursor, &realkey, &moddata, 
                                                 RDN_INDEX_CHILD, db_txn);
-            if (rc) {
+            if (rc && (DB_KEYEXIST != rc)) { /* failed && ignore already exists */
                 goto bail0;
             }
             if (curr_childnum + 1 == childnum) {
@@ -2531,7 +2533,7 @@ _entryrdn_insert_key(backend *be,
         slapi_ch_free_string(&dn);
         goto bail;
     }
-    elem = _entryrdn_new_rdn_elem(be, 0 /*fake id*/, tmpsrdn, &len);
+    elem = _entryrdn_new_rdn_elem(be, TMPID, tmpsrdn, &len);
     if (NULL == elem) {
         char *dn  = NULL;
         slapi_rdn_get_dn(tmpsrdn, &dn);
@@ -2551,12 +2553,13 @@ _entryrdn_insert_key(backend *be,
     rc = _entryrdn_get_elem(cursor, &key, &data, nrdn, &elem); 
     if (rc) {
         const char *myrdn = slapi_rdn_get_nrdn(srdn);
-        const char *ep = NULL;
+        const char **ep = NULL;
         int isexception = 0;
         /* Check the RDN is in the exception list */
-        for (ep = *rdn_exceptions; ep && *ep; ep++) {
-            if (!strcmp(ep, myrdn)) {
+        for (ep = rdn_exceptions; ep && *ep; ep++) {
+            if (!strcmp(*ep, myrdn)) {
                 isexception = 1;
+                break;
             }
         }
 
@@ -2636,7 +2639,7 @@ _entryrdn_insert_key(backend *be,
                 goto bail;
             }
         }
-        elem = _entryrdn_new_rdn_elem(be, 0 /*fake id*/, tmpsrdn, &len);
+        elem = _entryrdn_new_rdn_elem(be, TMPID, tmpsrdn, &len);
         if (NULL == elem) {
             char *dn  = NULL;
             slapi_rdn_get_dn(tmpsrdn, &dn);
@@ -2891,7 +2894,7 @@ _entryrdn_delete_key(backend *be,
                 slapi_ch_free_string(&dn);
                 goto bail;
             }
-            elem = _entryrdn_new_rdn_elem(be, 0 /*fake id*/, tmpsrdn, &len);
+            elem = _entryrdn_new_rdn_elem(be, TMPID, tmpsrdn, &len);
             if (NULL == elem) {
                 char *dn  = NULL;
                 slapi_rdn_get_dn(tmpsrdn, &dn);
@@ -3134,7 +3137,7 @@ _entryrdn_index_read(backend *be,
         slapi_ch_free_string(&dn);
         goto bail;
     }
-    *elem = _entryrdn_new_rdn_elem(be, 0 /*fake id*/, tmpsrdn, &len);
+    *elem = _entryrdn_new_rdn_elem(be, TMPID, tmpsrdn, &len);
     if (NULL == *elem) {
         char *dn  = NULL;
         slapi_rdn_get_dn(tmpsrdn, &dn);
@@ -3212,7 +3215,7 @@ _entryrdn_index_read(backend *be,
                 goto bail;
             }
         }
-        tmpelem = _entryrdn_new_rdn_elem(be, 0 /*fake id*/, tmpsrdn, &len);
+        tmpelem = _entryrdn_new_rdn_elem(be, TMPID, tmpsrdn, &len);
         if (NULL == tmpelem) {
             char *dn  = NULL;
             slapi_rdn_get_dn(tmpsrdn, &dn);
-- 
1.7.1