A flaw was found in 389 Directory Server (389-ds-base). During SASL PLAIN authentication, the idssaslcanonuser() function writes the resolved bind DN into a Cyrus SASL auxiliary property (propset) on every canonicalization attempt, including failed ones. A failed one-shot PLAIN exchange does not trigger SASL-context recreation in idssaslcheckbind() -- that only happens when CONNFLAGSASLCOMPLETE or continuing is already set. A subsequent successful SASL bind on the same connection retrieves the auxiliary property via propgetnames() and unconditionally trusts only the first stored value (dnval[0].values[0]), with no check on which SASL mechanism completed the second exchange and no check that the value corresponds to the identity actually just authenticated.
An unprivileged remote attacker can exploit this with zero valid credentials: first send a SASL PLAIN bind as cn=Directory Manager with an incorrect password (fails as expected, but leaves the Directory Manager DN in slot 0 of the auxiliary property), then complete a SASL ANONYMOUS bind on the same connection. The server installs the stale Directory Manager identity instead of the anonymous identity, granting full Directory Manager authority. This was independently confirmed by Red Hat Product Security in an isolated, network-disconnected sandbox against 389-ds-base-2.9.0: "Who Am I?" returned "cn=directory manager", and the Directory-Manager-only cn=config attribute nsslapd-rootdn became readable. The same stale-identity mechanism also allows escalation via a valid low-privileged account's own successful second bind (originally reported variant, requiring one valid account), independently reproduced against the reporter's own PoC.
Root cause: ldap/servers/slapd/saslbind.c, idssaslcanonuser() (identity write, unconditional per mechanism) and idssaslcheckbind() (identity read-back and installation, no mechanism check, no freshness check). Verified directly against commit 33c0e0115c03017ba94ee02f144383704de32a25; unchanged since a September 2024 logging-format cleanup.
A flaw was found in 389 Directory Server (389-ds-base). The getruvelementfromberval() function in ldap/servers/plugins/replication/repl5ruv.c copies digit characters from a network-supplied RUV berval into a fixed 16-byte stack buffer (ridbuff[RIDSTRSIZE]) without bounds checking the loop counter. A remote unauthenticated attacker can crash the ns-slapd process by sending a crafted StartNSDS50ReplicationRequest LDAP extended operation (OID 2.16.840.1.113730.3.5.12) containing more than 16 consecutive digit characters in the replica ID field. The overflow occurs during payload decoding in decodestartreplextop(), before the replicaisupdatedn() authorization check runs, making it exploitable without credentials on default configurations where anonymous access is enabled. On production builds with stack protectors, the impact is limited to denial of service (process abort). The vulnerable code path is: decodestartreplextop() -> decoderuv() -> ruvinitfrombervals() -> getruvelementfromberval().
Three related heap buffer overflow bugs were found in the aclpnormalizeacltxt() function in ldap/servers/plugins/acl/aclparse.c of 389 Directory Server. The function is called during ACI (Access Control Instruction) parsing via aclparse() -> aclpparseaci() -> aclpsanitycheckacltxt() -> aclpnormalizeacltxt().
The root cause is that aclpnormalizeacltxt() blindly assumes the ACI string after whitespace stripping still has at least 3 characters (the "aci" or "acl" keyword), without any bounds check. The assert(s) on line 850 only checks for NULL, not for an empty or too-short string, and asserts are compiled out in release builds (NDEBUG).
The three bugs are:
1. Out-of-bounds WRITE (1 byte): On line 852, (s + 2) = 'l' writes one byte past the heap buffer when the string is too short after whitespace stripping.
2. Out-of-bounds READ (strchr): On line 856, strchr(aclstr, ';') reads past the buffer because the NUL terminator was clobbered or the string lacks a semicolon.
3. Out-of-bounds READ (strdup): On line 866, slapichstrdup(aclName) reads past the buffer in strdup for the same root cause.
To trigger the vulnerability, an attacker needs write access to the 'aci' attribute on a directory entry. In the default modern configuration (389-ds-base 2.x / RHDS 12), only the Directory Manager can write ACIs. However, in older deployments or those using common ACI patterns with negated targetattr rules (e.g., targetattr!="userPassword") or wildcards (targetattr=""), any authenticated user may be able to write to the 'aci' attribute.
ASAN is not enabled in production release builds (the spec file defaults to %bcond asan 0 / %global useasan 0). In production binaries, the heap corruption is silent — the 1-byte write corrupts adjacent heap memory without a deterministic crash, and the OOB reads silently read garbage from adjacent heap allocations. The practical impact in production builds is likely negligible, making this primarily a hardening issue.
The 1-byte write primitive is not controllable (fixed value 'l'/0x6C at fixed offset +2 from a small allocation) and is not realistically weaponizable for code execution.
Upstream fix: https://github.com/389ds/389-ds-base/pull/7542 Upstream issue: https://github.com/389ds/389-ds-base/issues/7541
A heap buffer overflow flaw was found in the SASL I/O layer of 389 Directory Server (389-ds-base). After a successful SASL bind with integrity protection (SSF > 0), an authenticated attacker can send a specially crafted oversized LDAP UNBIND packet that is copied into a 512-byte heap receive buffer without a bounds check in sasliorecv() in saslio.c. This allows up to approximately 2 megabytes of attacker-controlled data to overflow the buffer, causing a denial of service (server crash). In FreeIPA and Red Hat Identity Management deployments, any domain user with a valid Kerberos ticket, any enrolled host, or any service account can trigger this vulnerability over the network after authenticating via GSSAPI. The vulnerable code path has existed since approximately 2013 (389-ds-base 1.3.2) and was not addressed by the CVE-2025-14905 fix, which patched a separate heap overflow in schema.c only.