ticket48228_test.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. # --- BEGIN COPYRIGHT BLOCK ---
  2. # Copyright (C) 2016 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 logging
  10. import pytest
  11. from lib389.tasks import *
  12. from lib389.topologies import topology_st
  13. log = logging.getLogger(__name__)
  14. # Assuming DEFAULT_SUFFIX is "dc=example,dc=com", otherwise it does not work... :(
  15. SUBTREE_CONTAINER = 'cn=nsPwPolicyContainer,' + DEFAULT_SUFFIX
  16. SUBTREE_PWPDN = 'cn=nsPwPolicyEntry,' + DEFAULT_SUFFIX
  17. SUBTREE_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cdc\3Dexample\2Cdc\3Dcom,' + SUBTREE_CONTAINER
  18. SUBTREE_COS_TMPLDN = 'cn=nsPwTemplateEntry,' + DEFAULT_SUFFIX
  19. SUBTREE_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cdc\3Dexample\2Cdc\3Dcom,' + SUBTREE_CONTAINER
  20. SUBTREE_COS_DEF = 'cn=nsPwPolicy_CoS,' + DEFAULT_SUFFIX
  21. USER1_DN = 'uid=user1,' + DEFAULT_SUFFIX
  22. USER2_DN = 'uid=user2,' + DEFAULT_SUFFIX
  23. def set_global_pwpolicy(topology_st, inhistory):
  24. log.info(" +++++ Enable global password policy +++++\n")
  25. topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
  26. # Enable password policy
  27. try:
  28. topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', 'on')])
  29. except ldap.LDAPError as e:
  30. log.error('Failed to set pwpolicy-local: error ' + e.message['desc'])
  31. assert False
  32. log.info(" Set global password history on\n")
  33. try:
  34. topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordHistory', 'on')])
  35. except ldap.LDAPError as e:
  36. log.error('Failed to set passwordHistory: error ' + e.message['desc'])
  37. assert False
  38. log.info(" Set global passwords in history\n")
  39. try:
  40. count = "%d" % inhistory
  41. topology_st.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordInHistory', count)])
  42. except ldap.LDAPError as e:
  43. log.error('Failed to set passwordInHistory: error ' + e.message['desc'])
  44. assert False
  45. def set_subtree_pwpolicy(topology_st):
  46. log.info(" +++++ Enable subtree level password policy +++++\n")
  47. topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
  48. log.info(" Add the container")
  49. try:
  50. topology_st.standalone.add_s(Entry((SUBTREE_CONTAINER, {'objectclass': 'top nsContainer'.split(),
  51. 'cn': 'nsPwPolicyContainer'})))
  52. except ldap.LDAPError as e:
  53. log.error('Failed to add subtree container: error ' + e.message['desc'])
  54. assert False
  55. log.info(" Add the password policy subentry {passwordHistory: on, passwordInHistory: 6}")
  56. try:
  57. topology_st.standalone.add_s(Entry((SUBTREE_PWP, {'objectclass': 'top ldapsubentry passwordpolicy'.split(),
  58. 'cn': SUBTREE_PWPDN,
  59. 'passwordMustChange': 'off',
  60. 'passwordExp': 'off',
  61. 'passwordHistory': 'on',
  62. 'passwordInHistory': '6',
  63. 'passwordMinAge': '0',
  64. 'passwordChange': 'on',
  65. 'passwordStorageScheme': 'clear'})))
  66. except ldap.LDAPError as e:
  67. log.error('Failed to add passwordpolicy: error ' + e.message['desc'])
  68. assert False
  69. log.info(" Add the COS template")
  70. try:
  71. topology_st.standalone.add_s(
  72. Entry((SUBTREE_COS_TMPL, {'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
  73. 'cn': SUBTREE_PWPDN,
  74. 'cosPriority': '1',
  75. 'cn': SUBTREE_COS_TMPLDN,
  76. 'pwdpolicysubentry': SUBTREE_PWP})))
  77. except ldap.LDAPError as e:
  78. log.error('Failed to add COS template: error ' + e.message['desc'])
  79. assert False
  80. log.info(" Add the COS definition")
  81. try:
  82. topology_st.standalone.add_s(
  83. Entry((SUBTREE_COS_DEF, {'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
  84. 'cn': SUBTREE_PWPDN,
  85. 'costemplatedn': SUBTREE_COS_TMPL,
  86. 'cosAttribute': 'pwdpolicysubentry default operational-default'})))
  87. except ldap.LDAPError as e:
  88. log.error('Failed to add COS def: error ' + e.message['desc'])
  89. assert False
  90. def check_passwd_inhistory(topology_st, user, cpw, passwd):
  91. inhistory = 0
  92. log.info(" Bind as {%s,%s}" % (user, cpw))
  93. topology_st.standalone.simple_bind_s(user, cpw)
  94. try:
  95. topology_st.standalone.modify_s(user, [(ldap.MOD_REPLACE, 'userpassword', passwd)])
  96. except ldap.LDAPError as e:
  97. log.info(' The password ' + passwd + ' of user' + USER1_DN + ' in history: error ' + e.message['desc'])
  98. inhistory = 1
  99. time.sleep(1)
  100. return inhistory
  101. def update_passwd(topology_st, user, passwd, times):
  102. cpw = passwd
  103. for i in range(times):
  104. log.info(" Bind as {%s,%s}" % (user, cpw))
  105. topology_st.standalone.simple_bind_s(user, cpw)
  106. cpw = 'password%d' % i
  107. try:
  108. topology_st.standalone.modify_s(user, [(ldap.MOD_REPLACE, 'userpassword', cpw)])
  109. except ldap.LDAPError as e:
  110. log.fatal(
  111. 'test_ticket48228: Failed to update the password ' + cpw + ' of user ' + user + ': error ' + e.message[
  112. 'desc'])
  113. assert False
  114. time.sleep(1)
  115. # checking the first password, which is supposed to be in history
  116. inhistory = check_passwd_inhistory(topology_st, user, cpw, passwd)
  117. assert inhistory == 1
  118. def test_ticket48228_test_global_policy(topology_st):
  119. """
  120. Check global password policy
  121. """
  122. log.info(' Set inhistory = 6')
  123. set_global_pwpolicy(topology_st, 6)
  124. log.info(' Bind as directory manager')
  125. log.info("Bind as %s" % DN_DM)
  126. topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
  127. log.info(' Add an entry' + USER1_DN)
  128. try:
  129. topology_st.standalone.add_s(
  130. Entry((USER1_DN, {'objectclass': "top person organizationalPerson inetOrgPerson".split(),
  131. 'sn': '1',
  132. 'cn': 'user 1',
  133. 'uid': 'user1',
  134. 'givenname': 'user',
  135. 'mail': '[email protected]',
  136. 'userpassword': 'password'})))
  137. except ldap.LDAPError as e:
  138. log.fatal('test_ticket48228: Failed to add user' + USER1_DN + ': error ' + e.message['desc'])
  139. assert False
  140. log.info(' Update the password of ' + USER1_DN + ' 6 times')
  141. update_passwd(topology_st, USER1_DN, 'password', 6)
  142. log.info(' Set inhistory = 4')
  143. set_global_pwpolicy(topology_st, 4)
  144. log.info(' checking the first password, which is supposed NOT to be in history any more')
  145. cpw = 'password%d' % 5
  146. tpw = 'password'
  147. inhistory = check_passwd_inhistory(topology_st, USER1_DN, cpw, tpw)
  148. assert inhistory == 0
  149. log.info(' checking the second password, which is supposed NOT to be in history any more')
  150. cpw = tpw
  151. tpw = 'password%d' % 0
  152. inhistory = check_passwd_inhistory(topology_st, USER1_DN, cpw, tpw)
  153. assert inhistory == 0
  154. log.info(' checking the third password, which is supposed NOT to be in history any more')
  155. cpw = tpw
  156. tpw = 'password%d' % 1
  157. inhistory = check_passwd_inhistory(topology_st, USER1_DN, cpw, tpw)
  158. assert inhistory == 0
  159. log.info(' checking the sixth password, which is supposed to be in history')
  160. cpw = tpw
  161. tpw = 'password%d' % 5
  162. inhistory = check_passwd_inhistory(topology_st, USER1_DN, cpw, tpw)
  163. assert inhistory == 1
  164. log.info("Global policy was successfully verified.")
  165. def test_ticket48228_test_subtree_policy(topology_st):
  166. """
  167. Check subtree level password policy
  168. """
  169. log.info(' Set inhistory = 6')
  170. set_subtree_pwpolicy(topology_st)
  171. log.info(' Bind as directory manager')
  172. log.info("Bind as %s" % DN_DM)
  173. topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
  174. log.info(' Add an entry' + USER2_DN)
  175. try:
  176. topology_st.standalone.add_s(
  177. Entry((USER2_DN, {'objectclass': "top person organizationalPerson inetOrgPerson".split(),
  178. 'sn': '2',
  179. 'cn': 'user 2',
  180. 'uid': 'user2',
  181. 'givenname': 'user',
  182. 'mail': '[email protected]',
  183. 'userpassword': 'password'})))
  184. except ldap.LDAPError as e:
  185. log.fatal('test_ticket48228: Failed to add user' + USER2_DN + ': error ' + e.message['desc'])
  186. assert False
  187. log.info(' Update the password of ' + USER2_DN + ' 6 times')
  188. update_passwd(topology_st, USER2_DN, 'password', 6)
  189. log.info(' Set inhistory = 4')
  190. topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
  191. try:
  192. topology_st.standalone.modify_s(SUBTREE_PWP, [(ldap.MOD_REPLACE, 'passwordInHistory', '4')])
  193. except ldap.LDAPError as e:
  194. log.error('Failed to set pwpolicy-local: error ' + e.message['desc'])
  195. assert False
  196. log.info(' checking the first password, which is supposed NOT to be in history any more')
  197. cpw = 'password%d' % 5
  198. tpw = 'password'
  199. inhistory = check_passwd_inhistory(topology_st, USER2_DN, cpw, tpw)
  200. assert inhistory == 0
  201. log.info(' checking the second password, which is supposed NOT to be in history any more')
  202. cpw = tpw
  203. tpw = 'password%d' % 1
  204. inhistory = check_passwd_inhistory(topology_st, USER2_DN, cpw, tpw)
  205. assert inhistory == 0
  206. log.info(' checking the third password, which is supposed NOT to be in history any more')
  207. cpw = tpw
  208. tpw = 'password%d' % 2
  209. inhistory = check_passwd_inhistory(topology_st, USER2_DN, cpw, tpw)
  210. assert inhistory == 0
  211. log.info(' checking the six password, which is supposed to be in history')
  212. cpw = tpw
  213. tpw = 'password%d' % 5
  214. inhistory = check_passwd_inhistory(topology_st, USER2_DN, cpw, tpw)
  215. assert inhistory == 1
  216. log.info("Subtree level policy was successfully verified.")
  217. if __name__ == '__main__':
  218. # Run isolated
  219. # -s for DEBUG mode
  220. CURRENT_FILE = os.path.realpath(__file__)
  221. pytest.main("-s %s" % CURRENT_FILE)