Bug 2479031 (CVE-2026-92821)

Summary: CVE-2026-92821 sssd: SSSD: Access control bypass via premature LDAP access rule evaluation
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security DevOps Team <prodsec-dev>
Status: NEW --- QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: akhatavk, aos-team-art-private, asdas, dpaolell, jdelft, jupierce, lgarciaa, mbiarnes, ppalepu, ppostler, prdhamdh, rhel-process-autobot, security-response-team, sghai, sidsharm, suppawar, vlaad, watson-tool-maintainers
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
A flaw was found in SSSD. When configured to evaluate password expiration warnings before restrictive access rules in LDAP (Lightweight Directory Access Protocol) environments, an expired-password warning terminates rule evaluation early and treats the access request as successful. A remote authenticated user with an expired password using an alternative authentication method, such as SSH public key authentication, can exploit this flaw to bypass access control restrictions and gain unauthorized access to protected systems.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 2546244    
Bug Blocks:    

Description OSIDB Bzimport 2026-05-18 03:53:12 UTC
AI_ONLY_REPORT
package: sssd-2.12.0-1.el10
------
Summary: LDAP Access Control Bypass When `pwd_expire_policy_warn` Precedes  
Restrictive Rules in `ldap_access_order`: an expired-password warning is  
converted into a successful PAM result before later LDAP access rules run,  
allowing configured `filter`, `host`, or similar restrictive checks to be  
bypassed.
Requirements to exploit: A valid LDAP-backed account whose password is  
expired, an LDAP deployment using `access_provider = ldap` with a  
compatible password-expiration policy, `ldap_access_order` placing  
`pwd_expire_policy_warn` before restrictive rules, and a non-password  
authentication path such as SSH public key that still invokes SSSD  
account/access checks.
Component affected: `sssd-2.12.0-1.el10`, LDAP access-control evaluation in  
`src/providers/ldap/sdap_access.c` (`sdap_access_check_next_rule()`) and  
success mapping in `src/providers/ldap/ldap_access.c`  
(`sdap_pam_access_handler_done()`).
Version affected: `sssd-2.12.0-1.el10` in LDAP deployments where  
`ldap_access_order` places `pwd_expire_policy_warn` before restrictive  
rules.
Patch available: no released package fix established; proposed patch  
included below
Version fixed: unknown
Upstream coordination: Not notified.
CVSS: CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N - 6.8 (MEDIUM)
AV:N - reachable over the network through services that rely on SSSD  
LDAP account/access checks, such as SSH.
AC:H - exploitation depends on a specific non-default rule ordering, an  
expired-password state, and a compatible non-password authentication path.
PR:L - the attacker needs a valid account that can authenticate to the  
target service.
UI:N - no separate victim interaction is required once the attacker  
initiates authentication.
S:U - the impact remains within the vulnerable service's own security  
scope.
C:H - a successful bypass can expose data on systems or services that  
should have remained inaccessible under `filter`, `host`, or `rhost`  
restrictions.
I:H - the same bypass can permit unauthorized actions within those  
protected systems or services.
A:N - the flaw does not inherently reduce availability.
Impact: Moderate. This is a real authorization bypass with meaningful  
confidentiality and integrity consequences where LDAP access rules are used  
as security boundaries, but exploitation requires a valid account, an  
expired-password condition, and a specific non-default `ldap_access_order`  
configuration. That fits a security flaw that can compromise resources  
under certain circumstances, while being less easily exploitable than a  
default-path or broadly reachable access-control failure.
Embargo: no
Reason: the issue is configuration-dependent, requires an already valid  
account, and can be mitigated immediately by reordering or removing  
`pwd_expire_policy_warn` from the front of `ldap_access_order`.
Acknowledgement: Aisle Research
Vulnerability Details: The documented purpose of `pwd_expire_policy_warn`  
is to warn while still allowing login. The issue here is narrower: in the  
LDAP access path, that warning state terminates ordered rule evaluation  
before later restrictive checks are reached. In  
`sdap_access_check_next_rule()`, rule processing only continues while `ret  
== EOK`; when `LDAP_ACCESS_EXPIRE_POLICY_WARN` converts an expired password  
into `ERR_PASSWORD_EXPIRED_WARN`, the loop stops and returns that non-`EOK`  
status.
```c
while (ret == EOK) {
...
case LDAP_ACCESS_EXPIRE_POLICY_WARN:
ret = perform_pwexpire_policy(state, state->domain, state->pd,
state->access_ctx->type,
state->access_ctx->id_ctx->opts);
if (ret == ERR_PASSWORD_EXPIRED) {
ret = ERR_PASSWORD_EXPIRED_WARN;
}
break;
...
}
state->current_rule++;
}
return ret;
```
That returned status is then treated as success in  
`sdap_pam_access_handler_done()`, which maps both `EOK` and  
`ERR_PASSWORD_EXPIRED_WARN` to `PAM_SUCCESS`. In deployments using an  
ordered configuration such as `pwd_expire_policy_warn,filter,host`, later  
`filter`, `host`, or `rhost` checks are skipped entirely, so an  
expired-password user can be accepted by the warning path before the  
restrictive rules run.
Steps to reproduce:
1. Configure an LDAP-backed SSSD domain with `access_provider = ldap`,  
`ldap_pwd_policy = shadow` (or `mit_kerberos`), `ldap_access_order =  
pwd_expire_policy_warn,filter,host`, and a restrictive `ldap_access_filter`  
or host rule that should deny the test user.
2. Ensure the test user's password is marked expired in the LDAP attributes  
used by the selected password policy.
3. Authenticate through a non-password method that still invokes  
account/access checks, such as SSH public key login.
4. Expected result: a later `filter` or `host` rule denies access. Actual  
result: the warning path returns `ERR_PASSWORD_EXPIRED_WARN`, the handler  
maps it to `PAM_SUCCESS`, and the later restrictive rules are not evaluated.
Mitigation: Until a fix is available, do not place `pwd_expire_policy_warn`  
before restrictive entries in `ldap_access_order`. If warning behavior is  
still required, place it after `filter`, `host`, `rhost`, or other  
denial-capable rules, or use `pwd_expire_policy_reject` where expired  
accounts should not continue through the access chain.
Proposed Fix: Record the warning state, continue evaluating the remaining  
ordered rules, and only return `ERR_PASSWORD_EXPIRED_WARN` after all  
configured access rules have passed.
```diff
diff --git a/src/providers/ldap/sdap_access.c  
b/src/providers/ldap/sdap_access.c
— a/src/providers/ldap/sdap_access.c
+++ b/src/providers/ldap/sdap_access.c
@@
struct sdap_access_req_ctx {
@@
size_t current_rule;
enum sdap_access_control_type ac_type;
+    bool pw_expire_warn_seen;
};
@@
state->conn = conn;
state->current_rule = 0;
+    state->pw_expire_warn_seen = false;
@@ static errno_t sdap_access_check_next_rule(struct sdap_access_req_ctx  
*state,
case LDAP_ACCESS_EMPTY:
           /* we are done with no errors */

           return EOK;
+            /* all rules passed; preserve warn semantics if seen */
+            return state->pw_expire_warn_seen ?  
ERR_PASSWORD_EXPIRED_WARN : EOK;
@@
          case LDAP_ACCESS_EXPIRE_POLICY_WARN:
              ret = perform_pwexpire_policy(state, state->domain, state->pd,
                                            state->access_ctx->type,
                                            state->access_ctx->id_ctx->opts);
              if (ret == ERR_PASSWORD_EXPIRED) {

               ret = ERR_PASSWORD_EXPIRED_WARN;
+                state->pw_expire_warn_seen = true;
+                ret = EOK;
              }
              break;
```


------
This report was generated using AI technology. Always review AI-generated  
content prior to use