mod_dav_svn returns generic 401 for expired LDAP passwords with no way to distinguish them from bad credentials
0 reputation · 01 Sept 2022, 20:02 UTC
0 reputation · 01 Sept 2022, 20:02 UTC
I want a Subversion repository served by Apache httpd with mod_dav_svn and LDAP authentication to handle expired passwords in a predictable, least-privilege way: once a user's LDAP password expires, access should stop immediately and the failure should be identifiable as an expiration rather than a wrong password.
From what I can tell, mod_dav_svn surfaces an expired LDAP bind as a plain HTTP 401 with no distinguishing error body, so clients and administrators cannot tell expiration apart from malformed credentials without reading external LDAP logs. Separately, the Subversion client's credential cache (under ~/.subversion/auth/) may keep a previously successful authentication alive, meaning path-based authz rules continue to be evaluated against a stale identity until the cache is cleared or expires. This leaves a window where least-privilege controls appear effective but are not.
Assume a recent Subversion 1.14.x server with mod_dav_svn and mod_authnz_ldap; behavior may differ for svnserve with SASL, which I am not using.
No. With mod_dav_svn plus mod_authnz_ldap there is no supported configuration that turns an expired LDAP password into a distinguishable HTTP response. Both a wrong password and an expired password surface as an LDAP bind failure (LDAP error 49, invalidCredentials), and Apache maps any bind failure to a plain 401 with no differentiating body. This is partly deliberate: distinguishing "expired" from "wrong" leaks account state and aids enumeration, so the generic 401 is a security posture, not just a missing feature.
Confirmed behavior: HTTP Basic/Digest auth is stateless. The Subversion client resends credentials on every request, and mod_authnz_ldap re-binds to LDAP per request (modulo a short internal bind cache). So once a password expires in the directory, the next request fails server-side immediately. There is no server-side session keeping the user alive.
Likely explanation for your stale-access window: the directory itself can carry more detail — Active Directory returns subcodes in the bind error string (e.g., data 773, "user must reset password"), and OpenLDAP with ppolicy can return policy controls — but mod_authnz_ldap does not propagate these into the HTTP response. Depending on httpd version and LogLevel, some of this detail may appear in the Apache error log; treat that as version-sensitive and verify on your build rather than assuming the subcode will show up.
The stale-identity risk you describe is real but narrower than it first appears: because credentials are re-validated every request, an expired cached password is rejected on the next request. The genuine gap is when the user changed the password elsewhere and the client keeps silently sending the old one from ~/.subversion/auth/ — that fails too, but the user experience is a confusing 401 loop, not continued access. Continued access after expiration should not happen; if you observe it, suspect the mod_ldap bind cache or a second authentication path.
LDAPCacheTTL) if your build caches successful binds.svn info https://host/svn/repo --no-auth-cache --non-interactive and confirm a 401 in the Apache access log.~/.subversion/auth/ and confirm the client prompts again rather than reusing stale credentials.If step 3 unexpectedly succeeds, that is the one diagnostic detail that changes the recommendation: report which access method succeeded and whether mod_ldap caching is enabled, because that would indicate a caching or alternate-auth-path problem rather than expected behavior.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.