From 97e0d55745a125a933a8d4f9dddd31a752977948 Mon Sep 17 00:00:00 2001 From: Florence Blanc-Renaud Date: Mon, 6 Aug 2018 18:25:16 +0200 Subject: [PATCH] Tests: add integration test for password changes by dir mgr Add a test for issue 7601: - add a user, perform kinit user to modify the password, read krblastpwdchange and krbpasswordexpiration. - perform a ldapmodify on the password as dir mgr - make sure that krblastpwdchange and krbpasswordexpiration have been modified - perform the same check with ldappasswd Related to: https://pagure.io/freeipa/issue/7601 Reviewed-By: Thierry Bordaz --- ipatests/test_integration/test_commands.py | 127 +++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 ipatests/test_integration/test_commands.py diff --git a/ipatests/test_integration/test_commands.py b/ipatests/test_integration/test_commands.py new file mode 100644 index 0000000000000000000000000000000000000000..e277e4a2fe4089392b08719d46b011e6444e8094 --- /dev/null +++ b/ipatests/test_integration/test_commands.py @@ -0,0 +1,127 @@ +# +# Copyright (C) 2018 FreeIPA Contributors see COPYING for license +# +"""Misc test for 'ipa' CLI regressions +""" +from __future__ import print_function + +import re +from tempfile import NamedTemporaryFile +import textwrap +import time + +from ipaplatform.paths import paths + +from ipatests.test_integration.base import IntegrationTest +from ipatests.pytest_plugins.integration import tasks + + +class TestIPACommand(IntegrationTest): + """ + A lot of commands can be executed against a single IPA installation + so provide a generic class to execute one-off commands that need to be + tested without having to fire up a full server to run one command. + """ + topology = 'line' + + def test_ldapmodify_password_issue7601(self): + user = 'ipauser' + original_passwd = 'Secret123' + new_passwd = 'userPasswd123' + new_passwd2 = 'mynewPwd123' + master = self.master + base_dn = str(master.domain.basedn) # pylint: disable=no-member + + # Create a user with a password + tasks.kinit_admin(master) + add_password_stdin_text = "{pwd}\n{pwd}".format(pwd=original_passwd) + master.run_command(['ipa', 'user-add', user, + '--first', user, + '--last', user, + '--password'], + stdin_text=add_password_stdin_text) + # kinit as that user in order to modify the pwd + user_kinit_stdin_text = "{old}\n%{new}\n%{new}\n".format( + old=original_passwd, + new=original_passwd) + master.run_command(['kinit', user], stdin_text=user_kinit_stdin_text) + # Retrieve krblastpwdchange and krbpasswordexpiration + search_cmd = [ + 'ldapsearch', '-x', + '-D', 'cn=directory manager', + '-w', master.config.dirman_password, + '-s', 'base', + '-b', 'uid={user},cn=users,cn=accounts,{base_dn}'.format( + user=user, base_dn=base_dn), + '-o', 'ldif-wrap=no', + '-LLL', + 'krblastpwdchange', + 'krbpasswordexpiration'] + output = master.run_command(search_cmd).stdout_text.lower() + + # extract krblastpwdchange and krbpasswordexpiration + krbchg_pattern = 'krblastpwdchange: (.+)\n' + krbexp_pattern = 'krbpasswordexpiration: (.+)\n' + krblastpwdchange = re.findall(krbchg_pattern, output)[0] + krbexp = re.findall(krbexp_pattern, output)[0] + + # sleep 1 sec (krblastpwdchange and krbpasswordexpiration have at most + # a 1s precision) + time.sleep(1) + # perform ldapmodify on userpassword as dir mgr + mod = NamedTemporaryFile() + ldif_file = mod.name + entry_ldif = textwrap.dedent(""" + dn: uid={user},cn=users,cn=accounts,{base_dn} + changetype: modify + replace: userpassword + userpassword: {new_passwd} + """).format( + user=user, + base_dn=base_dn, + new_passwd=new_passwd) + master.put_file_contents(ldif_file, entry_ldif) + arg = ['ldapmodify', + '-h', master.hostname, + '-p', '389', '-D', + str(master.config.dirman_dn), # pylint: disable=no-member + '-w', master.config.dirman_password, + '-f', ldif_file] + master.run_command(arg) + + # Test new password with kinit + master.run_command(['kinit', user], stdin_text=new_passwd) + # Retrieve krblastpwdchange and krbpasswordexpiration + output = master.run_command(search_cmd).stdout_text.lower() + # extract krblastpwdchange and krbpasswordexpiration + newkrblastpwdchange = re.findall(krbchg_pattern, output)[0] + newkrbexp = re.findall(krbexp_pattern, output)[0] + + # both should have changed + assert newkrblastpwdchange != krblastpwdchange + assert newkrbexp != krbexp + + # Now test passwd modif with ldappasswd + time.sleep(1) + master.run_command([ + paths.LDAPPASSWD, + '-D', str(master.config.dirman_dn), # pylint: disable=no-member + '-w', master.config.dirman_password, + '-a', new_passwd, + '-s', new_passwd2, + '-x', '-ZZ', + '-H', 'ldap://{hostname}'.format(hostname=master.hostname), + 'uid={user},cn=users,cn=accounts,{base_dn}'.format( + user=user, base_dn=base_dn)] + ) + # Test new password with kinit + master.run_command(['kinit', user], stdin_text=new_passwd2) + # Retrieve krblastpwdchange and krbpasswordexpiration + output = master.run_command(search_cmd).stdout_text.lower() + # extract krblastpwdchange and krbpasswordexpiration + newkrblastpwdchange2 = re.findall(krbchg_pattern, output)[0] + newkrbexp2 = re.findall(krbexp_pattern, output)[0] + + # both should have changed + assert newkrblastpwdchange != newkrblastpwdchange2 + assert newkrbexp != newkrbexp2 -- 2.17.1