144 lines
5.3 KiB
Diff
144 lines
5.3 KiB
Diff
From 0bdb7445af5be162e18c26f7fc2b75536c467748 Mon Sep 17 00:00:00 2001
|
|
From: James Chapman <jachapma@redhat.com>
|
|
Date: Fri, 19 Feb 2021 16:32:22 +0000
|
|
Subject: [PATCH 4/4] Issue 4595 - Paged search lookthroughlimit bug (#4602)
|
|
|
|
Bug Description: During a paged search with lookthroughlimit enabled,
|
|
lookthroughcount is used to keep track of how many entries are
|
|
examined. A paged search reads ahead one entry to catch the end of the
|
|
search so it doesn't show the prompt when there are no more entries.
|
|
lookthroughcount doesn't take read ahead into account when tracking
|
|
how many entries have been examined.
|
|
|
|
Fix Description: Keep lookthroughcount in sync with read ahead by
|
|
by decrementing it during read ahead roll back.
|
|
|
|
Fixes: https://github.com/389ds/389-ds-base/issues/4595
|
|
|
|
Relates: https://github.com/389ds/389-ds-base/issues/4513
|
|
|
|
Reviewed by: droideck, mreynolds389, Firstyear, progier389 (Many thanks)
|
|
---
|
|
dirsrvtests/tests/suites/basic/basic_test.py | 85 ++++++++++++++++++++
|
|
ldap/servers/slapd/back-ldbm/ldbm_search.c | 1 +
|
|
2 files changed, 86 insertions(+)
|
|
|
|
diff --git a/dirsrvtests/tests/suites/basic/basic_test.py b/dirsrvtests/tests/suites/basic/basic_test.py
|
|
index 332f5bb8d..e1a31175a 100644
|
|
--- a/dirsrvtests/tests/suites/basic/basic_test.py
|
|
+++ b/dirsrvtests/tests/suites/basic/basic_test.py
|
|
@@ -95,6 +95,24 @@ def rootdse_attr(topology_st, request):
|
|
return rootdse_attr_name
|
|
|
|
|
|
+def change_conf_attr(topology_st, suffix, attr_name, attr_value):
|
|
+ """Change configuration attribute in the given suffix.
|
|
+
|
|
+ Returns previous attribute value.
|
|
+ """
|
|
+
|
|
+ entry = DSLdapObject(topology_st.standalone, suffix)
|
|
+
|
|
+ attr_value_bck = entry.get_attr_val_bytes(attr_name)
|
|
+ log.info('Set %s to %s. Previous value - %s. Modified suffix - %s.' % (
|
|
+ attr_name, attr_value, attr_value_bck, suffix))
|
|
+ if attr_value is None:
|
|
+ entry.remove_all(attr_name)
|
|
+ else:
|
|
+ entry.replace(attr_name, attr_value)
|
|
+ return attr_value_bck
|
|
+
|
|
+
|
|
def test_basic_ops(topology_st, import_example_ldif):
|
|
"""Tests adds, mods, modrdns, and deletes operations
|
|
|
|
@@ -607,6 +625,73 @@ def test_basic_searches(topology_st, import_example_ldif):
|
|
log.info('test_basic_searches: PASSED')
|
|
|
|
|
|
+@pytest.mark.parametrize('limit,resp',
|
|
+ ((('200'), 'PASS'),
|
|
+ (('50'), ldap.ADMINLIMIT_EXCEEDED)))
|
|
+def test_basic_search_lookthroughlimit(topology_st, limit, resp, import_example_ldif):
|
|
+ """
|
|
+ Tests normal search with lookthroughlimit set high and low.
|
|
+
|
|
+ :id: b5119970-6c9f-41b7-9649-de9233226fec
|
|
+
|
|
+ :setup: Standalone instance, add example.ldif to the database, search filter (uid=*).
|
|
+
|
|
+ :steps:
|
|
+ 1. Import ldif user file.
|
|
+ 2. Change lookthroughlimit to 200.
|
|
+ 3. Bind to server as low priv user
|
|
+ 4. Run search 1 with "high" lookthroughlimit.
|
|
+ 5. Change lookthroughlimit to 50.
|
|
+ 6. Run search 2 with "low" lookthroughlimit.
|
|
+ 8. Delete user from DB.
|
|
+ 9. Reset lookthroughlimit to original.
|
|
+
|
|
+ :expectedresults:
|
|
+ 1. First search should complete with no error.
|
|
+ 2. Second search should return ldap.ADMINLIMIT_EXCEEDED error.
|
|
+ """
|
|
+
|
|
+ log.info('Running test_basic_search_lookthroughlimit...')
|
|
+
|
|
+ search_filter = "(uid=*)"
|
|
+
|
|
+ ltl_orig = change_conf_attr(topology_st, 'cn=config,cn=ldbm database,cn=plugins,cn=config', 'nsslapd-lookthroughlimit', limit)
|
|
+
|
|
+ try:
|
|
+ users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX, rdn=None)
|
|
+ user = users.create_test_user()
|
|
+ user.replace('userPassword', PASSWORD)
|
|
+ except ldap.LDAPError as e:
|
|
+ log.fatal('Failed to create test user: error ' + e.args[0]['desc'])
|
|
+ assert False
|
|
+
|
|
+ try:
|
|
+ conn = UserAccount(topology_st.standalone, user.dn).bind(PASSWORD)
|
|
+ except ldap.LDAPError as e:
|
|
+ log.fatal('Failed to bind test user: error ' + e.args[0]['desc'])
|
|
+ assert False
|
|
+
|
|
+ try:
|
|
+ if resp == ldap.ADMINLIMIT_EXCEEDED:
|
|
+ with pytest.raises(ldap.ADMINLIMIT_EXCEEDED):
|
|
+ searchid = conn.search(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, search_filter)
|
|
+ rtype, rdata = conn.result(searchid)
|
|
+ else:
|
|
+ searchid = conn.search(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, search_filter)
|
|
+ rtype, rdata = conn.result(searchid)
|
|
+ assert(len(rdata) == 151) #151 entries in the imported ldif file using "(uid=*)"
|
|
+ except ldap.LDAPError as e:
|
|
+ log.fatal('Failed to perform search: error ' + e.args[0]['desc'])
|
|
+ assert False
|
|
+
|
|
+ finally:
|
|
+ #Cleanup
|
|
+ change_conf_attr(topology_st, 'cn=config,cn=ldbm database,cn=plugins,cn=config', 'nsslapd-lookthroughlimit', ltl_orig)
|
|
+ user.delete()
|
|
+
|
|
+ log.info('test_basic_search_lookthroughlimit: PASSED')
|
|
+
|
|
+
|
|
@pytest.fixture(scope="module")
|
|
def add_test_entry(topology_st, request):
|
|
# Add test entry
|
|
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
|
|
index 6e22debde..d0f52b6f7 100644
|
|
--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
|
|
+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
|
|
@@ -1885,6 +1885,7 @@ ldbm_back_prev_search_results(Slapi_PBlock *pb)
|
|
sr->sr_entry = NULL;
|
|
}
|
|
idl_iterator_decrement(&(sr->sr_current));
|
|
+ --sr->sr_lookthroughcount;
|
|
}
|
|
return;
|
|
}
|
|
--
|
|
2.31.1
|
|
|