Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 6417 - If an entry RDN is identical to the suffix, then Entryrd… #6418

Merged
merged 1 commit into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 107 additions & 1 deletion dirsrvtests/tests/suites/indexes/entryrdn_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@
import pytest
import ldap
import logging
from lib389 import Entry
from lib389._constants import DEFAULT_BENAME, DEFAULT_SUFFIX
from lib389.backend import Backends
from lib389.backend import Backends, Backend
from lib389.mappingTree import MappingTrees
from lib389.configurations.sample import create_base_domain
from lib389.idm.domain import Domain
from lib389.idm.user import UserAccounts, UserAccount
from lib389.idm.organizationalunit import OrganizationalUnits
from lib389.topologies import topology_m2 as topo_m2
from lib389.topologies import topology_st
from lib389.agreement import Agreements
from lib389.utils import ds_is_older, ensure_bytes
from lib389.tasks import Tasks,ExportTask, ImportTask
Expand Down Expand Up @@ -283,6 +288,107 @@ def test_long_rdn(topo_m2):
ou.delete()
assert not ou.exists()

def test_entry_rdn_same_as_suffix(topology_st, request):
"""
Test that a reindex is successful even if an entry
has a RDN that is identical to the suffix

:id: 7f5a38e9-b979-4664-b132-81df0e60f38a
:setup: standalone
:steps:
1. Create a new backend with suffix 'dc=dup_rdn' (ID 1)
2. Create a dummy entry 'ou=my_org,dc=dup_rdn' (ID 2)
3. Create the problematic entry 'dc=dup_rdn,dc=dup_rdn' (ID 3)
4. Create a dummy entry 'ou=my_org,dc=dup_rdn,dc=dup_rdn' (ID 4)
5. Do an offline reindex
6. Check that entryrdn contains the key P3 (parent of ID 3)
7. Check that error log does not contain 'entryrdn_insert_key - Same DN'
:expectedresults:
1. Should succeed
2. Should succeed
3. Should succeed
4. Should succeed
5. Should succeed
6. Should succeed
7. Should succeed
"""
inst = topology_st.standalone

# Create a suffix 'dc=dup_rdn'
be_name = 'domain'
dc_value = 'dup_rdn'
suffix = 'dc=' + dc_value
rdn = 'my_org'
be1 = Backend(inst)
be1.create(properties={
'cn': be_name,
'nsslapd-suffix': suffix,
},
create_mapping_tree=False
)

mts = MappingTrees(inst)
mt = mts.create(properties={
'cn': suffix,
'nsslapd-state': 'backend',
'nsslapd-backend': be_name,
})

# Create the domain entry 'dc=dup_rdn'
create_base_domain(inst, suffix)

# Create the org ou=my_org,dc=dup_rdn
ous = OrganizationalUnits(inst, suffix)
ou = ous.create(properties={ 'ou': rdn })

# when reindexing entryrdn the following entry
# (dc=dup_rdn,dc=dup_rdn) Triggers
# this message.
# This is because its RDN (dc=dup_rdn) is also
# the suffix DN
info_message = 'entryrdn_insert_key - Same DN (dn: %s) is already in the entryrdn file with different' % (ou.dn)
log.info("In case if the bug still exist this line should be in the error log")
log.info(" --> " + info_message)

# Create the domain entry 'dc=dup_rdn,dc=dup_rdn'
trigger_entry = suffix + "," + suffix
domain = Domain(inst, dn=trigger_entry)
domain.create(properties={
'dc': dc_value,
'description': 'Entry with RDN identical to suffix'
})

# Create the org ou=my_org,dc=dup_rdn,dc=dup_rdn
ous = OrganizationalUnits(inst, trigger_entry)
ou = ous.create(properties={ 'ou': rdn })


# Trigger an offline reindex
log.info('Offline reindex, stopping the server')
topology_st.standalone.stop()

log.info('Reindex all the suffix')
topology_st.standalone.db2index(bename=be_name)

# make sure the key 'P3' (parent of 'dc=dup_rdn,dc=dup_rdn') exists
dbscanout = topology_st.standalone.dbscan(bename=be_name, index='entryrdn')
log.info(dbscanout)
assert(ensure_bytes('P3') in ensure_bytes(dbscanout))

# make sure there is no failure detected/logged in error logs
if topology_st.standalone.get_db_lib() == "mdb":
pattern_str = ".*Inconsistent id2entry database.*"
else:
pattern_str = ".*entryrdn_insert_key - Same DN.*is already in the entryrdn file with different.*$"
assert not topology_st.standalone.ds_error_log.match(pattern_str)


def fin():
topology_st.standalone.restart()
mt.delete()
be1.delete()

request.addfinalizer(fin)

if __name__ == "__main__":
# Run isolated
Expand Down
2 changes: 1 addition & 1 deletion ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ get_entry_type(WorkerQueueData_t *wqelmt, Slapi_DN *sdn)
int len = SLAPI_ATTR_UNIQUEID_LENGTH;
const char *ndn = slapi_sdn_get_ndn(sdn);

if (slapi_be_issuffix(be, sdn)) {
if (slapi_be_issuffix(be, sdn) && (wqelmt->wait_id == 1)) {
return DNRC_SUFFIX;
}
if (PL_strncasecmp(ndn, SLAPI_ATTR_UNIQUEID, len) || ndn[len] != '=') {
Expand Down
11 changes: 10 additions & 1 deletion ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
Original file line number Diff line number Diff line change
Expand Up @@ -1077,7 +1077,16 @@ entryrdn_lookup_dn(backend *be,
_ENTRYRDN_DEBUG_GOTO_BAIL();
goto bail;
}
maybesuffix = 1;
if (workid == 1) {
/* The loop (workid) iterates from the starting 'id'
* up to the suffix ID (i.e. '1').
* A corner case (#6417) is if an entry, on the path
* 'id' -> suffix, has the same RDN than the suffix.
* In order to erroneously believe the loop hits the suffix
* we need to check that 'workid' is '1' (suffix)
*/
maybesuffix = 1;
}
} else {
_entryrdn_cursor_print_error("entryrdn_lookup_dn",
key.data, data.size, data.ulen, rc);
Expand Down
Loading