|
|
96373c |
From bb2d74ebe9d725b47e35893a2d8c8bd713d6dd4b Mon Sep 17 00:00:00 2001
|
|
|
6405db |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
6405db |
Date: Tue, 3 Oct 2017 17:22:37 -0400
|
|
|
6405db |
Subject: [PATCH] Ticket 49389 - unable to retrieve specific cosAttribute when
|
|
|
6405db |
subtree password policy is configured
|
|
|
6405db |
|
|
|
6405db |
Bug Description: If indirect cos is being used and a subtree password
|
|
|
6405db |
policy is added, th orignal COS attributes aren't always
|
|
|
6405db |
returned. The issue is that when the subtree password
|
|
|
6405db |
policy attribute was encountered during the virtual
|
|
|
6405db |
attribute processing it set a flag that said the attribute
|
|
|
6405db |
was operational (which is correct for the password policy
|
|
|
6405db |
attr: pwdpolicysubentry).
|
|
|
6405db |
|
|
|
6405db |
However, this flag was accidentally carried over to the
|
|
|
6405db |
following virtual attributes that were being processed.
|
|
|
6405db |
Which caused those attributes to be seen as operational
|
|
|
6405db |
which is why it was no longer being returned to the client.
|
|
|
6405db |
|
|
|
6405db |
Fix Description: Reset the prop flags before processing the next COS attribute
|
|
|
6405db |
|
|
|
6405db |
https://pagure.io/389-ds-base/issue/49389
|
|
|
6405db |
|
|
|
6405db |
Reviewed by: firstyear(Thanks!)
|
|
|
6405db |
|
|
|
6405db |
(cherry picked from commit 0953e6011368bc29300990e9493ac13e5aba9586)
|
|
|
6405db |
---
|
|
|
6405db |
dirsrvtests/tests/suites/cos/__init__.py | 0
|
|
|
6405db |
dirsrvtests/tests/suites/cos/indirect_cos_test.py | 191 ++++++++++++++++++++++
|
|
|
96373c |
ldap/servers/plugins/cos/cos_cache.c | 2 +-
|
|
|
96373c |
3 files changed, 192 insertions(+), 1 deletion(-)
|
|
|
6405db |
create mode 100644 dirsrvtests/tests/suites/cos/__init__.py
|
|
|
6405db |
create mode 100644 dirsrvtests/tests/suites/cos/indirect_cos_test.py
|
|
|
6405db |
|
|
|
6405db |
diff --git a/dirsrvtests/tests/suites/cos/__init__.py b/dirsrvtests/tests/suites/cos/__init__.py
|
|
|
6405db |
new file mode 100644
|
|
|
96373c |
index 000000000..e69de29bb
|
|
|
6405db |
diff --git a/dirsrvtests/tests/suites/cos/indirect_cos_test.py b/dirsrvtests/tests/suites/cos/indirect_cos_test.py
|
|
|
6405db |
new file mode 100644
|
|
|
96373c |
index 000000000..1aac6b8ed
|
|
|
6405db |
--- /dev/null
|
|
|
6405db |
+++ b/dirsrvtests/tests/suites/cos/indirect_cos_test.py
|
|
|
6405db |
@@ -0,0 +1,191 @@
|
|
|
6405db |
+import logging
|
|
|
6405db |
+import pytest
|
|
|
6405db |
+import os
|
|
|
6405db |
+import ldap
|
|
|
6405db |
+import time
|
|
|
6405db |
+import subprocess
|
|
|
6405db |
+
|
|
|
6405db |
+from lib389 import Entry
|
|
|
6405db |
+from lib389.idm.user import UserAccounts
|
|
|
6405db |
+from lib389.topologies import topology_st as topo
|
|
|
6405db |
+from lib389._constants import (DEFAULT_SUFFIX, DN_DM, PASSWORD, HOST_STANDALONE,
|
|
|
6405db |
+ SERVERID_STANDALONE, PORT_STANDALONE)
|
|
|
6405db |
+
|
|
|
6405db |
+
|
|
|
6405db |
+DEBUGGING = os.getenv("DEBUGGING", default=False)
|
|
|
6405db |
+if DEBUGGING:
|
|
|
6405db |
+ logging.getLogger(__name__).setLevel(logging.DEBUG)
|
|
|
6405db |
+else:
|
|
|
6405db |
+ logging.getLogger(__name__).setLevel(logging.INFO)
|
|
|
6405db |
+log = logging.getLogger(__name__)
|
|
|
6405db |
+
|
|
|
6405db |
+TEST_USER_DN = "uid=test_user,ou=people,dc=example,dc=com"
|
|
|
6405db |
+OU_PEOPLE = 'ou=people,{}'.format(DEFAULT_SUFFIX)
|
|
|
6405db |
+
|
|
|
6405db |
+PW_POLICY_CONT_PEOPLE = 'cn="cn=nsPwPolicyEntry,' \
|
|
|
6405db |
+ 'ou=people,dc=example,dc=com",' \
|
|
|
6405db |
+ 'cn=nsPwPolicyContainer,ou=people,dc=example,dc=com'
|
|
|
6405db |
+
|
|
|
6405db |
+PW_POLICY_CONT_PEOPLE2 = 'cn="cn=nsPwPolicyEntry,' \
|
|
|
6405db |
+ 'dc=example,dc=com",' \
|
|
|
6405db |
+ 'cn=nsPwPolicyContainerdc=example,dc=com'
|
|
|
6405db |
+
|
|
|
6405db |
+
|
|
|
6405db |
+def check_user(inst):
|
|
|
6405db |
+ """Search the test user and make sure it has the execpted attrs
|
|
|
6405db |
+ """
|
|
|
6405db |
+ try:
|
|
|
6405db |
+ entries = inst.search_s('dc=example,dc=com', ldap.SCOPE_SUBTREE, "uid=test_user")
|
|
|
6405db |
+ log.debug('user: \n' + str(entries[0]))
|
|
|
6405db |
+ assert entries[0].hasAttr('ou'), "Entry is missing ou cos attribute"
|
|
|
6405db |
+ assert entries[0].hasAttr('x-department'), "Entry is missing description cos attribute"
|
|
|
6405db |
+ assert entries[0].hasAttr('x-en-ou'), "Entry is missing givenname cos attribute"
|
|
|
6405db |
+ except ldap.LDAPError as e:
|
|
|
6405db |
+ log.fatal('Failed to search for user: ' + str(e))
|
|
|
6405db |
+ raise e
|
|
|
6405db |
+
|
|
|
6405db |
+
|
|
|
6405db |
+def setup_subtree_policy(topo):
|
|
|
6405db |
+ """Set up subtree password policy
|
|
|
6405db |
+ """
|
|
|
6405db |
+ try:
|
|
|
6405db |
+ topo.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE,
|
|
|
6405db |
+ 'nsslapd-pwpolicy-local',
|
|
|
6405db |
+ 'on')])
|
|
|
6405db |
+ except ldap.LDAPError as e:
|
|
|
6405db |
+ log.error('Failed to set fine-grained policy: error {}'.format(
|
|
|
6405db |
+ e.message['desc']))
|
|
|
6405db |
+ raise e
|
|
|
6405db |
+
|
|
|
6405db |
+ log.info('Create password policy for subtree {}'.format(OU_PEOPLE))
|
|
|
6405db |
+ try:
|
|
|
6405db |
+ subprocess.call(['%s/ns-newpwpolicy.pl' % topo.standalone.get_sbin_dir(),
|
|
|
6405db |
+ '-D', DN_DM, '-w', PASSWORD,
|
|
|
6405db |
+ '-p', str(PORT_STANDALONE), '-h', HOST_STANDALONE,
|
|
|
6405db |
+ '-S', DEFAULT_SUFFIX, '-Z', SERVERID_STANDALONE])
|
|
|
6405db |
+ except subprocess.CalledProcessError as e:
|
|
|
6405db |
+ log.error('Failed to create pw policy policy for {}: error {}'.format(
|
|
|
6405db |
+ OU_PEOPLE, e.message['desc']))
|
|
|
6405db |
+ raise e
|
|
|
6405db |
+
|
|
|
6405db |
+ log.info('Add pwdpolicysubentry attribute to {}'.format(OU_PEOPLE))
|
|
|
6405db |
+ try:
|
|
|
6405db |
+ topo.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_REPLACE,
|
|
|
6405db |
+ 'pwdpolicysubentry',
|
|
|
6405db |
+ PW_POLICY_CONT_PEOPLE2)])
|
|
|
6405db |
+ except ldap.LDAPError as e:
|
|
|
6405db |
+ log.error('Failed to pwdpolicysubentry pw policy '
|
|
|
6405db |
+ 'policy for {}: error {}'.format(OU_PEOPLE, e.message['desc']))
|
|
|
6405db |
+ raise e
|
|
|
6405db |
+ time.sleep(1)
|
|
|
6405db |
+
|
|
|
6405db |
+
|
|
|
6405db |
+def setup_indirect_cos(topo):
|
|
|
6405db |
+ """Setup indirect COS definition and template
|
|
|
6405db |
+ """
|
|
|
6405db |
+ cosDef = Entry(('cn=cosDefinition,dc=example,dc=com',
|
|
|
6405db |
+ {'objectclass': ['top', 'ldapsubentry',
|
|
|
6405db |
+ 'cossuperdefinition',
|
|
|
6405db |
+ 'cosIndirectDefinition'],
|
|
|
6405db |
+ 'cosAttribute': ['ou merge-schemes',
|
|
|
6405db |
+ 'x-department merge-schemes',
|
|
|
6405db |
+ 'x-en-ou merge-schemes'],
|
|
|
6405db |
+ 'cosIndirectSpecifier': 'seeAlso',
|
|
|
6405db |
+ 'cn': 'cosDefinition'}))
|
|
|
6405db |
+
|
|
|
6405db |
+ cosTemplate = Entry(('cn=cosTemplate,dc=example,dc=com',
|
|
|
6405db |
+ {'objectclass': ['top',
|
|
|
6405db |
+ 'extensibleObject',
|
|
|
6405db |
+ 'cosTemplate'],
|
|
|
6405db |
+ 'ou': 'My COS Org',
|
|
|
6405db |
+ 'x-department': 'My COS x-department',
|
|
|
6405db |
+ 'x-en-ou': 'my COS x-en-ou',
|
|
|
6405db |
+ 'cn': 'cosTemplate'}))
|
|
|
6405db |
+ try:
|
|
|
6405db |
+ topo.standalone.add_s(cosDef)
|
|
|
6405db |
+ topo.standalone.add_s(cosTemplate)
|
|
|
6405db |
+ except ldap.LDAPError as e:
|
|
|
6405db |
+ log.fatal('Failed to add cos: error ' + str(e))
|
|
|
6405db |
+ raise e
|
|
|
6405db |
+ time.sleep(1)
|
|
|
6405db |
+
|
|
|
6405db |
+
|
|
|
6405db |
+@pytest.fixture(scope="module")
|
|
|
6405db |
+def setup(topo, request):
|
|
|
6405db |
+ """Add schema, and test user
|
|
|
6405db |
+ """
|
|
|
6405db |
+ log.info('Add custom schema...')
|
|
|
6405db |
+ try:
|
|
|
6405db |
+ ATTR_1 = ("( 1.3.6.1.4.1.409.389.2.189 NAME 'x-department' " +
|
|
|
6405db |
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )")
|
|
|
6405db |
+ ATTR_2 = ("( 1.3.6.1.4.1.409.389.2.187 NAME 'x-en-ou' " +
|
|
|
6405db |
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' )")
|
|
|
6405db |
+ OC = ("( xPerson-oid NAME 'xPerson' DESC '' SUP person STRUCTURAL MAY " +
|
|
|
6405db |
+ "( x-department $ x-en-ou ) X-ORIGIN 'user defined' )")
|
|
|
6405db |
+ topo.standalone.modify_s("cn=schema", [(ldap.MOD_ADD, 'attributeTypes', ATTR_1),
|
|
|
6405db |
+ (ldap.MOD_ADD, 'attributeTypes', ATTR_2),
|
|
|
6405db |
+ (ldap.MOD_ADD, 'objectClasses', OC)])
|
|
|
6405db |
+ except ldap.LDAPError as e:
|
|
|
6405db |
+ log.fatal('Failed to add custom schema')
|
|
|
6405db |
+ raise e
|
|
|
6405db |
+ time.sleep(1)
|
|
|
6405db |
+
|
|
|
6405db |
+ log.info('Add test user...')
|
|
|
6405db |
+ users = UserAccounts(topo.standalone, DEFAULT_SUFFIX)
|
|
|
6405db |
+
|
|
|
6405db |
+ user_properties = {
|
|
|
6405db |
+ 'uid': 'test_user',
|
|
|
6405db |
+ 'cn': 'test user',
|
|
|
6405db |
+ 'sn': 'user',
|
|
|
6405db |
+ 'uidNumber': '1000',
|
|
|
6405db |
+ 'gidNumber': '2000',
|
|
|
6405db |
+ 'homeDirectory': '/home/test_user',
|
|
|
6405db |
+ 'seeAlso': 'cn=cosTemplate,dc=example,dc=com'
|
|
|
6405db |
+ }
|
|
|
6405db |
+ users.create(properties=user_properties)
|
|
|
6405db |
+ try:
|
|
|
6405db |
+ topo.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_ADD,
|
|
|
6405db |
+ 'objectclass',
|
|
|
6405db |
+ 'xPerson')])
|
|
|
6405db |
+ except ldap.LDAPError as e:
|
|
|
6405db |
+ log.fatal('Failed to add objectclass to user')
|
|
|
6405db |
+ raise e
|
|
|
6405db |
+
|
|
|
6405db |
+ # Setup COS
|
|
|
6405db |
+ log.info("Setup indirect COS...")
|
|
|
6405db |
+ setup_indirect_cos(topo)
|
|
|
6405db |
+
|
|
|
6405db |
+
|
|
|
6405db |
+def test_indirect_cos(topo, setup):
|
|
|
6405db |
+ """Test indirect cos
|
|
|
6405db |
+
|
|
|
6405db |
+ :id: 890d5929-7d52-4a56-956e-129611b4649a
|
|
|
6405db |
+ :setup: standalone
|
|
|
6405db |
+ :steps:
|
|
|
6405db |
+ 1. Test cos is working for test user
|
|
|
6405db |
+ 2. Add subtree password policy
|
|
|
6405db |
+ 3. Test cos is working for test user
|
|
|
6405db |
+ :expectedresults:
|
|
|
6405db |
+ 1. User has expected cos attrs
|
|
|
6405db |
+ 2. Substree password policy setup is successful
|
|
|
6405db |
+ 3 User still has expected cos attrs
|
|
|
6405db |
+ """
|
|
|
6405db |
+
|
|
|
6405db |
+ # Step 1 - Search user and see if the COS attrs are included
|
|
|
6405db |
+ log.info('Checking user...')
|
|
|
6405db |
+ check_user(topo.standalone)
|
|
|
6405db |
+
|
|
|
6405db |
+ # Step 2 - Add subtree password policy (Second COS - operational attribute)
|
|
|
6405db |
+ setup_subtree_policy(topo)
|
|
|
6405db |
+
|
|
|
6405db |
+ # Step 3 - Check user again now hat we have a mix of vattrs
|
|
|
6405db |
+ log.info('Checking user...')
|
|
|
6405db |
+ check_user(topo.standalone)
|
|
|
6405db |
+
|
|
|
6405db |
+
|
|
|
6405db |
+if __name__ == '__main__':
|
|
|
6405db |
+ # Run isolated
|
|
|
6405db |
+ # -s for DEBUG mode
|
|
|
6405db |
+ CURRENT_FILE = os.path.realpath(__file__)
|
|
|
6405db |
+ pytest.main("-s %s" % CURRENT_FILE)
|
|
|
6405db |
+
|
|
|
6405db |
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
|
|
|
96373c |
index c7897ba05..9ae15db15 100644
|
|
|
6405db |
--- a/ldap/servers/plugins/cos/cos_cache.c
|
|
|
6405db |
+++ b/ldap/servers/plugins/cos/cos_cache.c
|
|
|
96373c |
@@ -2094,7 +2094,6 @@ cos_cache_vattr_types(vattr_sp_handle *handle __attribute__((unused)),
|
|
|
96373c |
int index = 0;
|
|
|
96373c |
cosCache *pCache;
|
|
|
96373c |
char *lastattr = "thisisfakeforcos";
|
|
|
96373c |
- int props = 0;
|
|
|
6405db |
|
|
|
96373c |
slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "--> cos_cache_vattr_types\n");
|
|
|
6405db |
|
|
|
96373c |
@@ -2105,6 +2104,7 @@ cos_cache_vattr_types(vattr_sp_handle *handle __attribute__((unused)),
|
|
|
96373c |
}
|
|
|
6405db |
|
|
|
96373c |
while (index < pCache->attrCount) {
|
|
|
6405db |
+ int props = 0;
|
|
|
96373c |
if (slapi_utf8casecmp(
|
|
|
96373c |
(unsigned char *)pCache->ppAttrIndex[index]->pAttrName,
|
|
|
96373c |
(unsigned char *)lastattr)) {
|
|
|
6405db |
--
|
|
|
96373c |
2.13.6
|
|
|
6405db |
|