浏览代码

Ticket #548 - CI test: added test cases for ticket 548

Description: RFE: Allow AD password sync to update shadowLastChange

1) Use DEFAULT_SUFFIX_ESCAPED for the escaped DEFAULT_SUFFIX.
2) Check USER1's shadow values are adjusted by changing the password
   policy.  First, the default values.  Next, Global password policy
   then fine-grained password policy is added.
3) Checks changes to the global pw policy are reflected on pw change
3) Checks changes to the subtree pw policy are reflected on pw change

Author: nhosoi, wibrown

Review: nhosoi, wibrown
Noriko Hosoi 9 年之前
父节点
当前提交
097239c506
共有 1 个文件被更改,包括 108 次插入23 次删除
  1. 108 23
      dirsrvtests/tickets/ticket548_test.py

+ 108 - 23
dirsrvtests/tickets/ticket548_test.py

@@ -26,9 +26,9 @@ installation_prefix = None
 # Assuming DEFAULT_SUFFIX is "dc=example,dc=com", otherwise it does not work... :(
 # Assuming DEFAULT_SUFFIX is "dc=example,dc=com", otherwise it does not work... :(
 SUBTREE_CONTAINER = 'cn=nsPwPolicyContainer,' + DEFAULT_SUFFIX
 SUBTREE_CONTAINER = 'cn=nsPwPolicyContainer,' + DEFAULT_SUFFIX
 SUBTREE_PWPDN = 'cn=nsPwPolicyEntry,' + DEFAULT_SUFFIX
 SUBTREE_PWPDN = 'cn=nsPwPolicyEntry,' + DEFAULT_SUFFIX
-SUBTREE_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cdc\3Dexample\2Cdc\3Dcom,' + SUBTREE_CONTAINER
+SUBTREE_PWP = 'cn=cn\3DnsPwPolicyEntry\2C' + DEFAULT_SUFFIX_ESCAPED + ',' + SUBTREE_CONTAINER
 SUBTREE_COS_TMPLDN = 'cn=nsPwTemplateEntry,' + DEFAULT_SUFFIX
 SUBTREE_COS_TMPLDN = 'cn=nsPwTemplateEntry,' + DEFAULT_SUFFIX
-SUBTREE_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cdc\3Dexample\2Cdc\3Dcom,' + SUBTREE_CONTAINER
+SUBTREE_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2C' + DEFAULT_SUFFIX_ESCAPED + ',' + SUBTREE_CONTAINER
 SUBTREE_COS_DEF = 'cn=nsPwPolicy_CoS,' + DEFAULT_SUFFIX
 SUBTREE_COS_DEF = 'cn=nsPwPolicy_CoS,' + DEFAULT_SUFFIX
 
 
 USER1_DN = 'uid=user1,' + DEFAULT_SUFFIX
 USER1_DN = 'uid=user1,' + DEFAULT_SUFFIX
@@ -72,8 +72,12 @@ def topology(request):
 
 
     return TopologyStandalone(standalone)
     return TopologyStandalone(standalone)
 
 
+def days_to_secs(days):
+    # Value of 60 * 60 * 24
+    return days * 86400
 
 
-def set_global_pwpolicy(topology):
+# Values are in days
+def set_global_pwpolicy(topology, min_=1, max_=10, warn=3):
     log.info("	+++++ Enable global password policy +++++\n")
     log.info("	+++++ Enable global password policy +++++\n")
     # Enable password policy
     # Enable password policy
     try:
     try:
@@ -82,47 +86,64 @@ def set_global_pwpolicy(topology):
         log.error('Failed to set pwpolicy-local: error ' + e.message['desc'])
         log.error('Failed to set pwpolicy-local: error ' + e.message['desc'])
         assert False
         assert False
 
 
-    log.info("		Set global password Min Age -- 1 day\n")
+    # Convert our values to seconds
+    min_secs = days_to_secs(min_)
+    max_secs = days_to_secs(max_)
+    warn_secs = days_to_secs(warn)
+
+    log.info("		Set global password Min Age -- %s day\n"% min_)
     try:
     try:
-        topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordMinAge', '86400')])
+        topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordMinAge', '%s' % min_secs)])
     except ldap.LDAPError as e:
     except ldap.LDAPError as e:
         log.error('Failed to set passwordMinAge: error ' + e.message['desc'])
         log.error('Failed to set passwordMinAge: error ' + e.message['desc'])
         assert False
         assert False
 
 
-    log.info("		Set global password Max Age -- 10 days\n")
+    log.info("		Set global password Max Age -- %s days\n" % max_)
     try:
     try:
-        topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordMaxAge', '864000')])
+        topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordMaxAge', '%s' % max_secs)])
     except ldap.LDAPError as e:
     except ldap.LDAPError as e:
         log.error('Failed to set passwordMaxAge: error ' + e.message['desc'])
         log.error('Failed to set passwordMaxAge: error ' + e.message['desc'])
         assert False
         assert False
 
 
-    log.info("		Set global password Warning -- 3 days\n")
+    log.info("		Set global password Warning -- %s days\n" % warn)
     try:
     try:
-        topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordWarning', '259200')])
+        topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'passwordWarning', '%s' % warn_secs)])
     except ldap.LDAPError as e:
     except ldap.LDAPError as e:
         log.error('Failed to set passwordWarning: error ' + e.message['desc'])
         log.error('Failed to set passwordWarning: error ' + e.message['desc'])
         assert False
         assert False
 
 
 
 
-def set_subtree_pwpolicy(topology):
+def set_subtree_pwpolicy(topology, min_=2, max_=20, warn=6):
     log.info("	+++++ Enable subtree level password policy +++++\n")
     log.info("	+++++ Enable subtree level password policy +++++\n")
+
+    # Convert our values to seconds
+    min_secs = days_to_secs(min_)
+    max_secs = days_to_secs(max_)
+    warn_secs = days_to_secs(warn)
+
     log.info("		Add the container")
     log.info("		Add the container")
     try:
     try:
         topology.standalone.add_s(Entry((SUBTREE_CONTAINER, {'objectclass': 'top nsContainer'.split(),
         topology.standalone.add_s(Entry((SUBTREE_CONTAINER, {'objectclass': 'top nsContainer'.split(),
                                                              'cn': 'nsPwPolicyContainer'})))
                                                              'cn': 'nsPwPolicyContainer'})))
     except ldap.LDAPError as e:
     except ldap.LDAPError as e:
         log.error('Failed to add subtree container: error ' + e.message['desc'])
         log.error('Failed to add subtree container: error ' + e.message['desc'])
-        assert False
+        #assert False
 
 
-    log.info("		Add the password policy subentry {passwordMustChange: on, passwordMinAge: 2, passwordMaxAge: 20, passwordWarning: 6}")
+    try:
+        # Purge the old policy
+        topology.standalone.delete_s(SUBTREE_PWP)
+    except:
+        pass
+
+    log.info("		Add the password policy subentry {passwordMustChange: on, passwordMinAge: %s, passwordMaxAge: %s, passwordWarning: %s}" % (min_, max_, warn))
     try:
     try:
         topology.standalone.add_s(Entry((SUBTREE_PWP, {'objectclass': 'top ldapsubentry passwordpolicy'.split(),
         topology.standalone.add_s(Entry((SUBTREE_PWP, {'objectclass': 'top ldapsubentry passwordpolicy'.split(),
                                                        'cn': SUBTREE_PWPDN,
                                                        'cn': SUBTREE_PWPDN,
                                                        'passwordMustChange': 'on',
                                                        'passwordMustChange': 'on',
                                                        'passwordExp': 'on',
                                                        'passwordExp': 'on',
-                                                       'passwordMinAge': '172800',
-                                                       'passwordMaxAge': '1728000',
-                                                       'passwordWarning': '518400',
+                                                       'passwordMinAge': '%s' % min_secs,
+                                                       'passwordMaxAge': '%s' % max_secs,
+                                                       'passwordWarning': '%s' % warn_secs,
                                                        'passwordChange': 'on',
                                                        'passwordChange': 'on',
                                                        'passwordStorageScheme': 'clear'})))
                                                        'passwordStorageScheme': 'clear'})))
     except ldap.LDAPError as e:
     except ldap.LDAPError as e:
@@ -138,7 +159,7 @@ def set_subtree_pwpolicy(topology):
                                                             'pwdpolicysubentry': SUBTREE_PWP})))
                                                             'pwdpolicysubentry': SUBTREE_PWP})))
     except ldap.LDAPError as e:
     except ldap.LDAPError as e:
         log.error('Failed to add COS template: error ' + e.message['desc'])
         log.error('Failed to add COS template: error ' + e.message['desc'])
-        assert False
+        #assert False
 
 
     log.info("		Add the COS definition")
     log.info("		Add the COS definition")
     try:
     try:
@@ -148,11 +169,10 @@ def set_subtree_pwpolicy(topology):
                                                            'cosAttribute': 'pwdpolicysubentry default operational-default'})))
                                                            'cosAttribute': 'pwdpolicysubentry default operational-default'})))
     except ldap.LDAPError as e:
     except ldap.LDAPError as e:
         log.error('Failed to add COS def: error ' + e.message['desc'])
         log.error('Failed to add COS def: error ' + e.message['desc'])
-        assert False
+        #assert False
 
 
     time.sleep(1)
     time.sleep(1)
 
 
-
 def update_passwd(topology, user, passwd, newpasswd):
 def update_passwd(topology, user, passwd, newpasswd):
     log.info("		Bind as {%s,%s}" % (user, passwd))
     log.info("		Bind as {%s,%s}" % (user, passwd))
     topology.standalone.simple_bind_s(user, passwd)
     topology.standalone.simple_bind_s(user, passwd)
@@ -195,7 +215,7 @@ def test_ticket548_test_with_no_policy(topology):
                                      'cn': 'user 1',
                                      'cn': 'user 1',
                                      'uid': 'user1',
                                      'uid': 'user1',
                                      'givenname': 'user',
                                      'givenname': 'user',
-                                     'mail': 'user1@example.com',
+                                     'mail': 'user1@' + DEFAULT_SUFFIX,
                                      'userpassword': USER_PW})))
                                      'userpassword': USER_PW})))
     except ldap.LDAPError as e:
     except ldap.LDAPError as e:
         log.fatal('test_ticket548: Failed to add user' + USER1_DN + ': error ' + e.message['desc'])
         log.fatal('test_ticket548: Failed to add user' + USER1_DN + ': error ' + e.message['desc'])
@@ -231,16 +251,33 @@ def test_ticket548_test_global_policy(topology):
                                      'cn': 'user 2',
                                      'cn': 'user 2',
                                      'uid': 'user2',
                                      'uid': 'user2',
                                      'givenname': 'user',
                                      'givenname': 'user',
-                                     'mail': 'user2@example.com',
+                                     'mail': 'user2@' + DEFAULT_SUFFIX,
                                      'userpassword': USER_PW})))
                                      'userpassword': USER_PW})))
     except ldap.LDAPError as e:
     except ldap.LDAPError as e:
         log.fatal('test_ticket548: Failed to add user' + USER2_DN + ': error ' + e.message['desc'])
         log.fatal('test_ticket548: Failed to add user' + USER2_DN + ': error ' + e.message['desc'])
         assert False
         assert False
 
 
+    edate = int(time.time() / (60 * 60 * 24))
+
+    log.info("Bind as %s" % USER1_DN)
+    topology.standalone.simple_bind_s(USER1_DN, USER_PW)
+
+    log.info('Search entry %s' % USER1_DN)
+    entry = topology.standalone.getEntry(USER1_DN, ldap.SCOPE_BASE, "(objectclass=*)")
+    check_shadow_attr_value(entry, 'shadowLastChange', edate, USER1_DN)
+
+    # passwordMinAge -- 1 day
+    check_shadow_attr_value(entry, 'shadowMin', 1, USER1_DN)
+
+    # passwordMaxAge -- 10 days
+    check_shadow_attr_value(entry, 'shadowMax', 10, USER1_DN)
+
+    # passwordWarning -- 3 days
+    check_shadow_attr_value(entry, 'shadowWarning', 3, USER1_DN)
+
     log.info("Bind as %s" % USER2_DN)
     log.info("Bind as %s" % USER2_DN)
     topology.standalone.simple_bind_s(USER2_DN, USER_PW)
     topology.standalone.simple_bind_s(USER2_DN, USER_PW)
 
 
-    edate = int(time.time() / (60 * 60 * 24))
     log.info('Search entry %s' % USER2_DN)
     log.info('Search entry %s' % USER2_DN)
     entry = topology.standalone.getEntry(USER2_DN, ldap.SCOPE_BASE, "(objectclass=*)")
     entry = topology.standalone.getEntry(USER2_DN, ldap.SCOPE_BASE, "(objectclass=*)")
     check_shadow_attr_value(entry, 'shadowLastChange', edate, USER2_DN)
     check_shadow_attr_value(entry, 'shadowLastChange', edate, USER2_DN)
@@ -254,6 +291,34 @@ def test_ticket548_test_global_policy(topology):
     # passwordWarning -- 3 days
     # passwordWarning -- 3 days
     check_shadow_attr_value(entry, 'shadowWarning', 3, USER2_DN)
     check_shadow_attr_value(entry, 'shadowWarning', 3, USER2_DN)
 
 
+    # Bind as DM again, change policy
+    log.info("Bind as %s" % DN_DM)
+    topology.standalone.simple_bind_s(DN_DM, PASSWORD)
+    set_global_pwpolicy(topology, 3, 30, 9)
+
+    # change the user password, then check again.
+    log.info("Bind as %s" % USER2_DN)
+    topology.standalone.simple_bind_s(USER2_DN, USER_PW)
+
+    newpasswd = USER_PW + '2'
+    update_passwd(topology, USER2_DN, USER_PW, newpasswd)
+
+    log.info("Re-bind as %s with new password" % USER2_DN)
+    topology.standalone.simple_bind_s(USER2_DN, newpasswd)
+
+    ## This tests if we update the shadow values on password change.
+    log.info('Search entry %s' % USER2_DN)
+    entry = topology.standalone.getEntry(USER2_DN, ldap.SCOPE_BASE, "(objectclass=*)")
+
+    # passwordMinAge -- 1 day
+    check_shadow_attr_value(entry, 'shadowMin', 3, USER2_DN)
+
+    # passwordMaxAge -- 10 days
+    check_shadow_attr_value(entry, 'shadowMax', 30, USER2_DN)
+
+    # passwordWarning -- 3 days
+    check_shadow_attr_value(entry, 'shadowWarning', 9, USER2_DN)
+
     log.info("Check shadowAccount with global policy was successfully verified.")
     log.info("Check shadowAccount with global policy was successfully verified.")
 
 
 
 
@@ -266,8 +331,9 @@ def test_ticket548_test_subtree_policy(topology):
 
 
     log.info("Bind as %s" % DN_DM)
     log.info("Bind as %s" % DN_DM)
     topology.standalone.simple_bind_s(DN_DM, PASSWORD)
     topology.standalone.simple_bind_s(DN_DM, PASSWORD)
+    # Check the global policy values
 
 
-    set_subtree_pwpolicy(topology)
+    set_subtree_pwpolicy(topology, 2, 20, 6)
 
 
     log.info('Add an entry' + USER3_DN)
     log.info('Add an entry' + USER3_DN)
     try:
     try:
@@ -276,7 +342,7 @@ def test_ticket548_test_subtree_policy(topology):
                                      'cn': 'user 3',
                                      'cn': 'user 3',
                                      'uid': 'user3',
                                      'uid': 'user3',
                                      'givenname': 'user',
                                      'givenname': 'user',
-                                     'mail': 'user3@example.com',
+                                     'mail': 'user3@' + DEFAULT_SUFFIX,
                                      'userpassword': USER_PW})))
                                      'userpassword': USER_PW})))
     except ldap.LDAPError as e:
     except ldap.LDAPError as e:
         log.fatal('test_ticket548: Failed to add user' + USER3_DN + ': error ' + e.message['desc'])
         log.fatal('test_ticket548: Failed to add user' + USER3_DN + ': error ' + e.message['desc'])
@@ -312,6 +378,12 @@ def test_ticket548_test_subtree_policy(topology):
     log.info("Bind as %s and updating the password with a new one" % USER3_DN)
     log.info("Bind as %s and updating the password with a new one" % USER3_DN)
     topology.standalone.simple_bind_s(USER3_DN, USER_PW)
     topology.standalone.simple_bind_s(USER3_DN, USER_PW)
 
 
+    # Bind as DM again, change policy
+    log.info("Bind as %s" % DN_DM)
+    topology.standalone.simple_bind_s(DN_DM, PASSWORD)
+
+    set_subtree_pwpolicy(topology, 4, 40, 12)
+
     newpasswd = USER_PW + '0'
     newpasswd = USER_PW + '0'
     update_passwd(topology, USER3_DN, USER_PW, newpasswd)
     update_passwd(topology, USER3_DN, USER_PW, newpasswd)
 
 
@@ -329,6 +401,19 @@ def test_ticket548_test_subtree_policy(topology):
     log.info('Expecting shadowLastChange %d once userPassword is updated', edate)
     log.info('Expecting shadowLastChange %d once userPassword is updated', edate)
     check_shadow_attr_value(entry2, 'shadowLastChange', edate, USER3_DN)
     check_shadow_attr_value(entry2, 'shadowLastChange', edate, USER3_DN)
 
 
+    log.info('Search entry %s' % USER3_DN)
+    entry = topology.standalone.getEntry(USER3_DN, ldap.SCOPE_BASE, "(objectclass=*)")
+    check_shadow_attr_value(entry, 'shadowLastChange', edate, USER3_DN)
+
+    # passwordMinAge -- 1 day
+    check_shadow_attr_value(entry, 'shadowMin', 4, USER3_DN)
+
+    # passwordMaxAge -- 10 days
+    check_shadow_attr_value(entry, 'shadowMax', 40, USER3_DN)
+
+    # passwordWarning -- 3 days
+    check_shadow_attr_value(entry, 'shadowWarning', 12, USER3_DN)
+
     log.info("Check shadowAccount with subtree level policy was successfully verified.")
     log.info("Check shadowAccount with subtree level policy was successfully verified.")