Blame SOURCES/0005-Ticket-49389-unable-to-retrieve-specific-cosAttribut.patch

081b2d
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 ++++++++++++++++++++++
081b2d
 ldap/servers/plugins/cos/cos_cache.c              |   2 +-
081b2d
 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
081b2d
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
081b2d
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
081b2d
index c7897ba05..9ae15db15 100644
6405db
--- a/ldap/servers/plugins/cos/cos_cache.c
6405db
+++ b/ldap/servers/plugins/cos/cos_cache.c
081b2d
@@ -2094,7 +2094,6 @@ cos_cache_vattr_types(vattr_sp_handle *handle __attribute__((unused)),
081b2d
     int index = 0;
081b2d
     cosCache *pCache;
081b2d
     char *lastattr = "thisisfakeforcos";
081b2d
-    int props = 0;
6405db
 
081b2d
     slapi_log_err(SLAPI_LOG_TRACE, COS_PLUGIN_SUBSYSTEM, "--> cos_cache_vattr_types\n");
6405db
 
081b2d
@@ -2105,6 +2104,7 @@ cos_cache_vattr_types(vattr_sp_handle *handle __attribute__((unused)),
081b2d
     }
6405db
 
081b2d
     while (index < pCache->attrCount) {
6405db
+        int props = 0;
081b2d
         if (slapi_utf8casecmp(
081b2d
                 (unsigned char *)pCache->ppAttrIndex[index]->pAttrName,
081b2d
                 (unsigned char *)lastattr)) {
6405db
-- 
081b2d
2.13.6
6405db