739 lines
30 KiB
Diff
739 lines
30 KiB
Diff
|
From 67e19da62a9e8958458de54173dcd9bcaf53164d Mon Sep 17 00:00:00 2001
|
||
|
From: tbordaz <tbordaz@redhat.com>
|
||
|
Date: Thu, 30 Sep 2021 15:59:40 +0200
|
||
|
Subject: [PATCH 01/12] Issue 4678 - RFE automatique disable of virtual
|
||
|
attribute checking (#4918)
|
||
|
|
||
|
Bug description:
|
||
|
Virtual attributes are configured via Roles or COS definitions
|
||
|
and registered during initialization of those plugins.
|
||
|
Virtual attributes are processed during search evaluation of
|
||
|
filter and returned attributes. This processing is expensive
|
||
|
and prone to create contention between searches.
|
||
|
Use of virtual attribute is not frequent. So many of the
|
||
|
deployement process virtual attribute even if there is none.
|
||
|
|
||
|
Fix description:
|
||
|
The fix configure the server to ignore virtual attribute by
|
||
|
default (nsslapd-ignore-virtual-attrs: on).
|
||
|
At startup, if a new virtual attribute is registered or
|
||
|
it exists Roles/COS definitions, then the server is
|
||
|
configured to process the virtual attributes
|
||
|
(nsslapd-ignore-virtual-attrs: off)
|
||
|
design: https://www.port389.org/docs/389ds/design/vattr-automatic-toggle.html
|
||
|
|
||
|
relates: https://github.com/389ds/389-ds-base/issues/4678
|
||
|
|
||
|
Reviewed by: William Brown, Simon Pichugin, Mark Reynolds (Thanks !!)
|
||
|
|
||
|
Platforms tested: F34
|
||
|
---
|
||
|
.../tests/suites/config/config_test.py | 40 +++-
|
||
|
dirsrvtests/tests/suites/cos/cos_test.py | 94 ++++++--
|
||
|
dirsrvtests/tests/suites/roles/basic_test.py | 200 +++++++++++++++++-
|
||
|
ldap/servers/plugins/roles/roles_cache.c | 9 +
|
||
|
ldap/servers/slapd/libglobs.c | 2 +-
|
||
|
ldap/servers/slapd/main.c | 2 +
|
||
|
ldap/servers/slapd/proto-slap.h | 1 +
|
||
|
ldap/servers/slapd/vattr.c | 127 +++++++++++
|
||
|
src/lib389/lib389/idm/role.py | 4 +
|
||
|
9 files changed, 455 insertions(+), 24 deletions(-)
|
||
|
|
||
|
diff --git a/dirsrvtests/tests/suites/config/config_test.py b/dirsrvtests/tests/suites/config/config_test.py
|
||
|
index 2ecff8f98..19232c87d 100644
|
||
|
--- a/dirsrvtests/tests/suites/config/config_test.py
|
||
|
+++ b/dirsrvtests/tests/suites/config/config_test.py
|
||
|
@@ -351,7 +351,7 @@ def test_ignore_virtual_attrs(topo):
|
||
|
:setup: Standalone instance
|
||
|
:steps:
|
||
|
1. Check the attribute nsslapd-ignore-virtual-attrs is present in cn=config
|
||
|
- 2. Check the default value of attribute nsslapd-ignore-virtual-attrs should be OFF
|
||
|
+ 2. Check the default value of attribute nsslapd-ignore-virtual-attrs should be ON
|
||
|
3. Set the valid values i.e. on/ON and off/OFF for nsslapd-ignore-virtual-attrs
|
||
|
4. Set invalid value for attribute nsslapd-ignore-virtual-attrs
|
||
|
5. Set nsslapd-ignore-virtual-attrs=off
|
||
|
@@ -374,8 +374,8 @@ def test_ignore_virtual_attrs(topo):
|
||
|
log.info("Check the attribute nsslapd-ignore-virtual-attrs is present in cn=config")
|
||
|
assert topo.standalone.config.present('nsslapd-ignore-virtual-attrs')
|
||
|
|
||
|
- log.info("Check the default value of attribute nsslapd-ignore-virtual-attrs should be OFF")
|
||
|
- assert topo.standalone.config.get_attr_val_utf8('nsslapd-ignore-virtual-attrs') == "off"
|
||
|
+ log.info("Check the default value of attribute nsslapd-ignore-virtual-attrs should be ON")
|
||
|
+ assert topo.standalone.config.get_attr_val_utf8('nsslapd-ignore-virtual-attrs') == "on"
|
||
|
|
||
|
log.info("Set the valid values i.e. on/ON and off/OFF for nsslapd-ignore-virtual-attrs")
|
||
|
for attribute_value in ['on', 'off', 'ON', 'OFF']:
|
||
|
@@ -415,6 +415,40 @@ def test_ignore_virtual_attrs(topo):
|
||
|
log.info("Test if virtual attribute i.e. postal code not shown while nsslapd-ignore-virtual-attrs: on")
|
||
|
assert not test_user.present('postalcode', '117')
|
||
|
|
||
|
+def test_ignore_virtual_attrs_after_restart(topo):
|
||
|
+ """Test nsslapd-ignore-virtual-attrs configuration attribute
|
||
|
+ The attribute is ON by default. If it set to OFF, it keeps
|
||
|
+ its value on restart
|
||
|
+
|
||
|
+ :id: ac368649-4fda-473c-9ef8-e0c728b162af
|
||
|
+ :setup: Standalone instance
|
||
|
+ :steps:
|
||
|
+ 1. Check the attribute nsslapd-ignore-virtual-attrs is present in cn=config
|
||
|
+ 2. Check the default value of attribute nsslapd-ignore-virtual-attrs should be ON
|
||
|
+ 3. Set nsslapd-ignore-virtual-attrs=off
|
||
|
+ 4. restart the instance
|
||
|
+ 5. Check the attribute nsslapd-ignore-virtual-attrs is OFF
|
||
|
+ :expectedresults:
|
||
|
+ 1. This should be successful
|
||
|
+ 2. This should be successful
|
||
|
+ 3. This should be successful
|
||
|
+ 4. This should be successful
|
||
|
+ 5. This should be successful
|
||
|
+ """
|
||
|
+
|
||
|
+ log.info("Check the attribute nsslapd-ignore-virtual-attrs is present in cn=config")
|
||
|
+ assert topo.standalone.config.present('nsslapd-ignore-virtual-attrs')
|
||
|
+
|
||
|
+ log.info("Check the default value of attribute nsslapd-ignore-virtual-attrs should be ON")
|
||
|
+ assert topo.standalone.config.get_attr_val_utf8('nsslapd-ignore-virtual-attrs') == "on"
|
||
|
+
|
||
|
+ log.info("Set nsslapd-ignore-virtual-attrs = off")
|
||
|
+ topo.standalone.config.set('nsslapd-ignore-virtual-attrs', 'off')
|
||
|
+
|
||
|
+ topo.standalone.restart()
|
||
|
+
|
||
|
+ log.info("Check the default value of attribute nsslapd-ignore-virtual-attrs should be OFF")
|
||
|
+ assert topo.standalone.config.present('nsslapd-ignore-virtual-attrs', 'off')
|
||
|
|
||
|
@pytest.mark.bz918694
|
||
|
@pytest.mark.ds408
|
||
|
diff --git a/dirsrvtests/tests/suites/cos/cos_test.py b/dirsrvtests/tests/suites/cos/cos_test.py
|
||
|
index d6a498c73..d1f99f96f 100644
|
||
|
--- a/dirsrvtests/tests/suites/cos/cos_test.py
|
||
|
+++ b/dirsrvtests/tests/suites/cos/cos_test.py
|
||
|
@@ -6,6 +6,8 @@
|
||
|
# See LICENSE for details.
|
||
|
# --- END COPYRIGHT BLOCK ---
|
||
|
|
||
|
+import logging
|
||
|
+import time
|
||
|
import pytest, os, ldap
|
||
|
from lib389.cos import CosClassicDefinition, CosClassicDefinitions, CosTemplate
|
||
|
from lib389._constants import DEFAULT_SUFFIX
|
||
|
@@ -14,26 +16,37 @@ from lib389.idm.role import FilteredRoles
|
||
|
from lib389.idm.nscontainer import nsContainer
|
||
|
from lib389.idm.user import UserAccount
|
||
|
|
||
|
+logging.getLogger(__name__).setLevel(logging.INFO)
|
||
|
+log = logging.getLogger(__name__)
|
||
|
+
|
||
|
pytestmark = pytest.mark.tier1
|
||
|
+@pytest.fixture(scope="function")
|
||
|
+def reset_ignore_vattr(topo, request):
|
||
|
+ default_ignore_vattr_value = topo.standalone.config.get_attr_val_utf8('nsslapd-ignore-virtual-attrs')
|
||
|
+ def fin():
|
||
|
+ topo.standalone.config.set('nsslapd-ignore-virtual-attrs', default_ignore_vattr_value)
|
||
|
|
||
|
-def test_positive(topo):
|
||
|
- """
|
||
|
- :id: a5a74235-597f-4fe8-8c38-826860927472
|
||
|
- :setup: server
|
||
|
- :steps:
|
||
|
- 1. Add filter role entry
|
||
|
- 2. Add ns container
|
||
|
- 3. Add cos template
|
||
|
- 4. Add CosClassic Definition
|
||
|
- 5. Cos entries should be added and searchable
|
||
|
- 6. employeeType attribute should be there in user entry as per the cos plugin property
|
||
|
- :expectedresults:
|
||
|
- 1. Operation should success
|
||
|
- 2. Operation should success
|
||
|
- 3. Operation should success
|
||
|
- 4. Operation should success
|
||
|
- 5. Operation should success
|
||
|
- 6. Operation should success
|
||
|
+ request.addfinalizer(fin)
|
||
|
+
|
||
|
+def test_positive(topo, reset_ignore_vattr):
|
||
|
+ """CoS positive tests
|
||
|
+
|
||
|
+ :id: a5a74235-597f-4fe8-8c38-826860927472
|
||
|
+ :setup: server
|
||
|
+ :steps:
|
||
|
+ 1. Add filter role entry
|
||
|
+ 2. Add ns container
|
||
|
+ 3. Add cos template
|
||
|
+ 4. Add CosClassic Definition
|
||
|
+ 5. Cos entries should be added and searchable
|
||
|
+ 6. employeeType attribute should be there in user entry as per the cos plugin property
|
||
|
+ :expectedresults:
|
||
|
+ 1. Operation should success
|
||
|
+ 2. Operation should success
|
||
|
+ 3. Operation should success
|
||
|
+ 4. Operation should success
|
||
|
+ 5. Operation should success
|
||
|
+ 6. Operation should success
|
||
|
"""
|
||
|
# Adding ns filter role
|
||
|
roles = FilteredRoles(topo.standalone, DEFAULT_SUFFIX)
|
||
|
@@ -77,7 +90,52 @@ def test_positive(topo):
|
||
|
|
||
|
# CoS definition entry's cosSpecifier attribute specifies the employeeType attribute
|
||
|
assert user.present('employeeType')
|
||
|
+ cosdef.delete()
|
||
|
+
|
||
|
+def test_vattr_on_cos_definition(topo, reset_ignore_vattr):
|
||
|
+ """Test nsslapd-ignore-virtual-attrs configuration attribute
|
||
|
+ The attribute is ON by default. If a cos definition is
|
||
|
+ added it is moved to OFF
|
||
|
+
|
||
|
+ :id: e7ef5254-386f-4362-bbb4-9409f3f51b08
|
||
|
+ :setup: Standalone instance
|
||
|
+ :steps:
|
||
|
+ 1. Check the attribute nsslapd-ignore-virtual-attrs is present in cn=config
|
||
|
+ 2. Check the default value of attribute nsslapd-ignore-virtual-attrs should be ON
|
||
|
+ 3. Create a cos definition for employeeType
|
||
|
+ 4. Check the value of nsslapd-ignore-virtual-attrs should be OFF (with a delay for postop processing)
|
||
|
+ 5. Check a message "slapi_vattrspi_regattr - Because employeeType,.." in error logs
|
||
|
+ :expectedresults:
|
||
|
+ 1. This should be successful
|
||
|
+ 2. This should be successful
|
||
|
+ 3. This should be successful
|
||
|
+ 4. This should be successful
|
||
|
+ 5. This should be successful
|
||
|
+ """
|
||
|
+
|
||
|
+ log.info("Check the attribute nsslapd-ignore-virtual-attrs is present in cn=config")
|
||
|
+ assert topo.standalone.config.present('nsslapd-ignore-virtual-attrs')
|
||
|
+
|
||
|
+ log.info("Check the default value of attribute nsslapd-ignore-virtual-attrs should be ON")
|
||
|
+ assert topo.standalone.config.get_attr_val_utf8('nsslapd-ignore-virtual-attrs') == "on"
|
||
|
+
|
||
|
+ # creating CosClassicDefinition
|
||
|
+ log.info("Create a cos definition")
|
||
|
+ properties = {'cosTemplateDn': 'cn=cosClassicGenerateEmployeeTypeUsingnsroleTemplates,{}'.format(DEFAULT_SUFFIX),
|
||
|
+ 'cosAttribute': 'employeeType',
|
||
|
+ 'cosSpecifier': 'nsrole',
|
||
|
+ 'cn': 'cosClassicGenerateEmployeeTypeUsingnsrole'}
|
||
|
+ cosdef = CosClassicDefinition(topo.standalone,'cn=cosClassicGenerateEmployeeTypeUsingnsrole,{}'.format(DEFAULT_SUFFIX))\
|
||
|
+ .create(properties=properties)
|
||
|
+
|
||
|
+ log.info("Check the default value of attribute nsslapd-ignore-virtual-attrs should be OFF")
|
||
|
+ time.sleep(2)
|
||
|
+ assert topo.standalone.config.present('nsslapd-ignore-virtual-attrs', 'off')
|
||
|
|
||
|
+ topo.standalone.stop()
|
||
|
+ assert topo.standalone.searchErrorsLog("slapi_vattrspi_regattr - Because employeeType is a new registered virtual attribute , nsslapd-ignore-virtual-attrs was set to \'off\'")
|
||
|
+ topo.standalone.start()
|
||
|
+ cosdef.delete()
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
CURRENT_FILE = os.path.realpath(__file__)
|
||
|
diff --git a/dirsrvtests/tests/suites/roles/basic_test.py b/dirsrvtests/tests/suites/roles/basic_test.py
|
||
|
index 47a531794..bec3aedfc 100644
|
||
|
--- a/dirsrvtests/tests/suites/roles/basic_test.py
|
||
|
+++ b/dirsrvtests/tests/suites/roles/basic_test.py
|
||
|
@@ -11,6 +11,8 @@
|
||
|
Importing necessary Modules.
|
||
|
"""
|
||
|
|
||
|
+import logging
|
||
|
+import time
|
||
|
import os
|
||
|
import pytest
|
||
|
|
||
|
@@ -22,6 +24,9 @@ from lib389.topologies import topology_st as topo
|
||
|
from lib389.idm.role import FilteredRoles, ManagedRoles, NestedRoles
|
||
|
from lib389.idm.domain import Domain
|
||
|
|
||
|
+logging.getLogger(__name__).setLevel(logging.INFO)
|
||
|
+log = logging.getLogger(__name__)
|
||
|
+
|
||
|
pytestmark = pytest.mark.tier1
|
||
|
|
||
|
DNBASE = "o=acivattr,{}".format(DEFAULT_SUFFIX)
|
||
|
@@ -35,7 +40,7 @@ FILTERROLESALESROLE = "cn=FILTERROLESALESROLE,{}".format(DNBASE)
|
||
|
FILTERROLEENGROLE = "cn=FILTERROLEENGROLE,{}".format(DNBASE)
|
||
|
|
||
|
|
||
|
-def test_filterrole(topo):
|
||
|
+def test_filterrole(topo, request):
|
||
|
"""Test Filter Role
|
||
|
|
||
|
:id: 8ada4064-786b-11e8-8634-8c16451d917b
|
||
|
@@ -136,8 +141,20 @@ def test_filterrole(topo):
|
||
|
SALES_OU, DNBASE]:
|
||
|
UserAccount(topo.standalone, dn_dn).delete()
|
||
|
|
||
|
+ def fin():
|
||
|
+ topo.standalone.restart()
|
||
|
+ try:
|
||
|
+ filtered_roles = FilteredRoles(topo.standalone, DEFAULT_SUFFIX)
|
||
|
+ for i in filtered_roles.list():
|
||
|
+ i.delete()
|
||
|
+ except:
|
||
|
+ pass
|
||
|
+ topo.standalone.config.set('nsslapd-ignore-virtual-attrs', 'on')
|
||
|
+
|
||
|
+ request.addfinalizer(fin)
|
||
|
+
|
||
|
|
||
|
-def test_managedrole(topo):
|
||
|
+def test_managedrole(topo, request):
|
||
|
"""Test Managed Role
|
||
|
|
||
|
:id: d52a9c00-3bf6-11e9-9b7b-8c16451d917b
|
||
|
@@ -209,6 +226,16 @@ def test_managedrole(topo):
|
||
|
for i in roles.list():
|
||
|
i.delete()
|
||
|
|
||
|
+ def fin():
|
||
|
+ topo.standalone.restart()
|
||
|
+ try:
|
||
|
+ role = ManagedRoles(topo.standalone, DEFAULT_SUFFIX).get('ROLE1')
|
||
|
+ role.delete()
|
||
|
+ except:
|
||
|
+ pass
|
||
|
+ topo.standalone.config.set('nsslapd-ignore-virtual-attrs', 'on')
|
||
|
+
|
||
|
+ request.addfinalizer(fin)
|
||
|
|
||
|
@pytest.fixture(scope="function")
|
||
|
def _final(request, topo):
|
||
|
@@ -220,6 +247,7 @@ def _final(request, topo):
|
||
|
def finofaci():
|
||
|
"""
|
||
|
Removes and Restores ACIs and other users after the test.
|
||
|
+ And restore nsslapd-ignore-virtual-attrs to default
|
||
|
"""
|
||
|
domain = Domain(topo.standalone, DEFAULT_SUFFIX)
|
||
|
domain.remove_all('aci')
|
||
|
@@ -234,6 +262,8 @@ def _final(request, topo):
|
||
|
for i in aci_list:
|
||
|
domain.add("aci", i)
|
||
|
|
||
|
+ topo.standalone.config.set('nsslapd-ignore-virtual-attrs', 'on')
|
||
|
+
|
||
|
request.addfinalizer(finofaci)
|
||
|
|
||
|
|
||
|
@@ -296,6 +326,172 @@ def test_nestedrole(topo, _final):
|
||
|
conn = users.get('test_user_3').bind(PW_DM)
|
||
|
assert UserAccounts(conn, DEFAULT_SUFFIX).list()
|
||
|
|
||
|
+def test_vattr_on_filtered_role(topo, request):
|
||
|
+ """Test nsslapd-ignore-virtual-attrs configuration attribute
|
||
|
+ The attribute is ON by default. If a filtered role is
|
||
|
+ added it is moved to OFF
|
||
|
+
|
||
|
+ :id: 88b3ad3c-f39a-4eb7-a8c9-07c685f11908
|
||
|
+ :setup: Standalone instance
|
||
|
+ :steps:
|
||
|
+ 1. Check the attribute nsslapd-ignore-virtual-attrs is present in cn=config
|
||
|
+ 2. Check the default value of attribute nsslapd-ignore-virtual-attrs should be ON
|
||
|
+ 3. Create a filtered role
|
||
|
+ 4. Check the value of nsslapd-ignore-virtual-attrs should be OFF
|
||
|
+ 5. Check a message "roles_cache_trigger_update_role - Because of virtual attribute.." in error logs
|
||
|
+ :expectedresults:
|
||
|
+ 1. This should be successful
|
||
|
+ 2. This should be successful
|
||
|
+ 3. This should be successful
|
||
|
+ 4. This should be successful
|
||
|
+ 5. This should be successful
|
||
|
+ """
|
||
|
+
|
||
|
+ log.info("Check the attribute nsslapd-ignore-virtual-attrs is present in cn=config")
|
||
|
+ assert topo.standalone.config.present('nsslapd-ignore-virtual-attrs')
|
||
|
+
|
||
|
+ log.info("Check the default value of attribute nsslapd-ignore-virtual-attrs should be ON")
|
||
|
+ assert topo.standalone.config.get_attr_val_utf8('nsslapd-ignore-virtual-attrs') == "on"
|
||
|
+
|
||
|
+ log.info("Create a filtered role")
|
||
|
+ try:
|
||
|
+ Organization(topo.standalone).create(properties={"o": "acivattr"}, basedn=DEFAULT_SUFFIX)
|
||
|
+ except:
|
||
|
+ pass
|
||
|
+ roles = FilteredRoles(topo.standalone, DNBASE)
|
||
|
+ roles.create(properties={'cn': 'FILTERROLEENGROLE', 'nsRoleFilter': 'cn=eng*'})
|
||
|
+
|
||
|
+ log.info("Check the default value of attribute nsslapd-ignore-virtual-attrs should be OFF")
|
||
|
+ assert topo.standalone.config.present('nsslapd-ignore-virtual-attrs', 'off')
|
||
|
+
|
||
|
+ topo.standalone.stop()
|
||
|
+ assert topo.standalone.searchErrorsLog("roles_cache_trigger_update_role - Because of virtual attribute definition \(role\), nsslapd-ignore-virtual-attrs was set to \'off\'")
|
||
|
+
|
||
|
+ def fin():
|
||
|
+ topo.standalone.restart()
|
||
|
+ try:
|
||
|
+ filtered_roles = FilteredRoles(topo.standalone, DEFAULT_SUFFIX)
|
||
|
+ for i in filtered_roles.list():
|
||
|
+ i.delete()
|
||
|
+ except:
|
||
|
+ pass
|
||
|
+ topo.standalone.config.set('nsslapd-ignore-virtual-attrs', 'on')
|
||
|
+
|
||
|
+ request.addfinalizer(fin)
|
||
|
+
|
||
|
+def test_vattr_on_filtered_role_restart(topo, request):
|
||
|
+ """Test nsslapd-ignore-virtual-attrs configuration attribute
|
||
|
+ If it exists a filtered role definition at restart then
|
||
|
+ nsslapd-ignore-virtual-attrs should be set to 'off'
|
||
|
+
|
||
|
+ :id: 972183f7-d18f-40e0-94ab-580e7b7d78d0
|
||
|
+ :setup: Standalone instance
|
||
|
+ :steps:
|
||
|
+ 1. Check the attribute nsslapd-ignore-virtual-attrs is present in cn=config
|
||
|
+ 2. Check the default value of attribute nsslapd-ignore-virtual-attrs should be ON
|
||
|
+ 3. Create a filtered role
|
||
|
+ 4. Check the value of nsslapd-ignore-virtual-attrs should be OFF
|
||
|
+ 5. restart the instance
|
||
|
+ 6. Check the presence of virtual attribute is detected
|
||
|
+ 7. Check the value of nsslapd-ignore-virtual-attrs should be OFF
|
||
|
+ :expectedresults:
|
||
|
+ 1. This should be successful
|
||
|
+ 2. This should be successful
|
||
|
+ 3. This should be successful
|
||
|
+ 4. This should be successful
|
||
|
+ 5. This should be successful
|
||
|
+ 6. This should be successful
|
||
|
+ 7. This should be successful
|
||
|
+ """
|
||
|
+
|
||
|
+ log.info("Check the attribute nsslapd-ignore-virtual-attrs is present in cn=config")
|
||
|
+ assert topo.standalone.config.present('nsslapd-ignore-virtual-attrs')
|
||
|
+
|
||
|
+ log.info("Check the default value of attribute nsslapd-ignore-virtual-attrs should be ON")
|
||
|
+ assert topo.standalone.config.get_attr_val_utf8('nsslapd-ignore-virtual-attrs') == "on"
|
||
|
+
|
||
|
+ log.info("Create a filtered role")
|
||
|
+ try:
|
||
|
+ Organization(topo.standalone).create(properties={"o": "acivattr"}, basedn=DEFAULT_SUFFIX)
|
||
|
+ except:
|
||
|
+ pass
|
||
|
+ roles = FilteredRoles(topo.standalone, DNBASE)
|
||
|
+ roles.create(properties={'cn': 'FILTERROLEENGROLE', 'nsRoleFilter': 'cn=eng*'})
|
||
|
+
|
||
|
+ log.info("Check the default value of attribute nsslapd-ignore-virtual-attrs should be OFF")
|
||
|
+ assert topo.standalone.config.present('nsslapd-ignore-virtual-attrs', 'off')
|
||
|
+
|
||
|
+
|
||
|
+ log.info("Check the virtual attribute definition is found (after a required delay)")
|
||
|
+ topo.standalone.restart()
|
||
|
+ time.sleep(5)
|
||
|
+ assert topo.standalone.searchErrorsLog("Found a role/cos definition in")
|
||
|
+ assert topo.standalone.searchErrorsLog("roles_cache_trigger_update_role - Because of virtual attribute definition \(role\), nsslapd-ignore-virtual-attrs was set to \'off\'")
|
||
|
+
|
||
|
+ log.info("Check the default value of attribute nsslapd-ignore-virtual-attrs should be OFF")
|
||
|
+ assert topo.standalone.config.present('nsslapd-ignore-virtual-attrs', 'off')
|
||
|
+
|
||
|
+ def fin():
|
||
|
+ topo.standalone.restart()
|
||
|
+ try:
|
||
|
+ filtered_roles = FilteredRoles(topo.standalone, DEFAULT_SUFFIX)
|
||
|
+ for i in filtered_roles.list():
|
||
|
+ i.delete()
|
||
|
+ except:
|
||
|
+ pass
|
||
|
+ topo.standalone.config.set('nsslapd-ignore-virtual-attrs', 'on')
|
||
|
+
|
||
|
+ request.addfinalizer(fin)
|
||
|
+
|
||
|
+
|
||
|
+def test_vattr_on_managed_role(topo, request):
|
||
|
+ """Test nsslapd-ignore-virtual-attrs configuration attribute
|
||
|
+ The attribute is ON by default. If a managed role is
|
||
|
+ added it is moved to OFF
|
||
|
+
|
||
|
+ :id: 664b722d-c1ea-41e4-8f6c-f9c87a212346
|
||
|
+ :setup: Standalone instance
|
||
|
+ :steps:
|
||
|
+ 1. Check the attribute nsslapd-ignore-virtual-attrs is present in cn=config
|
||
|
+ 2. Check the default value of attribute nsslapd-ignore-virtual-attrs should be ON
|
||
|
+ 3. Create a managed role
|
||
|
+ 4. Check the value of nsslapd-ignore-virtual-attrs should be OFF
|
||
|
+ 5. Check a message "roles_cache_trigger_update_role - Because of virtual attribute.." in error logs
|
||
|
+ :expectedresults:
|
||
|
+ 1. This should be successful
|
||
|
+ 2. This should be successful
|
||
|
+ 3. This should be successful
|
||
|
+ 4. This should be successful
|
||
|
+ 5. This should be successful
|
||
|
+ """
|
||
|
+
|
||
|
+ log.info("Check the attribute nsslapd-ignore-virtual-attrs is present in cn=config")
|
||
|
+ assert topo.standalone.config.present('nsslapd-ignore-virtual-attrs')
|
||
|
+
|
||
|
+ log.info("Check the default value of attribute nsslapd-ignore-virtual-attrs should be ON")
|
||
|
+ assert topo.standalone.config.get_attr_val_utf8('nsslapd-ignore-virtual-attrs') == "on"
|
||
|
+
|
||
|
+ log.info("Create a managed role")
|
||
|
+ roles = ManagedRoles(topo.standalone, DEFAULT_SUFFIX)
|
||
|
+ role = roles.create(properties={"cn": 'ROLE1'})
|
||
|
+
|
||
|
+ log.info("Check the default value of attribute nsslapd-ignore-virtual-attrs should be OFF")
|
||
|
+ assert topo.standalone.config.present('nsslapd-ignore-virtual-attrs', 'off')
|
||
|
+
|
||
|
+ topo.standalone.stop()
|
||
|
+ assert topo.standalone.searchErrorsLog("roles_cache_trigger_update_role - Because of virtual attribute definition \(role\), nsslapd-ignore-virtual-attrs was set to \'off\'")
|
||
|
+
|
||
|
+ def fin():
|
||
|
+ topo.standalone.restart()
|
||
|
+ try:
|
||
|
+ filtered_roles = ManagedRoles(topo.standalone, DEFAULT_SUFFIX)
|
||
|
+ for i in filtered_roles.list():
|
||
|
+ i.delete()
|
||
|
+ except:
|
||
|
+ pass
|
||
|
+ topo.standalone.config.set('nsslapd-ignore-virtual-attrs', 'on')
|
||
|
+
|
||
|
+ request.addfinalizer(fin)
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
CURRENT_FILE = os.path.realpath(__file__)
|
||
|
diff --git a/ldap/servers/plugins/roles/roles_cache.c b/ldap/servers/plugins/roles/roles_cache.c
|
||
|
index 3d076a4cb..cd00e0aba 100644
|
||
|
--- a/ldap/servers/plugins/roles/roles_cache.c
|
||
|
+++ b/ldap/servers/plugins/roles/roles_cache.c
|
||
|
@@ -530,6 +530,15 @@ roles_cache_trigger_update_role(char *dn, Slapi_Entry *roles_entry, Slapi_DN *be
|
||
|
}
|
||
|
|
||
|
slapi_rwlock_unlock(global_lock);
|
||
|
+ {
|
||
|
+ /* A role definition has been updated, enable vattr handling */
|
||
|
+ char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE];
|
||
|
+ errorbuf[0] = '\0';
|
||
|
+ config_set_ignore_vattrs(CONFIG_IGNORE_VATTRS, "off", errorbuf, 1);
|
||
|
+ slapi_log_err(SLAPI_LOG_INFO,
|
||
|
+ "roles_cache_trigger_update_role",
|
||
|
+ "Because of virtual attribute definition (role), %s was set to 'off'\n", CONFIG_IGNORE_VATTRS);
|
||
|
+ }
|
||
|
|
||
|
slapi_log_err(SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM, "<-- roles_cache_trigger_update_role: %p \n", roles_list);
|
||
|
}
|
||
|
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
|
||
|
index 2ea4cd760..f6dacce30 100644
|
||
|
--- a/ldap/servers/slapd/libglobs.c
|
||
|
+++ b/ldap/servers/slapd/libglobs.c
|
||
|
@@ -1803,7 +1803,7 @@ FrontendConfig_init(void)
|
||
|
init_ndn_cache_enabled = cfg->ndn_cache_enabled = LDAP_ON;
|
||
|
cfg->ndn_cache_max_size = SLAPD_DEFAULT_NDN_SIZE;
|
||
|
init_sasl_mapping_fallback = cfg->sasl_mapping_fallback = LDAP_OFF;
|
||
|
- init_ignore_vattrs = cfg->ignore_vattrs = LDAP_OFF;
|
||
|
+ init_ignore_vattrs = cfg->ignore_vattrs = LDAP_ON;
|
||
|
cfg->sasl_max_bufsize = SLAPD_DEFAULT_SASL_MAXBUFSIZE;
|
||
|
cfg->unhashed_pw_switch = SLAPD_DEFAULT_UNHASHED_PW_SWITCH;
|
||
|
init_return_orig_type = cfg->return_orig_type = LDAP_OFF;
|
||
|
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
|
||
|
index 4931a4ca4..61ed40b7d 100644
|
||
|
--- a/ldap/servers/slapd/main.c
|
||
|
+++ b/ldap/servers/slapd/main.c
|
||
|
@@ -1042,6 +1042,8 @@ main(int argc, char **argv)
|
||
|
eq_start(); /* must be done after plugins started - DEPRECATED */
|
||
|
eq_start_rel(); /* must be done after plugins started */
|
||
|
|
||
|
+ vattr_check(); /* Check if it exists virtual attribute definitions */
|
||
|
+
|
||
|
#ifdef HPUX10
|
||
|
/* HPUX linker voodoo */
|
||
|
if (collation_init == NULL) {
|
||
|
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
|
||
|
index c143f3772..442a621aa 100644
|
||
|
--- a/ldap/servers/slapd/proto-slap.h
|
||
|
+++ b/ldap/servers/slapd/proto-slap.h
|
||
|
@@ -1462,6 +1462,7 @@ void subentry_create_filter(Slapi_Filter **filter);
|
||
|
*/
|
||
|
void vattr_init(void);
|
||
|
void vattr_cleanup(void);
|
||
|
+void vattr_check(void);
|
||
|
|
||
|
/*
|
||
|
* slapd_plhash.c - supplement to NSPR plhash
|
||
|
diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c
|
||
|
index 09dab6ecf..24750a57c 100644
|
||
|
--- a/ldap/servers/slapd/vattr.c
|
||
|
+++ b/ldap/servers/slapd/vattr.c
|
||
|
@@ -64,6 +64,10 @@
|
||
|
#define SOURCEFILE "vattr.c"
|
||
|
static char *sourcefile = SOURCEFILE;
|
||
|
|
||
|
+/* stolen from roles_cache.h, must remain in sync */
|
||
|
+#define NSROLEATTR "nsRole"
|
||
|
+static Slapi_Eq_Context vattr_check_ctx = {0};
|
||
|
+
|
||
|
/* Define only for module test code */
|
||
|
/* #define VATTR_TEST_CODE */
|
||
|
|
||
|
@@ -130,6 +134,112 @@ vattr_cleanup()
|
||
|
{
|
||
|
/* We need to free and remove anything that was inserted first */
|
||
|
vattr_map_destroy();
|
||
|
+ slapi_eq_cancel_rel(vattr_check_ctx);
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+vattr_check_thread(void *arg)
|
||
|
+{
|
||
|
+ Slapi_Backend *be = NULL;
|
||
|
+ char *cookie = NULL;
|
||
|
+ Slapi_DN *base_sdn = NULL;
|
||
|
+ Slapi_PBlock *search_pb = NULL;
|
||
|
+ Slapi_Entry **entries = NULL;
|
||
|
+ int32_t rc;
|
||
|
+ int32_t check_suffix; /* used to skip suffixes in ignored_backend */
|
||
|
+ PRBool exist_vattr_definition = PR_FALSE;
|
||
|
+ char *ignored_backend[5] = {"cn=config", "cn=schema", "cn=monitor", "cn=changelog", NULL}; /* suffixes to ignore */
|
||
|
+ char *suffix;
|
||
|
+ int ignore_vattrs;
|
||
|
+
|
||
|
+ ignore_vattrs = config_get_ignore_vattrs();
|
||
|
+
|
||
|
+ if (!ignore_vattrs) {
|
||
|
+ /* Nothing to do more, we are already evaluating virtual attribute */
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ search_pb = slapi_pblock_new();
|
||
|
+ be = slapi_get_first_backend(&cookie);
|
||
|
+ while (be && !exist_vattr_definition && !slapi_is_shutting_down()) {
|
||
|
+ base_sdn = (Slapi_DN *) slapi_be_getsuffix(be, 0);
|
||
|
+ suffix = (char *) slapi_sdn_get_dn(base_sdn);
|
||
|
+
|
||
|
+ if (suffix) {
|
||
|
+ /* First check that we need to check that suffix */
|
||
|
+ check_suffix = 1;
|
||
|
+ for (size_t i = 0; ignored_backend[i]; i++) {
|
||
|
+ if (strcasecmp(suffix, ignored_backend[i]) == 0) {
|
||
|
+ check_suffix = 0;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ /* search for a role or cos definition */
|
||
|
+ if (check_suffix) {
|
||
|
+ slapi_search_internal_set_pb(search_pb, slapi_sdn_get_dn(base_sdn),
|
||
|
+ LDAP_SCOPE_SUBTREE, "(&(objectclass=ldapsubentry)(|(objectclass=nsRoleDefinition)(objectclass=cosSuperDefinition)))",
|
||
|
+ NULL, 0, NULL, NULL, (void *) plugin_get_default_component_id(), 0);
|
||
|
+ slapi_search_internal_pb(search_pb);
|
||
|
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
|
||
|
+
|
||
|
+ if (rc == LDAP_SUCCESS) {
|
||
|
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
|
||
|
+ if (entries && entries[0]) {
|
||
|
+ /* it exists at least a cos or role definition */
|
||
|
+ exist_vattr_definition = PR_TRUE;
|
||
|
+ slapi_log_err(SLAPI_LOG_INFO,
|
||
|
+ "vattr_check_thread",
|
||
|
+ "Found a role/cos definition in %s\n", slapi_entry_get_dn(entries[0]));
|
||
|
+ } else {
|
||
|
+ slapi_log_err(SLAPI_LOG_INFO,
|
||
|
+ "vattr_check_thread",
|
||
|
+ "No role/cos definition in %s\n", slapi_sdn_get_dn(base_sdn));
|
||
|
+ }
|
||
|
+ }
|
||
|
+ slapi_free_search_results_internal(search_pb);
|
||
|
+ } /* check_suffix */
|
||
|
+ } /* suffix */
|
||
|
+ be = (backend *) slapi_get_next_backend(cookie);
|
||
|
+ }
|
||
|
+ slapi_pblock_destroy(search_pb);
|
||
|
+ slapi_ch_free_string(&cookie);
|
||
|
+
|
||
|
+ /* Now if a virtual attribute is defined, then CONFIG_IGNORE_VATTRS -> off */
|
||
|
+ if (exist_vattr_definition) {
|
||
|
+ char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE];
|
||
|
+ errorbuf[0] = '\0';
|
||
|
+ config_set_ignore_vattrs(CONFIG_IGNORE_VATTRS, "off", errorbuf, 1);
|
||
|
+ slapi_log_err(SLAPI_LOG_INFO,
|
||
|
+ "vattr_check_thread",
|
||
|
+ "Because of virtual attribute definition, %s was set to 'off'\n", CONFIG_IGNORE_VATTRS);
|
||
|
+ }
|
||
|
+}
|
||
|
+static void
|
||
|
+vattr_check_schedule_once(time_t when __attribute__((unused)), void *arg)
|
||
|
+{
|
||
|
+ if (PR_CreateThread(PR_USER_THREAD,
|
||
|
+ vattr_check_thread,
|
||
|
+ (void *) arg,
|
||
|
+ PR_PRIORITY_NORMAL,
|
||
|
+ PR_GLOBAL_THREAD,
|
||
|
+ PR_UNJOINABLE_THREAD,
|
||
|
+ SLAPD_DEFAULT_THREAD_STACKSIZE) == NULL) {
|
||
|
+ slapi_log_err(SLAPI_LOG_ERR,
|
||
|
+ "vattr_check_schedule_once",
|
||
|
+ "Fails to check if %s needs to be toggled to FALSE\n", CONFIG_IGNORE_VATTRS);
|
||
|
+ }
|
||
|
+}
|
||
|
+#define VATTR_CHECK_DELAY 3
|
||
|
+void
|
||
|
+vattr_check()
|
||
|
+{
|
||
|
+ /* Schedule running a callback that will create a thread
|
||
|
+ * but make sure it is called a first thing when event loop is created */
|
||
|
+ time_t now;
|
||
|
+
|
||
|
+ now = slapi_current_rel_time_t();
|
||
|
+ vattr_check_ctx = slapi_eq_once_rel(vattr_check_schedule_once, NULL, now + VATTR_CHECK_DELAY);
|
||
|
}
|
||
|
|
||
|
/* The public interface functions start here */
|
||
|
@@ -1631,6 +1741,9 @@ slapi_vattrspi_regattr(vattr_sp_handle *h, char *type_name_to_register, char *DN
|
||
|
char *type_to_add;
|
||
|
int free_type_to_add = 0;
|
||
|
Slapi_DN original_dn;
|
||
|
+ int ignore_vattrs;
|
||
|
+
|
||
|
+ ignore_vattrs = config_get_ignore_vattrs();
|
||
|
|
||
|
slapi_sdn_init(&original_dn);
|
||
|
|
||
|
@@ -1676,6 +1789,20 @@ slapi_vattrspi_regattr(vattr_sp_handle *h, char *type_name_to_register, char *DN
|
||
|
if (free_type_to_add) {
|
||
|
slapi_ch_free((void **)&type_to_add);
|
||
|
}
|
||
|
+ if (ignore_vattrs && strcasecmp(type_name_to_register, NSROLEATTR)) {
|
||
|
+ /* A new virtual attribute is registered.
|
||
|
+ * This new vattr being *different* than the default roles vattr 'nsRole'
|
||
|
+ * It is time to allow vattr lookup
|
||
|
+ */
|
||
|
+ char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE];
|
||
|
+ errorbuf[0] = '\0';
|
||
|
+ config_set_ignore_vattrs(CONFIG_IGNORE_VATTRS, "off", errorbuf, 1);
|
||
|
+ slapi_log_err(SLAPI_LOG_INFO,
|
||
|
+ "slapi_vattrspi_regattr",
|
||
|
+ "Because %s is a new registered virtual attribute , %s was set to 'off'\n",
|
||
|
+ type_name_to_register,
|
||
|
+ CONFIG_IGNORE_VATTRS);
|
||
|
+ }
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
diff --git a/src/lib389/lib389/idm/role.py b/src/lib389/lib389/idm/role.py
|
||
|
index fe91aab6f..9a2bff3d6 100644
|
||
|
--- a/src/lib389/lib389/idm/role.py
|
||
|
+++ b/src/lib389/lib389/idm/role.py
|
||
|
@@ -252,6 +252,8 @@ class FilteredRole(Role):
|
||
|
self._rdn_attribute = 'cn'
|
||
|
self._create_objectclasses = ['nsComplexRoleDefinition', 'nsFilteredRoleDefinition']
|
||
|
|
||
|
+ self._protected = False
|
||
|
+
|
||
|
|
||
|
|
||
|
class FilteredRoles(Roles):
|
||
|
@@ -285,6 +287,7 @@ class ManagedRole(Role):
|
||
|
self._rdn_attribute = 'cn'
|
||
|
self._create_objectclasses = ['nsSimpleRoleDefinition', 'nsManagedRoleDefinition']
|
||
|
|
||
|
+ self._protected = False
|
||
|
|
||
|
class ManagedRoles(Roles):
|
||
|
"""DSLdapObjects that represents all Managed Roles entries
|
||
|
@@ -320,6 +323,7 @@ class NestedRole(Role):
|
||
|
self._rdn_attribute = 'cn'
|
||
|
self._create_objectclasses = ['nsComplexRoleDefinition', 'nsNestedRoleDefinition']
|
||
|
|
||
|
+ self._protected = False
|
||
|
|
||
|
class NestedRoles(Roles):
|
||
|
"""DSLdapObjects that represents all NestedRoles entries in suffix.
|
||
|
--
|
||
|
2.31.1
|
||
|
|