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