pwdPolicy_syntax_test.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. # --- BEGIN COPYRIGHT BLOCK ---
  2. # Copyright (C) 2015 Red Hat, Inc.
  3. # All rights reserved.
  4. #
  5. # License: GPL (version 3 or any later version).
  6. # See LICENSE for details.
  7. # --- END COPYRIGHT BLOCK ---
  8. #
  9. import os
  10. import time
  11. import ldap
  12. import logging
  13. import pytest
  14. from lib389 import DirSrv, Entry
  15. from lib389._constants import *
  16. from lib389.properties import *
  17. from lib389.tasks import *
  18. logging.getLogger(__name__).setLevel(logging.DEBUG)
  19. log = logging.getLogger(__name__)
  20. DEBUGGING = False
  21. USER_DN = 'uid=user,ou=People,%s' % DEFAULT_SUFFIX
  22. if DEBUGGING:
  23. logging.getLogger(__name__).setLevel(logging.DEBUG)
  24. else:
  25. logging.getLogger(__name__).setLevel(logging.INFO)
  26. log = logging.getLogger(__name__)
  27. class TopologyStandalone(object):
  28. """The DS Topology Class"""
  29. def __init__(self, standalone):
  30. """Init"""
  31. standalone.open()
  32. self.standalone = standalone
  33. @pytest.fixture(scope="module")
  34. def topology(request):
  35. """Create DS Deployment"""
  36. # Creating standalone instance ...
  37. if DEBUGGING:
  38. standalone = DirSrv(verbose=True)
  39. else:
  40. standalone = DirSrv(verbose=False)
  41. args_instance[SER_HOST] = HOST_STANDALONE
  42. args_instance[SER_PORT] = PORT_STANDALONE
  43. args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
  44. args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
  45. args_standalone = args_instance.copy()
  46. standalone.allocate(args_standalone)
  47. instance_standalone = standalone.exists()
  48. if instance_standalone:
  49. standalone.delete()
  50. standalone.create()
  51. standalone.open()
  52. def fin():
  53. """If we are debugging just stop the instances, otherwise remove
  54. them
  55. """
  56. if DEBUGGING:
  57. standalone.stop()
  58. else:
  59. standalone.delete()
  60. request.addfinalizer(fin)
  61. return TopologyStandalone(standalone)
  62. def _create_user(inst):
  63. """Create the test user."""
  64. inst.add_s(Entry((
  65. USER_DN, {
  66. 'objectClass': 'top account simplesecurityobject'.split(),
  67. 'uid': 'user',
  68. 'userpassword': PASSWORD
  69. })))
  70. def setPolicy(inst, attr, value):
  71. """Bind as ROot DN, set polcy, and then bind as user"""
  72. try:
  73. inst.simple_bind_s(DN_DM, PASSWORD)
  74. except ldap.LDAPError as e:
  75. log.fatal("Failed to bind as Directory Manager: " + str(e))
  76. assert False
  77. value = str(value)
  78. """
  79. if value == '0':
  80. # Remove the policy attribute
  81. try:
  82. inst.modify_s("cn=config",
  83. [(ldap.MOD_DELETE, attr, None)])
  84. except ldap.LDAPError as e:
  85. log.fatal("Failed to rmeove password policy %s: %s" %
  86. (attr, str(e)))
  87. assert False
  88. else:
  89. """
  90. # Set the policy value
  91. inst.config.set(attr, value)
  92. try:
  93. inst.simple_bind_s(USER_DN, PASSWORD)
  94. except ldap.LDAPError as e:
  95. log.fatal("Failed to bind: " + str(e))
  96. assert False
  97. def resetPasswd(inst):
  98. """Reset the user password for the next test"""
  99. # First, bind as the ROOT DN so we can set the password
  100. try:
  101. inst.simple_bind_s(DN_DM, PASSWORD)
  102. except ldap.LDAPError as e:
  103. log.fatal("Failed to bind as Directory Manager: " + str(e))
  104. assert False
  105. # Now set the password
  106. try:
  107. inst.modify_s(USER_DN,
  108. [(ldap.MOD_REPLACE, 'userpassword', PASSWORD)])
  109. except ldap.LDAPError as e:
  110. log.fatal("Failed to reset user password: " + str(e))
  111. assert False
  112. def tryPassword(inst, policy_attr, value, reset_value, pw_bad, pw_good, msg):
  113. """Attempt to change the users password
  114. inst: DirSrv Object
  115. password: password
  116. msg - error message if failure
  117. """
  118. setPolicy(inst, policy_attr, value)
  119. try:
  120. inst.modify_s(USER_DN,
  121. [(ldap.MOD_REPLACE, 'userpassword', pw_bad)])
  122. log.fatal('Invalid password was unexpectedly accepted (%s)' %
  123. (policy_attr))
  124. assert False
  125. except ldap.CONSTRAINT_VIOLATION:
  126. log.info('Invalid password correctly rejected by %s: %s' %
  127. (policy_attr, msg))
  128. pass
  129. except ldap.LDAPError as e:
  130. log.fatal("Failed to change password: " + str(e))
  131. assert False
  132. # Change password that is allowed
  133. try:
  134. inst.modify_s(USER_DN,
  135. [(ldap.MOD_REPLACE, 'userpassword', pw_good)])
  136. except ldap.LDAPError as e:
  137. log.fatal("Failed to change password: " + str(e))
  138. assert False
  139. # Reset for the next test
  140. resetPasswd(inst)
  141. setPolicy(inst, policy_attr, reset_value)
  142. def test_pwdPolicy_syntax(topology):
  143. '''
  144. Password policy test: Ensure that on a password change, the policy syntax
  145. is enforced correctly.
  146. '''
  147. # Create a user
  148. _create_user(topology.standalone)
  149. # Set the password policy globally
  150. topology.standalone.config.set('passwordCheckSyntax', 'on')
  151. topology.standalone.config.set('nsslapd-pwpolicy-local', 'off')
  152. topology.standalone.config.set('passwordMinCategories', '1')
  153. #
  154. # Test each syntax catagory
  155. #
  156. # Min Length
  157. tryPassword(topology.standalone, 'passwordMinLength', 10, 2, 'passwd',
  158. 'password123', 'length too short')
  159. # Min Digit
  160. tryPassword(topology.standalone, 'passwordMinDigits', 2, 0, 'passwd',
  161. 'password123', 'does not contain minimum number of digits')
  162. # Min Alphas
  163. tryPassword(topology.standalone, 'passwordMinAlphas', 2, 0, 'p123456789',
  164. 'password123', 'does not contain minimum number of alphas')
  165. # Max Repeats
  166. tryPassword(topology.standalone, 'passwordMaxRepeats', 2, 0, 'passsword',
  167. 'pasword123', 'too many repeating characters')
  168. # Min Specials
  169. tryPassword(topology.standalone, 'passwordMinSpecials', 2, 0, 'passwd',
  170. 'password_#$',
  171. 'does not contain minimum number of special characters')
  172. # Min Lowers
  173. tryPassword(topology.standalone, 'passwordMinLowers', 2, 0, 'PASSWORD123',
  174. 'password123',
  175. 'does not contain minimum number of lowercase characters')
  176. # Min Uppers
  177. tryPassword(topology.standalone, 'passwordMinUppers', 2, 0, 'password',
  178. 'PASSWORD',
  179. 'does not contain minimum number of lowercase characters')
  180. # Min 8-bits - "ldap" package only accepts ascii strings at the moment
  181. log.info('pwdPolicy tests PASSED')
  182. if __name__ == '__main__':
  183. # Run isolated
  184. # -s for DEBUG mode
  185. CURRENT_FILE = os.path.realpath(__file__)
  186. pytest.main("-s %s" % CURRENT_FILE)