From 27147915fbea307fce63e2d3bb3404ca80b8e52c Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Wed, 08 Jul 2026 16:17:55 +0000
Subject: [PATCH] Fix ACI grouped bind rule wrongly rejected when a value contains parentheses (#716)

---
 opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/BindRule.java |   26 +++++++++++++++++---------
 1 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/BindRule.java b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/BindRule.java
index 52f7b09..8952ea6 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/BindRule.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/BindRule.java
@@ -13,6 +13,7 @@
  *
  * Copyright 2008 Sun Microsystems, Inc.
  * Portions Copyright 2013-2016 ForgeRock AS.
+ * Portions Copyright 2026 3A Systems, LLC
  */
 package org.opends.server.authorization.dseecompat;
 
@@ -133,11 +134,10 @@
     }
 
     /*
-     * TODO Verify this method handles escaped parentheses by writing
-     * a unit test.
-     *
-     * It doesn't look like the decode() method handles the possibility of
-     * escaped parentheses in a bind rule.
+     * Parentheses embedded in a quoted bind rule expression (for example a DN
+     * value such as userdn="ldap:///cn=a(b),dc=example,dc=com") are treated as
+     * literal data and are not mistaken for grouping parentheses. See the
+     * quote-aware scan below and BindRuleParenTest for the covering cases.
      */
     /**
      * Decode an ACI bind rule string representation.
@@ -160,19 +160,27 @@
           int currentPos;
           int numOpen = 0;
           int numClose = 0;
+          boolean inQuotes = false;
 
-          // Find the associated closed parenthesis
+          // Find the associated closed parenthesis. Parentheses that appear
+          // inside a quoted bind rule expression (e.g. a DN value containing
+          // '(' or ')') are literal data and must not be counted as grouping.
           for (currentPos = 0; currentPos < bindruleArray.length; currentPos++)
           {
-            if (bindruleArray[currentPos] == '(')
+            char currentChar = bindruleArray[currentPos];
+            if (currentChar == '"')
+            {
+              inQuotes = !inQuotes;
+            }
+            else if (!inQuotes && currentChar == '(')
             {
               numOpen++;
             }
-            else if (bindruleArray[currentPos] == ')')
+            else if (!inQuotes && currentChar == ')')
             {
               numClose++;
             }
-            if (numClose == numOpen)
+            if (!inQuotes && numClose == numOpen)
             {
               // We found the associated closed parenthesis the parenthesis are removed
               String bindruleStr1 = bindruleStr.substring(1, currentPos);

--
Gitblit v1.10.0