|
|
74ca47 |
From 18491418e661b5dc1b9ca4c6bb4adb85bfb0bf0d Mon Sep 17 00:00:00 2001
|
|
|
74ca47 |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
74ca47 |
Date: Tue, 9 May 2017 16:31:52 -0400
|
|
|
74ca47 |
Subject: [PATCH] Ticket 49246 - ns-slapd crashes in role cache creation
|
|
|
74ca47 |
|
|
|
74ca47 |
Bug Description: Using a nested filter for a filtered role can
|
|
|
74ca47 |
cause a crash. This was due to the way the filter
|
|
|
74ca47 |
was being checked by the roles plugin.
|
|
|
74ca47 |
|
|
|
74ca47 |
Fix Description: Properly resurse over a filter.
|
|
|
74ca47 |
|
|
|
74ca47 |
https://pagure.io/389-ds-base/issue/49246
|
|
|
74ca47 |
|
|
|
74ca47 |
Reviewed by: firstyear & tbordaz(Thanks!!)
|
|
|
74ca47 |
|
|
|
74ca47 |
(cherry picked from commit 54e4fca35899550e0c25b25e7f7c756302d258ce)
|
|
|
74ca47 |
---
|
|
|
74ca47 |
dirsrvtests/tests/tickets/ticket49122_test.py | 61 ++++++++++++++++++---------
|
|
|
74ca47 |
ldap/servers/plugins/roles/roles_cache.c | 34 +++++++++++----
|
|
|
74ca47 |
2 files changed, 66 insertions(+), 29 deletions(-)
|
|
|
74ca47 |
|
|
|
74ca47 |
diff --git a/dirsrvtests/tests/tickets/ticket49122_test.py b/dirsrvtests/tests/tickets/ticket49122_test.py
|
|
|
74ca47 |
index ff1e8d1..0945122 100644
|
|
|
74ca47 |
--- a/dirsrvtests/tests/tickets/ticket49122_test.py
|
|
|
74ca47 |
+++ b/dirsrvtests/tests/tickets/ticket49122_test.py
|
|
|
74ca47 |
@@ -2,8 +2,7 @@ import time
|
|
|
74ca47 |
import ldap
|
|
|
74ca47 |
import logging
|
|
|
74ca47 |
import pytest
|
|
|
74ca47 |
-from lib389 import DirSrv, Entry, tools, tasks
|
|
|
74ca47 |
-from lib389.tools import DirSrvTools
|
|
|
74ca47 |
+from lib389 import Entry
|
|
|
74ca47 |
from lib389._constants import *
|
|
|
74ca47 |
from lib389.properties import *
|
|
|
74ca47 |
from lib389.tasks import *
|
|
|
74ca47 |
@@ -19,6 +18,15 @@ log = logging.getLogger(__name__)
|
|
|
74ca47 |
|
|
|
74ca47 |
USER_DN = 'uid=user,' + DEFAULT_SUFFIX
|
|
|
74ca47 |
ROLE_DN = 'cn=Filtered_Role_That_Includes_Empty_Role,' + DEFAULT_SUFFIX
|
|
|
74ca47 |
+filters = ['nsrole=cn=empty,dc=example,dc=com',
|
|
|
74ca47 |
+ '(nsrole=cn=empty,dc=example,dc=com)',
|
|
|
74ca47 |
+ '(&(nsrole=cn=empty,dc=example,dc=com))',
|
|
|
74ca47 |
+ '(!(nsrole=cn=empty,dc=example,dc=com))',
|
|
|
74ca47 |
+ '(&(|(objectclass=person)(sn=app*))(userpassword=*))',
|
|
|
74ca47 |
+ '(&(|(objectclass=person)(nsrole=cn=empty,dc=example,dc=com))(userpassword=*))',
|
|
|
74ca47 |
+ '(&(|(nsrole=cn=empty,dc=example,dc=com)(sn=app*))(userpassword=*))',
|
|
|
74ca47 |
+ '(&(|(objectclass=person)(sn=app*))(nsrole=cn=empty,dc=example,dc=com))',
|
|
|
74ca47 |
+ '(&(|(&(cn=*)(objectclass=person)(nsrole=cn=empty,dc=example,dc=com)))(uid=*))']
|
|
|
74ca47 |
|
|
|
74ca47 |
|
|
|
74ca47 |
def test_ticket49122(topo):
|
|
|
74ca47 |
@@ -29,18 +37,6 @@ def test_ticket49122(topo):
|
|
|
74ca47 |
topo.standalone.plugins.enable(name=PLUGIN_ROLES)
|
|
|
74ca47 |
topo.standalone.restart()
|
|
|
74ca47 |
|
|
|
74ca47 |
- # Add invalid role
|
|
|
74ca47 |
- try:
|
|
|
74ca47 |
- topo.standalone.add_s(Entry((
|
|
|
74ca47 |
- ROLE_DN, {'objectclass': ['top', 'ldapsubentry', 'nsroledefinition',
|
|
|
74ca47 |
- 'nscomplexroledefinition', 'nsfilteredroledefinition'],
|
|
|
74ca47 |
- 'cn': 'Filtered_Role_That_Includes_Empty_Role',
|
|
|
74ca47 |
- 'nsRoleFilter': '(!(nsrole=cn=This_Is_An_Empty_Managed_NsRoleDefinition,dc=example,dc=com))',
|
|
|
74ca47 |
- 'description': 'A filtered role with filter that will crash the server'})))
|
|
|
74ca47 |
- except ldap.LDAPError as e:
|
|
|
74ca47 |
- topo.standalone.log.fatal('Failed to add filtered role: error ' + e.message['desc'])
|
|
|
74ca47 |
- assert False
|
|
|
74ca47 |
-
|
|
|
74ca47 |
# Add test user
|
|
|
74ca47 |
try:
|
|
|
74ca47 |
topo.standalone.add_s(Entry((
|
|
|
74ca47 |
@@ -51,16 +47,39 @@ def test_ticket49122(topo):
|
|
|
74ca47 |
assert False
|
|
|
74ca47 |
|
|
|
74ca47 |
if DEBUGGING:
|
|
|
74ca47 |
- # Add debugging steps(if any)...
|
|
|
74ca47 |
print("Attach gdb")
|
|
|
74ca47 |
time.sleep(20)
|
|
|
74ca47 |
|
|
|
74ca47 |
- # Search for the role
|
|
|
74ca47 |
- try:
|
|
|
74ca47 |
- topo.standalone.search_s(USER_DN, ldap.SCOPE_SUBTREE, 'objectclass=*', ['nsrole'])
|
|
|
74ca47 |
- except ldap.LDAPError as e:
|
|
|
74ca47 |
- topo.standalone.log.fatal('Search failed: error ' + str(e))
|
|
|
74ca47 |
- assert False
|
|
|
74ca47 |
+ # Loop over filters
|
|
|
74ca47 |
+ for role_filter in filters:
|
|
|
74ca47 |
+ log.info('Testing filter: ' + role_filter)
|
|
|
74ca47 |
+
|
|
|
74ca47 |
+ # Add invalid role
|
|
|
74ca47 |
+ try:
|
|
|
74ca47 |
+ topo.standalone.add_s(Entry((
|
|
|
74ca47 |
+ ROLE_DN, {'objectclass': ['top', 'ldapsubentry', 'nsroledefinition',
|
|
|
74ca47 |
+ 'nscomplexroledefinition', 'nsfilteredroledefinition'],
|
|
|
74ca47 |
+ 'cn': 'Filtered_Role_That_Includes_Empty_Role',
|
|
|
74ca47 |
+ 'nsRoleFilter': role_filter,
|
|
|
74ca47 |
+ 'description': 'A filtered role with filter that will crash the server'})))
|
|
|
74ca47 |
+ except ldap.LDAPError as e:
|
|
|
74ca47 |
+ topo.standalone.log.fatal('Failed to add filtered role: error ' + e.message['desc'])
|
|
|
74ca47 |
+ assert False
|
|
|
74ca47 |
+
|
|
|
74ca47 |
+ # Search for the role
|
|
|
74ca47 |
+ try:
|
|
|
74ca47 |
+ topo.standalone.search_s(USER_DN, ldap.SCOPE_SUBTREE, 'objectclass=*', ['nsrole'])
|
|
|
74ca47 |
+ except ldap.LDAPError as e:
|
|
|
74ca47 |
+ topo.standalone.log.fatal('Search failed: error ' + str(e))
|
|
|
74ca47 |
+ assert False
|
|
|
74ca47 |
+
|
|
|
74ca47 |
+ # Cleanup
|
|
|
74ca47 |
+ try:
|
|
|
74ca47 |
+ topo.standalone.delete_s(ROLE_DN)
|
|
|
74ca47 |
+ except ldap.LDAPError as e:
|
|
|
74ca47 |
+ topo.standalone.log.fatal('delete failed: error ' + str(e))
|
|
|
74ca47 |
+ assert False
|
|
|
74ca47 |
+ time.sleep(1)
|
|
|
74ca47 |
|
|
|
74ca47 |
topo.standalone.log.info('Test Passed')
|
|
|
74ca47 |
|
|
|
74ca47 |
diff --git a/ldap/servers/plugins/roles/roles_cache.c b/ldap/servers/plugins/roles/roles_cache.c
|
|
|
74ca47 |
index 4f27c4c..3697eaa 100644
|
|
|
74ca47 |
--- a/ldap/servers/plugins/roles/roles_cache.c
|
|
|
74ca47 |
+++ b/ldap/servers/plugins/roles/roles_cache.c
|
|
|
74ca47 |
@@ -1073,20 +1073,38 @@ static int roles_cache_create_role_under(roles_cache_def** roles_cache_suffix, S
|
|
|
74ca47 |
}
|
|
|
74ca47 |
|
|
|
74ca47 |
/*
|
|
|
74ca47 |
- * Check that we are not using nsrole in the filter
|
|
|
74ca47 |
+ * Check that we are not using nsrole in the filter, recurse over all the
|
|
|
74ca47 |
+ * nested filters.
|
|
|
74ca47 |
*/
|
|
|
74ca47 |
static int roles_check_filter(Slapi_Filter *filter_list)
|
|
|
74ca47 |
{
|
|
|
74ca47 |
Slapi_Filter *f;
|
|
|
74ca47 |
char *type = NULL;
|
|
|
74ca47 |
|
|
|
74ca47 |
- for ( f = slapi_filter_list_first( filter_list );
|
|
|
74ca47 |
- f != NULL;
|
|
|
74ca47 |
- f = slapi_filter_list_next( filter_list, f ) )
|
|
|
74ca47 |
- {
|
|
|
74ca47 |
- slapi_filter_get_attribute_type(f, &type);
|
|
|
74ca47 |
- if (strcasecmp(type, NSROLEATTR) == 0){
|
|
|
74ca47 |
- return -1;
|
|
|
74ca47 |
+ f = slapi_filter_list_first( filter_list );
|
|
|
74ca47 |
+ if (f == NULL){
|
|
|
74ca47 |
+ /* Single filter */
|
|
|
74ca47 |
+ if (slapi_filter_get_attribute_type(filter_list, &type) == 0){
|
|
|
74ca47 |
+ if (strcasecmp(type, NSROLEATTR) == 0){
|
|
|
74ca47 |
+ return -1;
|
|
|
74ca47 |
+ }
|
|
|
74ca47 |
+ }
|
|
|
74ca47 |
+ }
|
|
|
74ca47 |
+ for ( ; f != NULL; f = slapi_filter_list_next(filter_list, f) ){
|
|
|
74ca47 |
+ /* Complex filter */
|
|
|
74ca47 |
+ if (slapi_filter_list_first(f)) {
|
|
|
74ca47 |
+ /* Another filter list - recurse */
|
|
|
74ca47 |
+ if (roles_check_filter(f) == -1){
|
|
|
74ca47 |
+ /* Done, break out */
|
|
|
74ca47 |
+ return -1;
|
|
|
74ca47 |
+ }
|
|
|
74ca47 |
+ } else {
|
|
|
74ca47 |
+ /* Not a filter list, so check the type */
|
|
|
74ca47 |
+ if (slapi_filter_get_attribute_type(f, &type) == 0){
|
|
|
74ca47 |
+ if (strcasecmp(type, NSROLEATTR) == 0){
|
|
|
74ca47 |
+ return -1;
|
|
|
74ca47 |
+ }
|
|
|
74ca47 |
+ }
|
|
|
74ca47 |
}
|
|
|
74ca47 |
}
|
|
|
74ca47 |
|
|
|
74ca47 |
--
|
|
|
74ca47 |
2.9.4
|
|
|
74ca47 |
|