This is an automated email from the ASF dual-hosted git repository.

rmaucher pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 32df46a3e18eb76d356b1138595e91e6c86203d3
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 b23379b00a..e0813129e7 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 9f4bad879e..5b773073e9 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 10.1.62 (schultz)" 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]

Reply via email to