Ejemplo n.º 1
0
def test_local_TPR_supercedes_global_TPR(topo, _add_user,
                                         set_global_TPR_policies):
    """ One Time password with expiration
    
    :id: beb2dac4-e116-11eb-a85e-98fa9ba19b65
    :customerscenario: True
    :setup: Standalone
    :steps:
    1. Create DS Instance
    2. Create user with appropriate password
    3. Configure the Global Password policies with passwordTPRMaxUse 5     
    4. Configure different local password policy for passwordTPRMaxUse 3
    5. Trigger TPR by resetting the user password above
    6. Attempt an ldap search with an incorrect bind password for user above
    7. Repeat as many times as set by attribute passwordTPRMaxUse
    8. Should lock the account after value is set in the local passwordTPRMaxUse is reached
    9. Try to search with the correct password account will be locked.

    :expected results:
    1. Success
    2. Success
    3. Fail(ldap.INSUFFICIENT_ACCESS)
    4. Success
    5. Success
    6. Success
    7. Success
    8. Success
    9. Success 

"""

    user1 = UserAccount(topo.standalone,
                        f'uid=jdoe1,ou=People,{DEFAULT_SUFFIX}')
    user2 = UserAccount(topo.standalone,
                        f'uid=jdoe2,ou=People,{DEFAULT_SUFFIX}')
    log.info('Setting local password Temporary password reset policies')

    log.info('Setting Global TPR policy attributes')
    Config(topo.standalone).replace('passwordMustChange', 'on')
    Config(topo.standalone).replace('passwordTPRMaxUse', '5')
    Config(topo.standalone).replace('passwordTPRDelayExpireAt', '600')
    Config(topo.standalone).replace('passwordTPRDelayValidFrom', '6')
    log.info('Resetting {} password to trigger TPR policy'.format(user1))
    user1.replace('userpassword', 'not_allowed_change')
    count = 0

    while count < 4:
        if count == 4:
            with pytest.raises(ldap.CONSTRAINT_VIOLATION):
                user2.bind('badbadbad')
        else:
            with pytest.raises(ldap.INVALID_CREDENTIALS):
                count += 1
                user2.bind('badbadbad')
Ejemplo n.º 2
0
def test_password_repl_error(topo_m2, test_entry):
    """Check that error about userpassword replication is properly logged

    :id: 714130ff-e4f0-4633-9def-c1f4b24abfef
    :setup: Four masters replication setup, a test entry
    :steps:
        1. Change userpassword on the first master
        2. Restart the servers to flush the logs
        3. Check the error log for an replication error
    :expectedresults:
        1. Password should be successfully changed
        2. Server should be successfully restarted
        3. There should be no replication errors in the error log
    """

    m1 = topo_m2.ms["master1"]
    m2 = topo_m2.ms["master2"]
    TEST_ENTRY_NEW_PASS = '******'

    log.info('Clean the error log')
    m2.deleteErrorLogs()

    log.info('Set replication loglevel')
    m2.config.loglevel((ErrorLog.REPLICA, ))

    log.info('Modifying entry {} - change userpassword on master 1'.format(
        test_entry.dn))

    test_entry.set('userpassword', TEST_ENTRY_NEW_PASS)

    repl = ReplicationManager(DEFAULT_SUFFIX)
    repl.wait_for_replication(m1, m2)

    log.info('Restart the servers to flush the logs')
    for num in range(1, 3):
        topo_m2.ms["master{}".format(num)].restart()

    try:
        log.info('Check that password works on master 2')
        test_entry_m2 = UserAccount(m2, test_entry.dn)
        test_entry_m2.bind(TEST_ENTRY_NEW_PASS)

        log.info('Check the error log for the error with {}'.format(
            test_entry.dn))
        assert not m2.ds_error_log.match(
            '.*can.t add a change for {}.*'.format(test_entry.dn))
    finally:
        log.info('Set the default loglevel')
        m2.config.loglevel((ErrorLog.DEFAULT, ))
Ejemplo n.º 3
0
def test_once_TPR_reset_old_passwd_invalid(topo, _add_user,
                                           set_global_TPR_policies):
    """ Verify that once a password has been reset it cannot be reused
    
    :id: f3ea4f00-e89c-11eb-b81d-98fa9ba19b65
    :customerscenario: True
    :setup: Standalone
    :steps:
    1. Create DS Instance
    2. Create user jdoe1 with appropriate password
    3. Configure the Global Password policies enable passwordMustChange
    4. Trigger TPR by resetting the user jdoe1 password above
    5. Attempt to login with the old password
    6. Login as jdoe1 with the correct password and update the new password


    :expected results:
    1. Success
    2. Success
    3. Success
    4. Success
    5. Fail(ldap.CONSTRAINT_VIOLATION)
    6. Success

"""
    new_password = '******'
    log.info('Creating user jdoe1 with appropriate password')
    user1 = UserAccount(topo.standalone,
                        f'uid=jdoe1,ou=People,{DEFAULT_SUFFIX}')
    user1.replace('userpassword', new_password)
    log.info(
        'Making sure the Global Policy passwordTPRDelayValidFrom is short')
    config = Config(topo.standalone)
    config.replace_many(
        ('passwordLockout', 'off'),
        ('passwordMaxFailure', '3'),
        ('passwordLegacyPolicy', 'off'),
        ('passwordTPRDelayValidFrom', '-1'),
        ('nsslapd-pwpolicy-local', 'on'),
    )

    log.info(' Attempting to bind as {} with the old password {}'.format(
        user1, USER1_PASS))
    time.sleep(.5)
    with pytest.raises(ldap.INVALID_CREDENTIALS):
        user1.bind(USER1_PASS)
    log.info('Login as jdoe1 with the correct reset password')
    time.sleep(.5)
    user1.rebind(new_password)
Ejemplo n.º 4
0
def test_reset_pwd_before_passwordTPRDelayValidFrom(topo, _add_user,
                                                    set_global_TPR_policies):
    """ Verify that user cannot reset pwd 
        before passwordTPRDelayValidFrom value elapses 
    
    :id: 22987082-e8ae-11eb-a992-98fa9ba19b65
    :customerscenario: True
    :setup: Standalone
    :steps:
    1. Create DS Instance
    2. Create user jdoe2 with appropriate password
    3. Configure the Global Password policies disable passwordTPRDelayValidFrom to -1
    4. Trigger TPR by resetting the user jdoe1 password above
    5. Attempt to bind and rebind immediately 
    6. Set passwordTPRDelayValidFrom - 5secs elapses and bind rebind before 5 secs elapses
    6. Wait for the passwordTPRDelayValidFrom value to elapse and try to reset passwd

    :expected results:
    1. Success
    2. Success
    3. Success
    4. Success
    5. Success
    6. Fail(ldap.LDAP_CONSTRAINT_VIOLATION)
    7. Success


"""
    user2 = UserAccount(topo.standalone,
                        f'uid=jdoe2,ou=People,{DEFAULT_SUFFIX}')
    log.info('Creating user {} with appropriate password'.format(user2))
    log.info('Disabling TPR policy passwordTPRDelayValidFrom')
    topo.standalone.config.replace_many(('passwordMustChange', 'on'),
                                        ('passwordTPRDelayValidFrom', '10'))
    log.info('Triggering TPR and binding immediately after')
    user2.replace('userpassword', 'new_password')
    time.sleep(.5)
    with pytest.raises(ldap.CONSTRAINT_VIOLATION):
        user2.bind('new_password')
    time.sleep(.5)
    topo.standalone.config.replace_many(('passwordMustChange', 'on'),
                                        ('passwordTPRDelayValidFrom', '-1'))
    log.info(
        'Triggering TPR and binding immediately after with passwordTPRDelayValidFrom set to -1'
    )
    user2.replace('userpassword', 'new_password1')
    time.sleep(.5)
    user2.rebind('new_password1')
Ejemplo n.º 5
0
def userpw_reset(topology_st, suffix, subtree, userid, nousrs, bindusr, bindpw,
                 newpasw):
    """Reset user password"""

    while (nousrs > 0):
        usrrdn = '{}{}'.format(userid, nousrs)
        userdn = 'uid={},{},{}'.format(usrrdn, subtree, suffix)
        user = UserAccount(topology_st.standalone, dn=userdn)
        log.info('Reset user password for user-{}'.format(userdn))
        if (bindusr == "DirMgr"):
            try:
                user.replace('userPassword', newpasw)
            except ldap.LDAPError as e:
                log.error(
                    'Unable to reset userPassword for user-{}'.format(userdn))
                raise e
        elif (bindusr == "RegUsr"):
            user_conn = user.bind(bindpw)
            try:
                user_conn.replace('userPassword', newpasw)
            except ldap.LDAPError as e:
                log.error(
                    'Unable to reset userPassword for user-{}'.format(userdn))
                raise e
        nousrs = nousrs - 1
        time.sleep(1)
Ejemplo n.º 6
0
def test_only_user_can_reset_TPR(topo, _add_user, set_global_TPR_policies):
    """ One Time password with expiration
    
    :id: 07838d5e-db43-11eb-85e5-fa163ead4114
    :customerscenario: True
    :setup: Standalone
    :steps:
    1. Create DS Instance
    2. Create 2 users with appropriate password
    3. Create Global TPR policy enable passwordMustChange: on
    3. Trigger Temporary password and reset user1 password
    3. Bind as user#2 and attempt to Reset user#1 password as user#2
    4. Verify admin can reset users#1,2 passwords

    :expected results:
    1. Success
    2. Success
    3. Fail(ldap.INSUFFICIENT_ACCESS)
    4. Success 

"""
    log.info('Creating 2 users with appropriate password')
    user1 = UserAccount(topo.standalone,
                        f'uid=jdoe1,ou=People,{DEFAULT_SUFFIX}')
    user2 = UserAccount(topo.standalone,
                        f'uid=jdoe2,ou=People,{DEFAULT_SUFFIX}')
    log.info('Setting Local policies...')
    conn_user2 = user2.bind(USER2_PASS)

    UserAccount(conn_user2, user2.dn).replace('userpassword', 'reset_pass')
    log.info('Attempting to change user#1  password as user#2 ')

    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        UserAccount(conn_user2, user1.dn).replace('userpassword', 'reset_pass')
Ejemplo n.º 7
0
def pwacc_lock(topology_st, suffix, subtree, userid, nousrs):
    """Lockout user account by attempting invalid password binds"""

    log.info('Lockout user account by attempting invalid password binds')
    while (nousrs > 0):
        usrrdn = '{}{}'.format(userid, nousrs)
        userdn = 'uid={},{},{}'.format(usrrdn, subtree, suffix)
        user = UserAccount(topology_st.standalone,  dn=userdn)
        for i in range(3):
            with pytest.raises(ldap.INVALID_CREDENTIALS):
                user.bind(INVL_PASW)
                log.error('No invalid credentials error for User {}'.format(userdn))
        with pytest.raises(ldap.CONSTRAINT_VIOLATION):
            user.bind(USER_PASW)
            log.error('User {} is not locked, expected error 19'.format(userdn))
        nousrs = nousrs - 1
        time.sleep(1)
Ejemplo n.º 8
0
def change_password_of_user(topo, user_password_new_pass_list, pass_to_change):
    """
    Will change password with self binding.
    """
    for user, password, new_pass in user_password_new_pass_list:
        real_user = UserAccount(topo.standalone, f'{user},{DEFAULT_SUFFIX}')
        conn = real_user.bind(password)
        UserAccount(conn, pass_to_change).replace('userpassword', new_pass)
Ejemplo n.º 9
0
def test_password_repl_error(topo_m4, create_entry):
    """Check that error about userpassword replication is properly logged

    :id: d4f12dc0-cd2c-4b92-9b8d-d764a60f0698
    :feature: Multi master replication
    :setup: Four masters replication setup, a test entry
    :steps: 1. Change userpassword on master 1
            2. Restart the servers to flush the logs
            3. Check the error log for an replication error
    :expectedresults: We don't have a replication error in the error log
    """

    m1 = topo_m4.ms["master1"]
    m2 = topo_m4.ms["master2"]
    TEST_ENTRY_NEW_PASS = '******'.format(TEST_ENTRY_NAME)

    log.info('Clean the error log')
    m2.deleteErrorLogs()

    log.info('Set replication loglevel')
    m2.config.loglevel((ErrorLog.REPLICA, ))

    log.info('Modifying entry {} - change userpassword on master 2'.format(
        TEST_ENTRY_DN))
    test_user_m1 = UserAccount(topo_m4.ms["master1"], TEST_ENTRY_DN)
    test_user_m2 = UserAccount(topo_m4.ms["master2"], TEST_ENTRY_DN)
    test_user_m3 = UserAccount(topo_m4.ms["master3"], TEST_ENTRY_DN)
    test_user_m4 = UserAccount(topo_m4.ms["master4"], TEST_ENTRY_DN)

    test_user_m1.set('userpassword', TEST_ENTRY_NEW_PASS)

    log.info('Restart the servers to flush the logs')
    for num in range(1, 5):
        topo_m4.ms["master{}".format(num)].restart(timeout=10)

    m1_conn = test_user_m1.bind(TEST_ENTRY_NEW_PASS)
    m2_conn = test_user_m2.bind(TEST_ENTRY_NEW_PASS)
    m3_conn = test_user_m3.bind(TEST_ENTRY_NEW_PASS)
    m4_conn = test_user_m4.bind(TEST_ENTRY_NEW_PASS)

    log.info('Check the error log for the error with {}'.format(TEST_ENTRY_DN))
    assert not m2.ds_error_log.match(
        '.*can.t add a change for uid={}.*'.format(TEST_ENTRY_NAME))
Ejemplo n.º 10
0
def account_status(topology_st, suffix, subtree, userid, nousrs, ulimit,
                   tochck):
    """Check account status for the given suffix, subtree, userid and nousrs"""

    while (nousrs > ulimit):
        usrrdn = '{}{}'.format(userid, nousrs)
        userdn = 'uid={},{},{}'.format(usrrdn, subtree, suffix)
        user = UserAccount(topology_st.standalone, dn=userdn)
        if (tochck == "Enabled"):
            try:
                user.bind(USER_PASW)
            except ldap.LDAPError as e:
                log.error('User {} failed to login, expected 0'.format(userdn))
                raise e
        elif (tochck == "Expired"):
            with pytest.raises(ldap.INVALID_CREDENTIALS):
                user.bind(USER_PASW)
                log.error(
                    'User {} password not expired , expected error 49'.format(
                        userdn))
        elif (tochck == "Disabled"):
            with pytest.raises(ldap.CONSTRAINT_VIOLATION):
                user.bind(USER_PASW)
                log.error(
                    'User {} is not inactivated, expected error 19'.format(
                        userdn))
        nousrs = nousrs - 1
        time.sleep(1)
Ejemplo n.º 11
0
def test_local_password_policy(topo, _add_user):
    """Regression test for bz1044164 part 1.

    :id: d6f4a7fa-473b-11ea-8766-8c16451d917b
    :setup: Standalone
    :steps:
        1. Add a User as Password Admin
        2. Create a password admin user entry
        3. Add an aci to allow this user all rights
        4. Configure password admin
        5. Create local password policy and enable passwordmustchange
        6. Add another generic user but do not include the password (userpassword)
        7. Use admin user to perform a password update on generic user
        8. We don't need this ACI anymore. Delete it
    :expected results:
        1. Success
        2. Success
        3. Success
        4. Success
        5. Success
        6. Success
        7. Success
        8. Success
    """
    # Add a User as Password Admin
    # Create a password admin user entry
    user = _create_user(topo, 'pwadm_admin_1', None)
    user.replace('userpassword', 'Secret123')
    domian = Domain(topo.standalone, DEFAULT_SUFFIX)
    # Add an aci to allow this user all rights
    domian.set(
        "aci", f'(targetattr ="userpassword")'
        f'(version 3.0;acl "Allow password admin to write user '
        f'passwords";allow (write)(userdn = "ldap:///{user.dn}");)')
    # Configure password admin
    # Create local password policy and enable passwordmustchange
    Config(topo.standalone).replace_many(('passwordAdminDN', user.dn),
                                         ('passwordMustChange', 'off'),
                                         ('nsslapd-pwpolicy-local', 'on'))
    # Add another generic user but do not include the password (userpassword)
    # Use admin user to perform a password update on generic user
    real_user = UserAccount(topo.standalone,
                            f'uid=pwadm_admin_1,{DEFAULT_SUFFIX}')
    conn = real_user.bind('Secret123')
    UserAccount(conn, f'uid=pwadm_user_1,{DEFAULT_SUFFIX}').replace(
        'userpassword', 'hello')
    # We don't need this ACI anymore. Delete it
    domian.remove(
        "aci", f'(targetattr ="userpassword")'
        f'(version 3.0;acl "Allow password admin to write user '
        f'passwords";allow (write)(userdn = "ldap:///{user.dn}");)')
Ejemplo n.º 12
0
def test_password_gracelimit_section(topo):
    """Password grace limit section.

    :id: d6f4a7fa-473b-11ea-8766-8c16451d917c
    :setup: Standalone
    :steps:
        1. Resets the default password policy
        2. Turning on password expiration, passwordMaxAge: 30 and passwordGraceLimit: 7
        3. Check users have 7 grace login attempts after their password expires
        4. Reset the user passwords to start the clock
        5. The the 8th should fail
        6. Now try resetting the password before the grace login attempts run out
        7. Bind 6 times, and on the 7th change the password
        8. Setting passwordMaxAge: 1 and passwordGraceLimit: 7
        9. Modify the users passwords to start the clock of zero
        10. First 7 good attempts, 8th should fail
        11. Setting the passwordMaxAge to 3 seconds once more and the passwordGraceLimit to 0
        12. Modify the users passwords to start the clock
        13. Users should be blocked automatically after 3 second
    :expected results:
        1. Success
        2. Success
        3. Success
        4. Success
        5. Success
        6. Success
        7. Success
        8. Success
        9. Success
        10. Success
        11. Success
        12. Success
        13. Success
    """
    config = Config(topo.standalone)
    # Resets the default password policy
    config.replace_many(('passwordmincategories', '1'),
                        ('passwordStorageScheme', 'CLEAR'))
    user = UserAccounts(topo.standalone, DEFAULT_SUFFIX,
                        rdn=None).create_test_user()
    # Turning on password expiration, passwordMaxAge: 30 and passwordGraceLimit: 7
    config.replace_many(('passwordMaxAge', '3'), ('passwordGraceLimit', '7'),
                        ('passwordexp', 'on'), ('passwordwarning', '30'))
    # Reset the user passwords to start the clock
    # Check users have 7 grace login attempts after their password expires
    user.replace('userpassword', '00fr3d1')
    for _ in range(3):
        time.sleep(1)
    user_account = UserAccount(topo.standalone, user.dn)
    for _ in range(7):
        conn = user_account.bind('00fr3d1')
    # The the 8th should fail
    with pytest.raises(ldap.INVALID_CREDENTIALS):
        conn = user_account.bind('00fr3d1')
    # Now try resetting the password before the grace login attempts run out
    user.replace('userpassword', '00fr3d2')
    for _ in range(3):
        time.sleep(1)
    user_account = UserAccount(topo.standalone, user.dn)
    # Bind 6 times, and on the 7th change the password
    for _ in range(6):
        conn = user_account.bind('00fr3d2')
    user.replace('userpassword', '00fr3d1')
    for _ in range(3):
        time.sleep(1)
    for _ in range(7):
        conn = user_account.bind('00fr3d1')
    with pytest.raises(ldap.INVALID_CREDENTIALS):
        conn = user_account.bind('00fr3d1')
    # Setting passwordMaxAge: 1 and passwordGraceLimit: 7
    config.replace_many(('passwordMaxAge', '1'), ('passwordwarning', '1'))
    # Modify the users passwords to start the clock of zero
    user.replace('userpassword', '00fr3d2')
    time.sleep(1)
    # First 7 good attempts, 8th should fail
    user_account = UserAccount(topo.standalone, user.dn)
    for _ in range(7):
        conn = user_account.bind('00fr3d2')
    with pytest.raises(ldap.INVALID_CREDENTIALS):
        conn = user_account.bind('00fr3d2')
    # Setting the passwordMaxAge to 3 seconds once more and the passwordGraceLimit to 0
    config.replace_many(('passwordMaxAge', '3'), ('passwordGraceLimit', '0'))
    # Modify the users passwords to start the clock
    # Users should be blocked automatically after 3 second
    user.replace('userpassword', '00fr3d1')
    for _ in range(3):
        time.sleep(1)
    with pytest.raises(ldap.INVALID_CREDENTIALS):
        conn = user_account.bind('00fr3d1')
Ejemplo n.º 13
0
def test_admin_group_to_modify_password(topo, _add_user):
    """Regression test for bz1044164 part 2.

    :id: 12e09446-52da-11ea-aa11-8c16451d917b
    :setup: Standalone
    :steps:
        1. Create unique members of admin group
        2. Create admin group with unique members
        3. Edit ACIs for admin group
        4. Add group as password admin
        5. Test password admin group to modify password of another admin user
        6. Use admin user to perform a password update on Directory Manager user
        7. Test password admin group for local password policy
        8. Add top level container
        9. Add user
        10. Create local policy configuration entry
        11. Adding admin group for local policy
        12. Change user's password by admin user. Break the local policy rule
        13. Test password admin group for global password policy
        14. Add top level container
        15. Change user's password by admin user. Break the global policy rule
        16. Add new user in password admin group
        17. Modify ordinary user's password
        18. Modify user DN using modrdn of a user in password admin group
        19. Test assigning invalid value to password admin attribute
        20. Try to add more than one Password Admin attribute to config file
        21. Use admin group setup from previous testcases, but delete ACI from that
        22. Try to change user's password by admin user
        23. Restore ACI
        24. Edit ACIs for admin group
        25. Delete a user from password admin group
        26. Change users password by ex-admin user
        27. Remove group from password admin configuration
        28. Change admins
        29. Change user's password by ex-admin user
        30. Change admin user's password by ex-admin user
    :expected results:
        1. Success
        2. Success
        3. Success
        4. Success
        5. Success
        6. Fail(ldap.INSUFFICIENT_ACCESS)
        7. Success
        8. Success
        9. Success
        10. Success
        11. Success
        12. Success
        13. Success
        14. Success
        15. Success
        16. Success
        17. Success
        18. Success
        19. Fail
        20. Fail
        21. Success
        22. Success
        23. Success
        24. Success
        25. Success
        26. Success
        27. Success
        28. Success
        29. Fail
        30. Fail
    """
    # create unique members of admin group
    admin_grp = UniqueGroups(topo.standalone, DEFAULT_SUFFIX).create(properties={
        'cn': 'pwadm_group_adm',
        'description': 'pwadm_group_adm',
        'uniqueMember': [f'uid=pwadm_admin_2,ou=People,{DEFAULT_SUFFIX}',
                         f'uid=pwadm_admin_3,ou=People,{DEFAULT_SUFFIX}']
    })
    # Edit ACIs for admin group
    Domain(topo.standalone,
           f"ou=People,{DEFAULT_SUFFIX}").set('aci', f'(targetattr ="userpassword")'
                                                     f'(version 3.0;acl "Allow passwords admin to write user '
                                                     f'passwords";allow (write)(groupdn = "ldap:///{admin_grp.dn}");)')
    # Add group as password admin
    Config(topo.standalone).replace('passwordAdminDN', admin_grp.dn)
    # Test password admin group to modify password of another admin user
    change_password_of_user(topo, [
        ('uid=pwadm_admin_2,ou=People', 'Secret123', 'hello')],
                            f'uid=pwadm_admin_3,ou=people,{DEFAULT_SUFFIX}')
    # Use admin user to perform a password update on Directory Manager user
    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        change_password_of_user(topo, [('uid=pwadm_admin_2,ou=People', 'Secret123', 'hello')],
                                f'{DN_DM},{DEFAULT_SUFFIX}')
    # Add top level container
    ou = OrganizationalUnits(topo.standalone, DEFAULT_SUFFIX).create(properties={'ou': 'pwadm_locpol'})
    # Change user's password by admin user. Break the global policy rule
    # Add new user in password admin group
    user = _create_user(topo, 'pwadm_locpol_user', 'ou=pwadm_locpol')
    user.replace('userpassword', 'Secret123')
    # Create local policy configuration entry
    _create_pwp(topo, ou.dn)
    # Set parameter for pwp
    for para_meter, op_op in [
        ('passwordLockout', 'on'),
        ('passwordMaxFailure', '4'),
        ('passwordLockoutDuration', '10'),
        ('passwordResetFailureCount', '100'),
        ('passwordMinLength', '8'),
        ('passwordAdminDN', f'cn=pwadm_group_adm,ou=Groups,{DEFAULT_SUFFIX}')]:
        change_pwp_parameter(topo, 'ou=pwadm_locpol', para_meter, op_op)
    # Set ACI
    OrganizationalUnit(topo.standalone,
                       ou.dn).set('aci',
                                  f'(targetattr ="userpassword")'
                                  f'(version 3.0;acl "Allow passwords admin to write user '
                                  f'passwords";allow (write)'
                                  f'(groupdn = "ldap:///cn=pwadm_group_adm,ou=Groups,{DEFAULT_SUFFIX}");)')
    # Change password with new admin
    change_password_of_user(topo, [('uid=pwadm_admin_2,ou=People', 'Secret123', 'Sec')], user.dn)
    # Set global parameter
    Config(topo.standalone).replace_many(
        ('passwordTrackUpdateTime', 'on'),
        ('passwordGraceLimit', '4'),
        ('passwordHistory', 'on'),
        ('passwordInHistory', '4'))
    # Test password admin group for global password policy
    change_password_of_user(topo, [('uid=pwadm_admin_2,ou=People', 'Secret123', 'Sec')],
                            f'uid=pwadm_user_2,ou=People,{DEFAULT_SUFFIX}')
    # Adding admin group for local policy
    grp = UniqueGroup(topo.standalone, f'cn=pwadm_group_adm,ou=Groups,{DEFAULT_SUFFIX}')
    grp.add('uniqueMember', f'uid=pwadm_admin_4,ou=People,{DEFAULT_SUFFIX}')
    # Modify ordinary user's password
    change_password_of_user(topo, [('uid=pwadm_admin_4,ou=People', 'Secret123', 'Secret')],
                            f'uid=pwadm_user_2,ou=People,{DEFAULT_SUFFIX}')
    # Modify user DN using modrdn of a user in password admin group
    UserAccount(topo.standalone, f'uid=pwadm_admin_4,ou=People,{DEFAULT_SUFFIX}').rename('uid=pwadm_admin_4_new')
    # Remove admin
    grp.remove('uniqueMember', f'uid=pwadm_admin_4,ou=People,{DEFAULT_SUFFIX}')
    # Add Admin
    grp.add('uniqueMember', f'uid=pwadm_admin_4_new,ou=People,{DEFAULT_SUFFIX}')
    # Test the group pwp again
    with pytest.raises(ldap.INVALID_CREDENTIALS):
        change_password_of_user(topo, [(f'uid=pwadm_admin_4,ou=People', 'Secret123', 'Secret1')],
                                f'uid=pwadm_user_2,ou=People,{DEFAULT_SUFFIX}')
    change_password_of_user(topo, [(f'uid=pwadm_admin_4_new,ou=People', 'Secret123', 'Secret1')],
                            f'uid=pwadm_user_2,ou=People,{DEFAULT_SUFFIX}')
    with pytest.raises(ldap.INVALID_SYNTAX):
        Config(topo.standalone).replace('passwordAdminDN', "Invalid")
    # Test assigning invalid value to password admin attribute
    # Try to add more than one Password Admin attribute to config file
    with pytest.raises(ldap.OBJECT_CLASS_VIOLATION):
        Config(topo.standalone).replace('passwordAdminDN',
                                        [f'uid=pwadm_admin_2,ou=people,{DEFAULT_SUFFIX}',
                                         f'uid=pwadm_admin_3,ou=people,{DEFAULT_SUFFIX}'])
    # Use admin group setup from previous, but delete ACI from that
    people = Domain(topo.standalone, f"ou=People,{DEFAULT_SUFFIX}")
    people.remove('aci',
                  f'(targetattr ="userpassword")(version 3.0;acl '
                  f'"Allow passwords admin to write user '
                  f'passwords";allow (write)'
                  f'(groupdn = "ldap:///cn=pwadm_group_adm,ou=Groups,{DEFAULT_SUFFIX}");)')
    # Try to change user's password by admin user
    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        change_password_of_user(topo, [('uid=pwadm_admin_2,ou=People', 'Secret123', 'Sec')],
                                f'uid=pwadm_user_2,ou=People,{DEFAULT_SUFFIX}')
    # Restore ACI
    people.set('aci',
               f'(targetattr ="userpassword")(version 3.0;acl '
               f'"Allow passwords admin to write user '
               f'passwords";allow (write)(groupdn = "ldap:///cn=pwadm_group_adm,ou=Groups,{DEFAULT_SUFFIX}");)')
    # Edit ACIs for admin group
    people.add('aci',
               f'(targetattr ="userpassword")(version 3.0;acl '
               f'"Allow passwords admin to add user '
               f'passwords";allow (add)(groupdn = "ldap:///cn=pwadm_group_adm,ou=Groups,{DEFAULT_SUFFIX}");)')
    UserAccount(topo.standalone, f'uid=pwadm_user_2,ou=people,{DEFAULT_SUFFIX}').replace('userpassword', 'Secret')
    real_user = UserAccount(topo.standalone, f'uid=pwadm_user_2,ou=people,{DEFAULT_SUFFIX}')
    conn = real_user.bind('Secret')
    # Test new aci
    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        UserAccounts(conn, DEFAULT_SUFFIX, rdn='ou=People').create(properties={
            'uid': 'ok',
            'cn': 'ok',
            'sn': 'ok',
            'uidNumber': '1000',
            'gidNumber': 'ok',
            'homeDirectory': '/home/ok'})
    UserAccounts(topo.standalone, DEFAULT_SUFFIX).list()
    real_user = UserAccount(topo.standalone, f'uid=pwadm_admin_2,ou=People,{DEFAULT_SUFFIX}')
    conn = real_user.bind('Secret123')
    # Test new aci which has new rights
    for uid, cn, password in [
        ('pwadm_user_3', 'pwadm_user_1', 'U2VjcmV0MTIzCg=='),
        ('pwadm_user_4', 'pwadm_user_2', 'U2VjcmV0MTIzCg==')]:
        UserAccounts(conn, DEFAULT_SUFFIX, rdn='ou=People').create(properties={
            'uid': uid,
            'cn': cn,
            'sn': cn,
            'uidNumber': '1000',
            'gidNumber': '1001',
            'homeDirectory': f'/home/{uid}',
            'userpassword': password})
    # Remove ACI
    Domain(topo.standalone,
           f"ou=People,{DEFAULT_SUFFIX}").remove('aci',
                                                 f'(targetattr ="userpassword")'
                                                 f'(version 3.0;acl '
                                                 f'"Allow passwords admin to add user '
                                                 f'passwords";allow '
                                                 f'(add)(groupdn = '
                                                 f'"ldap:///cn=pwadm_group_adm,ou=Groups,{DEFAULT_SUFFIX}");)')
    # Delete a user from password admin group
    grp = UniqueGroup(topo.standalone, f'cn=pwadm_group_adm,ou=Groups,{DEFAULT_SUFFIX}')
    grp.remove('uniqueMember', f'uid=pwadm_admin_2,ou=People,{DEFAULT_SUFFIX}')
    # Change users password by ex-admin user
    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        change_password_of_user(topo, [('uid=pwadm_admin_2,ou=People', 'Secret123', 'Secret')],
                                f'uid=pwadm_user_2,ou=People,{DEFAULT_SUFFIX}')
    # Set aci for only user
    people = Domain(topo.standalone, f"ou=People,{DEFAULT_SUFFIX}")
    people.remove('aci',
                  f'(targetattr ="userpassword")(version 3.0;acl '
                  f'"Allow passwords admin to write user '
                  f'passwords";allow (write)(groupdn = "ldap:///cn=pwadm_group_adm,ou=Groups,{DEFAULT_SUFFIX}");)')
    people.set('aci',
               f'(targetattr ="userpassword")(version 3.0;acl "Allow passwords admin '
               f'to write user passwords";allow (write)(groupdn = "ldap:///uid=pwadm_admin_1,{DEFAULT_SUFFIX}");)')
    # Remove group from password admin configuration
    Config(topo.standalone).replace('passwordAdminDN', f"uid=pwadm_admin_1,{DEFAULT_SUFFIX}")
    # Change user's password by ex-admin user
    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        change_password_of_user(topo, [('uid=pwadm_admin_2,ou=People', 'Secret123', 'hellso')],
                                f'uid=pwadm_user_2,ou=People,{DEFAULT_SUFFIX}')
    with pytest.raises(ldap.INSUFFICIENT_ACCESS):
        change_password_of_user(topo, [('uid=pwadm_admin_2,ou=People', 'Secret123', 'hellso')],
                                f'uid=pwadm_admin_1,{DEFAULT_SUFFIX}')