| |
@@ -7,10 +7,11 @@
|
| |
# --- END COPYRIGHT BLOCK ---
|
| |
#
|
| |
import pytest
|
| |
+ import time
|
| |
from lib389.tasks import *
|
| |
from lib389.utils import *
|
| |
from lib389.topologies import topology_st
|
| |
-
|
| |
+ from lib389.idm.user import UserAccounts, TEST_USER_PROPERTIES
|
| |
from lib389._constants import DN_DM, DEFAULT_SUFFIX, PASSWORD
|
| |
|
| |
logging.getLogger(__name__).setLevel(logging.DEBUG)
|
| |
@@ -35,6 +36,10 @@
|
| |
6. Attempt to change the password to previous passwords
|
| |
7. Reset password by Directory Manager (admin reset)
|
| |
8. Try and change the password to the previous password before the reset
|
| |
+ 9. Test passwordInHistory set to "0" rejects only the current password
|
| |
+ 10. Test passwordInHistory set to "2" rejects previous passwords
|
| |
+
|
| |
+
|
| |
:expectedresults:
|
| |
1. Password history policy should be configured successfully
|
| |
2. User should be added successfully
|
| |
@@ -47,10 +52,10 @@
|
| |
7. Password should be successfully reset
|
| |
8. Password change should be correctly rejected
|
| |
with Constrant Violation error
|
| |
+ 9. Success
|
| |
+ 10. Success
|
| |
"""
|
| |
|
| |
- USER_DN = 'uid=testuser,' + DEFAULT_SUFFIX
|
| |
-
|
| |
#
|
| |
# Configure password history policy and add a test user
|
| |
#
|
| |
@@ -58,37 +63,25 @@
|
| |
topology_st.standalone.config.replace_many(('passwordHistory', 'on'),
|
| |
('passwordInHistory', '3'),
|
| |
('passwordChange', 'on'),
|
| |
- ('passwordStorageScheme', 'CLEAR'))
|
| |
+ ('passwordStorageScheme', 'CLEAR'),
|
| |
+ ('nsslapd-auditlog-logging-enabled', 'on'))
|
| |
log.info('Configured password policy.')
|
| |
except ldap.LDAPError as e:
|
| |
log.fatal('Failed to configure password policy: ' + str(e))
|
| |
assert False
|
| |
time.sleep(1)
|
| |
|
| |
- try:
|
| |
- topology_st.standalone.add_s(Entry((USER_DN, {
|
| |
- 'objectclass': ['top', 'extensibleObject'],
|
| |
- 'sn': 'user',
|
| |
- 'cn': 'test user',
|
| |
- 'uid': 'testuser',
|
| |
- 'userpassword': 'password'})))
|
| |
- except ldap.LDAPError as e:
|
| |
- log.fatal('Failed to add test user' + USER_DN + ': error ' + str(e))
|
| |
- assert False
|
| |
+ users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX)
|
| |
+ user = users.create(properties=TEST_USER_PROPERTIES)
|
| |
+ user.set('userpassword', 'password')
|
| |
+ user.rebind('password')
|
| |
|
| |
#
|
| |
# Test that password history is enforced.
|
| |
#
|
| |
- try:
|
| |
- topology_st.standalone.simple_bind_s(USER_DN, 'password')
|
| |
- except ldap.LDAPError as e:
|
| |
- log.fatal('Failed to bind as user: ' + str(e))
|
| |
- assert False
|
| |
-
|
| |
# Attempt to change password to the same password
|
| |
try:
|
| |
- topology_st.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE,
|
| |
- 'userpassword', b'password')])
|
| |
+ user.set('userpassword', 'password')
|
| |
log.info('Incorrectly able to to set password to existing password.')
|
| |
assert False
|
| |
except ldap.CONSTRAINT_VIOLATION:
|
| |
@@ -100,110 +93,109 @@
|
| |
#
|
| |
# Keep changing password until we fill the password history (3)
|
| |
#
|
| |
+ user.set('userpassword', 'password1')
|
| |
+ user.rebind('password1')
|
| |
+ user.set('userpassword', 'password2')
|
| |
+ user.rebind('password2')
|
| |
+ user.set('userpassword', 'password3')
|
| |
+ user.rebind('password3')
|
| |
+ user.set('userpassword', 'password4')
|
| |
+ user.rebind('password4')
|
| |
+ time.sleep(1)
|
| |
|
| |
- # password1
|
| |
- try:
|
| |
- topology_st.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE,
|
| |
- 'userpassword', b'password1')])
|
| |
- except ldap.LDAPError as e:
|
| |
- log.fatal('Failed to change password: ' + str(e))
|
| |
- assert False
|
| |
- try:
|
| |
- topology_st.standalone.simple_bind_s(USER_DN, 'password1')
|
| |
- except ldap.LDAPError as e:
|
| |
- log.fatal('Failed to bind as user using "password1": ' + str(e))
|
| |
+ #
|
| |
+ # Check that we only have 3 passwords stored in history
|
| |
+ #
|
| |
+ pwds = user.get_attr_vals('passwordHistory')
|
| |
+ if len(pwds) != 3:
|
| |
+ log.fatal('Incorrect number of passwords stored in history: %d' %
|
| |
+ len(pwds))
|
| |
+ log.error('password history: ' + str(pwds))
|
| |
assert False
|
| |
- time.sleep(1)
|
| |
+ else:
|
| |
+ log.info('Correct number of passwords found in history.')
|
| |
|
| |
- # password2
|
| |
+ #
|
| |
+ # Attempt to change the password to previous passwords
|
| |
+ #
|
| |
try:
|
| |
- topology_st.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE,
|
| |
- 'userpassword', b'password2')])
|
| |
- except ldap.LDAPError as e:
|
| |
- log.fatal('Failed to change password: ' + str(e))
|
| |
+ user.set('userpassword', 'password1')
|
| |
+ log.fatal('Incorrectly able to to set password to previous password1.')
|
| |
+ log.error('password history: ' + str(user.get_attr_vals('passwordhistory')))
|
| |
assert False
|
| |
- try:
|
| |
- topology_st.standalone.simple_bind_s(USER_DN, 'password2')
|
| |
+ except ldap.CONSTRAINT_VIOLATION:
|
| |
+ log.info('Password change correctly rejected')
|
| |
except ldap.LDAPError as e:
|
| |
- log.fatal('Failed to bind as user using "password2": ' + str(e))
|
| |
+ log.fatal('Failed to attempt to change password: ' + str(e))
|
| |
assert False
|
| |
- time.sleep(1)
|
| |
-
|
| |
- # password3
|
| |
try:
|
| |
- topology_st.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE,
|
| |
- 'userpassword', b'password3')])
|
| |
- except ldap.LDAPError as e:
|
| |
- log.fatal('Failed to change password: ' + str(e))
|
| |
+ user.set('userpassword', 'password2')
|
| |
+ log.fatal('Incorrectly able to to set password to previous password2.')
|
| |
+ log.error('password history: ' + str(user.get_attr_vals('passwordhistory')))
|
| |
assert False
|
| |
- try:
|
| |
- topology_st.standalone.simple_bind_s(USER_DN, 'password3')
|
| |
+ except ldap.CONSTRAINT_VIOLATION:
|
| |
+ log.info('Password change correctly rejected')
|
| |
except ldap.LDAPError as e:
|
| |
- log.fatal('Failed to bind as user using "password3": ' + str(e))
|
| |
+ log.fatal('Failed to attempt to change password: ' + str(e))
|
| |
assert False
|
| |
- time.sleep(1)
|
| |
-
|
| |
- # password4
|
| |
try:
|
| |
- topology_st.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE,
|
| |
- 'userpassword', b'password4')])
|
| |
- except ldap.LDAPError as e:
|
| |
- log.fatal('Failed to change password: ' + str(e))
|
| |
+ user.set('userpassword', 'password3')
|
| |
+ log.fatal('Incorrectly able to to set password to previous password3.')
|
| |
+ log.error('password history: ' + str(user.get_attr_vals('passwordhistory')))
|
| |
assert False
|
| |
- try:
|
| |
- topology_st.standalone.simple_bind_s(USER_DN, 'password4')
|
| |
+ except ldap.CONSTRAINT_VIOLATION:
|
| |
+ log.info('Password change correctly rejected')
|
| |
except ldap.LDAPError as e:
|
| |
- log.fatal('Failed to bind as user using "password4": ' + str(e))
|
| |
+ log.fatal('Failed to attempt to change password: ' + str(e))
|
| |
assert False
|
| |
- time.sleep(1)
|
| |
|
| |
#
|
| |
- # Check that we only have 3 passwords stored in history
|
| |
+ # Reset password by Directory Manager(admin reset)
|
| |
#
|
| |
try:
|
| |
- entry = topology_st.standalone.search_s(USER_DN, ldap.SCOPE_BASE,
|
| |
- 'objectclass=*',
|
| |
- ['passwordHistory'])
|
| |
- pwds = entry[0].getValues('passwordHistory')
|
| |
- if len(pwds) != 3:
|
| |
- log.fatal('Incorrect number of passwords stored in histry: %d' %
|
| |
- len(pwds))
|
| |
- assert False
|
| |
- else:
|
| |
- log.info('Correct number of passwords found in history.')
|
| |
+ topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
|
| |
except ldap.LDAPError as e:
|
| |
- log.fatal('Failed to get user entry: ' + str(e))
|
| |
+ log.fatal('Failed to bind as rootDN: ' + str(e))
|
| |
assert False
|
| |
+ user.set('userpassword', 'password-reset')
|
| |
+ time.sleep(1)
|
| |
|
| |
- #
|
| |
- # Attempt to change the password to previous passwords
|
| |
- #
|
| |
+ # Try and change the password to the previous password before the reset
|
| |
try:
|
| |
- topology_st.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE,
|
| |
- 'userpassword', b'password1')])
|
| |
- log.info('Incorrectly able to to set password to previous password1.')
|
| |
+ user.rebind('password-reset')
|
| |
+ user.set('userpassword', 'password4')
|
| |
+ log.fatal('Incorrectly able to to set password to previous password4.')
|
| |
+ log.error('password history: ' + str(user.get_attr_vals('passwordhistory')))
|
| |
assert False
|
| |
except ldap.CONSTRAINT_VIOLATION:
|
| |
log.info('Password change correctly rejected')
|
| |
except ldap.LDAPError as e:
|
| |
log.fatal('Failed to attempt to change password: ' + str(e))
|
| |
assert False
|
| |
- time.sleep(1)
|
| |
|
| |
+ #
|
| |
+ # Test passwordInHistory to 0
|
| |
+ #
|
| |
try:
|
| |
- topology_st.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE,
|
| |
- 'userpassword', b'password2')])
|
| |
- log.info('Incorrectly able to to set password to previous password2.')
|
| |
+ topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
|
| |
+ except ldap.LDAPError as e:
|
| |
+ log.fatal('Failed to bind as rootDN: ' + str(e))
|
| |
assert False
|
| |
- except ldap.CONSTRAINT_VIOLATION:
|
| |
- log.info('Password change correctly rejected')
|
| |
+
|
| |
+ try:
|
| |
+ topology_st.standalone.config.replace('passwordInHistory', '0')
|
| |
+ log.info('Configured passwordInHistory to 0.')
|
| |
except ldap.LDAPError as e:
|
| |
- log.fatal('Failed to attempt to change password: ' + str(e))
|
| |
+ log.fatal('Failed to configure password policy (passwordInHistory to 0): ' + str(e))
|
| |
assert False
|
| |
+
|
| |
+ # Verify the older passwords in the entry (passwordhistory) are ignored
|
| |
+ user.rebind('password-reset')
|
| |
+ user.set('userpassword', 'password4')
|
| |
try:
|
| |
- topology_st.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE,
|
| |
- 'userpassword', b'password3')])
|
| |
- log.info('Incorrectly able to to set password to previous password3.')
|
| |
+ user.set('userpassword', 'password4')
|
| |
+ log.fatal('Incorrectly able to to set password to current password4.')
|
| |
+ log.error('password history: ' + str(user.get_attr_vals('passwordhistory')))
|
| |
assert False
|
| |
except ldap.CONSTRAINT_VIOLATION:
|
| |
log.info('Password change correctly rejected')
|
| |
@@ -211,8 +203,12 @@
|
| |
log.fatal('Failed to attempt to change password: ' + str(e))
|
| |
assert False
|
| |
|
| |
+ # Need to make one successful update so history list is reset
|
| |
+ user.set('userpassword', 'password5')
|
| |
+
|
| |
#
|
| |
- # Reset password by Directory Manager(admin reset)
|
| |
+ # Set the history count back to a positive value and make sure things still work
|
| |
+ # as expected
|
| |
#
|
| |
try:
|
| |
topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
|
| |
@@ -221,33 +217,34 @@
|
| |
assert False
|
| |
|
| |
try:
|
| |
- topology_st.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE,
|
| |
- 'userpassword',
|
| |
- b'password-reset')])
|
| |
+ topology_st.standalone.config.replace('passwordInHistory', '2')
|
| |
+ log.info('Configured passwordInHistory to 2.')
|
| |
except ldap.LDAPError as e:
|
| |
- log.fatal('Failed to attempt to reset password: ' + str(e))
|
| |
+ log.fatal('Failed to configure password policy (passwordInHistory to 2): ' + str(e))
|
| |
assert False
|
| |
time.sleep(1)
|
| |
|
| |
- # Try and change the password to the previous password before the reset
|
| |
try:
|
| |
- topology_st.standalone.simple_bind_s(USER_DN, 'password-reset')
|
| |
+ user.rebind('password5')
|
| |
+ user.set('userpassword', 'password5')
|
| |
+ log.fatal('Incorrectly able to to set password to current password5.')
|
| |
+ log.error('password history: ' + str(user.get_attr_vals('passwordhistory')))
|
| |
+ assert False
|
| |
+ except ldap.CONSTRAINT_VIOLATION:
|
| |
+ log.info('Password change correctly rejected')
|
| |
except ldap.LDAPError as e:
|
| |
- log.fatal('Failed to bind as user: ' + str(e))
|
| |
+ log.fatal('Failed to attempt to change password: ' + str(e))
|
| |
assert False
|
| |
- time.sleep(1)
|
| |
|
| |
+ # Test that old password that was in history is not being checked
|
| |
try:
|
| |
- topology_st.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE,
|
| |
- 'userpassword', b'password4')])
|
| |
- log.info('Incorrectly able to to set password to previous password4.')
|
| |
- assert False
|
| |
- except ldap.CONSTRAINT_VIOLATION:
|
| |
- log.info('Password change correctly rejected')
|
| |
+ user.set('userpassword', 'password1')
|
| |
except ldap.LDAPError as e:
|
| |
log.fatal('Failed to attempt to change password: ' + str(e))
|
| |
+ log.error('password history: ' + str(user.get_attr_vals('passwordhistory')))
|
| |
assert False
|
| |
|
| |
+ # Done
|
| |
log.info('Test suite PASSED.')
|
| |
|
| |
|
| |
Description:
Currently if you set passwordinhistory 1, it checks the last recorded password and the current password. To get it to just check the current password we need to allow "0" in passwordinhistory. Then only check the current password, and not the entry's passwordHistory attributes (if any).
https://pagure.io/389-ds-base/issue/50155