From ad7573252147770c66ff3761add0f04fc8fa6f6c Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 3 Mar 2022 16:29:41 -0500 Subject: [PATCH 1/2] Issue 5221 - User with expired password can still login with full privledges 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!) --- .../suites/password/pw_expired_access_test.py | 62 +++++++++++++++++++ ldap/servers/slapd/pw_mgmt.c | 1 + 2 files changed, 63 insertions(+) create mode 100644 dirsrvtests/tests/suites/password/pw_expired_access_test.py 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 index 000000000..fb0afb190 --- /dev/null +++ b/dirsrvtests/tests/suites/password/pw_expired_access_test.py @@ -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]) diff --git a/ldap/servers/slapd/pw_mgmt.c b/ldap/servers/slapd/pw_mgmt.c index 59b90dfa6..b67c2c8c0 100644 --- a/ldap/servers/slapd/pw_mgmt.c +++ b/ldap/servers/slapd/pw_mgmt.c @@ -208,6 +208,7 @@ skip: slapi_pwpolicy_make_response_control(pb, -1, -1, LDAP_PWPOLICY_PWDEXPIRED); } slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0); + bind_credentials_clear(pb_conn, PR_FALSE, PR_TRUE); slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, "password expired!", 0, NULL); -- 2.31.1