[
https://issues.apache.org/jira/browse/CAMEL-25509?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Work on CAMEL-25509 started by shashank.
----------------------------------------
> camel-ldif - "changetype: modrdn" ignores newsuperior, and "changetype:
> moddn" without newsuperior moves the entry to the root
> ------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-25509
> URL: https://issues.apache.org/jira/browse/CAMEL-25509
> Project: Camel
> Issue Type: Bug
> Reporter: shashank
> Assignee: shashank
> Priority: Major
>
> RFC 2849 defines {{modrdn}} and {{moddn}} as the same change type
> ({{change-moddn = ("modrdn" / "moddn") SEP "newrdn:" ... "deleteoldrdn:" ...
> [SEP "newsuperior:" ...]}}): the entry gets the new RDN, and moves under the
> new superior only when {{newsuperior}} is given (RFC 4511 4.9).
> {{LdifProducer.processLdifEntry}} (lines 161-172 at main c578a42a776d) treats
> them as two different operations:
> {code:java}
> } else if (ldifEntry.isChangeModDn()) {
> conn.moveAndRename(ldifEntry.getDn(), new Dn(ldifEntry.getNewRdn(),
> ldifEntry.getNewSuperior()), ...);
> } else if (ldifEntry.isChangeModRdn()) {
> conn.rename(ldifEntry.getDn(), new Rdn(ldifEntry.getNewRdn()), ...);
> }
> {code}
> * A {{modrdn}} record with {{newsuperior}} renames the entry in place: it is
> not moved, and the result for the record is still {{success}}.
> * A {{moddn}} record without {{newsuperior}} (a plain rename, valid per RFC
> 2849) builds {{new Dn(newRdn, null)}}, which is the one-RDN DN {{uid=b}}, so
> the request moves the entry directly under the root and the server rejects it.
> The Apache LDAP API's {{LdifReader}} keeps the two keywords apart
> ({{ChangeType.ModRdn}}/{{ModDn}}) and reads {{newsuperior}} for both.
> h3. Reproduction
> New {{LdifModDnTest}}, with a stub {{LdapConnection}} (a
> {{java.lang.reflect.Proxy}}) that records the DN each rename/move gives the
> entry, so no LDAP server is needed. On main:
> {noformat}
> modRdnWithNewSuperiorMovesTheEntry: expected: <uid=b,ou=new,dc=example,dc=org
> deleteOldRdn=true> but was: <uid=b,ou=old,dc=example,dc=org deleteOldRdn=true>
> modDnWithoutNewSuperiorKeepsTheParent: expected:
> <uid=b,ou=old,dc=example,dc=org deleteOldRdn=true> but was: <uid=b
> deleteOldRdn=true>
> {noformat}
> The controls ({{moddn}} with {{newsuperior}}, {{modrdn}} without it, as in
> {{LdifRouteIT}}) pass.
> h3. Proposed fix
> One branch for both change types: {{moveAndRename(dn, new Dn(newRdn,
> newSuperior), deleteOldRdn)}} when {{newsuperior}} is given, {{rename(dn, new
> Rdn(newRdn), deleteOldRdn)}} otherwise. The requests for the two cases that
> worked are unchanged; a short upgrade guide note for 4.23 describes the two
> changed cases. camel-ldif unit tests with the fix: 5, 0 failures
> ({{LdifRouteIT}} needs the OpenLDAP container and was not run; its
> modDn/modRdn cases send the same requests as before).
> Found with a Lean 4 model of the dispatch (DNs as lists of RDNs, the effect
> of rename and moveAndRename on the entry's DN): "the new DN is newrdn under
> newsuperior if given, else under the current parent, for both keywords" fails
> for the two records above, and is proved to fail for every {{modrdn}} with a
> {{newsuperior}} other than the current parent and every {{moddn}} without
> {{newsuperior}} of an entry not directly under the root. The fix is proved
> correct for all records, and to send exactly main's request in the two cases
> main got right. Then confirmed with the real producer and LDAP API as above.
> Affected: main, camel-4.18.x, camel-4.14.x (same code, GitHub contents API).
> The component was added in 2017 (CAMEL-11778).
> Duplicate check (2026-10-09): JIRA text "ldif" (9 hits: component creation,
> URL opt-in CAMEL-24297, upgrades), "modrdn" (none); GitHub pull requests
> "ldif modrdn", "ldif newsuperior", "LdifProducer": none (only the CVE pin
> #25622).
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)