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