|
|
74ca47 |
From abc9ff876209819c8f0dd7e799f1ab6a1b084fe5 Mon Sep 17 00:00:00 2001
|
|
|
b7d5c1 |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
b7d5c1 |
Date: Mon, 20 Mar 2017 15:08:45 -0400
|
|
|
b7d5c1 |
Subject: [PATCH] Issue 49095 - targetattr wildcard evaluation is incorrectly
|
|
|
b7d5c1 |
case sensitive
|
|
|
b7d5c1 |
|
|
|
b7d5c1 |
Description: When processing an aci that uses a wildcard targetattr, the
|
|
|
b7d5c1 |
comparision should be done using case insensitive functions.
|
|
|
b7d5c1 |
|
|
|
b7d5c1 |
https://pagure.io/389-ds-base/issue/49095
|
|
|
b7d5c1 |
|
|
|
b7d5c1 |
Reviewed by: firstyear(Thanks!)
|
|
|
b7d5c1 |
---
|
|
|
b7d5c1 |
dirsrvtests/tests/tickets/ticket49095_test.py | 85 +++++++++++++++++++++++++++
|
|
|
b7d5c1 |
ldap/servers/plugins/acl/acl.c | 10 ++--
|
|
|
b7d5c1 |
2 files changed, 90 insertions(+), 5 deletions(-)
|
|
|
b7d5c1 |
create mode 100644 dirsrvtests/tests/tickets/ticket49095_test.py
|
|
|
b7d5c1 |
|
|
|
b7d5c1 |
diff --git a/dirsrvtests/tests/tickets/ticket49095_test.py b/dirsrvtests/tests/tickets/ticket49095_test.py
|
|
|
b7d5c1 |
new file mode 100644
|
|
|
b7d5c1 |
index 0000000..04f92b2
|
|
|
b7d5c1 |
--- /dev/null
|
|
|
b7d5c1 |
+++ b/dirsrvtests/tests/tickets/ticket49095_test.py
|
|
|
b7d5c1 |
@@ -0,0 +1,85 @@
|
|
|
b7d5c1 |
+import time
|
|
|
b7d5c1 |
+import ldap
|
|
|
b7d5c1 |
+import logging
|
|
|
b7d5c1 |
+import pytest
|
|
|
b7d5c1 |
+from lib389 import DirSrv, Entry, tools, tasks
|
|
|
b7d5c1 |
+from lib389.tools import DirSrvTools
|
|
|
b7d5c1 |
+from lib389._constants import *
|
|
|
b7d5c1 |
+from lib389.properties import *
|
|
|
b7d5c1 |
+from lib389.tasks import *
|
|
|
b7d5c1 |
+from lib389.utils import *
|
|
|
b7d5c1 |
+from lib389.topologies import topology_st as topo
|
|
|
b7d5c1 |
+
|
|
|
b7d5c1 |
+DEBUGGING = os.getenv("DEBUGGING", default=False)
|
|
|
b7d5c1 |
+if DEBUGGING:
|
|
|
b7d5c1 |
+ logging.getLogger(__name__).setLevel(logging.DEBUG)
|
|
|
b7d5c1 |
+else:
|
|
|
b7d5c1 |
+ logging.getLogger(__name__).setLevel(logging.INFO)
|
|
|
b7d5c1 |
+log = logging.getLogger(__name__)
|
|
|
b7d5c1 |
+
|
|
|
b7d5c1 |
+USER_DN = 'uid=testuser,dc=example,dc=com'
|
|
|
b7d5c1 |
+acis = ['(targetattr != "tele*") (version 3.0;acl "test case";allow (read,compare,search)(userdn = "ldap:///anyone");)',
|
|
|
b7d5c1 |
+ '(targetattr != "TELE*") (version 3.0;acl "test case";allow (read,compare,search)(userdn = "ldap:///anyone");)',
|
|
|
b7d5c1 |
+ '(targetattr != "telephonenum*") (version 3.0;acl "test case";allow (read,compare,search)(userdn = "ldap:///anyone");)',
|
|
|
b7d5c1 |
+ '(targetattr != "TELEPHONENUM*") (version 3.0;acl "test case";allow (read,compare,search)(userdn = "ldap:///anyone");)']
|
|
|
b7d5c1 |
+
|
|
|
b7d5c1 |
+
|
|
|
b7d5c1 |
+def test_ticket49095(topo):
|
|
|
b7d5c1 |
+ """Check that target attrbiutes with wildcards are case insensitive
|
|
|
b7d5c1 |
+ """
|
|
|
b7d5c1 |
+
|
|
|
b7d5c1 |
+ # Add an entry
|
|
|
b7d5c1 |
+ try:
|
|
|
b7d5c1 |
+ topo.standalone.add_s(Entry((USER_DN, {
|
|
|
b7d5c1 |
+ 'objectclass': 'top extensibleObject'.split(),
|
|
|
b7d5c1 |
+ 'uid': 'testuser',
|
|
|
b7d5c1 |
+ 'telephonenumber': '555-555-5555'
|
|
|
b7d5c1 |
+ })))
|
|
|
b7d5c1 |
+ except ldap.LDAPError as e:
|
|
|
b7d5c1 |
+ log.fatal('Failed to add test user: ' + e.message['desc'])
|
|
|
b7d5c1 |
+ assert False
|
|
|
b7d5c1 |
+
|
|
|
b7d5c1 |
+ for aci in acis:
|
|
|
b7d5c1 |
+ # Add ACI
|
|
|
b7d5c1 |
+ try:
|
|
|
b7d5c1 |
+ topo.standalone.modify_s(DEFAULT_SUFFIX,
|
|
|
b7d5c1 |
+ [(ldap.MOD_REPLACE, 'aci', aci)])
|
|
|
b7d5c1 |
+
|
|
|
b7d5c1 |
+ except ldap.LDAPError as e:
|
|
|
b7d5c1 |
+ log.fatal('Failed to set aci: ' + aci + ': ' + e.message['desc'])
|
|
|
b7d5c1 |
+ assert False
|
|
|
b7d5c1 |
+
|
|
|
b7d5c1 |
+ # Set Anonymous Bind to test aci
|
|
|
b7d5c1 |
+ try:
|
|
|
b7d5c1 |
+ topo.standalone.simple_bind_s("", "")
|
|
|
b7d5c1 |
+ except ldap.LDAPError as e:
|
|
|
b7d5c1 |
+ log.fatal('Failed to bind anonymously: ' + e.message['desc'])
|
|
|
b7d5c1 |
+ assert False
|
|
|
b7d5c1 |
+
|
|
|
b7d5c1 |
+ # Search for entry - should not get any results
|
|
|
b7d5c1 |
+ try:
|
|
|
b7d5c1 |
+ entry = topo.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_BASE,
|
|
|
b7d5c1 |
+ 'telephonenumber=*')
|
|
|
b7d5c1 |
+ if entry:
|
|
|
b7d5c1 |
+ log.fatal('The entry was incorrectly returned')
|
|
|
b7d5c1 |
+ assert False
|
|
|
b7d5c1 |
+ except ldap.LDAPError as e:
|
|
|
b7d5c1 |
+ log.fatal('Failed to search anonymously: ' + e.message['desc'])
|
|
|
b7d5c1 |
+ assert False
|
|
|
b7d5c1 |
+
|
|
|
b7d5c1 |
+ # Set root DN Bind so we can update aci's
|
|
|
b7d5c1 |
+ try:
|
|
|
b7d5c1 |
+ topo.standalone.simple_bind_s(DN_DM, PASSWORD)
|
|
|
b7d5c1 |
+ except ldap.LDAPError as e:
|
|
|
b7d5c1 |
+ log.fatal('Failed to bind anonymously: ' + e.message['desc'])
|
|
|
b7d5c1 |
+ assert False
|
|
|
b7d5c1 |
+
|
|
|
b7d5c1 |
+ log.info("Test Passed")
|
|
|
b7d5c1 |
+
|
|
|
b7d5c1 |
+
|
|
|
b7d5c1 |
+if __name__ == '__main__':
|
|
|
b7d5c1 |
+ # Run isolated
|
|
|
b7d5c1 |
+ # -s for DEBUG mode
|
|
|
b7d5c1 |
+ CURRENT_FILE = os.path.realpath(__file__)
|
|
|
b7d5c1 |
+ pytest.main("-s %s" % CURRENT_FILE)
|
|
|
b7d5c1 |
+
|
|
|
b7d5c1 |
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
|
|
|
74ca47 |
index 0a93808..48b8efc 100644
|
|
|
b7d5c1 |
--- a/ldap/servers/plugins/acl/acl.c
|
|
|
b7d5c1 |
+++ b/ldap/servers/plugins/acl/acl.c
|
|
|
b7d5c1 |
@@ -3407,19 +3407,19 @@ acl_match_substring ( Slapi_Filter *f, char *str, int exact_match)
|
|
|
b7d5c1 |
}
|
|
|
b7d5c1 |
|
|
|
b7d5c1 |
/* this assumes that str and the filter components are already
|
|
|
b7d5c1 |
- * normalized. If not, it shoul be done
|
|
|
b7d5c1 |
+ * normalized. If not, it should be done
|
|
|
b7d5c1 |
*/
|
|
|
b7d5c1 |
if ( initial != NULL) {
|
|
|
b7d5c1 |
len = strlen(initial);
|
|
|
b7d5c1 |
if (exact_match) {
|
|
|
b7d5c1 |
- int rc = strncmp(p, initial, len);
|
|
|
b7d5c1 |
+ int rc = strncasecmp(p, initial, len);
|
|
|
b7d5c1 |
if (rc) {
|
|
|
b7d5c1 |
return ACL_FALSE;
|
|
|
b7d5c1 |
} else {
|
|
|
b7d5c1 |
p += len;
|
|
|
b7d5c1 |
}
|
|
|
b7d5c1 |
} else {
|
|
|
b7d5c1 |
- p = strstr(p, initial);
|
|
|
b7d5c1 |
+ p = strcasestr(p, initial);
|
|
|
b7d5c1 |
if (p) {
|
|
|
b7d5c1 |
p += len;
|
|
|
b7d5c1 |
} else {
|
|
|
b7d5c1 |
@@ -3430,7 +3430,7 @@ acl_match_substring ( Slapi_Filter *f, char *str, int exact_match)
|
|
|
b7d5c1 |
|
|
|
b7d5c1 |
if ( any != NULL) {
|
|
|
b7d5c1 |
for (i = 0; any && any[i] != NULL; i++) {
|
|
|
b7d5c1 |
- p = strstr(p, any[i]);
|
|
|
b7d5c1 |
+ p = strcasestr(p, any[i]);
|
|
|
b7d5c1 |
if (p) {
|
|
|
b7d5c1 |
p += strlen(any[i]);
|
|
|
b7d5c1 |
} else {
|
|
|
b7d5c1 |
@@ -3444,7 +3444,7 @@ acl_match_substring ( Slapi_Filter *f, char *str, int exact_match)
|
|
|
b7d5c1 |
len = strlen(final);
|
|
|
b7d5c1 |
tlen = strlen(p);
|
|
|
b7d5c1 |
if (len > tlen) return ACL_FALSE;
|
|
|
b7d5c1 |
- if (strcmp(p+tlen-len, final)) return ACL_FALSE;
|
|
|
b7d5c1 |
+ if (strcasecmp(p+tlen-len, final)) return ACL_FALSE;
|
|
|
b7d5c1 |
}
|
|
|
b7d5c1 |
|
|
|
b7d5c1 |
return ACL_TRUE;
|
|
|
b7d5c1 |
--
|
|
|
b7d5c1 |
2.9.3
|
|
|
b7d5c1 |
|