Skip to content

Searching cn=changelog fails with RuntimeException(Not implemented) when aliases are dereferenced #737

Description

@vharseko

Version: 5.1.1, also present on master.

Summary

Any search based at cn=changelog fails with result code 80 (Other) when the client asks for alias dereferencing:

error code 80 - An unexpected error was encountered while processing a search in one of the
Directory Server backends: RuntimeException(Not implemented)

This hits every JNDI-based client out of the box, since java.naming.ldap.derefAliases defaults to always.

Steps to reproduce

On a server with replication and the external change log enabled (ds-cfg-compute-change-number: true):

# fails with error 80
ldapsearch -h localhost -p 1389 -D "cn=Directory Manager" -w password \
    -b "cn=changelog" -s one -a always "(changeNumber>=1)"

# same search, succeeds
ldapsearch -h localhost -p 1389 -D "cn=Directory Manager" -w password \
    -b "cn=changelog" -s one -a never "(changeNumber>=1)"

Only the dereference policy differs.

Cause

For any search whose deref policy is always or find (or search with subtree scope), LocalBackendSearchOperation fetches the base entry to check whether it is an alias — before handing the search to the backend:

opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java#L207-L213

//DereferenceAliasesPolicy
if (
        DereferenceAliasesPolicy.ALWAYS.equals(getDerefPolicy())
        || DereferenceAliasesPolicy.FINDING_BASE.equals(getDerefPolicy())
        || (DereferenceAliasesPolicy.IN_SEARCHING.equals(getDerefPolicy()) && SearchScope.WHOLE_SUBTREE.equals(getScope()))
) {
  final Entry baseEntry=DirectoryServer.getEntry(baseDN);

ChangelogBackend does not implement getEntry:

opendj-server-legacy/src/main/java/org/opends/server/backends/ChangelogBackend.java#L299-L309

@Override
public Entry getEntry(final DN entryDN) throws DirectoryException
{
  if (entryDN == null)
  {
    throw new DirectoryException(DirectoryServer.getCoreConfigManager().getServerErrorResultCode(),
        ERR_BACKEND_GET_ENTRY_NULL.get(getBackendID()));
  }
  throw new RuntimeException("Not implemented");
}

So the lookup throws before ChangelogBackend.search() — which handles change-number searches fine — is ever reached.

Regression

The base entry lookup came in with f771315 ("[#287] ADD alias dereferencing for search requests", #369, 2024-08-07). Before that, change log searches never went through getEntry.

Impact

The external change log is unreadable by any client that dereferences aliases. Concretely, the OpenICF LDAP connector's sync() cannot work against OpenDJ: it reads the change log over JNDI, which sends derefAliases: always unless explicitly told otherwise, so every sync call fails with the error above. Setting java.naming.ldap.derefAliases to never on the client makes the same search succeed, which confirms the dereference policy is the trigger.

Suggested fix

Entries under cn=changelog are never aliases, so the lookup has nothing to find there. Either:

  • skip the alias lookup when the backend cannot supply the base entry (or catch the failure and continue without dereferencing), or
  • implement ChangelogBackend.getEntry.

Metadata

Metadata

Assignees

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions