From 3796e26e93991ded631ac57053049e9aad44c53b Mon Sep 17 00:00:00 2001 From: Thierry Bordaz Date: Wed, 10 Oct 2018 15:35:12 +0200 Subject: [PATCH] Ticket 49968 - Confusing CRITICAL message: list_candidates - NULL idl was recieved from filter_candidates_ext Bug Description: When a filter component is indexed but returns an empty IDL an alarming message is logged although it is normal. Fix Description: Remove the alarming message https://pagure.io/389-ds-base/issue/49968 Reviewed by: Mark Reynolds Platforms tested: F27 + testcase Flag Day: no Doc impact: no --- dirsrvtests/tests/suites/basic/basic_test.py | 202 +++++++++++++++++++ ldap/servers/slapd/back-ldbm/filterindex.c | 10 +- 2 files changed, 204 insertions(+), 8 deletions(-) diff --git a/dirsrvtests/tests/suites/basic/basic_test.py b/dirsrvtests/tests/suites/basic/basic_test.py index 45988dc7a..dc366cd67 100644 --- a/dirsrvtests/tests/suites/basic/basic_test.py +++ b/dirsrvtests/tests/suites/basic/basic_test.py @@ -868,6 +868,208 @@ adds nsslapd-return-default-opattr attr with value of one operation attribute. log.fatal('Search failed, error: ' + e.message['desc']) assert False + +@pytest.fixture(scope="module") +def create_users(topology_st): + """Add users to the default suffix + """ + + users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX) + user_names = ["Directory", "Server", "389", "lib389", "pytest"] + + log.info('Adding 5 test users') + for name in user_names: + user = users.create(properties={ + 'uid': name, + 'sn': name, + 'cn': name, + 'uidNumber': '1000', + 'gidNumber': '1000', + 'homeDirectory': '/home/%s' % name, + 'mail': '%s@example.com' % name, + 'userpassword': 'pass%s' % name, + }) + + +def test_basic_anonymous_search(topology_st, create_users): + """Tests basic anonymous search operations + + :id: c7831e04-f458-4e50-83c7-b6f77109f639 + :setup: Standalone instance + Add 5 test users with different user names + :steps: + 1. Execute anonymous search with different filters + :expectedresults: + 1. Search should be successful + """ + + filters = ["uid=Directory", "(|(uid=S*)(uid=3*))", "(&(uid=l*)(mail=l*))", "(&(!(uid=D*))(ou=People))"] + log.info("Execute anonymous search with different filters") + for filtr in filters: + entries = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, filtr) + assert len(entries) != 0 + + +@pytest.mark.ds604 +@pytest.mark.bz915801 +def test_search_original_type(topology_st, create_users): + """Test ldapsearch returning original attributes + using nsslapd-search-return-original-type-switch + + :id: d7831d04-f558-4e50-93c7-b6f77109f640 + :setup: Standalone instance + Add some test entries + :steps: + 1. Set nsslapd-search-return-original-type-switch to ON + 2. Check that ldapsearch *does* return unknown attributes + 3. Turn off nsslapd-search-return-original-type-switch + 4. Check that ldapsearch doesn't return any unknown attributes + :expectedresults: + 1. nsslapd-search-return-original-type-switch should be set to ON + 2. ldapsearch should return unknown attributes + 3. nsslapd-search-return-original-type-switch should be OFF + 4. ldapsearch should not return any unknown attributes + """ + + log.info("Set nsslapd-search-return-original-type-switch to ON") + topology_st.standalone.config.set('nsslapd-search-return-original-type-switch', 'on') + + log.info("Check that ldapsearch *does* return unknown attributes") + entries = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'uid=Directory', + ['objectclass overflow', 'unknown']) + assert "objectclass overflow" in entries[0].getAttrs() + + log.info("Set nsslapd-search-return-original-type-switch to Off") + topology_st.standalone.config.set('nsslapd-search-return-original-type-switch', 'off') + log.info("Check that ldapsearch *does not* return unknown attributes") + entries = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'uid=Directory', + ['objectclass overflow', 'unknown']) + assert "objectclass overflow" not in entries[0].getAttrs() + + +@pytest.mark.bz192901 +def test_search_ou(topology_st): + """Test that DS should not return an entry that does not match the filter + + :id: d7831d05-f117-4e89-93c7-b6f77109f640 + :setup: Standalone instance + :steps: + 1. Create an OU entry without sub entries + 2. Search from the OU with the filter that does not match the OU + :expectedresults: + 1. Creation of OU should be successful + 2. Search should not return any results + """ + + log.info("Create a test OU without sub entries") + ou = OrganizationalUnits(topology_st.standalone, DEFAULT_SUFFIX) + ou.create(properties={ + 'ou': 'test_ou', + }) + + search_base = ("ou=test_ou,%s" % DEFAULT_SUFFIX) + log.info("Search from the OU with the filter that does not match the OU, it should not return anything") + entries = topology_st.standalone.search_s(search_base, ldap.SCOPE_SUBTREE, 'uid=*', ['dn']) + assert len(entries) == 0 + + +@pytest.mark.bz1044135 +@pytest.mark.ds47319 +def test_connection_buffer_size(topology_st): + """Test connection buffer size adjustable with different values(valid values and invalid) + + :id: e7831d05-f117-4ec9-1203-b6f77109f117 + :setup: Standalone instance + :steps: + 1. Set nsslapd-connection-buffer to some valid values (2, 0 , 1) + 2. Set nsslapd-connection-buffer to some invalid values (-1, a) + :expectedresults: + 1. This should pass + 2. This should fail + """ + + valid_values = ['2', '0', '1'] + for value in valid_values: + topology_st.standalone.config.replace('nsslapd-connection-buffer', value) + + invalid_values = ['-1', 'a'] + for value in invalid_values: + with pytest.raises(ldap.OPERATIONS_ERROR): + topology_st.standalone.config.replace('nsslapd-connection-buffer', value) + +@pytest.mark.bz1637439 +def test_critical_msg_on_empty_range_idl(topology_st): + """Doing a range index lookup should not report a critical message even if IDL is empty + + :id: a07a2222-0551-44a6-b113-401d23799364 + :setup: Standalone instance + :steps: + 1. Create an index for internationalISDNNumber. (attribute chosen because it is + unlikely that previous tests used it) + 2. telephoneNumber being indexed by default create 20 users without telephoneNumber + 3. add a telephoneNumber value and delete it to trigger an empty index database + 4. Do a search that triggers a range lookup on empty telephoneNumber + 5. Check that the critical message is not logged in error logs + :expectedresults: + 1. This should pass + 2. This should pass + 3. This should pass + 4. This should pass on normal build but could abort a debug build + 4. This should pass + """ + indexedAttr = 'internationalISDNNumber' + + # Step 1 + from lib389.index import Indexes + + indexes = Indexes(topology_st.standalone) + indexes.create(properties={ + 'cn': indexedAttr, + 'nsSystemIndex': 'false', + 'nsIndexType': 'eq' + }) + topology_st.standalone.restart() + + # Step 2 + users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX) + log.info('Adding 20 users without "%s"' % indexedAttr) + for i in range(20): + name = 'user_%d' % i + last_user = users.create(properties={ + 'uid': name, + 'sn': name, + 'cn': name, + 'uidNumber': '1000', + 'gidNumber': '1000', + 'homeDirectory': '/home/%s' % name, + 'mail': '%s@example.com' % name, + 'userpassword': 'pass%s' % name, + }) + + # Step 3 + # required update to create the indexAttr (i.e. 'loginShell') database, and then make it empty + topology_st.standalone.modify_s(last_user.dn, [(ldap.MOD_ADD, indexedAttr, b'1234')]) + ent = topology_st.standalone.getEntry(last_user.dn, ldap.SCOPE_BASE,) + assert ent + assert ent.hasAttr(indexedAttr) + topology_st.standalone.modify_s(last_user.dn, [(ldap.MOD_DELETE, indexedAttr, None)]) + ent = topology_st.standalone.getEntry(last_user.dn, ldap.SCOPE_BASE,) + assert ent + assert not ent.hasAttr(indexedAttr) + + # Step 4 + # The first component being not indexed the range on second is evaluated + try: + ents = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(&(sudoNotAfter=*)(%s>=111))' % indexedAttr) + assert len(ents) == 0 + except ldap.SERVER_DOWN: + log.error('Likely testing against a debug version that asserted') + pass + + # Step 5 + assert not topology_st.standalone.searchErrorsLog('CRIT - list_candidates - NULL idl was recieved from filter_candidates_ext.') + + if __name__ == '__main__': # Run isolated # -s for DEBUG mode diff --git a/ldap/servers/slapd/back-ldbm/filterindex.c b/ldap/servers/slapd/back-ldbm/filterindex.c index 6d36ba33e..3ef04f884 100644 --- a/ldap/servers/slapd/back-ldbm/filterindex.c +++ b/ldap/servers/slapd/back-ldbm/filterindex.c @@ -803,16 +803,10 @@ list_candidates( } /* - * Assert we recieved a valid idl. If it was NULL, it means somewhere we failed - * during the dblayer interactions. - * - * idl_set requires a valid idl structure to generate the linked list of - * idls that we insert. + * The IDL for that component is NULL, so no candidate retrieved from that component. This is all normal + * Just build a idl with an empty set */ if (tmp == NULL) { - slapi_log_err(SLAPI_LOG_CRIT, "list_candidates", "NULL idl was recieved from filter_candidates_ext."); - slapi_log_err(SLAPI_LOG_CRIT, "list_candidates", "Falling back to empty IDL set. This may affect your search results."); - PR_ASSERT(tmp); tmp = idl_alloc(0); } -- 2.17.2