This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 09c6952c9d98539d7c8edfdeb00730e57c827410 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 396552c747..e664bf6e03 100644 --- a/java/org/apache/catalina/realm/JNDIRealm.java +++ b/java/org/apache/catalina/realm/JNDIRealm.java @@ -2204,8 +2204,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()); @@ -2217,7 +2216,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 65b42a9b9c..3f62d69765 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 9.0.124 (remm)" 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> </section> <section name="Tomcat 9.0.123 (remm)" rtext="release in progress"> <subsection name="Catalina"> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
