From 4b29fe4ce75c0d2c922de09d18e77d285478b0b9 Mon Sep 17 00:00:00 2001 From: Arun Bansal Date: Fri, 23 Jan 2026 16:02:04 +0530 Subject: [PATCH] Bump version to 1.4.3.39-21 - Resolves: RHEL-141419 - (&(cn:dn:=groups)) no longer returns results [rhel-8.10.z] - Resolves: RHEL-140272 - ipa-healthcheck is complaining about missing or incorrectly configured system indexes. [rhel-8.10.z] --- ...h-filter-cn-dn-groups-no-longer-retu.patch | 91 +++++++ ...0007-generates-incorrect-remediation.patch | 235 ++++++++++++++++++ 389-ds-base.spec | 9 +- 3 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 0076-Issue-7071-search-filter-cn-dn-groups-no-longer-retu.patch create mode 100644 0077-Issue-7189-DSBLE0007-generates-incorrect-remediation.patch diff --git a/0076-Issue-7071-search-filter-cn-dn-groups-no-longer-retu.patch b/0076-Issue-7071-search-filter-cn-dn-groups-no-longer-retu.patch new file mode 100644 index 0000000..6c9f249 --- /dev/null +++ b/0076-Issue-7071-search-filter-cn-dn-groups-no-longer-retu.patch @@ -0,0 +1,91 @@ +From c160ef5a53f0ae9725790ebcd2667dcda2089f14 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 28 Oct 2025 10:49:18 -0400 +Subject: [PATCH 1/2] Issue 7071 - search filter (&(cn:dn:=groups)) no longer + returns results + +Description: + +When processing an "and" filter and it only contains one filter component then +the logic in the code breaks down and the filter is seen as not matching. + +The logic breaks down because we are not setting "nomatch" after the access +check is successful. If there are two components then it works fine +because we do the access check on the first filter component and set that +the access check was done(access_check_done), but "nomatch" is not set yet. +So when the next filter component is checked for access we see that the access +check was done and then we set "nomatch". + +To recap we always need to set "nomatch" when the access check is successful +in order to handle the case where an "and" fitler only has one component. + +Relates: https://github.com/389ds/389-ds-base/issues/7071 + +Reviewed by: spichugi(Thanks!) +--- + .../tests/suites/filter/complex_filters_test.py | 17 ++++++++++++++--- + ldap/servers/slapd/filterentry.c | 7 ++++++- + 2 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/dirsrvtests/tests/suites/filter/complex_filters_test.py b/dirsrvtests/tests/suites/filter/complex_filters_test.py +index 62be27381..3180ab229 100644 +--- a/dirsrvtests/tests/suites/filter/complex_filters_test.py ++++ b/dirsrvtests/tests/suites/filter/complex_filters_test.py +@@ -25,8 +25,15 @@ AND_FILTERS = [("(&(uid=uid1)(sn=last1)(givenname=first1))", 1), + ("(&(uid=*)(&(sn=last3)(givenname=*)))", 1), + ("(&(uid=uid5)(&(&(sn=*))(&(givenname=*))))", 1), + ("(&(objectclass=*)(uid=*)(sn=last*))", 5), +- ("(&(objectclass=*)(uid=*)(sn=last1))", 1)] +- ++ ("(&(objectclass=*)(uid=*)(sn=last1))", 1), ++ ("(&(sn:dn:=last1))", 1), ++ ("(&(sn:dn:=last1)(givenname:dn:=first1))", 1), ++ ("(&(sn:dn:=last1)(givenname=first1))", 1), ++ ("(&(sn=last1)(givenname=first1)(uid:dn:=uid1))", 1), ++ ("(&(uid:dn:=uid1))", 1), ++ ("(&(uid:dn:=uid1)(cn:dn:=full1))", 1), ++ ("(&(uid:dn:=uid1)(givenname:dn:=first1))", 1), ++ ("(&(uid:dn:=uid1)(givenname:dn:=first1)(cn:dn:=full1))", 1)] + OR_FILTERS = [("(|(uid=uid1)(sn=last1)(givenname=first1))", 1), + ("(|(uid=uid1)(|(sn=last1)(givenname=first1)))", 1), + ("(|(uid=uid1)(|(|(sn=last1))(|(givenname=first1))))", 1), +@@ -51,7 +58,11 @@ ZERO_AND_FILTERS = [("(&(uid=uid1)(sn=last1)(givenname=NULL))", 0), + ("(&(uid=uid1)(&(sn=last1)(givenname=NULL)))", 0), + ("(&(uid=uid1)(&(&(sn=last1))(&(givenname=NULL))))", 0), + ("(&(uid=uid1)(&(&(sn=last1))(&(givenname=NULL)(sn=*)))(|(sn=NULL)))", 0), +- ("(&(uid=uid1)(&(&(sn=last*))(&(givenname=first*)))(&(sn=NULL)))", 0)] ++ ("(&(uid=uid1)(&(&(sn=last*))(&(givenname=first*)))(&(sn=NULL)))", 0), ++ ("(&(uid:dn:=not_uid))", 0), ++ ("(&(uid:dn:=not_uid)(cn:dn:=full1))", 0), ++ ("(&(uid:dn:=uid1)(givenname:dn:=not_first1))", 0), ++ ("(&(uid:dn:=uid1)(givenname:dn:=first1)(cn:dn:=not_full1))", 0)] + + ZERO_OR_FILTERS = [("(|(uid=NULL)(sn=NULL)(givenname=NULL))", 0), + ("(|(uid=NULL)(|(sn=NULL)(givenname=NULL)))", 0), +diff --git a/ldap/servers/slapd/filterentry.c b/ldap/servers/slapd/filterentry.c +index cae5c7edc..1c513fe62 100644 +--- a/ldap/servers/slapd/filterentry.c ++++ b/ldap/servers/slapd/filterentry.c +@@ -1011,13 +1011,18 @@ vattr_test_filter_list_and( + nomatch = -1; + break; + } else { ++ /* We have a match, but we need to check access */ + if (!verify_access || (*access_check_done)) { + nomatch = 0; + } else { + /* check access */ + rc = slapi_vattr_filter_test_ext_internal(pb, e, f, verify_access, 1, access_check_done); +- if (rc) ++ if (rc) { + undefined = rc; ++ } else { ++ /* Access is good so mark this as a match */ ++ nomatch = 0; ++ } + } + } + } +-- +2.52.0 + diff --git a/0077-Issue-7189-DSBLE0007-generates-incorrect-remediation.patch b/0077-Issue-7189-DSBLE0007-generates-incorrect-remediation.patch new file mode 100644 index 0000000..3480cfd --- /dev/null +++ b/0077-Issue-7189-DSBLE0007-generates-incorrect-remediation.patch @@ -0,0 +1,235 @@ +From 05ce84ae76e0e71381bcc7b8491a74e7edcd888f Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Tue, 20 Jan 2026 09:52:47 +0100 +Subject: [PATCH 2/2] Issue 7189 - DSBLE0007 generates incorrect remediation + commands for scan limits + +Bug Description: + +The generated dsconf commands for fixing missing system indexes had two issues: + +1. The --add-scanlimit value was not quoted, causing the shell to interpret + "limit=5000 type=eq flags=AND" as multiple arguments instead of a single + value, resulting in "unrecognized arguments: type=eq flags=AND" error. + +2. When both matching rule and scanlimit were missing, two separate commands + were generated where the second would fail because the matching rule was + already added by the first command. + +Fix Description: + +1. Quote the scanlimit value in all remediation commands + +2. Combine matching rule and scanlimit fixes into a single command when + both are missing for the same index instead of expected_scanlimit) + +Fixes: https://github.com/389ds/389-ds-base/issues/7189 + +Reviewed by: @progier389, @droideck (Thanks!) +--- + .../healthcheck/health_system_indexes_test.py | 126 ++++++++++++++++++ + src/lib389/lib389/backend.py | 39 +++--- + 2 files changed, 147 insertions(+), 18 deletions(-) + +diff --git a/dirsrvtests/tests/suites/healthcheck/health_system_indexes_test.py b/dirsrvtests/tests/suites/healthcheck/health_system_indexes_test.py +index 1700ba207..f25de4214 100644 +--- a/dirsrvtests/tests/suites/healthcheck/health_system_indexes_test.py ++++ b/dirsrvtests/tests/suites/healthcheck/health_system_indexes_test.py +@@ -406,6 +406,132 @@ def test_retrocl_plugin_missing_matching_rule(topology_st, retrocl_plugin_enable + run_healthcheck_and_flush_log(topology_st, standalone, json=True, searched_code=JSON_OUTPUT) + + ++def test_missing_scanlimit(topology_st, log_buffering_enabled): ++ """Check if healthcheck returns DSBLE0007 code when parentId index is missing scanlimit ++ ++ :id: 40e1bf6a-2397-459b-bdf3-f787ca118b86 ++ :setup: Standalone instance ++ :steps: ++ 1. Create DS instance ++ 2. Remove nsIndexIDListScanLimit from parentId index ++ 3. Use healthcheck without --json option ++ 4. Use healthcheck with --json option ++ 5. Verify the remediation command has properly quoted scanlimit ++ 6. Re-add the scanlimit ++ 7. Use healthcheck without --json option ++ 8. Use healthcheck with --json option ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. healthcheck reports DSBLE0007 code and related details ++ 4. healthcheck reports DSBLE0007 code and related details ++ 5. The scanlimit value is quoted in the remediation command ++ 6. Success ++ 7. healthcheck reports no issues found ++ 8. healthcheck reports no issues found ++ """ ++ ++ RET_CODE = "DSBLE0007" ++ PARENTID_DN = "cn=parentid,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config" ++ SCANLIMIT_VALUE = "limit=5000 type=eq flags=AND" ++ ++ standalone = topology_st.standalone ++ ++ log.info("Remove nsIndexIDListScanLimit from parentId index") ++ parentid_index = Index(standalone, PARENTID_DN) ++ parentid_index.remove("nsIndexIDListScanLimit", SCANLIMIT_VALUE) ++ ++ run_healthcheck_and_flush_log(topology_st, standalone, json=False, searched_code=RET_CODE) ++ ++ # Verify the remediation command has properly quoted scanlimit ++ args = FakeArgs() ++ args.instance = standalone.serverid ++ args.verbose = standalone.verbose ++ args.list_errors = False ++ args.list_checks = False ++ args.exclude_check = [] ++ args.check = ["backends"] ++ args.dry_run = False ++ args.json = False ++ health_check_run(standalone, topology_st.logcap.log, args) ++ # Check that the scanlimit is quoted in the output ++ assert topology_st.logcap.contains('--add-scanlimit "limit=5000 type=eq flags=AND"') ++ log.info("Verified scanlimit is properly quoted in remediation command") ++ topology_st.logcap.flush() ++ ++ run_healthcheck_and_flush_log(topology_st, standalone, json=True, searched_code=RET_CODE) ++ ++ log.info("Re-add the nsIndexIDListScanLimit") ++ parentid_index = Index(standalone, PARENTID_DN) ++ parentid_index.add("nsIndexIDListScanLimit", SCANLIMIT_VALUE) ++ ++ run_healthcheck_and_flush_log(topology_st, standalone, json=False, searched_code=CMD_OUTPUT) ++ run_healthcheck_and_flush_log(topology_st, standalone, json=True, searched_code=JSON_OUTPUT) ++ ++ ++def test_missing_matching_rule_and_scanlimit(topology_st, log_buffering_enabled): ++ """Check if healthcheck generates a single combined command when both matching rule and scanlimit are missing ++ ++ :id: af8214ad-5e4c-422a-8f74-3e99227551df ++ :setup: Standalone instance ++ :steps: ++ 1. Create DS instance ++ 2. Remove both integerOrderingMatch and nsIndexIDListScanLimit from parentId index ++ 3. Use healthcheck and verify a single combined command is generated ++ 4. Re-add the matching rule and scanlimit ++ 5. Use healthcheck without --json option ++ 6. Use healthcheck with --json option ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. healthcheck reports DSBLE0007 and generates a single command with both --add-mr and --add-scanlimit ++ 4. Success ++ 5. healthcheck reports no issues found ++ 6. healthcheck reports no issues found ++ """ ++ ++ RET_CODE = "DSBLE0007" ++ PARENTID_DN = "cn=parentid,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config" ++ SCANLIMIT_VALUE = "limit=5000 type=eq flags=AND" ++ ++ standalone = topology_st.standalone ++ ++ log.info("Remove both integerOrderingMatch and nsIndexIDListScanLimit from parentId index") ++ parentid_index = Index(standalone, PARENTID_DN) ++ parentid_index.remove("nsMatchingRule", "integerOrderingMatch") ++ parentid_index.remove("nsIndexIDListScanLimit", SCANLIMIT_VALUE) ++ ++ # Run healthcheck and verify combined command ++ args = FakeArgs() ++ args.instance = standalone.serverid ++ args.verbose = standalone.verbose ++ args.list_errors = False ++ args.list_checks = False ++ args.exclude_check = [] ++ args.check = ["backends"] ++ args.dry_run = False ++ args.json = False ++ health_check_run(standalone, topology_st.logcap.log, args) ++ ++ # Verify DSBLE0007 is reported ++ assert topology_st.logcap.contains(RET_CODE) ++ log.info("healthcheck returned code: %s" % RET_CODE) ++ ++ # Verify a single combined command is generated with both --add-mr and --add-scanlimit ++ assert topology_st.logcap.contains('--add-mr integerOrderingMatch --add-scanlimit "limit=5000 type=eq flags=AND"') ++ log.info("Verified combined command with both --add-mr and --add-scanlimit") ++ ++ topology_st.logcap.flush() ++ ++ log.info("Re-add the integerOrderingMatch matching rule and scanlimit") ++ parentid_index = Index(standalone, PARENTID_DN) ++ parentid_index.add("nsMatchingRule", "integerOrderingMatch") ++ parentid_index.add("nsIndexIDListScanLimit", SCANLIMIT_VALUE) ++ ++ run_healthcheck_and_flush_log(topology_st, standalone, json=False, searched_code=CMD_OUTPUT) ++ run_healthcheck_and_flush_log(topology_st, standalone, json=True, searched_code=JSON_OUTPUT) ++ ++ + def test_multiple_missing_indexes(topology_st, log_buffering_enabled): + """Check if healthcheck returns DSBLE0007 code when multiple system indexes are missing + +diff --git a/src/lib389/lib389/backend.py b/src/lib389/lib389/backend.py +index 14b64d1d3..3cea0df36 100644 +--- a/src/lib389/lib389/backend.py ++++ b/src/lib389/lib389/backend.py +@@ -602,7 +602,7 @@ class Backend(DSLdapObject): + if expected_config.get('matching_rule'): + cmd += f" --matching-rule {expected_config['matching_rule']}" + if expected_config.get('scanlimit'): +- cmd += f" --add-scanlimit {expected_config['scanlimit']}" ++ cmd += f" --add-scanlimit \"{expected_config['scanlimit']}\"" + remediation_commands.append(cmd) + reindex_attrs.add(attr_name) # New index needs reindexing + else: +@@ -624,28 +624,31 @@ class Backend(DSLdapObject): + remediation_commands.append(cmd) + reindex_attrs.add(attr_name) + +- # Check matching rules ++ # Check matching rules and scanlimit together to generate a single combined command + expected_mr = expected_config.get('matching_rule') ++ expected_scanlimit = expected_config.get('scanlimit') ++ ++ missing_mr = False + if expected_mr: + actual_mrs_lower = [mr.lower() for mr in actual_mrs] + if expected_mr.lower() not in actual_mrs_lower: + discrepancies.append(f"Index {attr_name} missing matching rule: {expected_mr}") +- # Add the missing matching rule +- cmd = f"dsconf YOUR_INSTANCE backend index set {bename} --attr {attr_name} --add-mr {expected_mr}" +- remediation_commands.append(cmd) +- reindex_attrs.add(attr_name) +- +- # Check fine grain definitions for parentid ONLY +- expected_scanlimit = expected_config.get('scanlimit') +- if (attr_name.lower() == "parentid") and expected_scanlimit and (len(actual_scanlimit) == 0): +- discrepancies.append(f"Index {attr_name} missing fine grain definition of IDs limit: {expected_mr}") +- # Add the missing scanlimit +- if expected_mr: +- cmd = f"dsconf YOUR_INSTANCE backend index set {bename} --attr {attr_name} --add-mr {expected_mr} --add-scanlimit {expected_scanlimit}" +- else: +- cmd = f"dsconf YOUR_INSTANCE backend index set {bename} --attr {attr_name} --add-scanlimit {expected_scanlimit}" +- remediation_commands.append(cmd) +- reindex_attrs.add(attr_name) ++ missing_mr = True ++ ++ missing_scanlimit = False ++ if expected_scanlimit and (len(actual_scanlimit) == 0): ++ discrepancies.append(f"Index {attr_name} missing fine grain definition of IDs limit: {expected_scanlimit}") ++ missing_scanlimit = True ++ ++ # Generate a single combined command for all missing items ++ if missing_mr or missing_scanlimit: ++ cmd = f"dsconf YOUR_INSTANCE backend index set {bename} --attr {attr_name}" ++ if missing_mr: ++ cmd += f" --add-mr {expected_mr}" ++ if missing_scanlimit: ++ cmd += f" --add-scanlimit \"{expected_scanlimit}\"" ++ remediation_commands.append(cmd) ++ reindex_attrs.add(attr_name) + + except Exception as e: + self._log.debug(f"_lint_system_indexes - Error checking index {attr_name}: {e}") +-- +2.52.0 + diff --git a/389-ds-base.spec b/389-ds-base.spec index b93507d..1e112da 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -52,7 +52,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 1.4.3.39 -Release: %{?relprefix}20%{?prerel}%{?dist} +Release: %{?relprefix}21%{?prerel}%{?dist} License: GPL-3.0-or-later WITH GPL-3.0-389-ds-base-exception AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSD-2-Clause OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR LGPL-2.1-or-later OR MIT) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (MIT OR Apache-2.0) AND Unicode-3.0 AND (MIT OR Unlicense) AND Apache-2.0 AND BSD-3-Clause AND MIT AND MPL-2.0 URL: https://www.port389.org Group: System Environment/Daemons @@ -373,6 +373,8 @@ Patch72: 0072-Issue-6966-2nd-On-large-DB-unlimited-IDL-scan-limit-.patc Patch73: 0073-Issue-7056-DSBLE0007-doesn-t-generate-remediation-st.patch Patch74: 0074-Issue-7172-Index-ordering-mismatch-after-upgrade-717.patch Patch75: 0075-Issue-7172-2nd-Index-ordering-mismatch-after-upgrade.patch +Patch76: 0076-Issue-7071-search-filter-cn-dn-groups-no-longer-retu.patch +Patch77: 0077-Issue-7189-DSBLE0007-generates-incorrect-remediation.patch #Patch100: cargo.patch @@ -998,6 +1000,11 @@ exit 0 %doc README.md %changelog +* Fri Jan 23 2026 Arun Bansal - 1.4.3.39-21 +- Resolves: RHEL-141419 - (&(cn:dn:=groups)) no longer returns results [rhel-8.10.z] +- Resolves: RHEL-140272 - ipa-healthcheck is complaining about missing or + incorrectly configured system indexes. [rhel-8.10.z] + * Tue Jan 13 2026 Arun Bansal - 1.4.3.39-20 - Resolves: RHEL-140086 - Upgrading IDM to latest version: 389-ds-base and ipa-server breaks replication [rhel-8.10.z]