https://bugs.openldap.org/show_bug.cgi?id=10508
Issue ID: 10508 Summary: syncrepl: be_modrdn / message_to_op called without orm_no_opattrs=1, modifiersName clobbered by consumer rootdn Product: OpenLDAP Version: 2.6.13 Hardware: i386 OS: Linux Status: UNCONFIRMED Keywords: needs_review Severity: normal Priority: --- Component: slapd Assignee: bugs@openldap.org Reporter: apostnikov@gmail.com Target Milestone: ---
Created attachment 1150 --> https://bugs.openldap.org/attachment.cgi?id=1150&action=edit 0001-syncrepl-set-orm_no_opattrs-for-backend-ops.patch
When syncrepl applies provider changes locally it invokes the backend through be_add / be_modify / be_modrdn / be_delete, carrying the provider's operational attributes in the modlist. Without `op->orm_no_opattrs = 1` the backend (verified on back-mdb; servers/slapd/back-mdb/modrdn.c:76 and modify.c:619) calls slap_mods_opattrs(), which auto-injects a `replace modifiersName=<op->o_dn>` mod whenever modifiersName is not already present in the modlist. For syncrepl, `op->o_dn` is the consumer's local rootdn (set at syncrepl.c:2165 — `op->o_dn = op->o_bd->be_rootdn`), so the consumer ends up with `modifiersName=cn=<consumer-rootdn>` instead of the provider's value.
ITS#4820 originally papered over this in syncrepl_diff_entry() with a kludge that always forced modifiersName/modifyTimestamp into the diff (`if (*mods && (modifiersName||modifyTimestamp)) attr_cmp(NULL,new)`). ITS#10250 commit 87933f3e removed that kludge with the rationale "the mod is being passed to the backend with orm_no_opattrs these days". But two code paths in syncrepl.c never actually set orm_no_opattrs:
1. syncrepl_entry() refresh-mode rename-with-content path (around line 4788 on master): the parallel be_modify branch sets `orm_no_opattrs = 1/0` around its call; the be_modrdn branch does not.
2. syncrepl_message_to_op() (delta-sync log replay; whole function from line 3180 on master): none of the four backend dispatches (be_add, be_modify, be_modrdn, be_delete) set the flag.
Once 87933f3e removed the kludge, the auto-inject surfaced whenever provider and consumer happened to already agree on modifiersName so syncrepl_diff_entry produced no mod for it. Whether that happens for a given entry depends on attribute iteration order in the diff (attribute hash bucket order), which is why x86_64/aarch64 mostly mask the bug while x86/armv7/armhf/s390x (QEMU builders) trigger it deterministically and ppc64le sees it as flake in test063.
Worst case the consumer ends up with the provider's entryCSN (the modrdn bumped it) but the wrong modifiersName, and ITS#10358's assert-retry then sees identical entryCSN, takes no further action, and the corruption is permanent until something else updates the entry.
Reproducer ----------------------------------------------------------------
Native: 32-bit or big-endian build of HEAD; run
cd tests make BACKEND=mdb mdb-mod TESTS=test017-syncreplication-refresh
Cross-arch via Alpine's CI image (any host):
docker run --rm --platform linux/386 -v $PWD:/mnt \
registry.alpinelinux.org/alpine/infra/docker/alpine-gitlab-ci:latest-x86 \ sh -c 'cd /mnt && ./configure --enable-modules --enable-mdb=mod \ --enable-syncprov=mod && make && cd tests && make mdb-mod'
Expected on affected builders:
>>>>> Starting test017-syncreplication-refresh for mdb... ... test failed - provider and consumer databases differ >>>>> Failed test017-syncreplication-refresh for mdb
Capturing the diff (modify defines.sh's CMPOUT temporarily) shows:
348c348 < description: Example, Inc. ITS test domain --- > description: Example, Inc. modify+modrdn test domain 350c350 < modifiersName: cn=Manager,dc=example,dc=com --- > modifiersName: cn=consumer,dc=example,dc=com
(Both entries carry the SAME final entryCSN — that's the smoking gun: the consumer adopted the provider's CSN via the modrdn, but the follow-up modify hit `err=122 LDAP_ASSERTION_FAILED` because of the CSN bump, and ITS#10358's retry then short-circuited.)
Proposed fix ----------------------------------------------------------------
Six added lines in servers/slapd/syncrepl.c — see attached patch 0001-syncrepl-set-orm_no_opattrs-for-backend-ops.patch. Tested against OPENLDAP_REL_ENG_2_6_13: full make test suite passes on x86 (linux/386 QEMU) including all six tests that ITS#10250 patched plus test043-delta-syncrepl and test063-delta-multiprovider.
References / related ITS ----------------------------------------------------------------
ITS#4820 — the original modifiersName/modifyTimestamp kludge added in 2007 ITS#10250 — kludge removed (MR#817, commit 87933f3e), exposing this bug ITS#10358 — assert-control retry (MR#781) — masks the divergence as silent data loss ITS#8852 — sorted_attr_cmp() prerequisite for ITS#10250 (commit 8986f99d)
https://bugs.openldap.org/show_bug.cgi?id=10508
--- Comment #1 from apostnikov@gmail.com --- Using this patch created by Claude Opus 4,7 to upgrade https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/96778
https://bugs.openldap.org/show_bug.cgi?id=10508
--- Comment #2 from Howard Chu hyc@openldap.org --- (In reply to apostnikov from comment #1)
Using this patch created by Claude Opus 4,7 to upgrade https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/96778
As our Contributor guidelines clearly state, AI contributions are not allowed. We will not examine the above link.
https://bugs.openldap.org/show_bug.cgi?id=10508
Ondřej Kuzník ondra@mistotebe.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution|--- |DUPLICATE
--- Comment #3 from Ondřej Kuzník ondra@mistotebe.net --- Hi, this is most likely a duplicate of ITS#10480. Have a look at that first and let us know if you believe the fix (coming in 2.6.14) is incomplete and why.
*** This issue has been marked as a duplicate of issue 10480 ***
https://bugs.openldap.org/show_bug.cgi?id=10508
Ondřej Kuzník ondra@mistotebe.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |UNCONFIRMED Resolution|DUPLICATE |---
--- Comment #4 from Ondřej Kuzník ondra@mistotebe.net --- On second inspection, it actually doesn't look like a duplicate of ITS#10480. However the analysis is highly suspicious: ITS#10250 was never going to be applied to 2.6 so it can't have exposed this issue on 2.6.13 as reported.
https://bugs.openldap.org/show_bug.cgi?id=10508
--- Comment #5 from apostnikov@gmail.com --- As I got it's some remains that been not fixes in the issue and it was blocking upgrade to latest secure releases as tests did not pass in 32-bit arches for Alpinelinux which is finishing upcoming release build
https://bugs.openldap.org/show_bug.cgi?id=10508
--- Comment #6 from Ondřej Kuzník ondra@mistotebe.net --- Hi, I'm not sure what your last comment is saying.
https://bugs.openldap.org/show_bug.cgi?id=10508
--- Comment #7 from Ryan Tandy ryan@openldap.org --- I'm also affected by test017 failing consistently on (at least) 32-bit x86. I reproduced it on a 64-bit Debian host like this:
sudo apt install gcc-multilib ./configure CFLAGS='-O2 -m32' --disable-backends --enable-mdb --disable-overlays --enable-syncprov make cd tests ./run test017
git bisect points to b3821e772a "ITS#10358 Retry if entry changed (use assert control to detect this)".
ITS#10480 did not fix it. Still fails as of today's master (35a0fb5ac1).
https://bugs.openldap.org/show_bug.cgi?id=10508
--- Comment #8 from Howard Chu hyc@openldap.org --- For clarity - the referenced kludge, removed for ITS#10250, was put in for ITS#4827, not ITS#4820.
The lack of op->orm_no_opattrs in the syncrepl_entry() modrdn path definitely breaks test017 on 32bit build, and setting it fixes it.
The lack in syncrepl_message_to_op() is irrelevant since delta-sync ops will always include all of these opattrs and there's no diff step that could elide them.
https://bugs.openldap.org/show_bug.cgi?id=10508
Quanah Gibson-Mount quanah@openldap.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Keywords|needs_review | Assignee|bugs@openldap.org |hyc@openldap.org Status|UNCONFIRMED |IN_PROGRESS Target Milestone|--- |2.6.14
https://bugs.openldap.org/show_bug.cgi?id=10508
Quanah Gibson-Mount quanah@openldap.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|IN_PROGRESS |RESOLVED Resolution|--- |TEST
--- Comment #9 from Quanah Gibson-Mount quanah@openldap.org --- head:
• 8d81c22e by Howard Chu at 2026-06-02T15:21:29+00:00 ITS#10508 syncrepl: set no_opattrs on modrdn
RE27:
• e4d7ca29 by Howard Chu at 2026-06-03T22:42:32+00:00 ITS#10508 syncrepl: set no_opattrs on modrdn