From 36660f00bf11f89c632f581d6f82b7383b1aa190 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 26 Jan 2023 08:16:49 -0500 Subject: [PATCH 4/5] Issue 5497 - boolean attributes should be case insensitive Description: Boolean values are supposed to be case insensitive, but in our code it is senstiive even though the code is in the "cis" file. relates: https://github.com/389ds/389-ds-base/issues/5497 Reviewed by: spichugi(Thanks!) --- .../tests/suites/syntax/acceptance_test.py | 248 ++++++++++++++++++ ldap/servers/plugins/syntaxes/cis.c | 4 +- 2 files changed, 250 insertions(+), 2 deletions(-) create mode 100644 dirsrvtests/tests/suites/syntax/acceptance_test.py diff --git a/dirsrvtests/tests/suites/syntax/acceptance_test.py b/dirsrvtests/tests/suites/syntax/acceptance_test.py new file mode 100644 index 000000000..807936892 --- /dev/null +++ b/dirsrvtests/tests/suites/syntax/acceptance_test.py @@ -0,0 +1,248 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2023 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- + +import ldap +import pytest +import os +from lib389.schema import Schema +from lib389.config import Config +from lib389.idm.user import UserAccounts +from lib389.idm.group import Group, Groups +from lib389._constants import DEFAULT_SUFFIX +from lib389.topologies import log, topology_st as topo + +pytestmark = pytest.mark.tier0 + +log = log.getChild(__name__) + + +@pytest.fixture(scope="function") +def validate_syntax_off(topo, request): + config = Config(topo.standalone) + config.replace("nsslapd-syntaxcheck", "off") + + def fin(): + config.replace("nsslapd-syntaxcheck", "on") + request.addfinalizer(fin) + + +def test_valid(topo, validate_syntax_off): + """Test syntax-validate task with valid entries + + :id: ec402a5b-bfb1-494d-b751-71b0d31a4d83 + :setup: Standalone instance + :steps: + 1. Set nsslapd-syntaxcheck to off + 2. Clean error log + 3. Run syntax validate task + 4. Assert that there are no errors in the error log + 5. Set nsslapd-syntaxcheck to on + :expectedresults: + 1. It should succeed + 2. It should succeed + 3. It should succeed + 4. It should succeed + 5. It should succeed + """ + + inst = topo.standalone + + log.info('Clean the error log') + inst.deleteErrorLogs() + + schema = Schema(inst) + log.info('Attempting to add task entry...') + validate_task = schema.validate_syntax(DEFAULT_SUFFIX) + validate_task.wait() + exitcode = validate_task.get_exit_code() + assert exitcode == 0 + error_lines = inst.ds_error_log.match('.*Found 0 invalid entries.*') + assert (len(error_lines) == 1) + log.info('Found 0 invalid entries - Success') + + +def test_invalid_uidnumber(topo, validate_syntax_off): + """Test syntax-validate task with invalid uidNumber attribute value + + :id: 30fdcae6-ffa6-4ec4-8da9-6fb138fc1828 + :setup: Standalone instance + :steps: + 1. Set nsslapd-syntaxcheck to off + 2. Clean error log + 3. Add a user with uidNumber attribute set to an invalid value (string) + 4. Run syntax validate task + 5. Assert that there is corresponding error in the error log + 6. Set nsslapd-syntaxcheck to on + :expectedresults: + 1. It should succeed + 2. It should succeed + 3. It should succeed + 4. It should succeed + 5. It should succeed + 6. It should succeed + """ + + inst = topo.standalone + + log.info('Clean the error log') + inst.deleteErrorLogs() + + users = UserAccounts(inst, DEFAULT_SUFFIX) + users.create_test_user(uid="invalid_value") + + schema = Schema(inst) + log.info('Attempting to add task entry...') + validate_task = schema.validate_syntax(DEFAULT_SUFFIX) + validate_task.wait() + exitcode = validate_task.get_exit_code() + assert exitcode == 0 + error_lines = inst.ds_error_log.match('.*uidNumber: value #0 invalid per syntax.*') + assert (len(error_lines) == 1) + log.info('Found an invalid entry with wrong uidNumber - Success') + + +def test_invalid_dn_syntax_crash(topo): + """Add an entry with an escaped space, restart the server, and try to delete + it. In this case the DN is not correctly parsed and causes cache revert to + to dereference a NULL pointer. So the delete can fail as long as the server + does not crash. + + :id: 62d87272-dfb8-4627-9ca1-dbe33082caf8 + :setup: Standalone Instance + :steps: + 1. Add entry with leading escaped space in the RDN + 2. Restart the server so the entry is rebuilt from the database + 3. Delete the entry + 4. The server should still be running + :expectedresults: + 1. Success + 2. Success + 3. Success + 4. Success + """ + + # Create group + groups = Groups(topo.standalone, DEFAULT_SUFFIX) + group = groups.create(properties={'cn': ' test'}) + + # Restart the server + topo.standalone.restart() + + # Delete group + try: + group.delete() + except ldap.NO_SUCH_OBJECT: + # This is okay in this case as we are only concerned about a crash + pass + + # Make sure server is still running + groups.list() + + +@pytest.mark.parametrize("props, rawdn", [ + ({'cn': ' leadingSpace'}, "cn=\\20leadingSpace,ou=Groups,dc=example,dc=com"), + ({'cn': 'trailingSpace '}, "cn=trailingSpace\\20,ou=Groups,dc=example,dc=com")]) +def test_dn_syntax_spaces_delete(topo, props, rawdn): + """Test that an entry with a space as the first character in the DN can be + deleted without error. We also want to make sure the indexes are properly + updated by repeatedly adding and deleting the entry, and that the entry cache + is properly maintained. + + :id: b993f37c-c2b0-4312-992c-a9048ff98965 + :customerscenario: True + :parametrized: yes + :setup: Standalone Instance + :steps: + 1. Create a group with a DN that has a space as the first/last + character. + 2. Delete group + 3. Add group + 4. Modify group + 5. Restart server and modify entry + 6. Delete group + 7. Add group back + 8. Delete group using specific DN + :expectedresults: + 1. Success + 2. Success + 3. Success + 4. Success + 5. Success + 6. Success + 7. Success + 8. Success + """ + + # Create group + groups = Groups(topo.standalone, DEFAULT_SUFFIX) + group = groups.create(properties=props.copy()) + + # Delete group (verifies DN/RDN parsing works and cache is correct) + group.delete() + + # Add group again (verifies entryrdn index was properly updated) + groups = Groups(topo.standalone, DEFAULT_SUFFIX) + group = groups.create(properties=props.copy()) + + # Modify the group (verifies dn/rdn parsing is correct) + group.replace('description', 'escaped space group') + + # Restart the server. This will pull the entry from the database and + # convert it into a cache entry, which is different than how a client + # first adds an entry and is put into the cache before being written to + # disk. + topo.standalone.restart() + + # Make sure we can modify the entry (verifies cache entry was created + # correctly) + group.replace('description', 'escaped space group after restart') + + # Make sure it can still be deleted (verifies cache again). + group.delete() + + # Add it back so we can delete it using a specific DN (sanity test to verify + # another DN/RDN parsing variation). + groups = Groups(topo.standalone, DEFAULT_SUFFIX) + group = groups.create(properties=props.copy()) + group = Group(topo.standalone, dn=rawdn) + group.delete() + + +def test_boolean_case(topo): + """Test that we can a boolean value in any case + + :id: 56777c1d-b058-41e1-abd5-87a6f1512db2 + :customerscenario: True + :setup: Standalone Instance + :steps: + 1. Create test user + 2. Add boolean attribute value that is lowercase "false" + :expectedresults: + 1. Success + 2. Success + """ + inst = topo.standalone + users = UserAccounts(inst, DEFAULT_SUFFIX) + user = users.create_test_user(uid=1011) + + user.add('objectclass', 'extensibleObject') + user.add('pamsecure', 'false') + user.replace('pamsecure', 'FALSE') + user.replace('pamsecure', 'true') + user.replace('pamsecure', 'TRUE') + + # Test some invalid syntax + with pytest.raises(ldap.INVALID_SYNTAX): + user.replace('pamsecure', 'blah') + + +if __name__ == '__main__': + # Run isolated + # -s for DEBUG mode + CURRENT_FILE = os.path.realpath(__file__) + pytest.main("-s %s" % CURRENT_FILE) diff --git a/ldap/servers/plugins/syntaxes/cis.c b/ldap/servers/plugins/syntaxes/cis.c index e1242e3f4..c9274f37f 100644 --- a/ldap/servers/plugins/syntaxes/cis.c +++ b/ldap/servers/plugins/syntaxes/cis.c @@ -853,12 +853,12 @@ boolean_validate( */ if (val != NULL) { if (val->bv_len == 4) { - if (strncmp(val->bv_val, "TRUE", 4) != 0) { + if (strncasecmp(val->bv_val, "TRUE", 4) != 0) { rc = 1; goto exit; } } else if (val->bv_len == 5) { - if (strncmp(val->bv_val, "FALSE", 5) != 0) { + if (strncasecmp(val->bv_val, "FALSE", 5) != 0) { rc = 1; goto exit; } -- 2.39.1