From 4ccd4703cf08537494276d64bd5ba06565139f1f Mon Sep 17 00:00:00 2001
From: Simon Pichugin <spichugi@redhat.com>
Date: Wed, 24 Aug 2016 10:08:29 +0200
Subject: [PATCH] Ticket 48967 - Add CI test and refactor test suite

Description: Add a test case to password policy test suite.
Refactor structure of password test suite so it would become more
logical.

https://fedorahosted.org/389/ticket/48967

Reviewed by: ?
---
 .../suites/password/pwdPolicy_attribute_test.py    | 339 +++++++++++++++++++++
 .../tests/suites/password/pwdPolicy_syntax_test.py | 224 ++++++++++++++
 .../tests/suites/password/pwdPolicy_test.py        | 224 --------------
 .../tests/suites/password/pwd_change_policytest.py | 240 ---------------
 4 files changed, 563 insertions(+), 464 deletions(-)
 create mode 100644 dirsrvtests/tests/suites/password/pwdPolicy_attribute_test.py
 create mode 100644 dirsrvtests/tests/suites/password/pwdPolicy_syntax_test.py
 delete mode 100644 dirsrvtests/tests/suites/password/pwdPolicy_test.py
 delete mode 100644 dirsrvtests/tests/suites/password/pwd_change_policytest.py

diff --git a/dirsrvtests/tests/suites/password/pwdPolicy_attribute_test.py b/dirsrvtests/tests/suites/password/pwdPolicy_attribute_test.py
new file mode 100644
index 0000000..d3be7e2
--- /dev/null
+++ b/dirsrvtests/tests/suites/password/pwdPolicy_attribute_test.py
@@ -0,0 +1,339 @@
+import os
+import sys
+import time
+import subprocess
+import ldap
+import logging
+import pytest
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from lib389.utils import *
+
+DEBUGGING = False
+OU_PEOPLE = 'ou=people,{}'.format(DEFAULT_SUFFIX)
+TEST_USER_NAME = 'simplepaged_test'
+TEST_USER_DN = 'uid={},{}'.format(TEST_USER_NAME, OU_PEOPLE)
+TEST_USER_PWD = 'simplepaged_test'
+PW_POLICY_CONT_USER = 'cn="cn=nsPwPolicyEntry,uid=simplepaged_test,'\
+                      'ou=people,dc=example,dc=com",'\
+                      'cn=nsPwPolicyContainer,ou=people,dc=example,dc=com'
+PW_POLICY_CONT_PEOPLE = 'cn="cn=nsPwPolicyEntry,'\
+                        'ou=people,dc=example,dc=com",'\
+                        'cn=nsPwPolicyContainer,ou=people,dc=example,dc=com'
+
+if DEBUGGING:
+    logging.getLogger(__name__).setLevel(logging.DEBUG)
+else:
+    logging.getLogger(__name__).setLevel(logging.INFO)
+
+log = logging.getLogger(__name__)
+
+
+class TopologyStandalone(object):
+    """The DS Topology Class"""
+    def __init__(self, standalone):
+        """Init"""
+        standalone.open()
+        self.standalone = standalone
+
+
+@pytest.fixture(scope="module")
+def topology(request):
+    """Create DS Deployment"""
+
+    # Creating standalone instance ...
+    if DEBUGGING:
+        standalone = DirSrv(verbose=True)
+    else:
+        standalone = DirSrv(verbose=False)
+    args_instance[SER_HOST] = HOST_STANDALONE
+    args_instance[SER_PORT] = PORT_STANDALONE
+    args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+    args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
+    args_standalone = args_instance.copy()
+    standalone.allocate(args_standalone)
+    instance_standalone = standalone.exists()
+    if instance_standalone:
+        standalone.delete()
+    standalone.create()
+    standalone.open()
+
+    def fin():
+        """If we are debugging just stop the instances, otherwise remove
+        them
+        """
+        if DEBUGGING:
+            standalone.stop()
+        else:
+            standalone.delete()
+
+    request.addfinalizer(fin)
+
+
+    return TopologyStandalone(standalone)
+
+
+@pytest.fixture(scope="module")
+def test_user(topology, request):
+    """User for binding operation"""
+
+    log.info('Adding user {}'.format(TEST_USER_DN))
+    try:
+        topology.standalone.add_s(Entry((TEST_USER_DN, {
+                                        'objectclass': 'top person'.split(),
+                                        'objectclass': 'organizationalPerson',
+                                        'objectclass': 'inetorgperson',
+                                        'cn': TEST_USER_NAME,
+                                        'sn': TEST_USER_NAME,
+                                        'userpassword': TEST_USER_PWD,
+                                        'mail': '%s@redhat.com' % TEST_USER_NAME,
+                                        'uid': TEST_USER_NAME
+                                        })))
+    except ldap.LDAPError as e:
+        log.error('Failed to add user (%s): error (%s)' % (TEST_USER_DN,
+                                                           e.message['desc']))
+        raise e
+
+    def fin():
+        log.info('Deleting user {}'.format(TEST_USER_DN))
+        topology.standalone.delete_s(TEST_USER_DN)
+    request.addfinalizer(fin)
+
+
+@pytest.fixture(scope="module")
+def password_policy(topology, test_user):
+    """Set up password policy for subtree and user"""
+
+    log.info('Enable fine-grained policy')
+    try:
+        topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE,
+                                                  'nsslapd-pwpolicy-local',
+                                                  'on')])
+    except ldap.LDAPError as e:
+        log.error('Failed to set fine-grained policy: error {}'.format(
+            e.message['desc']))
+        raise e
+
+    log.info('Create password policy for subtree {}'.format(OU_PEOPLE))
+    try:
+        subprocess.call(['ns-newpwpolicy.pl', '-D', DN_DM, '-w', PASSWORD,
+                         '-p', str(PORT_STANDALONE), '-h', HOST_STANDALONE,
+                         '-S', OU_PEOPLE, '-Z', SERVERID_STANDALONE])
+    except subprocess.CalledProcessError as e:
+        log.error('Failed to create pw policy policy for {}: error {}'.format(
+            OU_PEOPLE, e.message['desc']))
+        raise e
+
+    log.info('Add pwdpolicysubentry attribute to {}'.format(OU_PEOPLE))
+    try:
+        topology.standalone.modify_s(OU_PEOPLE, [(ldap.MOD_REPLACE,
+                                                  'pwdpolicysubentry',
+                                                  PW_POLICY_CONT_PEOPLE)])
+    except ldap.LDAPError as e:
+        log.error('Failed to pwdpolicysubentry pw policy '\
+                  'policy for {}: error {}'.format(OU_PEOPLE,
+                                                   e.message['desc']))
+        raise e
+
+    log.info('Create password policy for subtree {}'.format(TEST_USER_DN))
+    try:
+        subprocess.call(['ns-newpwpolicy.pl', '-D', DN_DM, '-w', PASSWORD,
+                         '-p', str(PORT_STANDALONE), '-h', HOST_STANDALONE,
+                         '-U', TEST_USER_DN, '-Z', SERVERID_STANDALONE])
+    except subprocess.CalledProcessError as e:
+        log.error('Failed to create pw policy policy for {}: error {}'.format(
+            TEST_USER_DN, e.message['desc']))
+        raise e
+
+    log.info('Add pwdpolicysubentry attribute to {}'.format(TEST_USER_DN))
+    try:
+        topology.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_REPLACE,
+                                                     'pwdpolicysubentry',
+                                                     PW_POLICY_CONT_USER)])
+    except ldap.LDAPError as e:
+        log.error('Failed to pwdpolicysubentry pw policy '\
+                  'policy for {}: error {}'.format(TEST_USER_DN,
+                                                   e.message['desc']))
+        raise e
+
+
+@pytest.mark.parametrize('subtree_pwchange,user_pwchange,exception',
+                         [('on', 'off', ldap.UNWILLING_TO_PERFORM),
+                          ('off', 'off', ldap.UNWILLING_TO_PERFORM),
+                          ('off', 'on', None), ('on', 'on', None)])
+def test_change_pwd(topology, test_user, password_policy,
+                    subtree_pwchange, user_pwchange, exception):
+    """Verify that 'passwordChange' attr works as expected
+    User should have a priority over a subtree.
+
+    :Feature: Password policy
+
+    :Setup: Standalone instance, test user,
+            password policy entries for a user and a subtree
+
+    :Steps: 1. Set passwordChange on the user and the subtree
+               to various combinations
+            2. Bind as test user
+            3. Try to change password
+
+    :Assert: Subtree/User passwordChange - result
+             off/on, on/on - success
+             on/off, off/off - UNWILLING_TO_PERFORM
+    """
+
+    log.info('Set passwordChange to "{}" - {}'.format(subtree_pwchange,
+                                                      PW_POLICY_CONT_PEOPLE))
+    try:
+        topology.standalone.modify_s(PW_POLICY_CONT_PEOPLE, [(ldap.MOD_REPLACE,
+                                                             'passwordChange',
+                                                             subtree_pwchange)])
+    except ldap.LDAPError as e:
+        log.error('Failed to set passwordChange '\
+                  'policy for {}: error {}'.format(PW_POLICY_CONT_PEOPLE,
+                                                   e.message['desc']))
+        raise e
+
+
+    log.info('Set passwordChange to "{}" - {}'.format(user_pwchange,
+                                                      PW_POLICY_CONT_USER))
+    try:
+        topology.standalone.modify_s(PW_POLICY_CONT_USER, [(ldap.MOD_REPLACE,
+                                                            'passwordChange',
+                                                            user_pwchange)])
+    except ldap.LDAPError as e:
+        log.error('Failed to set passwordChange '\
+                  'policy for {}: error {}'.format(PW_POLICY_CONT_USER,
+                                                   e.message['desc']))
+        raise e
+
+    try:
+        log.info('Bind as user and modify userPassword')
+        topology.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
+        if exception:
+            with pytest.raises(exception):
+                topology.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_REPLACE,
+                                                            'userPassword',
+                                                            'new_pass')])
+        else:
+            topology.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_REPLACE,
+                                                        'userPassword',
+                                                        'new_pass')])
+    except ldap.LDAPError as e:
+        log.error('Failed to change userpassword for {}: error {}'.format(
+            TEST_USER_DN, e.message['info']))
+        raise e
+    finally:
+        log.info('Bind as DM')
+        topology.standalone.simple_bind_s(DN_DM, PASSWORD)
+        topology.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_REPLACE,
+                                                     'userPassword',
+                                                     TEST_USER_PWD)])
+
+
+def test_pwd_min_age(topology, test_user, password_policy):
+    """If we set passwordMinAge to some value, for example to 10, then it
+    should not allow the user to change the password within 10 seconds after
+    his previous change.
+
+    :Feature: Password policy
+
+    :Setup: Standalone instance, test user,
+            password policy entries for a user and a subtree
+
+    :Steps: 1. Set passwordMinAge to 10 on the user pwpolicy entry
+            2. Set passwordMinAge to 10 on the subtree pwpolicy entry
+            3. Set passwordMinAge to 10 on the cn=config entry
+            4. Bind as test user
+            5. Try to change password two times in a row
+            6. Wait 12 seconds
+            7. Try to change password
+
+    :Assert: User should be not allowed to change the password
+             right after previous change - CONSTRAINT_VIOLATION
+             User should be not allowed to change the password
+             after 12 seconds passed
+    """
+
+    num_seconds = '10'
+
+    log.info('Set passwordminage to "{}" - {}'.format(num_seconds, PW_POLICY_CONT_PEOPLE))
+    try:
+        topology.standalone.modify_s(PW_POLICY_CONT_PEOPLE, [(ldap.MOD_REPLACE,
+                                                             'passwordminage',
+                                                             num_seconds)])
+    except ldap.LDAPError as e:
+        log.error('Failed to set passwordminage '\
+                  'policy for {}: error {}'.format(PW_POLICY_CONT_PEOPLE,
+                                                   e.message['desc']))
+        raise e
+
+    log.info('Set passwordminage to "{}" - {}'.format(num_seconds, PW_POLICY_CONT_USER))
+    try:
+        topology.standalone.modify_s(PW_POLICY_CONT_USER, [(ldap.MOD_REPLACE,
+                                                            'passwordminage',
+                                                            num_seconds)])
+    except ldap.LDAPError as e:
+        log.error('Failed to set passwordminage '\
+                  'policy for {}: error {}'.format(PW_POLICY_CONT_USER,
+                                                   e.message['desc']))
+        raise e
+
+    log.info('Set passwordminage to "{}" - {}'.format(num_seconds, DN_CONFIG))
+    try:
+        topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE,
+                                                  'passwordminage',
+                                                  num_seconds)])
+    except ldap.LDAPError as e:
+        log.error('Failed to set passwordminage '\
+                  'policy for {}: error {}'.format(DN_CONFIG,
+                                                   e.message['desc']))
+        raise e
+
+    try:
+        log.info('Bind as user and modify userPassword')
+        topology.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
+        topology.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_REPLACE,
+                                                     'userPassword',
+                                                     'new_pass')])
+    except ldap.LDAPError as e:
+        log.error('Failed to change userpassword for {}: error {}'.format(
+            TEST_USER_DN, e.message['info']))
+        raise e
+
+
+    log.info('Bind as user and modify userPassword straight away after previous change')
+    topology.standalone.simple_bind_s(TEST_USER_DN, 'new_pass')
+    with pytest.raises(ldap.CONSTRAINT_VIOLATION):
+        topology.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_REPLACE,
+                                                     'userPassword',
+                                                     'new_new_pass')])
+
+    log.info('Wait {} second'.format(int(num_seconds) + 2))
+    time.sleep(int(num_seconds) + 2)
+
+    try:
+        log.info('Bind as user and modify userPassword')
+        topology.standalone.simple_bind_s(TEST_USER_DN, 'new_pass')
+        topology.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_REPLACE,
+                                                     'userPassword',
+                                                     TEST_USER_PWD)])
+    except ldap.LDAPError as e:
+        log.error('Failed to change userpassword for {}: error {}'.format(
+            TEST_USER_DN, e.message['info']))
+        raise e
+    finally:
+        log.info('Bind as DM')
+        topology.standalone.simple_bind_s(DN_DM, PASSWORD)
+        topology.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_REPLACE,
+                                                     'userPassword',
+                                                     TEST_USER_PWD)])
+
+
+if __name__ == '__main__':
+    # Run isolated
+    # -s for DEBUG mode
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s %s" % CURRENT_FILE)
diff --git a/dirsrvtests/tests/suites/password/pwdPolicy_syntax_test.py b/dirsrvtests/tests/suites/password/pwdPolicy_syntax_test.py
new file mode 100644
index 0000000..aad4e40
--- /dev/null
+++ b/dirsrvtests/tests/suites/password/pwdPolicy_syntax_test.py
@@ -0,0 +1,224 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import os
+import time
+import ldap
+import logging
+import pytest
+from lib389 import DirSrv, Entry
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+DEBUGGING = False
+
+USER_DN = 'uid=user,ou=People,%s' % DEFAULT_SUFFIX
+
+if DEBUGGING:
+    logging.getLogger(__name__).setLevel(logging.DEBUG)
+else:
+    logging.getLogger(__name__).setLevel(logging.INFO)
+
+
+log = logging.getLogger(__name__)
+
+
+class TopologyStandalone(object):
+    """The DS Topology Class"""
+    def __init__(self, standalone):
+        """Init"""
+        standalone.open()
+        self.standalone = standalone
+
+
+@pytest.fixture(scope="module")
+def topology(request):
+    """Create DS Deployment"""
+
+    # Creating standalone instance ...
+    if DEBUGGING:
+        standalone = DirSrv(verbose=True)
+    else:
+        standalone = DirSrv(verbose=False)
+    args_instance[SER_HOST] = HOST_STANDALONE
+    args_instance[SER_PORT] = PORT_STANDALONE
+    args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+    args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
+    args_standalone = args_instance.copy()
+    standalone.allocate(args_standalone)
+    instance_standalone = standalone.exists()
+    if instance_standalone:
+        standalone.delete()
+    standalone.create()
+    standalone.open()
+
+    def fin():
+        """If we are debugging just stop the instances, otherwise remove
+        them
+        """
+        if DEBUGGING:
+            standalone.stop()
+        else:
+            standalone.delete()
+
+    request.addfinalizer(fin)
+
+    return TopologyStandalone(standalone)
+
+
+def _create_user(inst):
+    """Create the test user."""
+    inst.add_s(Entry((
+                USER_DN, {
+                    'objectClass': 'top account simplesecurityobject'.split(),
+                     'uid': 'user',
+                     'userpassword': PASSWORD
+                })))
+
+
+def setPolicy(inst, attr, value):
+    """Bind as ROot DN, set polcy, and then bind as user"""
+    try:
+        inst.simple_bind_s(DN_DM, PASSWORD)
+    except ldap.LDAPError as e:
+        log.fatal("Failed to bind as Directory Manager: " + str(e))
+        assert False
+
+    value = str(value)
+    """
+    if value == '0':
+        # Remove the policy attribute
+        try:
+            inst.modify_s("cn=config",
+                [(ldap.MOD_DELETE, attr, None)])
+        except ldap.LDAPError as e:
+            log.fatal("Failed to rmeove password policy %s: %s" %
+                      (attr, str(e)))
+            assert False
+    else:
+    """
+    # Set the policy value
+    inst.config.set(attr, value)
+
+    try:
+        inst.simple_bind_s(USER_DN, PASSWORD)
+    except ldap.LDAPError as e:
+        log.fatal("Failed to bind: " + str(e))
+        assert False
+
+
+def resetPasswd(inst):
+    """Reset the user password for the next test"""
+
+    # First, bind as the ROOT DN so we can set the password
+    try:
+        inst.simple_bind_s(DN_DM, PASSWORD)
+    except ldap.LDAPError as e:
+        log.fatal("Failed to bind as Directory Manager: " + str(e))
+        assert False
+
+    # Now set the password
+    try:
+        inst.modify_s(USER_DN,
+            [(ldap.MOD_REPLACE, 'userpassword', PASSWORD)])
+    except ldap.LDAPError as e:
+        log.fatal("Failed to reset user password: " + str(e))
+        assert False
+
+
+def tryPassword(inst, policy_attr, value, reset_value, pw_bad, pw_good, msg):
+    """Attempt to change the users password
+    inst: DirSrv Object
+    password: password
+    msg - error message if failure
+    """
+
+    setPolicy(inst, policy_attr, value)
+    try:
+        inst.modify_s(USER_DN,
+            [(ldap.MOD_REPLACE, 'userpassword', pw_bad)])
+        log.fatal('Invalid password was unexpectedly accepted (%s)' %
+                  (policy_attr))
+        assert False
+    except ldap.CONSTRAINT_VIOLATION:
+        log.info('Invalid password correctly rejected by %s:  %s' %
+                 (policy_attr, msg))
+        pass
+    except ldap.LDAPError as e:
+        log.fatal("Failed to change password: " + str(e))
+        assert False
+
+    # Change password that is allowed
+    try:
+        inst.modify_s(USER_DN,
+            [(ldap.MOD_REPLACE, 'userpassword', pw_good)])
+    except ldap.LDAPError as e:
+        log.fatal("Failed to change password: " + str(e))
+        assert False
+
+    # Reset for the next test
+    resetPasswd(inst)
+    setPolicy(inst, policy_attr, reset_value)
+
+
+def test_pwdPolicy_syntax(topology):
+    '''
+    Password policy test: Ensure that on a password change, the policy syntax
+    is enforced correctly.
+    '''
+
+    # Create a user
+    _create_user(topology.standalone)
+
+    # Set the password policy globally
+    topology.standalone.config.set('passwordCheckSyntax', 'on')
+    topology.standalone.config.set('nsslapd-pwpolicy-local', 'off')
+    topology.standalone.config.set('passwordMinCategories', '1')
+
+    #
+    # Test each syntax catagory
+    #
+
+    # Min Length
+    tryPassword(topology.standalone, 'passwordMinLength', 10, 2, 'passwd',
+                'password123', 'length too short')
+    # Min Digit
+    tryPassword(topology.standalone, 'passwordMinDigits', 2, 0, 'passwd',
+                'password123', 'does not contain minimum number of digits')
+    # Min Alphas
+    tryPassword(topology.standalone, 'passwordMinAlphas', 2, 0, 'p123456789',
+                'password123', 'does not contain minimum number of alphas')
+    # Max Repeats
+    tryPassword(topology.standalone, 'passwordMaxRepeats', 2, 0, 'passsword',
+                'pasword123', 'too many repeating characters')
+    # Min Specials
+    tryPassword(topology.standalone, 'passwordMinSpecials', 2, 0, 'passwd',
+                'password_#$',
+                'does not contain minimum number of special characters')
+    # Min Lowers
+    tryPassword(topology.standalone, 'passwordMinLowers', 2, 0, 'PASSWORD123',
+                'password123',
+                'does not contain minimum number of lowercase characters')
+    # Min Uppers
+    tryPassword(topology.standalone, 'passwordMinUppers', 2, 0, 'password',
+                'PASSWORD',
+                'does not contain minimum number of lowercase characters')
+    # Min 8-bits - "ldap" package only accepts ascii strings at the moment
+
+    log.info('pwdPolicy tests PASSED')
+
+
+if __name__ == '__main__':
+    # Run isolated
+    # -s for DEBUG mode
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s %s" % CURRENT_FILE)
diff --git a/dirsrvtests/tests/suites/password/pwdPolicy_test.py b/dirsrvtests/tests/suites/password/pwdPolicy_test.py
deleted file mode 100644
index aad4e40..0000000
--- a/dirsrvtests/tests/suites/password/pwdPolicy_test.py
+++ /dev/null
@@ -1,224 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-#
-import os
-import time
-import ldap
-import logging
-import pytest
-from lib389 import DirSrv, Entry
-from lib389._constants import *
-from lib389.properties import *
-from lib389.tasks import *
-
-logging.getLogger(__name__).setLevel(logging.DEBUG)
-log = logging.getLogger(__name__)
-
-DEBUGGING = False
-
-USER_DN = 'uid=user,ou=People,%s' % DEFAULT_SUFFIX
-
-if DEBUGGING:
-    logging.getLogger(__name__).setLevel(logging.DEBUG)
-else:
-    logging.getLogger(__name__).setLevel(logging.INFO)
-
-
-log = logging.getLogger(__name__)
-
-
-class TopologyStandalone(object):
-    """The DS Topology Class"""
-    def __init__(self, standalone):
-        """Init"""
-        standalone.open()
-        self.standalone = standalone
-
-
-@pytest.fixture(scope="module")
-def topology(request):
-    """Create DS Deployment"""
-
-    # Creating standalone instance ...
-    if DEBUGGING:
-        standalone = DirSrv(verbose=True)
-    else:
-        standalone = DirSrv(verbose=False)
-    args_instance[SER_HOST] = HOST_STANDALONE
-    args_instance[SER_PORT] = PORT_STANDALONE
-    args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
-    args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
-    args_standalone = args_instance.copy()
-    standalone.allocate(args_standalone)
-    instance_standalone = standalone.exists()
-    if instance_standalone:
-        standalone.delete()
-    standalone.create()
-    standalone.open()
-
-    def fin():
-        """If we are debugging just stop the instances, otherwise remove
-        them
-        """
-        if DEBUGGING:
-            standalone.stop()
-        else:
-            standalone.delete()
-
-    request.addfinalizer(fin)
-
-    return TopologyStandalone(standalone)
-
-
-def _create_user(inst):
-    """Create the test user."""
-    inst.add_s(Entry((
-                USER_DN, {
-                    'objectClass': 'top account simplesecurityobject'.split(),
-                     'uid': 'user',
-                     'userpassword': PASSWORD
-                })))
-
-
-def setPolicy(inst, attr, value):
-    """Bind as ROot DN, set polcy, and then bind as user"""
-    try:
-        inst.simple_bind_s(DN_DM, PASSWORD)
-    except ldap.LDAPError as e:
-        log.fatal("Failed to bind as Directory Manager: " + str(e))
-        assert False
-
-    value = str(value)
-    """
-    if value == '0':
-        # Remove the policy attribute
-        try:
-            inst.modify_s("cn=config",
-                [(ldap.MOD_DELETE, attr, None)])
-        except ldap.LDAPError as e:
-            log.fatal("Failed to rmeove password policy %s: %s" %
-                      (attr, str(e)))
-            assert False
-    else:
-    """
-    # Set the policy value
-    inst.config.set(attr, value)
-
-    try:
-        inst.simple_bind_s(USER_DN, PASSWORD)
-    except ldap.LDAPError as e:
-        log.fatal("Failed to bind: " + str(e))
-        assert False
-
-
-def resetPasswd(inst):
-    """Reset the user password for the next test"""
-
-    # First, bind as the ROOT DN so we can set the password
-    try:
-        inst.simple_bind_s(DN_DM, PASSWORD)
-    except ldap.LDAPError as e:
-        log.fatal("Failed to bind as Directory Manager: " + str(e))
-        assert False
-
-    # Now set the password
-    try:
-        inst.modify_s(USER_DN,
-            [(ldap.MOD_REPLACE, 'userpassword', PASSWORD)])
-    except ldap.LDAPError as e:
-        log.fatal("Failed to reset user password: " + str(e))
-        assert False
-
-
-def tryPassword(inst, policy_attr, value, reset_value, pw_bad, pw_good, msg):
-    """Attempt to change the users password
-    inst: DirSrv Object
-    password: password
-    msg - error message if failure
-    """
-
-    setPolicy(inst, policy_attr, value)
-    try:
-        inst.modify_s(USER_DN,
-            [(ldap.MOD_REPLACE, 'userpassword', pw_bad)])
-        log.fatal('Invalid password was unexpectedly accepted (%s)' %
-                  (policy_attr))
-        assert False
-    except ldap.CONSTRAINT_VIOLATION:
-        log.info('Invalid password correctly rejected by %s:  %s' %
-                 (policy_attr, msg))
-        pass
-    except ldap.LDAPError as e:
-        log.fatal("Failed to change password: " + str(e))
-        assert False
-
-    # Change password that is allowed
-    try:
-        inst.modify_s(USER_DN,
-            [(ldap.MOD_REPLACE, 'userpassword', pw_good)])
-    except ldap.LDAPError as e:
-        log.fatal("Failed to change password: " + str(e))
-        assert False
-
-    # Reset for the next test
-    resetPasswd(inst)
-    setPolicy(inst, policy_attr, reset_value)
-
-
-def test_pwdPolicy_syntax(topology):
-    '''
-    Password policy test: Ensure that on a password change, the policy syntax
-    is enforced correctly.
-    '''
-
-    # Create a user
-    _create_user(topology.standalone)
-
-    # Set the password policy globally
-    topology.standalone.config.set('passwordCheckSyntax', 'on')
-    topology.standalone.config.set('nsslapd-pwpolicy-local', 'off')
-    topology.standalone.config.set('passwordMinCategories', '1')
-
-    #
-    # Test each syntax catagory
-    #
-
-    # Min Length
-    tryPassword(topology.standalone, 'passwordMinLength', 10, 2, 'passwd',
-                'password123', 'length too short')
-    # Min Digit
-    tryPassword(topology.standalone, 'passwordMinDigits', 2, 0, 'passwd',
-                'password123', 'does not contain minimum number of digits')
-    # Min Alphas
-    tryPassword(topology.standalone, 'passwordMinAlphas', 2, 0, 'p123456789',
-                'password123', 'does not contain minimum number of alphas')
-    # Max Repeats
-    tryPassword(topology.standalone, 'passwordMaxRepeats', 2, 0, 'passsword',
-                'pasword123', 'too many repeating characters')
-    # Min Specials
-    tryPassword(topology.standalone, 'passwordMinSpecials', 2, 0, 'passwd',
-                'password_#$',
-                'does not contain minimum number of special characters')
-    # Min Lowers
-    tryPassword(topology.standalone, 'passwordMinLowers', 2, 0, 'PASSWORD123',
-                'password123',
-                'does not contain minimum number of lowercase characters')
-    # Min Uppers
-    tryPassword(topology.standalone, 'passwordMinUppers', 2, 0, 'password',
-                'PASSWORD',
-                'does not contain minimum number of lowercase characters')
-    # Min 8-bits - "ldap" package only accepts ascii strings at the moment
-
-    log.info('pwdPolicy tests PASSED')
-
-
-if __name__ == '__main__':
-    # Run isolated
-    # -s for DEBUG mode
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main("-s %s" % CURRENT_FILE)
diff --git a/dirsrvtests/tests/suites/password/pwd_change_policytest.py b/dirsrvtests/tests/suites/password/pwd_change_policytest.py
deleted file mode 100644
index 1d48c65..0000000
--- a/dirsrvtests/tests/suites/password/pwd_change_policytest.py
+++ /dev/null
@@ -1,240 +0,0 @@
-import os
-import sys
-import time
-import subprocess
-import ldap
-import logging
-import pytest
-from lib389 import DirSrv, Entry, tools, tasks
-from lib389.tools import DirSrvTools
-from lib389._constants import *
-from lib389.properties import *
-from lib389.tasks import *
-from lib389.utils import *
-
-DEBUGGING = False
-OU_PEOPLE = 'ou=people,{}'.format(DEFAULT_SUFFIX)
-TEST_USER_NAME = 'simplepaged_test'
-TEST_USER_DN = 'uid={},{}'.format(TEST_USER_NAME, OU_PEOPLE)
-TEST_USER_PWD = 'simplepaged_test'
-PW_POLICY_CONT_USER = 'cn="cn=nsPwPolicyEntry,uid=simplepaged_test,'\
-                      'ou=people,dc=example,dc=com",'\
-                      'cn=nsPwPolicyContainer,ou=people,dc=example,dc=com'
-PW_POLICY_CONT_PEOPLE = 'cn="cn=nsPwPolicyEntry,'\
-                        'ou=people,dc=example,dc=com",'\
-                        'cn=nsPwPolicyContainer,ou=people,dc=example,dc=com'
-
-if DEBUGGING:
-    logging.getLogger(__name__).setLevel(logging.DEBUG)
-else:
-    logging.getLogger(__name__).setLevel(logging.INFO)
-
-log = logging.getLogger(__name__)
-
-
-class TopologyStandalone(object):
-    """The DS Topology Class"""
-    def __init__(self, standalone):
-        """Init"""
-        standalone.open()
-        self.standalone = standalone
-
-
-@pytest.fixture(scope="module")
-def topology(request):
-    """Create DS Deployment"""
-
-    # Creating standalone instance ...
-    if DEBUGGING:
-        standalone = DirSrv(verbose=True)
-    else:
-        standalone = DirSrv(verbose=False)
-    args_instance[SER_HOST] = HOST_STANDALONE
-    args_instance[SER_PORT] = PORT_STANDALONE
-    args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
-    args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
-    args_standalone = args_instance.copy()
-    standalone.allocate(args_standalone)
-    instance_standalone = standalone.exists()
-    if instance_standalone:
-        standalone.delete()
-    standalone.create()
-    standalone.open()
-
-    def fin():
-        """If we are debugging just stop the instances, otherwise remove
-        them
-        """
-        if DEBUGGING:
-            standalone.stop()
-        else:
-            standalone.delete()
-
-    request.addfinalizer(fin)
-
-
-    return TopologyStandalone(standalone)
-
-
-@pytest.fixture(scope="module")
-def test_user(topology, request):
-    """User for binding operation"""
-
-    log.info('Adding user {}'.format(TEST_USER_DN))
-    try:
-        topology.standalone.add_s(Entry((TEST_USER_DN, {
-                                        'objectclass': 'top person'.split(),
-                                        'objectclass': 'organizationalPerson',
-                                        'objectclass': 'inetorgperson',
-                                        'cn': TEST_USER_NAME,
-                                        'sn': TEST_USER_NAME,
-                                        'userpassword': TEST_USER_PWD,
-                                        'mail': '%s@redhat.com' % TEST_USER_NAME,
-                                        'uid': TEST_USER_NAME
-                                        })))
-    except ldap.LDAPError as e:
-        log.error('Failed to add user (%s): error (%s)' % (TEST_USER_DN,
-                                                           e.message['desc']))
-        raise e
-
-    def fin():
-        log.info('Deleting user {}'.format(TEST_USER_DN))
-        topology.standalone.delete_s(TEST_USER_DN)
-    request.addfinalizer(fin)
-
-
-@pytest.fixture(scope="module")
-def password_policy(topology, test_user):
-    """Set up password policy for subtree and user"""
-
-    log.info('Enable fine-grained policy')
-    try:
-        topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE,
-                                                  'nsslapd-pwpolicy-local',
-                                                  'on')])
-    except ldap.LDAPError as e:
-        log.error('Failed to set fine-grained policy: error {}'.format(
-            e.message['desc']))
-        raise e
-
-    log.info('Create password policy for subtree {}'.format(OU_PEOPLE))
-    try:
-        subprocess.call(['ns-newpwpolicy.pl', '-D', DN_DM, '-w', PASSWORD,
-                         '-p', str(PORT_STANDALONE), '-h', HOST_STANDALONE,
-                         '-S', OU_PEOPLE, '-Z', SERVERID_STANDALONE])
-    except subprocess.CalledProcessError as e:
-        log.error('Failed to create pw policy policy for {}: error {}'.format(
-            OU_PEOPLE, e.message['desc']))
-        raise e
-
-    log.info('Add pwdpolicysubentry attribute to {}'.format(OU_PEOPLE))
-    try:
-        topology.standalone.modify_s(OU_PEOPLE, [(ldap.MOD_REPLACE,
-                                                  'pwdpolicysubentry',
-                                                  PW_POLICY_CONT_PEOPLE)])
-    except ldap.LDAPError as e:
-        log.error('Failed to pwdpolicysubentry pw policy '\
-                  'policy for {}: error {}'.format(OU_PEOPLE,
-                                                   e.message['desc']))
-        raise e
-
-    log.info('Create password policy for subtree {}'.format(TEST_USER_DN))
-    try:
-        subprocess.call(['ns-newpwpolicy.pl', '-D', DN_DM, '-w', PASSWORD,
-                         '-p', str(PORT_STANDALONE), '-h', HOST_STANDALONE,
-                         '-U', TEST_USER_DN, '-Z', SERVERID_STANDALONE])
-    except subprocess.CalledProcessError as e:
-        log.error('Failed to create pw policy policy for {}: error {}'.format(
-            TEST_USER_DN, e.message['desc']))
-        raise e
-
-    log.info('Add pwdpolicysubentry attribute to {}'.format(TEST_USER_DN))
-    try:
-        topology.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_REPLACE,
-                                                     'pwdpolicysubentry',
-                                                     PW_POLICY_CONT_USER)])
-    except ldap.LDAPError as e:
-        log.error('Failed to pwdpolicysubentry pw policy '\
-                  'policy for {}: error {}'.format(TEST_USER_DN,
-                                                   e.message['desc']))
-        raise e
-
-
-@pytest.mark.parametrize('subtree_pwchange,user_pwchange,exception',
-                         [('off', 'on', None), ('on', 'on', None),
-                          ('on', 'off', ldap.UNWILLING_TO_PERFORM),
-                          ('off', 'off', ldap.UNWILLING_TO_PERFORM)])
-def test_change_pwd(topology, test_user, password_policy,
-                    subtree_pwchange, user_pwchange, exception):
-    """Verify that 'passwordChange' attr works as expected
-    User should have a priority over a subtree.
-
-    :Feature: Password policy
-
-    :Setup: Standalone instance, test user,
-            password policy entries for a user and a subtree
-
-    :Steps: 1. Set passwordChange on the user and the subtree
-               to various combinations
-            2. Bind as test user
-            3. Try to change password
-
-    :Assert: Subtree/User passwordChange - result
-             off/on, on/on - success
-             on/off, off/off - UNWILLING_TO_PERFORM
-    """
-
-    log.info('Set passwordChange to "{}" - {}'.format(subtree_pwchange,
-                                                      PW_POLICY_CONT_PEOPLE))
-    try:
-        topology.standalone.modify_s(PW_POLICY_CONT_PEOPLE, [(ldap.MOD_REPLACE,
-                                                             'passwordChange',
-                                                             subtree_pwchange)])
-    except ldap.LDAPError as e:
-        log.error('Failed to set passwordChange '\
-                  'policy for {}: error {}'.format(PW_POLICY_CONT_PEOPLE,
-                                                   e.message['desc']))
-        raise e
-
-
-    log.info('Set passwordChange to "{}" - {}'.format(user_pwchange,
-                                                      PW_POLICY_CONT_USER))
-    try:
-        topology.standalone.modify_s(PW_POLICY_CONT_USER, [(ldap.MOD_REPLACE,
-                                                            'passwordChange',
-                                                            user_pwchange)])
-    except ldap.LDAPError as e:
-        log.error('Failed to set passwordChange '\
-                  'policy for {}: error {}'.format(PW_POLICY_CONT_USER,
-                                                   e.message['desc']))
-        raise e
-
-    try:
-        log.info('Bind as user and modify userPassword')
-        topology.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PWD)
-        if exception:
-            with pytest.raises(exception):
-                topology.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_REPLACE,
-                                                            'userPassword',
-                                                            'new_pass')])
-        else:
-            topology.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_REPLACE,
-                                                        'userPassword',
-                                                        'new_pass')])
-    except ldap.LDAPError as e:
-        log.error('Failed to change userpassword for {}: error {}'.format(
-            TEST_USER_DN, e.message['info']))
-        raise e
-    finally:
-        log.info('Bind as DM')
-        topology.standalone.simple_bind_s(DN_DM, PASSWORD)
-        topology.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_REPLACE,
-                                                     'userPassword',
-                                                     TEST_USER_PWD)])
-
-
-if __name__ == '__main__':
-    # Run isolated
-    # -s for DEBUG mode
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main("-s %s" % CURRENT_FILE)
-- 
2.7.4

