|
|
dc8c34 |
From 056d9a6e679696422b1fa686d03a60657b77565b Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
dc8c34 |
Date: Mon, 5 Jan 2015 16:56:09 -0500
|
|
|
dc8c34 |
Subject: [PATCH 287/305] Ticket 47980 - Nested COS definitions can be
|
|
|
dc8c34 |
incorrectly processed
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Bug Description: The COS cache attribute index gets incorrectly sorted
|
|
|
dc8c34 |
and results in unexpected COS values being applied to
|
|
|
dc8c34 |
an entry.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Fix Description: The sorting method for comparing the target tree does
|
|
|
dc8c34 |
not work as indended, but we don't need to sort by the
|
|
|
dc8c34 |
target tree if the cos attributes are the same, as the
|
|
|
dc8c34 |
list is already in the proper tree order as returned by
|
|
|
dc8c34 |
the internal search. The fix was just to remove the
|
|
|
dc8c34 |
target tree comparison from the qsort compare function.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://fedorahosted.org/389/ticket/47980
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Reviewed by: nhosoi(Thanks!)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
(cherry picked from commit 987580d6fb42e358d84539a78879ae9a00393bd1)
|
|
|
dc8c34 |
(cherry picked from commit 322d7d0dabb0b3cf52a0c544f0e4fb09e9af9080)
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
dirsrvtests/tickets/ticket47980_test.py | 710 ++++++++++++++++++++++++++++++++
|
|
|
dc8c34 |
ldap/servers/plugins/cos/cos_cache.c | 20 +-
|
|
|
dc8c34 |
2 files changed, 717 insertions(+), 13 deletions(-)
|
|
|
dc8c34 |
create mode 100644 dirsrvtests/tickets/ticket47980_test.py
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/dirsrvtests/tickets/ticket47980_test.py b/dirsrvtests/tickets/ticket47980_test.py
|
|
|
dc8c34 |
new file mode 100644
|
|
|
dc8c34 |
index 0000000..406d72d
|
|
|
dc8c34 |
--- /dev/null
|
|
|
dc8c34 |
+++ b/dirsrvtests/tickets/ticket47980_test.py
|
|
|
dc8c34 |
@@ -0,0 +1,710 @@
|
|
|
dc8c34 |
+import os
|
|
|
dc8c34 |
+import sys
|
|
|
dc8c34 |
+import time
|
|
|
dc8c34 |
+import ldap
|
|
|
dc8c34 |
+import ldap.sasl
|
|
|
dc8c34 |
+import logging
|
|
|
dc8c34 |
+import socket
|
|
|
dc8c34 |
+import pytest
|
|
|
dc8c34 |
+from lib389 import DirSrv, Entry, tools, tasks
|
|
|
dc8c34 |
+from lib389.tools import DirSrvTools
|
|
|
dc8c34 |
+from lib389._constants import *
|
|
|
dc8c34 |
+from lib389.properties import *
|
|
|
dc8c34 |
+from lib389.tasks import *
|
|
|
dc8c34 |
+from constants import *
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+log = logging.getLogger(__name__)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+installation_prefix = None
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+BRANCH1 = 'ou=level1,' + DEFAULT_SUFFIX
|
|
|
dc8c34 |
+BRANCH2 = 'ou=level2,ou=level1,' + DEFAULT_SUFFIX
|
|
|
dc8c34 |
+BRANCH3 = 'ou=level3,ou=level2,ou=level1,' + DEFAULT_SUFFIX
|
|
|
dc8c34 |
+BRANCH4 = 'ou=people,' + DEFAULT_SUFFIX
|
|
|
dc8c34 |
+BRANCH5 = 'ou=lower,ou=people,' + DEFAULT_SUFFIX
|
|
|
dc8c34 |
+BRANCH6 = 'ou=lower,ou=lower,ou=people,' + DEFAULT_SUFFIX
|
|
|
dc8c34 |
+USER1_DN = 'uid=user1,%s' % (BRANCH1)
|
|
|
dc8c34 |
+USER2_DN = 'uid=user2,%s' % (BRANCH2)
|
|
|
dc8c34 |
+USER3_DN = 'uid=user3,%s' % (BRANCH3)
|
|
|
dc8c34 |
+USER4_DN = 'uid=user4,%s' % (BRANCH4)
|
|
|
dc8c34 |
+USER5_DN = 'uid=user5,%s' % (BRANCH5)
|
|
|
dc8c34 |
+USER6_DN = 'uid=user6,%s' % (BRANCH6)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+BRANCH1_CONTAINER = 'cn=nsPwPolicyContainer,ou=level1,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH1_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cou\3Dlevel1\2Cdc\3Dexample\2Cdc\3Dcom,' + \
|
|
|
dc8c34 |
+ 'cn=nsPwPolicyContainer,ou=level1,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH1_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cou\3Dlevel1\2Cdc\3Dexample\2Cdc\3Dcom,' + \
|
|
|
dc8c34 |
+ 'cn=nsPwPolicyContainer,ou=level1,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH1_COS_DEF = 'cn=nsPwPolicy_CoS,ou=level1,dc=example,dc=com'
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+BRANCH2_CONTAINER = 'cn=nsPwPolicyContainer,ou=level2,ou=level1,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH2_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cou\3Dlevel2\2Cou\3Dlevel1\2Cdc\3Dexample\2Cdc\3Dcom,' + \
|
|
|
dc8c34 |
+ 'cn=nsPwPolicyContainer,ou=level2,ou=level1,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH2_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cou\3Dlevel2\2Cou\3Dlevel1\2Cdc\3Dexample\2Cdc\3Dcom,' + \
|
|
|
dc8c34 |
+ 'cn=nsPwPolicyContainer,ou=level2,ou=level1,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH2_COS_DEF = 'cn=nsPwPolicy_CoS,ou=level2,ou=level1,dc=example,dc=com'
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+BRANCH3_CONTAINER = 'cn=nsPwPolicyContainer,ou=level3,ou=level2,ou=level1,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH3_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cou\3Dlevel3\2Cou\3Dlevel2\2Cou\3Dlevel1\2Cdc\3Dexample\2Cdc\3Dcom,' + \
|
|
|
dc8c34 |
+ 'cn=nsPwPolicyContainer,ou=level3,ou=level2,ou=level1,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH3_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cou\3Dlevel3\2Cou\3Dlevel2\2Cou\3Dlevel1\2Cdc\3Dexample\2Cdc\3Dcom,' + \
|
|
|
dc8c34 |
+ 'cn=nsPwPolicyContainer,ou=level3,ou=level2,ou=level1,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH3_COS_DEF = 'cn=nsPwPolicy_CoS,ou=level3,ou=level2,ou=level1,dc=example,dc=com'
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+BRANCH4_CONTAINER = 'cn=nsPwPolicyContainer,ou=people,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH4_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cou\3DPeople\2Cdc\3Dexample\2Cdc\3Dcom,' + \
|
|
|
dc8c34 |
+ 'cn=nsPwPolicyContainer,ou=People,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH4_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cou\3DPeople\2Cdc\3Dexample\2Cdc\3Dcom,' + \
|
|
|
dc8c34 |
+ 'cn=nsPwPolicyContainer,ou=People,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH4_COS_DEF = 'cn=nsPwPolicy_CoS,ou=people,dc=example,dc=com'
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+BRANCH5_CONTAINER = 'cn=nsPwPolicyContainer,ou=lower,ou=people,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH5_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cou\3Dlower\2Cou\3DPeople\2Cdc\3Dexample\2Cdc\3Dcom,' + \
|
|
|
dc8c34 |
+ 'cn=nsPwPolicyContainer,ou=lower,ou=People,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH5_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cou\3Dlower\2Cou\3DPeople\2Cdc\3Dexample\2Cdc\3Dcom,' + \
|
|
|
dc8c34 |
+ 'cn=nsPwPolicyContainer,ou=lower,ou=People,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH5_COS_DEF = 'cn=nsPwPolicy_CoS,ou=lower,ou=People,dc=example,dc=com'
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+BRANCH6_CONTAINER = 'cn=nsPwPolicyContainer,ou=lower,ou=lower,ou=People,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH6_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cou\3Dlower\2Cou\3Dlower\2Cou\3DPeople\2Cdc\3Dexample\2Cdc\3Dcom,' + \
|
|
|
dc8c34 |
+ 'cn=nsPwPolicyContainer,ou=lower,ou=lower,ou=People,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH6_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cou\3Dlower\2Cou\3Dlower\2Cou\3DPeople\2Cdc\3Dexample\2Cdc\3Dcom,' + \
|
|
|
dc8c34 |
+ 'cn=nsPwPolicyContainer,ou=lower,ou=lower,ou=People,dc=example,dc=com'
|
|
|
dc8c34 |
+BRANCH6_COS_DEF = 'cn=nsPwPolicy_CoS,ou=lower,ou=lower,ou=People,dc=example,dc=com'
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+class TopologyStandalone(object):
|
|
|
dc8c34 |
+ def __init__(self, standalone):
|
|
|
dc8c34 |
+ standalone.open()
|
|
|
dc8c34 |
+ self.standalone = standalone
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+@pytest.fixture(scope="module")
|
|
|
dc8c34 |
+def topology(request):
|
|
|
dc8c34 |
+ '''
|
|
|
dc8c34 |
+ This fixture is used to standalone topology for the 'module'.
|
|
|
dc8c34 |
+ At the beginning, It may exists a standalone instance.
|
|
|
dc8c34 |
+ It may also exists a backup for the standalone instance.
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ Principle:
|
|
|
dc8c34 |
+ If standalone instance exists:
|
|
|
dc8c34 |
+ restart it
|
|
|
dc8c34 |
+ If backup of standalone exists:
|
|
|
dc8c34 |
+ create/rebind to standalone
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ restore standalone instance from backup
|
|
|
dc8c34 |
+ else:
|
|
|
dc8c34 |
+ Cleanup everything
|
|
|
dc8c34 |
+ remove instance
|
|
|
dc8c34 |
+ remove backup
|
|
|
dc8c34 |
+ Create instance
|
|
|
dc8c34 |
+ Create backup
|
|
|
dc8c34 |
+ '''
|
|
|
dc8c34 |
+ global installation_prefix
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if installation_prefix:
|
|
|
dc8c34 |
+ args_instance[SER_DEPLOYED_DIR] = installation_prefix
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ standalone = DirSrv(verbose=False)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Args for the standalone instance
|
|
|
dc8c34 |
+ args_instance[SER_HOST] = HOST_STANDALONE
|
|
|
dc8c34 |
+ args_instance[SER_PORT] = PORT_STANDALONE
|
|
|
dc8c34 |
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
|
|
|
dc8c34 |
+ args_standalone = args_instance.copy()
|
|
|
dc8c34 |
+ standalone.allocate(args_standalone)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Get the status of the backups
|
|
|
dc8c34 |
+ backup_standalone = standalone.checkBackupFS()
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Get the status of the instance and restart it if it exists
|
|
|
dc8c34 |
+ instance_standalone = standalone.exists()
|
|
|
dc8c34 |
+ if instance_standalone:
|
|
|
dc8c34 |
+ # assuming the instance is already stopped, just wait 5 sec max
|
|
|
dc8c34 |
+ standalone.stop(timeout=5)
|
|
|
dc8c34 |
+ standalone.start(timeout=10)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if backup_standalone:
|
|
|
dc8c34 |
+ # The backup exist, assuming it is correct
|
|
|
dc8c34 |
+ # we just re-init the instance with it
|
|
|
dc8c34 |
+ if not instance_standalone:
|
|
|
dc8c34 |
+ standalone.create()
|
|
|
dc8c34 |
+ # Used to retrieve configuration information (dbdir, confdir...)
|
|
|
dc8c34 |
+ standalone.open()
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # restore standalone instance from backup
|
|
|
dc8c34 |
+ standalone.stop(timeout=10)
|
|
|
dc8c34 |
+ standalone.restoreFS(backup_standalone)
|
|
|
dc8c34 |
+ standalone.start(timeout=10)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ else:
|
|
|
dc8c34 |
+ # We should be here only in two conditions
|
|
|
dc8c34 |
+ # - This is the first time a test involve standalone instance
|
|
|
dc8c34 |
+ # - Something weird happened (instance/backup destroyed)
|
|
|
dc8c34 |
+ # so we discard everything and recreate all
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Remove the backup. So even if we have a specific backup file
|
|
|
dc8c34 |
+ # (e.g backup_standalone) we clear backup that an instance may have created
|
|
|
dc8c34 |
+ if backup_standalone:
|
|
|
dc8c34 |
+ standalone.clearBackupFS()
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Remove the instance
|
|
|
dc8c34 |
+ if instance_standalone:
|
|
|
dc8c34 |
+ standalone.delete()
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Create the instance
|
|
|
dc8c34 |
+ standalone.create()
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Used to retrieve configuration information (dbdir, confdir...)
|
|
|
dc8c34 |
+ standalone.open()
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Time to create the backups
|
|
|
dc8c34 |
+ standalone.stop(timeout=10)
|
|
|
dc8c34 |
+ standalone.backupfile = standalone.backupFS()
|
|
|
dc8c34 |
+ standalone.start(timeout=10)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # clear the tmp directory
|
|
|
dc8c34 |
+ standalone.clearTmpDir(__file__)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Here we have standalone instance up and running
|
|
|
dc8c34 |
+ # Either coming from a backup recovery
|
|
|
dc8c34 |
+ # or from a fresh (re)init
|
|
|
dc8c34 |
+ # Time to return the topology
|
|
|
dc8c34 |
+ return TopologyStandalone(standalone)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+def test_ticket47980(topology):
|
|
|
dc8c34 |
+ """
|
|
|
dc8c34 |
+ Multiple COS pointer definitions that use the same attribute are not correctly ordered.
|
|
|
dc8c34 |
+ The cos plugin was incorrectly sorting the attribute indexes based on subtree, which lead
|
|
|
dc8c34 |
+ to the wrong cos attribute value being applied to the entry.
|
|
|
dc8c34 |
+ """
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ log.info('Testing Ticket 47980 - Testing multiple nested COS pointer definitions are processed correctly')
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add our nested branches
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH1, {
|
|
|
dc8c34 |
+ 'objectclass': 'top extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'ou': 'level1'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add level1: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH2, {
|
|
|
dc8c34 |
+ 'objectclass': 'top extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'ou': 'level2'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add level2: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH3, {
|
|
|
dc8c34 |
+ 'objectclass': 'top extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'uid': 'level3'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add level3: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # People branch, might already exist
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH4, {
|
|
|
dc8c34 |
+ 'objectclass': 'top extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'ou': 'level4'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.ALREADY_EXISTS:
|
|
|
dc8c34 |
+ pass
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add level4: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH5, {
|
|
|
dc8c34 |
+ 'objectclass': 'top extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'ou': 'level5'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add level5: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH6, {
|
|
|
dc8c34 |
+ 'objectclass': 'top extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'uid': 'level6'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add level6: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add users to each branch
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((USER1_DN, {
|
|
|
dc8c34 |
+ 'objectclass': 'top extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'uid': 'user1'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add user1: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((USER2_DN, {
|
|
|
dc8c34 |
+ 'objectclass': 'top extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'uid': 'user2'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add user2: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((USER3_DN, {
|
|
|
dc8c34 |
+ 'objectclass': 'top extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'uid': 'user3'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add user3: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((USER4_DN, {
|
|
|
dc8c34 |
+ 'objectclass': 'top extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'uid': 'user4'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add user4: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((USER5_DN, {
|
|
|
dc8c34 |
+ 'objectclass': 'top extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'uid': 'user5'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add user5: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((USER6_DN, {
|
|
|
dc8c34 |
+ 'objectclass': 'top extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'uid': 'user6'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add user6: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Enable password policy
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', 'on')])
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to set pwpolicy-local: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Add subtree policy to branch 1
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Add the container
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH1_CONTAINER, {
|
|
|
dc8c34 |
+ 'objectclass': 'top nsContainer'.split(),
|
|
|
dc8c34 |
+ 'cn': 'nsPwPolicyContainer'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add subtree container for level1: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the password policy subentry
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH1_PWP, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=level1,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'passwordMustChange': 'off',
|
|
|
dc8c34 |
+ 'passwordExp': 'off',
|
|
|
dc8c34 |
+ 'passwordHistory': 'off',
|
|
|
dc8c34 |
+ 'passwordMinAge': '0',
|
|
|
dc8c34 |
+ 'passwordChange': 'off',
|
|
|
dc8c34 |
+ 'passwordStorageScheme': 'ssha'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add passwordpolicy for level1: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the COS template
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH1_COS_TMPL, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=level1,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'cosPriority': '1',
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwTemplateEntry,ou=level1,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'pwdpolicysubentry': BRANCH1_PWP
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add COS template for level1: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the COS definition
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH1_COS_DEF, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=level1,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'costemplatedn': BRANCH1_COS_TMPL,
|
|
|
dc8c34 |
+ 'cosAttribute': 'pwdpolicysubentry default operational-default'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add COS def for level1: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Add subtree policy to branch 2
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Add the container
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH2_CONTAINER, {
|
|
|
dc8c34 |
+ 'objectclass': 'top nsContainer'.split(),
|
|
|
dc8c34 |
+ 'cn': 'nsPwPolicyContainer'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add subtree container for level2: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the password policy subentry
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH2_PWP, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=level2,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'passwordMustChange': 'off',
|
|
|
dc8c34 |
+ 'passwordExp': 'off',
|
|
|
dc8c34 |
+ 'passwordHistory': 'off',
|
|
|
dc8c34 |
+ 'passwordMinAge': '0',
|
|
|
dc8c34 |
+ 'passwordChange': 'off',
|
|
|
dc8c34 |
+ 'passwordStorageScheme': 'ssha'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add passwordpolicy for level2: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the COS template
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH2_COS_TMPL, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=level2,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'cosPriority': '1',
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwTemplateEntry,ou=level2,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'pwdpolicysubentry': BRANCH2_PWP
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add COS template for level2: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the COS definition
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH2_COS_DEF, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=level2,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'costemplatedn': BRANCH2_COS_TMPL,
|
|
|
dc8c34 |
+ 'cosAttribute': 'pwdpolicysubentry default operational-default'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add COS def for level2: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Add subtree policy to branch 3
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Add the container
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH3_CONTAINER, {
|
|
|
dc8c34 |
+ 'objectclass': 'top nsContainer'.split(),
|
|
|
dc8c34 |
+ 'cn': 'nsPwPolicyContainer'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add subtree container for level3: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the password policy subentry
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH3_PWP, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=level3,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'passwordMustChange': 'off',
|
|
|
dc8c34 |
+ 'passwordExp': 'off',
|
|
|
dc8c34 |
+ 'passwordHistory': 'off',
|
|
|
dc8c34 |
+ 'passwordMinAge': '0',
|
|
|
dc8c34 |
+ 'passwordChange': 'off',
|
|
|
dc8c34 |
+ 'passwordStorageScheme': 'ssha'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add passwordpolicy for level3: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the COS template
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH3_COS_TMPL, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=level3,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'cosPriority': '1',
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwTemplateEntry,ou=level3,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'pwdpolicysubentry': BRANCH3_PWP
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add COS template for level3: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the COS definition
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH3_COS_DEF, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=level3,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'costemplatedn': BRANCH3_COS_TMPL,
|
|
|
dc8c34 |
+ 'cosAttribute': 'pwdpolicysubentry default operational-default'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add COS def for level3: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Add subtree policy to branch 4
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Add the container
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH4_CONTAINER, {
|
|
|
dc8c34 |
+ 'objectclass': 'top nsContainer'.split(),
|
|
|
dc8c34 |
+ 'cn': 'nsPwPolicyContainer'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add subtree container for level3: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the password policy subentry
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH4_PWP, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'passwordMustChange': 'off',
|
|
|
dc8c34 |
+ 'passwordExp': 'off',
|
|
|
dc8c34 |
+ 'passwordHistory': 'off',
|
|
|
dc8c34 |
+ 'passwordMinAge': '0',
|
|
|
dc8c34 |
+ 'passwordChange': 'off',
|
|
|
dc8c34 |
+ 'passwordStorageScheme': 'ssha'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add passwordpolicy for branch4: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the COS template
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH4_COS_TMPL, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'cosPriority': '1',
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwTemplateEntry,ou=people,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'pwdpolicysubentry': BRANCH4_PWP
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add COS template for level3: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the COS definition
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH4_COS_DEF, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'costemplatedn': BRANCH4_COS_TMPL,
|
|
|
dc8c34 |
+ 'cosAttribute': 'pwdpolicysubentry default operational-default'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add COS def for branch4: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Add subtree policy to branch 5
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Add the container
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH5_CONTAINER, {
|
|
|
dc8c34 |
+ 'objectclass': 'top nsContainer'.split(),
|
|
|
dc8c34 |
+ 'cn': 'nsPwPolicyContainer'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add subtree container for branch5: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the password policy subentry
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH5_PWP, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=people,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'passwordMustChange': 'off',
|
|
|
dc8c34 |
+ 'passwordExp': 'off',
|
|
|
dc8c34 |
+ 'passwordHistory': 'off',
|
|
|
dc8c34 |
+ 'passwordMinAge': '0',
|
|
|
dc8c34 |
+ 'passwordChange': 'off',
|
|
|
dc8c34 |
+ 'passwordStorageScheme': 'ssha'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add passwordpolicy for branch5: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the COS template
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH5_COS_TMPL, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=people,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'cosPriority': '1',
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwTemplateEntry,ou=lower,ou=people,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'pwdpolicysubentry': BRANCH5_PWP
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add COS template for branch5: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the COS definition
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH5_COS_DEF, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=people,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'costemplatedn': BRANCH5_COS_TMPL,
|
|
|
dc8c34 |
+ 'cosAttribute': 'pwdpolicysubentry default operational-default'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add COS def for level3: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Add subtree policy to branch 6
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Add the container
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH6_CONTAINER, {
|
|
|
dc8c34 |
+ 'objectclass': 'top nsContainer'.split(),
|
|
|
dc8c34 |
+ 'cn': 'nsPwPolicyContainer'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add subtree container for branch6: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the password policy subentry
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH6_PWP, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=level3,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'passwordMustChange': 'off',
|
|
|
dc8c34 |
+ 'passwordExp': 'off',
|
|
|
dc8c34 |
+ 'passwordHistory': 'off',
|
|
|
dc8c34 |
+ 'passwordMinAge': '0',
|
|
|
dc8c34 |
+ 'passwordChange': 'off',
|
|
|
dc8c34 |
+ 'passwordStorageScheme': 'ssha'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add passwordpolicy for branch6: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the COS template
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH6_COS_TMPL, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=lower,ou=people,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'cosPriority': '1',
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwTemplateEntry,ou=lower,ou=lower,ou=people,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'pwdpolicysubentry': BRANCH6_PWP
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add COS template for branch6: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # Add the COS definition
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ topology.standalone.add_s(Entry((BRANCH6_COS_DEF, {
|
|
|
dc8c34 |
+ 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
|
|
|
dc8c34 |
+ 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=lower,ou=people,dc=example,dc=com',
|
|
|
dc8c34 |
+ 'costemplatedn': BRANCH6_COS_TMPL,
|
|
|
dc8c34 |
+ 'cosAttribute': 'pwdpolicysubentry default operational-default'
|
|
|
dc8c34 |
+ })))
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.error('Failed to add COS def for branch6: error ' + e.message['desc'])
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ # Now check that each user has its expected passwordPolicy subentry
|
|
|
dc8c34 |
+ #
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ entries = topology.standalone.search_s(USER1_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
|
|
|
dc8c34 |
+ if not entries[0].hasValue('pwdpolicysubentry', BRANCH1_PWP):
|
|
|
dc8c34 |
+ log.fatal('User %s does not have expected pwdpolicysubentry!')
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.fatal('Unable to search for entry %s: error %s' % (USER1_DN, e.message['desc']))
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ entries = topology.standalone.search_s(USER2_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
|
|
|
dc8c34 |
+ if not entries[0].hasValue('pwdpolicysubentry', BRANCH2_PWP):
|
|
|
dc8c34 |
+ log.fatal('User %s does not have expected pwdpolicysubentry!' % USER2_DN)
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.fatal('Unable to search for entry %s: error %s' % (USER2_DN, e.message['desc']))
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ entries = topology.standalone.search_s(USER3_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
|
|
|
dc8c34 |
+ if not entries[0].hasValue('pwdpolicysubentry', BRANCH3_PWP):
|
|
|
dc8c34 |
+ log.fatal('User %s does not have expected pwdpolicysubentry!' % USER3_DN)
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.fatal('Unable to search for entry %s: error %s' % (USER3_DN, e.message['desc']))
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ entries = topology.standalone.search_s(USER4_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
|
|
|
dc8c34 |
+ if not entries[0].hasValue('pwdpolicysubentry', BRANCH4_PWP):
|
|
|
dc8c34 |
+ log.fatal('User %s does not have expected pwdpolicysubentry!' % USER4_DN)
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.fatal('Unable to search for entry %s: error %s' % (USER4_DN, e.message['desc']))
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ entries = topology.standalone.search_s(USER5_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
|
|
|
dc8c34 |
+ if not entries[0].hasValue('pwdpolicysubentry', BRANCH5_PWP):
|
|
|
dc8c34 |
+ log.fatal('User %s does not have expected pwdpolicysubentry!' % USER5_DN)
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.fatal('Unable to search for entry %s: error %s' % (USER5_DN, e.message['desc']))
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ try:
|
|
|
dc8c34 |
+ entries = topology.standalone.search_s(USER6_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
|
|
|
dc8c34 |
+ if not entries[0].hasValue('pwdpolicysubentry', BRANCH6_PWP):
|
|
|
dc8c34 |
+ log.fatal('User %s does not have expected pwdpolicysubentry!' % USER6_DN)
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+ except ldap.LDAPError, e:
|
|
|
dc8c34 |
+ log.fatal('Unable to search for entry %s: error %s' % (USER6_DN, e.message['desc']))
|
|
|
dc8c34 |
+ assert False
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ # If we got here the test passed
|
|
|
dc8c34 |
+ log.info('Test PASSED')
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+def test_ticket47980_final(topology):
|
|
|
dc8c34 |
+ topology.standalone.stop(timeout=10)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+def run_isolated():
|
|
|
dc8c34 |
+ '''
|
|
|
dc8c34 |
+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
|
|
|
dc8c34 |
+ To run isolated without py.test, you need to
|
|
|
dc8c34 |
+ - edit this file and comment '@pytest.fixture' line before 'topology' function.
|
|
|
dc8c34 |
+ - set the installation prefix
|
|
|
dc8c34 |
+ - run this program
|
|
|
dc8c34 |
+ '''
|
|
|
dc8c34 |
+ global installation_prefix
|
|
|
dc8c34 |
+ installation_prefix = None
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ topo = topology(True)
|
|
|
dc8c34 |
+ test_ticket47980(topo)
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+if __name__ == '__main__':
|
|
|
dc8c34 |
+ run_isolated()
|
|
|
dc8c34 |
\ No newline at end of file
|
|
|
dc8c34 |
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
|
|
|
dc8c34 |
index 10f475e..76cc8fd 100644
|
|
|
dc8c34 |
--- a/ldap/servers/plugins/cos/cos_cache.c
|
|
|
dc8c34 |
+++ b/ldap/servers/plugins/cos/cos_cache.c
|
|
|
dc8c34 |
@@ -3097,25 +3097,19 @@ static int cos_cache_attr_compare(const void *e1, const void *e2)
|
|
|
dc8c34 |
int com_Result;
|
|
|
dc8c34 |
cosAttributes *pAttr = (*(cosAttributes**)e1);
|
|
|
dc8c34 |
cosTemplates *pTemplate = (cosTemplates*)pAttr->pParent;
|
|
|
dc8c34 |
- cosDefinitions *pDef = (cosDefinitions*)pTemplate->pParent;
|
|
|
dc8c34 |
- cosAttrValue *pcostt = pDef->pCosTargetTree;
|
|
|
dc8c34 |
cosAttributes *pAttr1 = (*(cosAttributes**)e2);
|
|
|
dc8c34 |
cosTemplates *pTemplate1 = (cosTemplates*)pAttr1->pParent;
|
|
|
dc8c34 |
- cosDefinitions *pDef1 = (cosDefinitions*)pTemplate1->pParent;
|
|
|
dc8c34 |
- cosAttrValue *pcostt1 = pDef1->pCosTargetTree;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* Now compare the names of the attributes */
|
|
|
dc8c34 |
com_Result = slapi_utf8casecmp((unsigned char*)(*(cosAttributes**)e1)->pAttrName,(unsigned char*)(*(cosAttributes**)e2)->pAttrName);
|
|
|
dc8c34 |
+ if(0 == com_Result){
|
|
|
dc8c34 |
+ /* Now compare the cosPriorities */
|
|
|
dc8c34 |
+ com_Result = pTemplate->cosPriority - pTemplate1->cosPriority;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
if(0 == com_Result)
|
|
|
dc8c34 |
- /* Now compare the definition Dn parents */
|
|
|
dc8c34 |
- com_Result = slapi_utf8casecmp((unsigned char*)pcostt1->val,(unsigned char*)pcostt->val);
|
|
|
dc8c34 |
- if(0 == com_Result)
|
|
|
dc8c34 |
- /* Now compare the cosPririoties */
|
|
|
dc8c34 |
- com_Result = pTemplate->cosPriority - pTemplate1->cosPriority;
|
|
|
dc8c34 |
- /* Now compare the prirority */
|
|
|
dc8c34 |
- if(0 == com_Result)
|
|
|
dc8c34 |
- return -1;
|
|
|
dc8c34 |
- return com_Result;
|
|
|
dc8c34 |
+ return -1;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ return com_Result;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
static int cos_cache_string_compare(const void *e1, const void *e2)
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
1.9.3
|
|
|
dc8c34 |
|