[PATCH] Issue 5221 - User with expired password can still login with full privledges
authorMark Reynolds <mreynolds@redhat.com>
Thu, 3 Mar 2022 21:29:41 +0000 (16:29 -0500)
committerAnton Gladky <gladk@debian.org>
Mon, 24 Apr 2023 04:08:15 +0000 (05:08 +0100)
Bug Description:

A user with an expired password can still login and perform operations
with its typical access perimssions.  But an expired password means the
account should be considered anonymous.

Fix Description:

Clear the bind credentials if the password is expired

relates: https://github.com/389ds/389-ds-base/issues/5221

Reviewed by: progier(Thanks!)

Gbp-Pq: Name CVE-2022-0996.patch

dirsrvtests/tests/suites/password/pw_expired_access_test.py [new file with mode: 0644]
ldap/servers/slapd/pw_mgmt.c

diff --git a/dirsrvtests/tests/suites/password/pw_expired_access_test.py b/dirsrvtests/tests/suites/password/pw_expired_access_test.py
new file mode 100644 (file)
index 0000000..fb0afb1
--- /dev/null
@@ -0,0 +1,62 @@
+import ldap
+import logging
+import pytest
+import os
+import time
+from lib389._constants import DEFAULT_SUFFIX, PASSWORD
+from lib389.idm.domain import Domain
+from lib389.idm.user import UserAccounts
+from lib389.topologies import topology_st as topo
+
+log = logging.getLogger(__name__)
+
+def test_expired_user_has_no_privledge(topo):
+    """Specify a test case purpose or name here
+
+    :id: 3df86b45-9929-414b-9bf6-06c25301d207
+    :setup: Standalone Instance
+    :steps:
+        1. Set short password expiration time
+        2. Add user and wait for expiration time to run out
+        3. Set one aci that allows authenticated users full access
+        4. Bind as user (password should be expired)
+        5. Attempt modify
+    :expectedresults:
+        1. Success
+        2. Success
+        3. Success
+        4. Success
+        5. Success
+    """
+
+    # Configured password epxiration
+    topo.standalone.config.replace_many(('passwordexp', 'on'), ('passwordmaxage', '1'))
+
+    # Set aci
+    suffix = Domain(topo.standalone, DEFAULT_SUFFIX)
+    ACI_TEXT = '(targetattr="*")(version 3.0; acl "test aci"; allow (all) (userdn="ldap:///all");)'
+    suffix.replace('aci', ACI_TEXT)
+
+    # Add user
+    user = UserAccounts(topo.standalone, DEFAULT_SUFFIX, rdn=None).create_test_user()
+    user.replace('userpassword', PASSWORD)
+    time.sleep(2)
+
+    # Bind as user with expired password.  Need to use raw ldap calls because
+    # lib389 will close the connection when an error 49 is encountered.
+    ldap_object = ldap.initialize(topo.standalone.toLDAPURL())
+    with pytest.raises(ldap.INVALID_CREDENTIALS):
+        res_type, res_data, res_msgid, res_ctrls = ldap_object.simple_bind_s(
+            user.dn, PASSWORD)
+
+    # Try modify
+    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
+        modlist = [ (ldap.MOD_REPLACE, 'description', b'Should not work!') ]
+        ldap_object.modify_ext_s(DEFAULT_SUFFIX, modlist)
+
+
+if __name__ == '__main__':
+    # Run isolated
+    # -s for DEBUG mode
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main(["-s", CURRENT_FILE])
index befac50cd1c4f28b366a41c1794973158c6d09ca..cc34de9b2cdad06514b0cdf814d2beb44cbe4d48 100644 (file)
@@ -211,6 +211,7 @@ skip:
         if (pwresponse_req) {
             slapi_pwpolicy_make_response_control(pb, -1, -1, LDAP_PWPOLICY_PWDEXPIRED);
         }
+        bind_credentials_clear(pb_conn, PR_FALSE, PR_TRUE);
         slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL,
                                "password expired!", 0, NULL);