| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516 |
- """
- # --- BEGIN COPYRIGHT BLOCK ---
- # Copyright (C) 2020 Red Hat, Inc.
- # All rights reserved.
- #
- # License: GPL (version 3 or any later version).
- # See LICENSE for details.
- # --- END COPYRIGHT BLOCK ---
- """
- import os
- import pytest
- from lib389.topologies import topology_st as topo
- from lib389.idm.user import UserAccounts, UserAccount
- from lib389._constants import DEFAULT_SUFFIX
- from lib389.config import Config
- from lib389.idm.group import Group
- from lib389.utils import ds_is_older
- import ldap
- import time
- pytestmark = pytest.mark.tier1
- if ds_is_older('1.4'):
- DEFAULT_PASSWORD_STORAGE_SCHEME = 'SSHA512'
- else:
- DEFAULT_PASSWORD_STORAGE_SCHEME = 'PBKDF2_SHA256'
- def _create_user(topo, uid, cn, uidNumber, userpassword):
- """
- Will Create user
- """
- user = UserAccounts(topo.standalone, DEFAULT_SUFFIX).create(properties={
- 'uid': uid,
- 'sn': cn.split(' ')[-1],
- 'cn': cn,
- 'givenname': cn.split(' ')[0],
- 'uidNumber': uidNumber,
- 'gidNumber': uidNumber,
- 'mail': f'{uid}@example.com',
- 'userpassword': userpassword,
- 'homeDirectory': f'/home/{uid}'
- })
- return user
- def _change_password_with_own(topo, user_dn, password, new_password):
- """
- Change user password with user self
- """
- conn = UserAccount(topo.standalone, user_dn).bind(password)
- real_user = UserAccount(conn, user_dn)
- real_user.replace('userpassword', new_password)
- def _change_password_with_root(topo, user_dn, new_password):
- """
- Root will change user password
- """
- UserAccount(topo.standalone, user_dn).replace('userpassword', new_password)
- @pytest.fixture(scope="function")
- def _fix_password(topo, request):
- user = _create_user(topo, 'dbyers', 'Danny Byers', '1001', 'dbyers1')
- user.replace('userpassword', 'dbyers1')
- def fin():
- user.delete()
- request.addfinalizer(fin)
- def test_passwordchange_to_no(topo, _fix_password):
- """Change password fo a user even password even though pw policy is set to no
- :id: 16c64ef0-5a20-11ea-a902-8c16451d917b
- :setup: Standalone
- :steps:
- 1. Adding an user with uid=dbyers
- 2. Set Password change to Must Not Change After Reset
- 3. Setting Password policy to May Not Change Password
- 4. Try to change password fo a user even password even though pw policy is set to no
- 5. Set Password change to May Change Password
- 6. Try to change password fo a user even password
- 7. Try to change password with invalid credentials. Should see error message.
- :expected results:
- 1. Success
- 2. Success
- 3. Success
- 4. Success
- 5. Success
- 6. Success
- 7. Success
- """
- # Adding an user with uid=dbyers
- user = f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}'
- config = Config(topo.standalone)
- # Set Password change to Must Not Change After Reset
- config.replace_many(
- ('passwordmustchange', 'off'),
- ('passwordchange', 'off'))
- # Try to change password fo a user even password even though pw policy is set to no
- with pytest.raises(ldap.UNWILLING_TO_PERFORM):
- _change_password_with_own(topo, user, 'dbyers1', 'AB')
- # Set Password change to May Change Password
- config.replace('passwordchange', 'on')
- _change_password_with_own(topo, user, 'dbyers1', 'dbyers1')
- # Try to change password with invalid credentials. Should see error message.
- with pytest.raises(ldap.INVALID_CREDENTIALS):
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'AB', 'dbyers1')
- def test_password_check_syntax(topo, _fix_password):
- """Password check syntax
- :id: 1e6fcc9e-5a20-11ea-9659-8c16451d917b
- :setup: Standalone
- :steps:
- 1. Sets Password check syntax to on
- 2. Try to change to a password that violates length. Should get error
- 3. Attempt to Modify password to db which is in error to policy
- 4. change min pw length to 5
- 5. Attempt to Modify password to dby3rs which is in error to policy
- 6. Attempt to Modify password to danny which is in error to policy
- 7. Attempt to Modify password to byers which is in error to policy
- 8. Change min pw length to 6
- 9. Try to change the password
- 10. Trying to set to a password containing value of sn
- 11. Sets policy to not check pw syntax
- 12. Test that when checking syntax is off, you can use small passwords
- 13. Test that when checking syntax is off, trivial passwords can be used
- 14. Changing password minimum length from 6 to 10
- 15. Setting policy to Check Password Syntax again
- 16. Try to change to a password that violates length
- 17. Reset Password
- :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
- 14. Success
- 15. Success
- 16. Fail
- 17. Success
- """
- config = Config(topo.standalone)
- # Sets Password check syntax to on
- config.replace('passwordchecksyntax', 'on')
- # Try to change to a password that violates length. Should get error
- with pytest.raises(ldap.CONSTRAINT_VIOLATION):
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'dbyers2')
- # Attempt to Modify password to db which is in error to policy
- with pytest.raises(ldap.CONSTRAINT_VIOLATION):
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'db')
- # change min pw length to 5
- config.replace('passwordminlength', '5')
- # Attempt to Modify password to dby3rs which is in error to policy
- # Attempt to Modify password to danny which is in error to policy
- # Attempt to Modify password to byers which is in error to policy
- for password in ['dbyers', 'Danny', 'byers']:
- with pytest.raises(ldap.CONSTRAINT_VIOLATION):
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', password)
- # Change min pw length to 6
- config.replace('passwordminlength', '6')
- # Try to change the password
- # Trying to set to a password containing value of sn
- for password in ['dby3rs1', 'dbyers2', '67Danny89', 'YAByers8']:
- with pytest.raises(ldap.CONSTRAINT_VIOLATION):
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', password)
- # Sets policy to not check pw syntax
- # Test that when checking syntax is off, you can use small passwords
- # Test that when checking syntax is off, trivial passwords can be used
- config.replace('passwordchecksyntax', 'off')
- for password, new_pass in [('dbyers1', 'db'), ('db', 'dbyers'), ('dbyers', 'dbyers1')]:
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', password, new_pass)
- # Changing password minimum length from 6 to 10
- # Setting policy to Check Password Syntax again
- config.replace_many(
- ('passwordminlength', '10'),
- ('passwordchecksyntax', 'on'))
- # Try to change to a password that violates length
- with pytest.raises(ldap.CONSTRAINT_VIOLATION):
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'db')
- UserAccount(topo.standalone, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}').replace('userpassword', 'dbyers1')
- def test_too_big_password(topo, _fix_password):
- """Test for long long password
- :id: 299a3fb4-5a20-11ea-bba8-8c16451d917b
- :setup: Standalone
- :steps:
- 1. Setting policy to keep password histories
- 2. Changing number of password in history to 3
- 3. Modify password from dby3rs1 to dby3rs2
- 4. Checking that the passwordhistory attribute has been added
- 5. Add a password test for long long password
- 6. Changing number of password in history to 6 and passwordhistory off
- :expected results:
- 1. Success
- 2. Success
- 3. Success
- 4. Success
- 5. Success
- 6. Success
- """
- config = Config(topo.standalone)
- # Setting policy to keep password histories
- config.replace_many(
- ('passwordchecksyntax', 'off'),
- ('passwordhistory', 'on'))
- assert config.get_attr_val_utf8('passwordinhistory') == '6'
- # Changing number of password in history to 3
- config.replace('passwordinhistory', '3')
- # Modify password from dby3rs1 to dby3rs2
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'dbyers2')
- with pytest.raises(ldap.CONSTRAINT_VIOLATION):
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers2', 'dbyers1')
- # Checking that the passwordhistory attribute has been added
- assert UserAccount(topo.standalone, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}').get_attr_val_utf8('passwordhistory')
- # Add a password test for long long password
- long_pass = 50*'0123456789'+'LENGTH=510'
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers2', long_pass)
- with pytest.raises(ldap.CONSTRAINT_VIOLATION):
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', long_pass, long_pass)
- _change_password_with_root(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1')
- # Changing number of password in history to 6 and passwordhistory off
- config.replace_many(('passwordhistory', 'off'),
- ('passwordinhistory', '6'))
- def test_pwminage(topo, _fix_password):
- """Test pwminage
- :id: 2df7bf32-5a20-11ea-ad23-8c16451d917b
- :setup: Standalone
- :steps:
- 1. Get pwminage; should be 0 currently
- 2. Sets policy to pwminage 3
- 3. Change current password
- 4. Try to change password again
- 5. Try now after 3 secs is up, should work.
- :expected results:
- 1. Success
- 2. Success
- 3. Success
- 4. Fail
- 5. Success
- """
- config = Config(topo.standalone)
- # Get pwminage; should be 0 currently
- assert config.get_attr_val_utf8('passwordminage') == '0'
- # Sets policy to pwminage 3
- config.replace('passwordminage', '3')
- # Change current password
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'dbyers2')
- # Try to change password again
- with pytest.raises(ldap.CONSTRAINT_VIOLATION):
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers2', 'dbyers1')
- for _ in range(3):
- time.sleep(1)
- # Try now after 3 secs is up, should work.
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers2', 'dbyers1')
- config.replace('passwordminage', '0')
- def test_invalid_credentials(topo, _fix_password):
- """Test bind again with valid password: We should be locked
- :id: 3233ca78-5a20-11ea-8d35-8c16451d917b
- :setup: Standalone
- :steps:
- 1. Search if passwordlockout is off
- 2. Turns on passwordlockout
- 3. sets lockout duration to 3 seconds
- 4. Changing pw failure count reset duration to 3 sec and passwordminlength to 10
- 5. Try to bind with invalid credentials
- 6. Change password to password lockout forever
- 7. Try to bind with invalid credentials
- 8. Now bind again with valid password: We should be locked
- 9. Delete dby3rs before exiting
- 10. Reset server
- :expected results:
- 1. Success
- 2. Success
- 3. Success
- 4. Success
- 5. Fail
- 6. Success
- 7. Success
- 8. Success
- 9. Success
- 10. Success
- """
- config = Config(topo.standalone)
- # Search if passwordlockout is off
- assert config.get_attr_val_utf8('passwordlockout') == 'off'
- # Turns on passwordlockout
- # sets lockout duration to 3 seconds
- # Changing pw failure count reset duration to 3 sec and passwordminlength to 10
- config.replace_many(
- ('passwordlockout', 'on'),
- ('passwordlockoutduration', '3'),
- ('passwordresetfailurecount', '3'),
- ('passwordminlength', '10'))
- # Try to bind with invalid credentials
- for _ in range(3):
- with pytest.raises(ldap.INVALID_CREDENTIALS):
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'Invalid', 'dbyers1')
- with pytest.raises(ldap.CONSTRAINT_VIOLATION):
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'Invalid', 'dbyers1')
- for _ in range(3):
- time.sleep(1)
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'dbyers1')
- # Change password to password lockout forever
- config.replace('passwordunlock', 'off')
- # Try to bind with invalid credentials
- for _ in range(3):
- with pytest.raises(ldap.INVALID_CREDENTIALS):
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'Invalid', 'dbyers1')
- with pytest.raises(ldap.CONSTRAINT_VIOLATION):
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'Invalid', 'dbyers1')
- for _ in range(3):
- time.sleep(1)
- # Now bind again with valid password: We should be locked
- with pytest.raises(ldap.CONSTRAINT_VIOLATION):
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'dbyers1')
- # Delete dby3rs before exiting
- _change_password_with_root(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1')
- time.sleep(1)
- _change_password_with_own(topo, f'uid=dbyers,ou=People,{DEFAULT_SUFFIX}', 'dbyers1', 'dbyers1')
- # Reset server
- config.replace_many(
- ('passwordinhistory', '6'),
- ('passwordlockout', 'off'),
- ('passwordlockoutduration', '3600'),
- ('passwordminlength', '6'),
- ('passwordresetfailurecount', '600'),
- ('passwordunlock', 'on'))
- def test_expiration_date(topo, _fix_password):
- """Test check the expiration date is still in the future
- :id: 3691739a-5a20-11ea-8712-8c16451d917b
- :setup: Standalone
- :steps:
- 1. Password expiration
- 2. Add a user with a password expiration date
- 3. Modify their password
- 4. Check the expiration date is still in the future
- 5. Modify the password expiration date
- 6. Check the expiration date is still in the future
- 7. Change policy so that user can change passwords
- 8. Deleting user
- 9. Adding user
- 10. Set password history ON
- 11. Modify password Once
- 12. Try to change the password with same one
- :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. Fail
- """
- # Add a user with a password expiration date
- user = UserAccounts(topo.standalone, DEFAULT_SUFFIX).create_test_user()
- user.replace_many(
- ('userpassword', 'bind4now'),
- ('passwordExpirationTime', '20380119031404Z'))
- # Modify their password
- user.replace('userPassword', 'secreter')
- # Check the expiration date is still in the future
- assert user.get_attr_val_utf8('passwordExpirationTime') == '20380119031404Z'
- # Modify the password expiration date
- user.replace('passwordExpirationTime', '20380119031405Z')
- # Check the expiration date is still in the future
- assert user.get_attr_val_utf8('passwordExpirationTime') == '20380119031405Z'
- config = Config(topo.standalone)
- # Change policy so that user can change passwords
- config.replace('passwordchange', 'on')
- # Deleting user
- UserAccount(topo.standalone, f'uid=test_user_1000,ou=People,{DEFAULT_SUFFIX}').delete()
- # Adding user
- user = UserAccounts(topo.standalone, DEFAULT_SUFFIX).create_test_user()
- # Set password history ON
- config.replace('passwordhistory', 'on')
- # Modify password Once
- user.replace('userPassword', 'secreter')
- time.sleep(1)
- assert DEFAULT_PASSWORD_STORAGE_SCHEME in user.get_attr_val_utf8('userPassword')
- # Try to change the password with same one
- for _ in range(3):
- with pytest.raises(ldap.CONSTRAINT_VIOLATION):
- _change_password_with_own(topo, user.dn, 'secreter', 'secreter')
- user.delete()
- def test_passwordlockout(topo, _fix_password):
- """Test adding admin user diradmin to Directory Administrator group
- :id: 3ffcffda-5a20-11ea-a3af-8c16451d917b
- :setup: Standalone
- :steps:
- 1. Account Lockout must be cleared on successful password change
- 2. Adding admin user diradmin
- 3. Adding admin user diradmin to Directory Administrator group
- 4. Turn on passwordlockout
- 5. Sets lockout duration to 30 seconds
- 6. Sets failure count reset duration to 30 sec
- 7. Sets max password bind failure count to 3
- 8. Reset password retry count (to 0)
- 9. Try to bind with invalid credentials(3 times)
- 10. Try to bind with valid pw, should give lockout error
- 11. Reset password using admin login
- 12. Try to login as the user to check the unlocking of account. Will also change
- the password back to original
- 13. Change to account lockout forever until reset
- 14. Reset password retry count (to 0)
- 15. Try to bind with invalid credentials(3 times)
- 16. Try to bind with valid pw, should give lockout error
- 17. Reset password using admin login
- 18. Try to login as the user to check the unlocking of account. Will also change the
- password back to original
- :expected results:
- 1. Success
- 2. Success
- 3. Success
- 4. Success
- 5. Success
- 6. Success
- 7. Success
- 8. Success
- 9. Fail
- 10. Success
- 11. Success
- 12. Success
- 13. Success
- 14. Success
- 15. Fail
- 16. Success
- 17. Success
- 18. Success
- """
- config = Config(topo.standalone)
- # Adding admin user diradmin
- user = UserAccounts(topo.standalone, DEFAULT_SUFFIX).create_test_user()
- user.replace('userpassword', 'dby3rs2')
- admin = _create_user(topo, 'diradmin', 'Anuj Borah', '1002', 'diradmin')
- # Adding admin user diradmin to Directory Administrator group
- Group(topo.standalone, f'cn=user_passwd_reset,ou=permissions,{DEFAULT_SUFFIX}').add('member', admin.dn)
- # Turn on passwordlockout
- # Sets lockout duration to 30 seconds
- # Sets failure count reset duration to 30 sec
- # Sets max password bind failure count to 3
- # Reset password retry count (to 0)
- config.replace_many(
- ('passwordlockout', 'on'),
- ('passwordlockoutduration', '30'),
- ('passwordresetfailurecount', '30'),
- ('passwordmaxfailure', '3'),
- ('passwordhistory', 'off'))
- user.replace('passwordretrycount', '0')
- # Try to bind with invalid credentials(3 times)
- for _ in range(3):
- with pytest.raises(ldap.INVALID_CREDENTIALS):
- _change_password_with_own(topo, user.dn, 'Invalid', 'secreter')
- # Try to bind with valid pw, should give lockout error
- with pytest.raises(ldap.CONSTRAINT_VIOLATION):
- _change_password_with_own(topo, user.dn, 'Invalid', 'secreter')
- # Reset password using admin login
- conn = admin.bind('diradmin')
- UserAccount(conn, user.dn).replace('userpassword', 'dby3rs2')
- time.sleep(1)
- # Try to login as the user to check the unlocking of account. Will also change
- # the password back to original
- _change_password_with_own(topo, user.dn, 'dby3rs2', 'secreter')
- # Change to account lockout forever until reset
- # Reset password retry count (to 0)
- config.replace('passwordunlock', 'off')
- user.replace('passwordretrycount', '0')
- # Try to bind with invalid credentials(3 times)
- for _ in range(3):
- with pytest.raises(ldap.INVALID_CREDENTIALS):
- _change_password_with_own(topo, user.dn, 'Invalid', 'secreter')
- # Try to bind with valid pw, should give lockout error
- with pytest.raises(ldap.CONSTRAINT_VIOLATION):
- _change_password_with_own(topo, user.dn, 'Invalid', 'secreter')
- # Reset password using admin login
- UserAccount(conn, user.dn).replace('userpassword', 'dby3rs2')
- time.sleep(1)
- # Try to login as the user to check the unlocking of account. Will also change the
- # password back to original
- _change_password_with_own(topo, user.dn, 'dby3rs2', 'secreter')
- if __name__ == "__main__":
- CURRENT_FILE = os.path.realpath(__file__)
- pytest.main("-s -v %s" % CURRENT_FILE)
|