From 9d736d685f285fcfcaeb7d56ebc508b2522776ef Mon Sep 17 00:00:00 2001 From: Akshay Adhikari Date: Nov 20 2018 08:54:05 +0000 Subject: Issue 48081 - Add new CI tests for password Description: Added new tests in the password suite, performing extended password modify operations. https://pagure.io/389-ds-base/issue/48081 Reviewed by: spichugi(Thanks!) --- diff --git a/dirsrvtests/tests/suites/password/pwdModify_test.py b/dirsrvtests/tests/suites/password/pwdModify_test.py new file mode 100644 index 0000000..3a554cb --- /dev/null +++ b/dirsrvtests/tests/suites/password/pwdModify_test.py @@ -0,0 +1,267 @@ +# Copyright (C) 2018 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- +# +import pytest +import subprocess +import re +from ldap.controls import LDAPControl +from lib389._constants import * +from lib389.tasks import * +from lib389.utils import * +from lib389.topologies import topology_st as topo +from lib389.idm.user import UserAccounts, TEST_USER_PROPERTIES +from lib389.idm.organizationalunit import OrganizationalUnits +from lib389.idm.nscontainer import nsContainers +from lib389.pwpolicy import PwPolicyManager + +DEBUGGING = os.getenv("DEBUGGING", default=False) +if DEBUGGING: + logging.getLogger(__name__).setLevel(logging.DEBUG) +else: + logging.getLogger(__name__).setLevel(logging.INFO) +log = logging.getLogger(__name__) + + +OLD_PASSWD = 'password' +NEW_PASSWD = 'newpassword' +SHORT_PASSWD = 'wd' +TESTPEOPLE_OU = "TestPeople_bug834047" + + +@pytest.fixture(scope="function") +def pwd_policy_setup(topo, request): + """ + Setup to set passwordStorageScheme as CLEAR + passwordHistory to on + passwordStorageScheme to SSHA + passwordHistory off + """ + log.info("Change the pwd storage type to clear and change the password once to refresh it(for the rest of tests") + topo.standalone.config.set('passwordStorageScheme', 'CLEAR') + assert topo.standalone.passwd_s(user_2.dn, OLD_PASSWD, NEW_PASSWD) + topo.standalone.config.set('passwordHistory', 'on') + + def fin(): + topo.standalone.simple_bind_s(DN_DM, PASSWORD) + topo.standalone.config.set('passwordStorageScheme', 'SSHA') + topo.standalone.config.set('passwordHistory', 'off') + request.addfinalizer(fin) + + +def test_pwd_modify_with_different_operation(topo): + """Performing various password modify operation, + make sure that password is actually modified + + :id: e36d68a8-0960-48e4-932c-6c2f64abaebc + :setup: Standalone instance and TLS enabled + :steps: + 1. Attempt for Password change for an entry that does not exists + 2. Attempt for Password change for an entry that exists + 3. Attempt for Password change to old for an entry that exists + 4. Attempt for Password Change with Binddn as testuser but with wrong old password + 5. Attempt for Password Change with Binddn as testuser + 6. Attempt for Password Change without giving newpassword + 7. Checking password change Operation using a Non-Secure connection + 8. Testuser attempts to change password for testuser2(userPassword attribute is Set) + 9. Directory Manager attempts to change password for testuser2(userPassword attribute is Set) + 10. Create a password syntax policy. Attempt to change to password that violates that policy + 11. userPassword mod with control results in ber decode error + + :expectedresults: + 1. Operation should be successful + 2. Operation should be successful + 3. Operation should be successful + 4. Operation should not be successful + 5. Operation should be successful + 6. Operation should be successful + 7. Operation should not be successful + 8. Operation should not be successful + 9. Operation should be successful + 10. Operation should violates the policy + 11. Operation should be successful + """ + topo.standalone.enable_tls() + os.environ["LDAPTLS_CACERTDIR"] = topo.standalone.get_ssca_dir() + users = UserAccounts(topo.standalone, DEFAULT_SUFFIX) + TEST_USER_PROPERTIES['userpassword'] = OLD_PASSWD + global user + user = users.create(properties=TEST_USER_PROPERTIES) + with pytest.raises(ldap.NO_SUCH_OBJECT): + log.info("Attempt for Password change for an entry that does not exists") + assert topo.standalone.passwd_s('uid=testuser1,ou=People,dc=example,dc=com', OLD_PASSWD, NEW_PASSWD) + log.info("Attempt for Password change for an entry that exists") + assert topo.standalone.passwd_s(user.dn, OLD_PASSWD, NEW_PASSWD) + log.info("Attempt for Password change to old for an entry that exists") + assert topo.standalone.passwd_s(user.dn, NEW_PASSWD, OLD_PASSWD) + log.info("Attempt for Password Change with Binddn as testuser but with wrong old password") + topo.standalone.simple_bind_s(user.dn, OLD_PASSWD) + with pytest.raises(ldap.INVALID_CREDENTIALS): + topo.standalone.passwd_s(user.dn, NEW_PASSWD, NEW_PASSWD) + log.info("Attempt for Password Change with Binddn as testuser") + assert topo.standalone.passwd_s(user.dn, OLD_PASSWD, NEW_PASSWD) + log.info("Attempt for Password Change without giving newpassword") + assert topo.standalone.passwd_s(user.dn, None, OLD_PASSWD) + assert user.get_attr_val_utf8('uid') == 'testuser' + log.info("Change password to NEW_PASSWD i.e newpassword") + assert topo.standalone.passwd_s(user.dn, None, NEW_PASSWD) + assert topo.standalone.passwd_s(user.dn, NEW_PASSWD, None) + log.info("Check binding with old/new password") + password = [OLD_PASSWD, NEW_PASSWD] + for pass_val in password: + with pytest.raises(ldap.INVALID_CREDENTIALS): + topo.standalone.simple_bind_s(user.dn, pass_val) + log.info("Change password back to OLD_PASSWD i.e password") + topo.standalone.simple_bind_s(DN_DM, PASSWORD) + assert topo.standalone.passwd_s(user.dn, None, NEW_PASSWD) + log.info("Checking password change Operation using a Non-Secure connection") + conn = ldap.initialize("ldap://%s:%s" % (HOST_STANDALONE, PORT_STANDALONE)) + with pytest.raises(ldap.CONFIDENTIALITY_REQUIRED): + conn.passwd_s(user.dn, NEW_PASSWD, OLD_PASSWD) + log.info("Testuser attempts to change password for testuser2(userPassword attribute is Set)") + global user_2 + users = UserAccounts(topo.standalone, DEFAULT_SUFFIX) + user_2 = users.create(properties={ + 'uid': 'testuser2', + 'cn': 'testuser2', + 'sn': 'testuser2', + 'uidNumber': '3000', + 'gidNumber': '4000', + 'homeDirectory': '/home/testuser2', + 'userPassword': OLD_PASSWD + }) + topo.standalone.simple_bind_s(user.dn, NEW_PASSWD) + with pytest.raises(ldap.INSUFFICIENT_ACCESS): + assert topo.standalone.passwd_s(user_2.dn, OLD_PASSWD, NEW_PASSWD) + log.info("Directory Manager attempts to change password for testuser2(userPassword attribute is Set)") + topo.standalone.simple_bind_s(DN_DM, PASSWORD) + assert topo.standalone.passwd_s(user_2.dn, OLD_PASSWD, NEW_PASSWD) + log.info("Changing userPassword attribute to Undefined for testuser2") + topo.standalone.modify_s(user_2.dn, [(ldap.MOD_REPLACE, 'userPassword', None)]) + log.info("Testuser attempts to change password for testuser2(userPassword attribute is Undefined)") + with pytest.raises(ldap.INSUFFICIENT_ACCESS): + topo.standalone.simple_bind_s(user.dn, NEW_PASSWD) + assert topo.standalone.passwd_s(user_2.dn, None, NEW_PASSWD) + log.info("Directory Manager attempts to change password for testuser2(userPassword attribute is Undefined)") + topo.standalone.simple_bind_s(DN_DM, PASSWORD) + assert topo.standalone.passwd_s(user_2.dn, None, OLD_PASSWD) + log.info("Create a password syntax policy. Attempt to change to password that violates that policy") + topo.standalone.config.set('PasswordCheckSyntax', 'on') + with pytest.raises(ldap.CONSTRAINT_VIOLATION): + assert topo.standalone.passwd_s(user_2.dn, OLD_PASSWD, SHORT_PASSWD) + log.info("Reset password syntax policy") + topo.standalone.config.set('PasswordCheckSyntax', 'off') + log.info("userPassword mod with control results in ber decode error") + topo.standalone.simple_bind_s(DN_DM, PASSWORD) + assert topo.standalone.modify_ext_s(user.dn, [(ldap.MOD_REPLACE, 'userpassword', b'abcdefg')], + serverctrls=[LDAPControl('2.16.840.1.113730.3.4.2', 1, None)]) + log.info("Reseting the testuser's password") + topo.standalone.passwd_s(user.dn, 'abcdefg', NEW_PASSWD) + + +def test_pwd_modify_with_password_policy(topo, pwd_policy_setup): + """Performing various password modify operation, + with passwordStorageScheme as CLEAR + passwordHistory to on + + :id: 200bf0fd-20ab-4dde-849e-54067e98b917 + :setup: Standalone instance (TLS enabled) with pwd_policy_setup + :steps: + 1. Change the password and check that a new entry has been added to the history + 2. Try changing password to one stored in history + 3. Change the password several times in a row, and try binding after each change + 4. Try to bind using short password + + :expectedresults: + 1. Operation should be successful + 2. Operation should be unsuccessful + 3. Operation should be successful + 4. Operation should be unsuccessful + """ + log.info("Change the password and check that a new entry has been added to the history") + topo.standalone.passwd_s(user_2.dn, NEW_PASSWD, OLD_PASSWD) + regex = re.search('Z(.+)', user_2.get_attr_val_utf8('passwordhistory')) + assert NEW_PASSWD == regex.group(1) + log.info("Try changing password to one stored in history. Should fail") + with pytest.raises(ldap.CONSTRAINT_VIOLATION): + assert topo.standalone.passwd_s(user_2.dn, OLD_PASSWD, NEW_PASSWD) + log.info("Change the password several times in a row, and try binding after each change") + topo.standalone.passwd_s(user.dn, NEW_PASSWD, OLD_PASSWD) + assert topo.standalone.simple_bind_s(user.dn, OLD_PASSWD) + topo.standalone.passwd_s(user.dn, OLD_PASSWD, SHORT_PASSWD) + assert topo.standalone.simple_bind_s(user.dn, SHORT_PASSWD) + with pytest.raises(ldap.CONSTRAINT_VIOLATION): + topo.standalone.passwd_s(user.dn, SHORT_PASSWD, OLD_PASSWD) + + +def test_pwd_modify_with_subsuffix(topo): + """Performing various password modify operation. + + :id: 2255b4e6-3546-4ec5-84a5-cd8b3d894ac5 + :setup: Standalone instance (TLS enabled) + :steps: + 1. Add a new SubSuffix & password policy + 2. Add two New users under the SubEntry + 3. Change password of uid=test_user0,ou=TestPeople_bug834047,dc=example,dc=com to newpassword + 4. Try to delete password- case when password is specified + 5. Try to delete password- case when password is not specified + + :expectedresults: + 1. Operation should be successful + 2. Operation should be successful + 3. Operation should be successful + 4. Operation should be successful + 5. Operation should be successful + """ + + log.info("Add a new SubSuffix") + ous = OrganizationalUnits(topo.standalone, DEFAULT_SUFFIX) + ou_temp = ous.create(properties={'ou': TESTPEOPLE_OU}) + + log.info("Add the container & create password policies") + policy = PwPolicyManager(topo.standalone) + policy.create_subtree_policy(ou_temp.dn, properties={ + 'passwordHistory': 'on', + 'passwordInHistory': '6', + 'passwordChange': 'on', + 'passwordStorageScheme': 'CLEAR'}) + + log.info("Add two New users under the SubEntry") + user = UserAccounts(topo.standalone, DEFAULT_SUFFIX, rdn='ou=TestPeople_bug834047') + test_user0 = user.create(properties={ + 'uid': 'test_user0', + 'cn': 'test0', + 'sn': 'test0', + 'uidNumber': '3002', + 'gidNumber': '4002', + 'homeDirectory': '/home/test_user0', + 'userPassword': OLD_PASSWD + }) + test_user1 = user.create(properties={ + 'uid': 'test_user1', + 'cn': 'test1', + 'sn': 'test1', + 'uidNumber': '3003', + 'gidNumber': '4003', + 'homeDirectory': '/home/test_user3', + 'userPassword': OLD_PASSWD + }) + log.info(f"Changing password of {test_user0.dn} to newpassword") + topo.standalone.simple_bind_s(test_user0.dn, OLD_PASSWD) + topo.standalone.modify_s(test_user0.dn, [(ldap.MOD_REPLACE, 'userPassword', ensure_bytes(NEW_PASSWD))]) + topo.standalone.simple_bind_s(test_user0.dn, NEW_PASSWD) + log.info("Try to delete password- case when password is specified") + topo.standalone.modify_s(test_user0.dn, [(ldap.MOD_DELETE, 'userPassword', ensure_bytes(NEW_PASSWD))]) + topo.standalone.simple_bind_s(test_user1.dn, OLD_PASSWD) + log.info("Try to delete password- case when password is not specified") + topo.standalone.modify_s(test_user1.dn, [(ldap.MOD_DELETE, 'userPassword', None)]) + + +if __name__ == '__main__': + # Run isolated + # -s for DEBUG mode + CURRENT_FILE = os.path.realpath(__file__) + pytest.main(["-s", CURRENT_FILE])