PSMDB-2003 Implement caching for userToDN mapping#1797
Conversation
There was a problem hiding this comment.
Pull request overview
Implements an in-memory cache for LDAPManagerImpl::mapUserToDN() results to reduce LDAP roundtrips during auth flows, and wires cache invalidation to relevant LDAP-related runtime parameter updates.
Changes:
- Added an LRU+TTL cache for user→DN mapping results, plus an explicit cache invalidation API on
LDAPManager. - Introduced new server parameters
ldapUserToDNCacheTTLSecondsandldapUserToDNCacheSize, with runtime update hooks that invalidate the cache. - Updated LDAP option update paths (servers/bind creds/mapping) to invalidate the new cache when inputs affecting DN mapping change.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/mongo/db/ldap/ldap_manager.h |
Extends the LDAPManager interface with invalidateUserToDNCache(). |
src/mongo/db/ldap/ldap_manager_impl.h |
Adds cache data structures and locking members to LDAPManagerImpl. |
src/mongo/db/ldap/ldap_manager_impl.cpp |
Implements cache invalidation and integrates cache lookups/updates into mapUserToDN(). |
src/mongo/db/ldap_options.idl |
Adds new cache-related server parameters and on_update hooks for cache invalidation. |
src/mongo/db/ldap_options.h |
Declares new global params and on-update callbacks. |
src/mongo/db/ldap_options.cpp |
Implements invalidation helpers and on-update handlers to clear cache on relevant param updates. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Cache the result of LDAPManagerImpl::mapUserToDN() to reduce LDAP server roundtrips during authentication and authorization. The cache uses an LRU eviction policy (via LRUCache) and per-entry TTL. Two new server parameters control the cache: - ldapUserToDNCacheTTLSeconds (default 30, 0 disables) - ldapUserToDNCacheSize (default 10000, 0 disables) Synchronization uses a two-level locking scheme: - RWMutex: mapUserToDN() holds a shared lock for its entire duration; invalidateUserToDNCache() holds an exclusive lock to drain and reset. - Inner Mutex: serializes concurrent cache access from mapUserToDN(). The cache is invalidated on runtime changes to ldapUserToDNMapping, ldapUserToDNCacheTTLSeconds, ldapUserToDNCacheSize, ldapServers, ldapQueryUser, and ldapQueryPassword. ldapUserToDNMapping server parameter parsed on update and BSONArray result is stored in LDAPManagerImpl::_userToDNMappingSnapshot thus removing json parsing from each call to mapUserToDN()
Add a new ldapauthz JS test for ldapUserToDNMapping cache behavior. Cover authentication with cache enabled and disabled, runtime mapping updates, and cache invalidation when ldapUserToDNCacheTTLSeconds or ldapUserToDNCacheSize changes. Configure a short ldapUserCacheInvalidationInterval and wait after setParameter updates so each auth attempt re-resolves the DN instead of reusing the $external user cache.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Replace RWMutex-based synchronization with synchronized_value<shared_ptr> to avoid blocking mapUserToDN() callers during cache invalidation and avoid blocking admin setParameter commands on LDAP query timeouts. Cache configuration is now encapsulated in an immutable UserToDNCacheHolder that is atomically swapped on parameter changes. In-flight mapUserToDN() calls continue working with their snapshot while new calls pick up the fresh cache immediately.
| jsTestLog("Test: ldapUserToDNCacheTTLSeconds change invalidates the DN cache"); | ||
| setParam(conn, {ldapUserToDNMapping: ldapQueryMapping}); | ||
| assert(authLDAPUser(conn), "Auth should succeed to populate cache"); | ||
| setParam(conn, {ldapUserToDNCacheTTLSeconds: 60, ldapUserToDNMapping: brokenMapping}); |
There was a problem hiding this comment.
As far as I can see, changing ldapUserToDNMapping also invalidates the cache so that the cache would be invalidated even if ldapUserToDNCacheTTLSeconds hadn't been changed.
There was a problem hiding this comment.
We will address this in separate task
Cache the result of LDAPManagerImpl::mapUserToDN() to reduce LDAP server roundtrips during authentication and authorization. The cache uses an LRU eviction policy (via LRUCache) and per-entry TTL.
Two new server parameters control the cache:
Synchronization uses two synchronization mechanisms:
The cache is invalidated on runtime changes to ldapUserToDNMapping, ldapUserToDNCacheTTLSeconds, ldapUserToDNCacheSize, ldapServers, ldapQueryUser, and ldapQueryPassword.