Repository navigation
user_ldap: a lookup before mapping is cached for 30 days, so the user stays unknown in web requests after the sync or occ ldap:search maps them #66003
Description
⚠️ This issue respects the following points: ⚠️
- This is not a troubleshooting question, general support matter, or webserver/proxy problem, but likely a bug.
- This issue is not already reported on Github OR solved at the Community Help Forum (I've searched!).
- I'm using a maintained major version of Nextcloud Server and tested against the latest patch level.
- I agree to follow Nextcloud's Code of Conduct.
- I've tried my best to provide clear reproduction steps that someone unfamiliar with this bug could use to reproduce it.
Bug description
Since #54429 (Nextcloud 33), AbstractMapping::getDNByName() keeps its result in the local cache for 30 days (LOCAL_CACHE_TTL), and that includes a miss (false). If a web request looks up a user before user_ldap has mapped them, the miss is cached. Mapping the user from the CLI (occ ldap:search, or the Sync background job under cron) does not update that cache, because the CLI does not use the local mapping cache. Web requests then treat the user as unknown for up to 30 days, although the user is in oc_ldap_user_mapping.
Where it hurts: SSO with user_saml and "Only allow authentication if an account exists on some other backend". A new AD user who tries SSO before the background sync has mapped them gets "Not provisioned", and still gets it after the sync or occ ldap:search has mapped them. We ran into this on a customer setup (33.0.6) and reproduced it on 33.0.9. The code is the same on master.
The local mapping cache is used by default (use_local_mapping_cache unset, so auto) when the instance has at most 2,000 mapped users. occ config:app:set user_ldap use_local_mapping_cache --value=no works around it.
Steps to reproduce
- Nextcloud 33 with user_ldap configured, a
memcache.local(Redis here, APCu should behave the same), fewer than 2,000 mapped users,use_local_mapping_cachenot set. - Pick an LDAP user who is not mapped yet, here
CherylKirsch. - As admin, look the user up through a web request:
curl -u admin:<password> -H 'OCS-APIRequest: true' 'https://<host>/ocs/v2.php/cloud/users/CherylKirsch?format=json'
This returns 404, which is fine, the user is not mapped yet. - Map the user from the CLI:
occ ldap:search "Cheryl Kirsch"printsCheryl Kirsch (CherylKirsch), and the row is inoc_ldap_user_mapping. - Wait more than 10 minutes (
ldapCacheTTLis 600) without other lookups of that user, then repeat step 3: still 404. Here it was still 404 after 11 and after 23 minutes, for two users. The local cache holdsldap/map/u/CherylKirsch=falsewith a TTL of 30 days.
A user mapped with occ ldap:search before any web lookup returns 200 in step 3. When reproducing, note that a lookup from the CLI (for example occ user:info) can put a positive userExists result into the shared LDAP cache and hide the problem for ldapCacheTTL.
The same happens with user_saml (8.1.2, "Only allow authentication if an account exists on some other backend"): one SSO try before the mapping, then occ ldap:search maps the user, and SSO keeps failing with "Auto provisioning not allowed and user ... does not exist". Deleting only that cache key, or setting use_local_mapping_cache to no, lets the user log in once the 10 minute connection cache has expired.
Expected behavior
Once the user is mapped, web requests find them, at the latest after ldapCacheTTL. Not caching misses in getDNByName() would be enough, as far as I can see.
Nextcloud Server version
33.0.9 (customer on 33.0.6). getDNByName() is unchanged in 33.0.10 and on master.
PHP engine version
PHP 8.5.11
Web server
Apache 2.4.68
Database engine version
MariaDB 10.6.28
What user-backends are you using?
LDAP/ Active Directory, SSO - SAML
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTo triage
Activity