Branch '389-ds-base-1.3.3' - ldap/servers
by Noriko Hosoi
ldap/servers/slapd/slapi-plugin.h | 2 ++
1 file changed, 2 insertions(+)
New commits:
commit d6f7b97242e40d432d18baf690f216e29082d425
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Sun Mar 1 16:58:46 2015 -0800
Ticket #48109 - substring index with nssubstrbegin: 1 is not being used with filters like (attr=x*)
Description: commit ae69e4aa1dcec1c5f79af502b77d9e19a3d348ee introduced
an jenkins error:
------------------------------------------------------------
ldap/servers/slapd/plugin_syntax.c:911:2: warning: implicit declaration of
function 'slapi_attr_assertion2keys_sub_sv_pb' [-Wimplicit-function-declaration]
ldap/servers/slapd/back-ldbm/filterindex.c:956:5: warning: implicit declaration
of function 'slapi_attr_assertion2keys_sub_sv_pb' [-Wimplicit-function-declaration]
------------------------------------------------------------
Added a missing function declaration slapi_attr_assertion2keys_sub_sv_pb
to slapi-plugin.h.
(cherry picked from commit 370187574293b1d6f3a84e7f366986dc0cefc394)
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 69a7743..c420cce 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5860,6 +5860,8 @@ int slapi_attr_assertion2keys_ava_sv( const Slapi_Attr *sattr, Slapi_Value *val,
Slapi_Value ***ivals, int ftype );
int slapi_attr_assertion2keys_sub_sv( const Slapi_Attr *sattr, char *initial,
char **any, char *final, Slapi_Value ***ivals );
+int slapi_attr_assertion2keys_sub_sv_pb( Slapi_PBlock *pb, const Slapi_Attr *sattr,
+ char *initial, char **any, char *final, Slapi_Value ***ivals);
/**
* Normalize the given value using the syntax associated with the
9 years, 1 month
ldap/servers
by Noriko Hosoi
ldap/servers/slapd/slapi-plugin.h | 2 ++
1 file changed, 2 insertions(+)
New commits:
commit 370187574293b1d6f3a84e7f366986dc0cefc394
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Sun Mar 1 16:58:46 2015 -0800
Ticket #48109 - substring index with nssubstrbegin: 1 is not being used with filters like (attr=x*)
Description: commit ae69e4aa1dcec1c5f79af502b77d9e19a3d348ee introduced
an jenkins error:
------------------------------------------------------------
ldap/servers/slapd/plugin_syntax.c:911:2: warning: implicit declaration of
function 'slapi_attr_assertion2keys_sub_sv_pb' [-Wimplicit-function-declaration]
ldap/servers/slapd/back-ldbm/filterindex.c:956:5: warning: implicit declaration
of function 'slapi_attr_assertion2keys_sub_sv_pb' [-Wimplicit-function-declaration]
------------------------------------------------------------
Added a missing function declaration slapi_attr_assertion2keys_sub_sv_pb
to slapi-plugin.h.
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 69a7743..c420cce 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5860,6 +5860,8 @@ int slapi_attr_assertion2keys_ava_sv( const Slapi_Attr *sattr, Slapi_Value *val,
Slapi_Value ***ivals, int ftype );
int slapi_attr_assertion2keys_sub_sv( const Slapi_Attr *sattr, char *initial,
char **any, char *final, Slapi_Value ***ivals );
+int slapi_attr_assertion2keys_sub_sv_pb( Slapi_PBlock *pb, const Slapi_Attr *sattr,
+ char *initial, char **any, char *final, Slapi_Value ***ivals);
/**
* Normalize the given value using the syntax associated with the
9 years, 1 month
Branch '389-ds-base-1.3.3' - 2 commits - dirsrvtests/tickets ldap/servers
by Noriko Hosoi
dirsrvtests/tickets/ticket48109_test.py | 386 +++++++++++++++++++++++++++++
ldap/servers/slapd/back-ldbm/filterindex.c | 5
ldap/servers/slapd/back-ldbm/ldbm_attr.c | 70 ++++-
ldap/servers/slapd/plugin_syntax.c | 22 +
ldap/servers/slapd/slapi-plugin.h | 2
5 files changed, 467 insertions(+), 18 deletions(-)
New commits:
commit 09fc02e509b94c9e6a859038afe370c0ed2c595d
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Sun Mar 1 14:59:57 2015 -0800
Ticket 48109 - CI test: added test cases for ticket 48109
Ticket #48109 - substring index with nssubstrbegin: 1 is not being used with filters like (attr=x*)
Testcases:
1. Set SubStr lengths to cn=uid,cn=index,...
objectClass: extensibleObject
nsIndexType: sub
nsSubStrBegin: 2
nsSubStrEnd: 2
Add an entry with uid=auser0; search with "(uid=a*)".
Check the search result in the access log; if notes=[AU] is not
found. The testcase is passed.
2. Set SubStr lengths to cn=uid,cn=index,...
nsIndexType: sub
nsMatchingRule: nsSubStrBegin=2
nsMatchingRule: nsSubStrEnd=2
Add an entry with uid=buser1; search with "(uid=b*)".
Check the search result in the access log; if notes=[AU] is not
found. The testcase is passed.
3. Set SubStr lengths to cn=uid,cn=index,...
objectClass: extensibleObject
nsIndexType: sub
nsSubStrBegin: 2
nsSubStrEnd: 2
nsMatchingRule: nsSubStrBegin=3
nsMatchingRule: nsSubStrEnd=3
Add an entry with uid=cuser2; search with "(uid=c*)" and (uid=*2).
Check the search result in the access log; if notes=[AU] is not
found. The testcase is passed. Note: nsSubStr{Begin,Middle,End}:
is honored over nsMatchingRule: nsSubStr{Begin,Middle,End}=.
https://fedorahosted.org/389/ticket/48109
(cherry picked from commit 71f7659d5f002a4e50f0dc123f0311b04ee87b79)
diff --git a/dirsrvtests/tickets/ticket48109_test.py b/dirsrvtests/tickets/ticket48109_test.py
new file mode 100644
index 0000000..ba470f0
--- /dev/null
+++ b/dirsrvtests/tickets/ticket48109_test.py
@@ -0,0 +1,386 @@
+import os
+import sys
+import time
+import ldap
+import logging
+import pytest
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from lib389.utils import *
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+installation1_prefix = None
+
+UID_INDEX = 'cn=uid,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config'
+
+class TopologyStandalone(object):
+ def __init__(self, standalone):
+ standalone.open()
+ self.standalone = standalone
+
+
+(a)pytest.fixture(scope="module")
+def topology(request):
+ global installation1_prefix
+ if installation1_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+
+ # Creating standalone instance ...
+ standalone = DirSrv(verbose=False)
+ args_instance[SER_HOST] = HOST_STANDALONE
+ args_instance[SER_PORT] = PORT_STANDALONE
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
+ args_standalone = args_instance.copy()
+ standalone.allocate(args_standalone)
+ instance_standalone = standalone.exists()
+ if instance_standalone:
+ standalone.delete()
+ standalone.create()
+ standalone.open()
+
+ # Clear out the tmp dir
+ standalone.clearTmpDir(__file__)
+
+ return TopologyStandalone(standalone)
+
+
+def test_ticket48109_0(topology):
+ '''
+ Set SubStr lengths to cn=uid,cn=index,...
+ objectClass: extensibleObject
+ nsIndexType: sub
+ nsSubStrBegin: 2
+ nsSubStrEnd: 2
+ '''
+ log.info('Test case 0')
+ # add substr setting to UID_INDEX
+ try:
+ topology.standalone.modify_s(UID_INDEX,
+ [(ldap.MOD_ADD, 'objectClass', 'extensibleObject'),
+ (ldap.MOD_ADD, 'nsIndexType', 'sub'),
+ (ldap.MOD_ADD, 'nsSubStrBegin', '2'),
+ (ldap.MOD_ADD, 'nsSubStrEnd', '2')])
+ except ldap.LDAPError, e:
+ log.error('Failed to add substr lengths: error ' + e.message['desc'])
+ assert False
+
+ # restart the server to apply the indexing
+ topology.standalone.restart(timeout=10)
+
+ # add a test user
+ UID = 'auser0'
+ USER_DN = 'uid=%s,%s' % (UID, SUFFIX)
+ try:
+ topology.standalone.add_s(Entry((USER_DN, {
+ 'objectclass': 'top person organizationalPerson inetOrgPerson'.split(),
+ 'cn': 'a user0',
+ 'sn': 'user0',
+ 'givenname': 'a',
+ 'mail': UID})))
+ except ldap.LDAPError, e:
+ log.error('Failed to add ' + USER_DN + ': error ' + e.message['desc'])
+ assert False
+
+ entries = topology.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, '(uid=a*)')
+ assert len(entries) == 1
+
+ # restart the server to check the access log
+ topology.standalone.restart(timeout=10)
+
+ cmdline = 'egrep %s %s | egrep "uid=a\*"' % (SUFFIX, topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l0 = p.readline()
+ if l0 == "":
+ log.error('Search with "(uid=a*)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ #regex = re.compile('\(conn=[0-9]* op=[0-9]*\) SRCH .*')
+ regex = re.compile(r'.*\s+(conn=\d+ op=\d+)\s+SRCH .*')
+ match = regex.match(l0)
+ log.info('match: %s' % match.group(1))
+ cmdline = 'egrep "%s" %s | egrep "RESULT"' % (match.group(1), topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l1 = p.readline()
+ if l1 == "":
+ log.error('Search result of "(uid=a*)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ log.info('l1: %s' % l1)
+ regex = re.compile(r'.*nentries=(\d+)\s+.*')
+ match = regex.match(l1)
+ log.info('match: nentires=%s' % match.group(1))
+ if match.group(1) == "0":
+ log.error('Entry uid=a* not found.')
+ assert False
+ else:
+ log.info('Entry uid=a* found.')
+ regex = re.compile(r'.*(notes=[AU]).*')
+ match = regex.match(l1)
+ if match:
+ log.error('%s - substr index was not used' % match.group(1))
+ assert False
+ else:
+ log.info('Test case 0 - OK - substr index used')
+
+ # clean up substr setting to UID_INDEX
+ try:
+ topology.standalone.modify_s(UID_INDEX,
+ [(ldap.MOD_DELETE, 'objectClass', 'extensibleObject'),
+ (ldap.MOD_DELETE, 'nsIndexType', 'sub'),
+ (ldap.MOD_DELETE, 'nsSubStrBegin', '2'),
+ (ldap.MOD_DELETE, 'nsSubStrEnd', '2')])
+ except ldap.LDAPError, e:
+ log.error('Failed to delete substr lengths: error ' + e.message['desc'])
+ assert False
+
+
+def test_ticket48109_1(topology):
+ '''
+ Set SubStr lengths to cn=uid,cn=index,...
+ nsIndexType: sub
+ nsMatchingRule: nsSubStrBegin=2
+ nsMatchingRule: nsSubStrEnd=2
+ '''
+ log.info('Test case 1')
+ # add substr setting to UID_INDEX
+ try:
+ topology.standalone.modify_s(UID_INDEX,
+ [(ldap.MOD_ADD, 'nsIndexType', 'sub'),
+ (ldap.MOD_ADD, 'nsMatchingRule', 'nssubstrbegin=2'),
+ (ldap.MOD_ADD, 'nsMatchingRule', 'nssubstrend=2')])
+ except ldap.LDAPError, e:
+ log.error('Failed to add substr lengths: error ' + e.message['desc'])
+ assert False
+
+ # restart the server to apply the indexing
+ topology.standalone.restart(timeout=10)
+
+ # add a test user
+ UID = 'buser1'
+ USER_DN = 'uid=%s,%s' % (UID, SUFFIX)
+ try:
+ topology.standalone.add_s(Entry((USER_DN, {
+ 'objectclass': 'top person organizationalPerson inetOrgPerson'.split(),
+ 'cn': 'b user1',
+ 'sn': 'user1',
+ 'givenname': 'b',
+ 'mail': UID})))
+ except ldap.LDAPError, e:
+ log.error('Failed to add ' + USER_DN + ': error ' + e.message['desc'])
+ assert False
+
+ entries = topology.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, '(uid=b*)')
+ assert len(entries) == 1
+
+ # restart the server to check the access log
+ topology.standalone.restart(timeout=10)
+
+ cmdline = 'egrep %s %s | egrep "uid=b\*"' % (SUFFIX, topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l0 = p.readline()
+ if l0 == "":
+ log.error('Search with "(uid=b*)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ #regex = re.compile('\(conn=[0-9]* op=[0-9]*\) SRCH .*')
+ regex = re.compile(r'.*\s+(conn=\d+ op=\d+)\s+SRCH .*')
+ match = regex.match(l0)
+ log.info('match: %s' % match.group(1))
+ cmdline = 'egrep "%s" %s | egrep "RESULT"' % (match.group(1), topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l1 = p.readline()
+ if l1 == "":
+ log.error('Search result of "(uid=*b)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ log.info('l1: %s' % l1)
+ regex = re.compile(r'.*nentries=(\d+)\s+.*')
+ match = regex.match(l1)
+ log.info('match: nentires=%s' % match.group(1))
+ if match.group(1) == "0":
+ log.error('Entry uid=*b not found.')
+ assert False
+ else:
+ log.info('Entry uid=*b found.')
+ regex = re.compile(r'.*(notes=[AU]).*')
+ match = regex.match(l1)
+ if match:
+ log.error('%s - substr index was not used' % match.group(1))
+ assert False
+ else:
+ log.info('Test case 1 - OK - substr index used')
+
+ # clean up substr setting to UID_INDEX
+ try:
+ topology.standalone.modify_s(UID_INDEX,
+ [(ldap.MOD_DELETE, 'nsIndexType', 'sub'),
+ (ldap.MOD_DELETE, 'nsMatchingRule', 'nssubstrbegin=2'),
+ (ldap.MOD_DELETE, 'nsMatchingRule', 'nssubstrend=2')])
+ except ldap.LDAPError, e:
+ log.error('Failed to delete substr lengths: error ' + e.message['desc'])
+ assert False
+
+
+def test_ticket48109_2(topology):
+ '''
+ Set SubStr conflict formats/lengths to cn=uid,cn=index,...
+ objectClass: extensibleObject
+ nsIndexType: sub
+ nsMatchingRule: nsSubStrBegin=3
+ nsMatchingRule: nsSubStrEnd=3
+ nsSubStrBegin: 2
+ nsSubStrEnd: 2
+ nsSubStr{Begin,End} are honored.
+ '''
+ log.info('Test case 2')
+
+ # add substr setting to UID_INDEX
+ try:
+ topology.standalone.modify_s(UID_INDEX,
+ [(ldap.MOD_ADD, 'nsIndexType', 'sub'),
+ (ldap.MOD_ADD, 'nsMatchingRule', 'nssubstrbegin=3'),
+ (ldap.MOD_ADD, 'nsMatchingRule', 'nssubstrend=3'),
+ (ldap.MOD_ADD, 'objectClass', 'extensibleObject'),
+ (ldap.MOD_ADD, 'nsSubStrBegin', '2'),
+ (ldap.MOD_ADD, 'nsSubStrEnd', '2')])
+ except ldap.LDAPError, e:
+ log.error('Failed to add substr lengths: error ' + e.message['desc'])
+ assert False
+
+ # restart the server to apply the indexing
+ topology.standalone.restart(timeout=10)
+
+ # add a test user
+ UID = 'cuser2'
+ USER_DN = 'uid=%s,%s' % (UID, SUFFIX)
+ try:
+ topology.standalone.add_s(Entry((USER_DN, {
+ 'objectclass': 'top person organizationalPerson inetOrgPerson'.split(),
+ 'cn': 'c user2',
+ 'sn': 'user2',
+ 'givenname': 'c',
+ 'mail': UID})))
+ except ldap.LDAPError, e:
+ log.error('Failed to add ' + USER_DN + ': error ' + e.message['desc'])
+ assert False
+
+ entries = topology.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, '(uid=c*)')
+ assert len(entries) == 1
+
+ entries = topology.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, '(uid=*2)')
+ assert len(entries) == 1
+
+ # restart the server to check the access log
+ topology.standalone.restart(timeout=10)
+
+ cmdline = 'egrep %s %s | egrep "uid=c\*"' % (SUFFIX, topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l0 = p.readline()
+ if l0 == "":
+ log.error('Search with "(uid=c*)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ #regex = re.compile('\(conn=[0-9]* op=[0-9]*\) SRCH .*')
+ regex = re.compile(r'.*\s+(conn=\d+ op=\d+)\s+SRCH .*')
+ match = regex.match(l0)
+ log.info('match: %s' % match.group(1))
+ cmdline = 'egrep "%s" %s | egrep "RESULT"' % (match.group(1), topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l1 = p.readline()
+ if l1 == "":
+ log.error('Search result of "(uid=c*)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ log.info('l1: %s' % l1)
+ regex = re.compile(r'.*nentries=(\d+)\s+.*')
+ match = regex.match(l1)
+ log.info('match: nentires=%s' % match.group(1))
+ if match.group(1) == "0":
+ log.error('Entry uid=c* not found.')
+ assert False
+ else:
+ log.info('Entry uid=c* found.')
+ regex = re.compile(r'.*(notes=[AU]).*')
+ match = regex.match(l1)
+ if match:
+ log.error('%s - substr index was not used' % match.group(1))
+ assert False
+ else:
+ log.info('Test case 2-1 - OK - correct substr index used')
+
+ cmdline = 'egrep %s %s | egrep "uid=\*2"' % (SUFFIX, topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l0 = p.readline()
+ if l0 == "":
+ log.error('Search with "(uid=*2)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ #regex = re.compile('\(conn=[0-9]* op=[0-9]*\) SRCH .*')
+ regex = re.compile(r'.*\s+(conn=\d+ op=\d+)\s+SRCH .*')
+ match = regex.match(l0)
+ log.info('match: %s' % match.group(1))
+ cmdline = 'egrep "%s" %s | egrep "RESULT"' % (match.group(1), topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l1 = p.readline()
+ if l1 == "":
+ log.error('Search result of "(uid=*2)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ log.info('l1: %s' % l1)
+ regex = re.compile(r'.*nentries=(\d+)\s+.*')
+ match = regex.match(l1)
+ log.info('match: nentires=%s' % match.group(1))
+ if match.group(1) == "0":
+ log.error('Entry uid=*2 not found.')
+ assert False
+ else:
+ log.info('Entry uid=*2 found.')
+ regex = re.compile(r'.*(notes=[AU]).*')
+ match = regex.match(l1)
+ if match:
+ log.error('%s - substr index was not used' % match.group(1))
+ assert False
+ else:
+ log.info('Test case 2-2 - OK - correct substr index used')
+
+ # clean up substr setting to UID_INDEX
+ try:
+ topology.standalone.modify_s(UID_INDEX,
+ [(ldap.MOD_DELETE, 'nsIndexType', 'sub'),
+ (ldap.MOD_DELETE, 'nsMatchingRule', 'nssubstrbegin=3'),
+ (ldap.MOD_DELETE, 'nsMatchingRule', 'nssubstrend=3'),
+ (ldap.MOD_DELETE, 'objectClass', 'extensibleObject'),
+ (ldap.MOD_DELETE, 'nsSubStrBegin', '2'),
+ (ldap.MOD_DELETE, 'nsSubStrEnd', '2')])
+ except ldap.LDAPError, e:
+ log.error('Failed to delete substr lengths: error ' + e.message['desc'])
+ assert False
+
+ log.info('Test complete')
+
+
+def test_ticket48109_final(topology):
+ topology.standalone.delete()
+ log.info('Testcase PASSED')
+
+
+def run_isolated():
+ global installation1_prefix
+ installation1_prefix = None
+
+ topo = topology(True)
+ test_ticket48109_0(topo)
+ test_ticket48109_1(topo)
+ test_ticket48109_2(topo)
+ test_ticket48109_final(topo)
+
+
+if __name__ == '__main__':
+ run_isolated()
+
commit 511ec03a94a09930ef9a43c223e95be4f3112ec4
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Feb 26 17:39:36 2015 -0800
Ticket #48109 - substring index with nssubstrbegin: 1 is not being used with filters like (attr=x*)
Description: subString index width was not properly passed to the
syntax plugin in the substr search. This patch fixes a couple of
issues.
1. Pass substrlen array to syntax plugin by stashing it in pblock
with SLAPI_SYNTAX_SUBSTRLENS.
2. Advertised format "nsSubStr{Begin,Middle,End}: width" was not
supported. It is again supported.
3. If both "nsSubStr{Begin,Middle,End}: width" and "nsMatchingRule:
nsSubStr{Begin,Middle,End}=width" are specified, the former is
honored, the latter is used if the former directive does not exist.
https://fedorahosted.org/389/ticket/48109
Reviewed by rmeggins(a)redhat.com (Thank you, Rich!!)
(cherry picked from commit ae69e4aa1dcec1c5f79af502b77d9e19a3d348ee)
diff --git a/ldap/servers/slapd/back-ldbm/filterindex.c b/ldap/servers/slapd/back-ldbm/filterindex.c
index 7054ef8..d5489d1 100644
--- a/ldap/servers/slapd/back-ldbm/filterindex.c
+++ b/ldap/servers/slapd/back-ldbm/filterindex.c
@@ -936,6 +936,7 @@ substring_candidates(
Slapi_Attr sattr;
back_txn txn = {NULL};
int pr_idx = -1;
+ struct attrinfo *ai = NULL;
LDAPDebug( LDAP_DEBUG_TRACE, "=> sub_candidates\n", 0, 0, 0 );
@@ -950,7 +951,9 @@ substring_candidates(
* assertion values
*/
slapi_attr_init(&sattr, type);
- slapi_attr_assertion2keys_sub_sv( &sattr, initial, any, final, &ivals );
+ ainfo_get(be, type, &ai);
+ slapi_pblock_set(pb, SLAPI_SYNTAX_SUBSTRLENS, ai->ai_substr_lens );
+ slapi_attr_assertion2keys_sub_sv_pb( pb, &sattr, initial, any, final, &ivals );
attr_done(&sattr);
slapi_pblock_get(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx);
if ( ivals == NULL || *ivals == NULL ) {
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attr.c b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
index 7b01acf..877d536 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_attr.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
@@ -677,6 +677,7 @@ attr_index_config(
Slapi_Attr *attr;
int mr_count = 0;
char myreturntext[SLAPI_DSE_RETURNTEXT_SIZE];
+ int substrval = 0;
/* Get the cn */
if (0 == slapi_entry_attr_find(e, "cn", &attr)) {
@@ -762,6 +763,31 @@ attr_index_config(
* ordering matching rule compatible with the attribute syntax, and there is
* a compare function. If not, we assume it is a RULE index definition.
*/
+ /*
+ * nsSubStrBegin: 2
+ * nsSubStrMiddle: 2
+ * nsSubStrEnd: 2
+ */
+ substrval = slapi_entry_attr_get_int(e, INDEX_ATTR_SUBSTRBEGIN);
+ if (substrval) {
+ substrlens = (int *)slapi_ch_calloc(1, sizeof(int) * INDEX_SUBSTRLEN);
+ substrlens[INDEX_SUBSTRBEGIN] = substrval;
+ }
+ substrval = slapi_entry_attr_get_int(e, INDEX_ATTR_SUBSTRMIDDLE);
+ if (substrval) {
+ if (!substrlens) {
+ substrlens = (int *)slapi_ch_calloc(1, sizeof(int) * INDEX_SUBSTRLEN);
+ }
+ substrlens[INDEX_SUBSTRMIDDLE] = substrval;
+ }
+ substrval = slapi_entry_attr_get_int(e, INDEX_ATTR_SUBSTREND);
+ if (substrval) {
+ if (!substrlens) {
+ substrlens = (int *)slapi_ch_calloc(1, sizeof(int) * INDEX_SUBSTRLEN);
+ }
+ substrlens[INDEX_SUBSTREND] = substrval;
+ }
+ a->ai_substr_lens = substrlens;
if(0 == slapi_entry_attr_find(e, "nsMatchingRule", &attr)){
char** official_rules;
@@ -778,21 +804,35 @@ attr_index_config(
Slapi_PBlock* pb = NULL;
int do_continue = 0; /* can we skip the RULE parsing stuff? */
attrValue = slapi_value_get_berval(sval);
-
- if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTRBEGIN)) {
- _set_attr_substrlen(INDEX_SUBSTRBEGIN, attrValue->bv_val, &substrlens);
- do_continue = 1; /* done with j - next j */
- } else if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTRMIDDLE)) {
- _set_attr_substrlen(INDEX_SUBSTRMIDDLE, attrValue->bv_val, &substrlens);
- do_continue = 1; /* done with j - next j */
- } else if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTREND)) {
- _set_attr_substrlen(INDEX_SUBSTREND, attrValue->bv_val, &substrlens);
- do_continue = 1; /* done with j - next j */
+ /*
+ * In case nsSubstr{Begin,Middle,End}: num is not set, but set by this format:
+ * nsMatchingRule: nsSubstrBegin=2
+ * nsMatchingRule: nsSubstrMiddle=2
+ * nsMatchingRule: nsSubstrEnd=2
+ */
+ if (!a->ai_substr_lens || !a->ai_substr_lens[INDEX_SUBSTRBEGIN]) {
+ if (PL_strcasestr(attrValue->bv_val, INDEX_ATTR_SUBSTRBEGIN)) {
+ _set_attr_substrlen(INDEX_SUBSTRBEGIN, attrValue->bv_val, &substrlens);
+ do_continue = 1; /* done with j - next j */
+ }
+ }
+ if (!a->ai_substr_lens || !a->ai_substr_lens[INDEX_SUBSTRMIDDLE]) {
+ if (PL_strcasestr(attrValue->bv_val, INDEX_ATTR_SUBSTRMIDDLE)) {
+ _set_attr_substrlen(INDEX_SUBSTRMIDDLE, attrValue->bv_val, &substrlens);
+ do_continue = 1; /* done with j - next j */
+ }
+ }
+ if (!a->ai_substr_lens || !a->ai_substr_lens[INDEX_SUBSTREND]) {
+ if (PL_strcasestr(attrValue->bv_val, INDEX_ATTR_SUBSTREND)) {
+ _set_attr_substrlen(INDEX_SUBSTREND, attrValue->bv_val, &substrlens);
+ do_continue = 1; /* done with j - next j */
+ }
+ }
/* check if this is a simple ordering specification
for an attribute that has no ordering matching rule */
- } else if (slapi_matchingrule_is_ordering(attrValue->bv_val, attrsyntax_oid) &&
- slapi_matchingrule_can_use_compare_fn(attrValue->bv_val) &&
- !a->ai_sattr.a_mr_ord_plugin) { /* no ordering for this attribute */
+ if (slapi_matchingrule_is_ordering(attrValue->bv_val, attrsyntax_oid) &&
+ slapi_matchingrule_can_use_compare_fn(attrValue->bv_val) &&
+ !a->ai_sattr.a_mr_ord_plugin) { /* no ordering for this attribute */
need_compare_fn = 1; /* get compare func for this attr */
do_continue = 1; /* done with j - next j */
}
@@ -844,7 +884,9 @@ attr_index_config(
slapi_pblock_destroy (pb);
}
official_rules[k] = NULL;
- a->ai_substr_lens = substrlens;
+ if (substrlens) {
+ a->ai_substr_lens = substrlens;
+ }
if (k > 0) {
a->ai_index_rules = official_rules;
a->ai_indexmask |= INDEX_RULES;
diff --git a/ldap/servers/slapd/plugin_syntax.c b/ldap/servers/slapd/plugin_syntax.c
index 878e107..fa05b0b 100644
--- a/ldap/servers/slapd/plugin_syntax.c
+++ b/ldap/servers/slapd/plugin_syntax.c
@@ -908,6 +908,19 @@ slapi_attr_assertion2keys_sub_sv(
Slapi_Value ***ivals
)
{
+ return slapi_attr_assertion2keys_sub_sv_pb(NULL, sattr, initial, any, final, ivals);
+}
+
+int
+slapi_attr_assertion2keys_sub_sv_pb(
+ Slapi_PBlock *pb,
+ const Slapi_Attr *sattr,
+ char *initial,
+ char **any,
+ char *final,
+ Slapi_Value ***ivals
+)
+{
int rc;
Slapi_PBlock pipb;
struct slapdplugin *pi = NULL;
@@ -927,13 +940,16 @@ slapi_attr_assertion2keys_sub_sv(
pi = sattr->a_plugin;
a2k_fn = sattr->a_plugin->plg_syntax_assertion2keys_sub;
}
- pblock_init( &pipb );
- slapi_pblock_set( &pipb, SLAPI_PLUGIN, pi );
+ if (NULL == pb) {
+ pblock_init( &pipb );
+ pb = &pipb;
+ }
+ slapi_pblock_set( pb, SLAPI_PLUGIN, pi );
rc = -1; /* means no assertion2keys function */
*ivals = NULL;
if ( a2k_fn != NULL ) {
- rc = (*a2k_fn)( &pipb, initial, any, final, ivals );
+ rc = (*a2k_fn)( pb, initial, any, final, ivals );
}
LDAPDebug( LDAP_DEBUG_FILTER,
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 3a1203a..69a7743 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5849,6 +5849,8 @@ int slapi_call_syntax_assertion2keys_ava_sv( void *vpi, Slapi_Value *val,
Slapi_Value ***ivals, int ftype );
int slapi_call_syntax_assertion2keys_sub_sv( void *vpi, char *initial,
char **any, char *final, Slapi_Value ***ivals );
+int slapi_call_syntax_assertion2keys_sub_sv_pb( Slapi_PBlock *pb, void *vpi,
+ char *initial, char **any, char *final, Slapi_Value ***ivals );
int slapi_attr_values2keys_sv( const Slapi_Attr *sattr, Slapi_Value **vals,
Slapi_Value ***ivals, int ftype );
9 years, 1 month
2 commits - dirsrvtests/tickets ldap/servers
by Noriko Hosoi
dirsrvtests/tickets/ticket48109_test.py | 386 +++++++++++++++++++++++++++++
ldap/servers/slapd/back-ldbm/filterindex.c | 5
ldap/servers/slapd/back-ldbm/ldbm_attr.c | 70 ++++-
ldap/servers/slapd/plugin_syntax.c | 22 +
ldap/servers/slapd/slapi-plugin.h | 2
5 files changed, 467 insertions(+), 18 deletions(-)
New commits:
commit 71f7659d5f002a4e50f0dc123f0311b04ee87b79
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Sun Mar 1 14:59:57 2015 -0800
Ticket 48109 - CI test: added test cases for ticket 48109
Ticket #48109 - substring index with nssubstrbegin: 1 is not being used with filters like (attr=x*)
Testcases:
1. Set SubStr lengths to cn=uid,cn=index,...
objectClass: extensibleObject
nsIndexType: sub
nsSubStrBegin: 2
nsSubStrEnd: 2
Add an entry with uid=auser0; search with "(uid=a*)".
Check the search result in the access log; if notes=[AU] is not
found. The testcase is passed.
2. Set SubStr lengths to cn=uid,cn=index,...
nsIndexType: sub
nsMatchingRule: nsSubStrBegin=2
nsMatchingRule: nsSubStrEnd=2
Add an entry with uid=buser1; search with "(uid=b*)".
Check the search result in the access log; if notes=[AU] is not
found. The testcase is passed.
3. Set SubStr lengths to cn=uid,cn=index,...
objectClass: extensibleObject
nsIndexType: sub
nsSubStrBegin: 2
nsSubStrEnd: 2
nsMatchingRule: nsSubStrBegin=3
nsMatchingRule: nsSubStrEnd=3
Add an entry with uid=cuser2; search with "(uid=c*)" and (uid=*2).
Check the search result in the access log; if notes=[AU] is not
found. The testcase is passed. Note: nsSubStr{Begin,Middle,End}:
is honored over nsMatchingRule: nsSubStr{Begin,Middle,End}=.
https://fedorahosted.org/389/ticket/48109
diff --git a/dirsrvtests/tickets/ticket48109_test.py b/dirsrvtests/tickets/ticket48109_test.py
new file mode 100644
index 0000000..ba470f0
--- /dev/null
+++ b/dirsrvtests/tickets/ticket48109_test.py
@@ -0,0 +1,386 @@
+import os
+import sys
+import time
+import ldap
+import logging
+import pytest
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from lib389.utils import *
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+installation1_prefix = None
+
+UID_INDEX = 'cn=uid,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config'
+
+class TopologyStandalone(object):
+ def __init__(self, standalone):
+ standalone.open()
+ self.standalone = standalone
+
+
+(a)pytest.fixture(scope="module")
+def topology(request):
+ global installation1_prefix
+ if installation1_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+
+ # Creating standalone instance ...
+ standalone = DirSrv(verbose=False)
+ args_instance[SER_HOST] = HOST_STANDALONE
+ args_instance[SER_PORT] = PORT_STANDALONE
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
+ args_standalone = args_instance.copy()
+ standalone.allocate(args_standalone)
+ instance_standalone = standalone.exists()
+ if instance_standalone:
+ standalone.delete()
+ standalone.create()
+ standalone.open()
+
+ # Clear out the tmp dir
+ standalone.clearTmpDir(__file__)
+
+ return TopologyStandalone(standalone)
+
+
+def test_ticket48109_0(topology):
+ '''
+ Set SubStr lengths to cn=uid,cn=index,...
+ objectClass: extensibleObject
+ nsIndexType: sub
+ nsSubStrBegin: 2
+ nsSubStrEnd: 2
+ '''
+ log.info('Test case 0')
+ # add substr setting to UID_INDEX
+ try:
+ topology.standalone.modify_s(UID_INDEX,
+ [(ldap.MOD_ADD, 'objectClass', 'extensibleObject'),
+ (ldap.MOD_ADD, 'nsIndexType', 'sub'),
+ (ldap.MOD_ADD, 'nsSubStrBegin', '2'),
+ (ldap.MOD_ADD, 'nsSubStrEnd', '2')])
+ except ldap.LDAPError, e:
+ log.error('Failed to add substr lengths: error ' + e.message['desc'])
+ assert False
+
+ # restart the server to apply the indexing
+ topology.standalone.restart(timeout=10)
+
+ # add a test user
+ UID = 'auser0'
+ USER_DN = 'uid=%s,%s' % (UID, SUFFIX)
+ try:
+ topology.standalone.add_s(Entry((USER_DN, {
+ 'objectclass': 'top person organizationalPerson inetOrgPerson'.split(),
+ 'cn': 'a user0',
+ 'sn': 'user0',
+ 'givenname': 'a',
+ 'mail': UID})))
+ except ldap.LDAPError, e:
+ log.error('Failed to add ' + USER_DN + ': error ' + e.message['desc'])
+ assert False
+
+ entries = topology.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, '(uid=a*)')
+ assert len(entries) == 1
+
+ # restart the server to check the access log
+ topology.standalone.restart(timeout=10)
+
+ cmdline = 'egrep %s %s | egrep "uid=a\*"' % (SUFFIX, topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l0 = p.readline()
+ if l0 == "":
+ log.error('Search with "(uid=a*)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ #regex = re.compile('\(conn=[0-9]* op=[0-9]*\) SRCH .*')
+ regex = re.compile(r'.*\s+(conn=\d+ op=\d+)\s+SRCH .*')
+ match = regex.match(l0)
+ log.info('match: %s' % match.group(1))
+ cmdline = 'egrep "%s" %s | egrep "RESULT"' % (match.group(1), topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l1 = p.readline()
+ if l1 == "":
+ log.error('Search result of "(uid=a*)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ log.info('l1: %s' % l1)
+ regex = re.compile(r'.*nentries=(\d+)\s+.*')
+ match = regex.match(l1)
+ log.info('match: nentires=%s' % match.group(1))
+ if match.group(1) == "0":
+ log.error('Entry uid=a* not found.')
+ assert False
+ else:
+ log.info('Entry uid=a* found.')
+ regex = re.compile(r'.*(notes=[AU]).*')
+ match = regex.match(l1)
+ if match:
+ log.error('%s - substr index was not used' % match.group(1))
+ assert False
+ else:
+ log.info('Test case 0 - OK - substr index used')
+
+ # clean up substr setting to UID_INDEX
+ try:
+ topology.standalone.modify_s(UID_INDEX,
+ [(ldap.MOD_DELETE, 'objectClass', 'extensibleObject'),
+ (ldap.MOD_DELETE, 'nsIndexType', 'sub'),
+ (ldap.MOD_DELETE, 'nsSubStrBegin', '2'),
+ (ldap.MOD_DELETE, 'nsSubStrEnd', '2')])
+ except ldap.LDAPError, e:
+ log.error('Failed to delete substr lengths: error ' + e.message['desc'])
+ assert False
+
+
+def test_ticket48109_1(topology):
+ '''
+ Set SubStr lengths to cn=uid,cn=index,...
+ nsIndexType: sub
+ nsMatchingRule: nsSubStrBegin=2
+ nsMatchingRule: nsSubStrEnd=2
+ '''
+ log.info('Test case 1')
+ # add substr setting to UID_INDEX
+ try:
+ topology.standalone.modify_s(UID_INDEX,
+ [(ldap.MOD_ADD, 'nsIndexType', 'sub'),
+ (ldap.MOD_ADD, 'nsMatchingRule', 'nssubstrbegin=2'),
+ (ldap.MOD_ADD, 'nsMatchingRule', 'nssubstrend=2')])
+ except ldap.LDAPError, e:
+ log.error('Failed to add substr lengths: error ' + e.message['desc'])
+ assert False
+
+ # restart the server to apply the indexing
+ topology.standalone.restart(timeout=10)
+
+ # add a test user
+ UID = 'buser1'
+ USER_DN = 'uid=%s,%s' % (UID, SUFFIX)
+ try:
+ topology.standalone.add_s(Entry((USER_DN, {
+ 'objectclass': 'top person organizationalPerson inetOrgPerson'.split(),
+ 'cn': 'b user1',
+ 'sn': 'user1',
+ 'givenname': 'b',
+ 'mail': UID})))
+ except ldap.LDAPError, e:
+ log.error('Failed to add ' + USER_DN + ': error ' + e.message['desc'])
+ assert False
+
+ entries = topology.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, '(uid=b*)')
+ assert len(entries) == 1
+
+ # restart the server to check the access log
+ topology.standalone.restart(timeout=10)
+
+ cmdline = 'egrep %s %s | egrep "uid=b\*"' % (SUFFIX, topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l0 = p.readline()
+ if l0 == "":
+ log.error('Search with "(uid=b*)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ #regex = re.compile('\(conn=[0-9]* op=[0-9]*\) SRCH .*')
+ regex = re.compile(r'.*\s+(conn=\d+ op=\d+)\s+SRCH .*')
+ match = regex.match(l0)
+ log.info('match: %s' % match.group(1))
+ cmdline = 'egrep "%s" %s | egrep "RESULT"' % (match.group(1), topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l1 = p.readline()
+ if l1 == "":
+ log.error('Search result of "(uid=*b)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ log.info('l1: %s' % l1)
+ regex = re.compile(r'.*nentries=(\d+)\s+.*')
+ match = regex.match(l1)
+ log.info('match: nentires=%s' % match.group(1))
+ if match.group(1) == "0":
+ log.error('Entry uid=*b not found.')
+ assert False
+ else:
+ log.info('Entry uid=*b found.')
+ regex = re.compile(r'.*(notes=[AU]).*')
+ match = regex.match(l1)
+ if match:
+ log.error('%s - substr index was not used' % match.group(1))
+ assert False
+ else:
+ log.info('Test case 1 - OK - substr index used')
+
+ # clean up substr setting to UID_INDEX
+ try:
+ topology.standalone.modify_s(UID_INDEX,
+ [(ldap.MOD_DELETE, 'nsIndexType', 'sub'),
+ (ldap.MOD_DELETE, 'nsMatchingRule', 'nssubstrbegin=2'),
+ (ldap.MOD_DELETE, 'nsMatchingRule', 'nssubstrend=2')])
+ except ldap.LDAPError, e:
+ log.error('Failed to delete substr lengths: error ' + e.message['desc'])
+ assert False
+
+
+def test_ticket48109_2(topology):
+ '''
+ Set SubStr conflict formats/lengths to cn=uid,cn=index,...
+ objectClass: extensibleObject
+ nsIndexType: sub
+ nsMatchingRule: nsSubStrBegin=3
+ nsMatchingRule: nsSubStrEnd=3
+ nsSubStrBegin: 2
+ nsSubStrEnd: 2
+ nsSubStr{Begin,End} are honored.
+ '''
+ log.info('Test case 2')
+
+ # add substr setting to UID_INDEX
+ try:
+ topology.standalone.modify_s(UID_INDEX,
+ [(ldap.MOD_ADD, 'nsIndexType', 'sub'),
+ (ldap.MOD_ADD, 'nsMatchingRule', 'nssubstrbegin=3'),
+ (ldap.MOD_ADD, 'nsMatchingRule', 'nssubstrend=3'),
+ (ldap.MOD_ADD, 'objectClass', 'extensibleObject'),
+ (ldap.MOD_ADD, 'nsSubStrBegin', '2'),
+ (ldap.MOD_ADD, 'nsSubStrEnd', '2')])
+ except ldap.LDAPError, e:
+ log.error('Failed to add substr lengths: error ' + e.message['desc'])
+ assert False
+
+ # restart the server to apply the indexing
+ topology.standalone.restart(timeout=10)
+
+ # add a test user
+ UID = 'cuser2'
+ USER_DN = 'uid=%s,%s' % (UID, SUFFIX)
+ try:
+ topology.standalone.add_s(Entry((USER_DN, {
+ 'objectclass': 'top person organizationalPerson inetOrgPerson'.split(),
+ 'cn': 'c user2',
+ 'sn': 'user2',
+ 'givenname': 'c',
+ 'mail': UID})))
+ except ldap.LDAPError, e:
+ log.error('Failed to add ' + USER_DN + ': error ' + e.message['desc'])
+ assert False
+
+ entries = topology.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, '(uid=c*)')
+ assert len(entries) == 1
+
+ entries = topology.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, '(uid=*2)')
+ assert len(entries) == 1
+
+ # restart the server to check the access log
+ topology.standalone.restart(timeout=10)
+
+ cmdline = 'egrep %s %s | egrep "uid=c\*"' % (SUFFIX, topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l0 = p.readline()
+ if l0 == "":
+ log.error('Search with "(uid=c*)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ #regex = re.compile('\(conn=[0-9]* op=[0-9]*\) SRCH .*')
+ regex = re.compile(r'.*\s+(conn=\d+ op=\d+)\s+SRCH .*')
+ match = regex.match(l0)
+ log.info('match: %s' % match.group(1))
+ cmdline = 'egrep "%s" %s | egrep "RESULT"' % (match.group(1), topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l1 = p.readline()
+ if l1 == "":
+ log.error('Search result of "(uid=c*)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ log.info('l1: %s' % l1)
+ regex = re.compile(r'.*nentries=(\d+)\s+.*')
+ match = regex.match(l1)
+ log.info('match: nentires=%s' % match.group(1))
+ if match.group(1) == "0":
+ log.error('Entry uid=c* not found.')
+ assert False
+ else:
+ log.info('Entry uid=c* found.')
+ regex = re.compile(r'.*(notes=[AU]).*')
+ match = regex.match(l1)
+ if match:
+ log.error('%s - substr index was not used' % match.group(1))
+ assert False
+ else:
+ log.info('Test case 2-1 - OK - correct substr index used')
+
+ cmdline = 'egrep %s %s | egrep "uid=\*2"' % (SUFFIX, topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l0 = p.readline()
+ if l0 == "":
+ log.error('Search with "(uid=*2)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ #regex = re.compile('\(conn=[0-9]* op=[0-9]*\) SRCH .*')
+ regex = re.compile(r'.*\s+(conn=\d+ op=\d+)\s+SRCH .*')
+ match = regex.match(l0)
+ log.info('match: %s' % match.group(1))
+ cmdline = 'egrep "%s" %s | egrep "RESULT"' % (match.group(1), topology.standalone.accesslog)
+ p = os.popen(cmdline, "r")
+ l1 = p.readline()
+ if l1 == "":
+ log.error('Search result of "(uid=*2)" is not logged in ' + topology.standalone.accesslog)
+ assert False
+ else:
+ log.info('l1: %s' % l1)
+ regex = re.compile(r'.*nentries=(\d+)\s+.*')
+ match = regex.match(l1)
+ log.info('match: nentires=%s' % match.group(1))
+ if match.group(1) == "0":
+ log.error('Entry uid=*2 not found.')
+ assert False
+ else:
+ log.info('Entry uid=*2 found.')
+ regex = re.compile(r'.*(notes=[AU]).*')
+ match = regex.match(l1)
+ if match:
+ log.error('%s - substr index was not used' % match.group(1))
+ assert False
+ else:
+ log.info('Test case 2-2 - OK - correct substr index used')
+
+ # clean up substr setting to UID_INDEX
+ try:
+ topology.standalone.modify_s(UID_INDEX,
+ [(ldap.MOD_DELETE, 'nsIndexType', 'sub'),
+ (ldap.MOD_DELETE, 'nsMatchingRule', 'nssubstrbegin=3'),
+ (ldap.MOD_DELETE, 'nsMatchingRule', 'nssubstrend=3'),
+ (ldap.MOD_DELETE, 'objectClass', 'extensibleObject'),
+ (ldap.MOD_DELETE, 'nsSubStrBegin', '2'),
+ (ldap.MOD_DELETE, 'nsSubStrEnd', '2')])
+ except ldap.LDAPError, e:
+ log.error('Failed to delete substr lengths: error ' + e.message['desc'])
+ assert False
+
+ log.info('Test complete')
+
+
+def test_ticket48109_final(topology):
+ topology.standalone.delete()
+ log.info('Testcase PASSED')
+
+
+def run_isolated():
+ global installation1_prefix
+ installation1_prefix = None
+
+ topo = topology(True)
+ test_ticket48109_0(topo)
+ test_ticket48109_1(topo)
+ test_ticket48109_2(topo)
+ test_ticket48109_final(topo)
+
+
+if __name__ == '__main__':
+ run_isolated()
+
commit ae69e4aa1dcec1c5f79af502b77d9e19a3d348ee
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Feb 26 17:39:36 2015 -0800
Ticket #48109 - substring index with nssubstrbegin: 1 is not being used with filters like (attr=x*)
Description: subString index width was not properly passed to the
syntax plugin in the substr search. This patch fixes a couple of
issues.
1. Pass substrlen array to syntax plugin by stashing it in pblock
with SLAPI_SYNTAX_SUBSTRLENS.
2. Advertised format "nsSubStr{Begin,Middle,End}: width" was not
supported. It is again supported.
3. If both "nsSubStr{Begin,Middle,End}: width" and "nsMatchingRule:
nsSubStr{Begin,Middle,End}=width" are specified, the former is
honored, the latter is used if the former directive does not exist.
https://fedorahosted.org/389/ticket/48109
Reviewed by rmeggins(a)redhat.com (Thank you, Rich!!)
diff --git a/ldap/servers/slapd/back-ldbm/filterindex.c b/ldap/servers/slapd/back-ldbm/filterindex.c
index 7054ef8..d5489d1 100644
--- a/ldap/servers/slapd/back-ldbm/filterindex.c
+++ b/ldap/servers/slapd/back-ldbm/filterindex.c
@@ -936,6 +936,7 @@ substring_candidates(
Slapi_Attr sattr;
back_txn txn = {NULL};
int pr_idx = -1;
+ struct attrinfo *ai = NULL;
LDAPDebug( LDAP_DEBUG_TRACE, "=> sub_candidates\n", 0, 0, 0 );
@@ -950,7 +951,9 @@ substring_candidates(
* assertion values
*/
slapi_attr_init(&sattr, type);
- slapi_attr_assertion2keys_sub_sv( &sattr, initial, any, final, &ivals );
+ ainfo_get(be, type, &ai);
+ slapi_pblock_set(pb, SLAPI_SYNTAX_SUBSTRLENS, ai->ai_substr_lens );
+ slapi_attr_assertion2keys_sub_sv_pb( pb, &sattr, initial, any, final, &ivals );
attr_done(&sattr);
slapi_pblock_get(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx);
if ( ivals == NULL || *ivals == NULL ) {
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attr.c b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
index 7b01acf..877d536 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_attr.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
@@ -677,6 +677,7 @@ attr_index_config(
Slapi_Attr *attr;
int mr_count = 0;
char myreturntext[SLAPI_DSE_RETURNTEXT_SIZE];
+ int substrval = 0;
/* Get the cn */
if (0 == slapi_entry_attr_find(e, "cn", &attr)) {
@@ -762,6 +763,31 @@ attr_index_config(
* ordering matching rule compatible with the attribute syntax, and there is
* a compare function. If not, we assume it is a RULE index definition.
*/
+ /*
+ * nsSubStrBegin: 2
+ * nsSubStrMiddle: 2
+ * nsSubStrEnd: 2
+ */
+ substrval = slapi_entry_attr_get_int(e, INDEX_ATTR_SUBSTRBEGIN);
+ if (substrval) {
+ substrlens = (int *)slapi_ch_calloc(1, sizeof(int) * INDEX_SUBSTRLEN);
+ substrlens[INDEX_SUBSTRBEGIN] = substrval;
+ }
+ substrval = slapi_entry_attr_get_int(e, INDEX_ATTR_SUBSTRMIDDLE);
+ if (substrval) {
+ if (!substrlens) {
+ substrlens = (int *)slapi_ch_calloc(1, sizeof(int) * INDEX_SUBSTRLEN);
+ }
+ substrlens[INDEX_SUBSTRMIDDLE] = substrval;
+ }
+ substrval = slapi_entry_attr_get_int(e, INDEX_ATTR_SUBSTREND);
+ if (substrval) {
+ if (!substrlens) {
+ substrlens = (int *)slapi_ch_calloc(1, sizeof(int) * INDEX_SUBSTRLEN);
+ }
+ substrlens[INDEX_SUBSTREND] = substrval;
+ }
+ a->ai_substr_lens = substrlens;
if(0 == slapi_entry_attr_find(e, "nsMatchingRule", &attr)){
char** official_rules;
@@ -778,21 +804,35 @@ attr_index_config(
Slapi_PBlock* pb = NULL;
int do_continue = 0; /* can we skip the RULE parsing stuff? */
attrValue = slapi_value_get_berval(sval);
-
- if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTRBEGIN)) {
- _set_attr_substrlen(INDEX_SUBSTRBEGIN, attrValue->bv_val, &substrlens);
- do_continue = 1; /* done with j - next j */
- } else if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTRMIDDLE)) {
- _set_attr_substrlen(INDEX_SUBSTRMIDDLE, attrValue->bv_val, &substrlens);
- do_continue = 1; /* done with j - next j */
- } else if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTREND)) {
- _set_attr_substrlen(INDEX_SUBSTREND, attrValue->bv_val, &substrlens);
- do_continue = 1; /* done with j - next j */
+ /*
+ * In case nsSubstr{Begin,Middle,End}: num is not set, but set by this format:
+ * nsMatchingRule: nsSubstrBegin=2
+ * nsMatchingRule: nsSubstrMiddle=2
+ * nsMatchingRule: nsSubstrEnd=2
+ */
+ if (!a->ai_substr_lens || !a->ai_substr_lens[INDEX_SUBSTRBEGIN]) {
+ if (PL_strcasestr(attrValue->bv_val, INDEX_ATTR_SUBSTRBEGIN)) {
+ _set_attr_substrlen(INDEX_SUBSTRBEGIN, attrValue->bv_val, &substrlens);
+ do_continue = 1; /* done with j - next j */
+ }
+ }
+ if (!a->ai_substr_lens || !a->ai_substr_lens[INDEX_SUBSTRMIDDLE]) {
+ if (PL_strcasestr(attrValue->bv_val, INDEX_ATTR_SUBSTRMIDDLE)) {
+ _set_attr_substrlen(INDEX_SUBSTRMIDDLE, attrValue->bv_val, &substrlens);
+ do_continue = 1; /* done with j - next j */
+ }
+ }
+ if (!a->ai_substr_lens || !a->ai_substr_lens[INDEX_SUBSTREND]) {
+ if (PL_strcasestr(attrValue->bv_val, INDEX_ATTR_SUBSTREND)) {
+ _set_attr_substrlen(INDEX_SUBSTREND, attrValue->bv_val, &substrlens);
+ do_continue = 1; /* done with j - next j */
+ }
+ }
/* check if this is a simple ordering specification
for an attribute that has no ordering matching rule */
- } else if (slapi_matchingrule_is_ordering(attrValue->bv_val, attrsyntax_oid) &&
- slapi_matchingrule_can_use_compare_fn(attrValue->bv_val) &&
- !a->ai_sattr.a_mr_ord_plugin) { /* no ordering for this attribute */
+ if (slapi_matchingrule_is_ordering(attrValue->bv_val, attrsyntax_oid) &&
+ slapi_matchingrule_can_use_compare_fn(attrValue->bv_val) &&
+ !a->ai_sattr.a_mr_ord_plugin) { /* no ordering for this attribute */
need_compare_fn = 1; /* get compare func for this attr */
do_continue = 1; /* done with j - next j */
}
@@ -844,7 +884,9 @@ attr_index_config(
slapi_pblock_destroy (pb);
}
official_rules[k] = NULL;
- a->ai_substr_lens = substrlens;
+ if (substrlens) {
+ a->ai_substr_lens = substrlens;
+ }
if (k > 0) {
a->ai_index_rules = official_rules;
a->ai_indexmask |= INDEX_RULES;
diff --git a/ldap/servers/slapd/plugin_syntax.c b/ldap/servers/slapd/plugin_syntax.c
index 878e107..fa05b0b 100644
--- a/ldap/servers/slapd/plugin_syntax.c
+++ b/ldap/servers/slapd/plugin_syntax.c
@@ -908,6 +908,19 @@ slapi_attr_assertion2keys_sub_sv(
Slapi_Value ***ivals
)
{
+ return slapi_attr_assertion2keys_sub_sv_pb(NULL, sattr, initial, any, final, ivals);
+}
+
+int
+slapi_attr_assertion2keys_sub_sv_pb(
+ Slapi_PBlock *pb,
+ const Slapi_Attr *sattr,
+ char *initial,
+ char **any,
+ char *final,
+ Slapi_Value ***ivals
+)
+{
int rc;
Slapi_PBlock pipb;
struct slapdplugin *pi = NULL;
@@ -927,13 +940,16 @@ slapi_attr_assertion2keys_sub_sv(
pi = sattr->a_plugin;
a2k_fn = sattr->a_plugin->plg_syntax_assertion2keys_sub;
}
- pblock_init( &pipb );
- slapi_pblock_set( &pipb, SLAPI_PLUGIN, pi );
+ if (NULL == pb) {
+ pblock_init( &pipb );
+ pb = &pipb;
+ }
+ slapi_pblock_set( pb, SLAPI_PLUGIN, pi );
rc = -1; /* means no assertion2keys function */
*ivals = NULL;
if ( a2k_fn != NULL ) {
- rc = (*a2k_fn)( &pipb, initial, any, final, ivals );
+ rc = (*a2k_fn)( pb, initial, any, final, ivals );
}
LDAPDebug( LDAP_DEBUG_FILTER,
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 3a1203a..69a7743 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5849,6 +5849,8 @@ int slapi_call_syntax_assertion2keys_ava_sv( void *vpi, Slapi_Value *val,
Slapi_Value ***ivals, int ftype );
int slapi_call_syntax_assertion2keys_sub_sv( void *vpi, char *initial,
char **any, char *final, Slapi_Value ***ivals );
+int slapi_call_syntax_assertion2keys_sub_sv_pb( Slapi_PBlock *pb, void *vpi,
+ char *initial, char **any, char *final, Slapi_Value ***ivals );
int slapi_attr_values2keys_sv( const Slapi_Attr *sattr, Slapi_Value **vals,
Slapi_Value ***ivals, int ftype );
9 years, 1 month