This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch 11.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit d7829e828b3e23849d5a858b620642095492c9a5 Author: opencode <[email protected]> AuthorDate: Wed Oct 7 15:04:55 2026 +0200 Fix nested role search DN computation in JNDIRealm In getRoles(), the direct role search computed result DNs using the per-user formatted roleBase (the base actually searched) while the nested group search round still used the raw roleBase field. When roleBase contained {0}..{n} pattern replacements, the computed DNs embedded the literal placeholder text so the member filter of the next search round could never match and groups nested more than one level deep were silently missed. With roleBase set to null, the raw field also caused an NPE when composing relative result names. This completes the fix applied in 81f16b0a71 which addressed the same issue in the direct search path. Add regression coverage: a group nested one level below the group directly containing the user in TestJNDIRealmIntegration, exercised with a patterned roleBase. The new parameter sets fail without the fix. Include a changelog entry. --- java/org/apache/catalina/realm/JNDIRealm.java | 5 ++--- .../apache/catalina/realm/TestJNDIRealmIntegration.java | 17 +++++++++++++++-- webapps/docs/changelog.xml | 10 ++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/java/org/apache/catalina/realm/JNDIRealm.java b/java/org/apache/catalina/realm/JNDIRealm.java index bda00be27c..b1da7d8bee 100644 --- a/java/org/apache/catalina/realm/JNDIRealm.java +++ b/java/org/apache/catalina/realm/JNDIRealm.java @@ -2206,8 +2206,7 @@ public class JNDIRealm extends RealmBase { doFilterEscaping(doAttributeValueEscaping(group.getValue())) }); if (containerLog.isTraceEnabled()) { - containerLog - .trace("Perform a nested group search with base " + roleBase + " and filter " + filter); + containerLog.trace("Perform a nested group search with base " + base + " and filter " + filter); } results = searchAsUser(connection.context, user, base, filter, controls, isRoleSearchAsUser()); @@ -2219,7 +2218,7 @@ public class JNDIRealm extends RealmBase { if (attrs == null) { continue; } - String dname = getDistinguishedName(connection.context, roleBase, result); + String dname = getDistinguishedName(connection.context, base, result); String name = getAttributeValue(roleName, attrs); if (name != null && dname != null && !groupMap.containsKey(dname)) { groupMap.put(dname, name); diff --git a/test/org/apache/catalina/realm/TestJNDIRealmIntegration.java b/test/org/apache/catalina/realm/TestJNDIRealmIntegration.java index 060a95fe52..d16418d6e1 100644 --- a/test/org/apache/catalina/realm/TestJNDIRealmIntegration.java +++ b/test/org/apache/catalina/realm/TestJNDIRealmIntegration.java @@ -75,10 +75,12 @@ public class TestJNDIRealmIntegration { } } parameterSets.add(new Object[] { "cn={0},ou=s\\;ub,ou=people,dc=example,dc=com", null, null, ROLE_SEARCH_A, - "{3},ou=people,dc=example,dc=com", "testsub", "test", new String[] { "TestGroup4" }, + "{3},ou=people,dc=example,dc=com", "testsub", "test", + new String[] { "TestGroup4", "TestGroup5" }, userRoleAttribute, Integer.valueOf(1) }); parameterSets.add(new Object[] { "cn={0},ou=s\\;ub,ou=people,dc=example,dc=com", null, null, ROLE_SEARCH_A, - "{3},ou=people,dc=example,dc=com", "testsub", "test", new String[] { "TestGroup4" }, + "{3},ou=people,dc=example,dc=com", "testsub", "test", + new String[] { "TestGroup4", "TestGroup5" }, userRoleAttribute, Integer.valueOf(4) }); } /* @@ -319,6 +321,17 @@ public class TestJNDIRealmIntegration { result = conn.processOperation(addGroupTest4); Assert.assertEquals(ResultCode.SUCCESS, result.getResultCode()); + // Nested one level below TestGroup4 so the patterned roleBase must be resolved correctly for the + // member filter of the second nested search round to match + AddRequest addGroupTest5 = new AddRequest( + "dn: cn=TestGroup5,ou=s\\;ub,ou=people,dc=example,dc=com", + "objectClass: top", + "objectClass: groupOfNames", + "cn: TestGroup5", + "member: cn=TestGroup4,ou=s\\;ub,ou=people,dc=example,dc=com"); + result = conn.processOperation(addGroupTest5); + Assert.assertEquals(ResultCode.SUCCESS, result.getResultCode()); + // Bug 65373 AddRequest addUserBug65373 = new AddRequest( "dn: cn=\\3C\\3E\\2B=\\22#\\3B\\2Crrr,ou=people,dc=example,dc=com", diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 843d066f46..176522dbe5 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -108,6 +108,16 @@ issues do not "pop up" wrt. others). --> <section name="Tomcat 11.0.28 (markt)" rtext="in development"> + <subsection name="Catalina"> + <changelog> + <fix> + Use the resolved <code>roleBase</code> value when computing the + distinguished name of a group found during a nested role search in + <code>JNDIRealm</code>, so that groups nested more than one level deep + are found when <code>roleBase</code> uses pattern replacements. (remm) + </fix> + </changelog> + </subsection> <subsection name="Web applications"> <changelog> <fix> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
