From 3f4deb91789189521d577457bd6da27de8fd75b1 Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Wed, 07 Oct 2026 08:31:10 +0000
Subject: [PATCH] [#1153] Parse the whole DN string, and build or split DN strings through DN instead of string operations (#1171)
---
opendj-server-legacy/src/main/java/org/opends/server/config/JMXMBean.java | 113 ++++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 80 insertions(+), 33 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/config/JMXMBean.java b/opendj-server-legacy/src/main/java/org/opends/server/config/JMXMBean.java
index 8e06561..318101c 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/config/JMXMBean.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/config/JMXMBean.java
@@ -13,7 +13,7 @@
*
* Portions Copyright 2006-2007-2008 Sun Microsystems, Inc.
* Portions Copyright 2013-2016 ForgeRock AS.
- * Portions Copyright 2023-2025 3A Systems LLC.
+ * Portions Copyright 2023-2026 3A Systems LLC.
*/
package org.opends.server.config;
@@ -49,6 +49,7 @@
import static org.opends.server.protocols.internal.Requests.newSearchRequest;
import static org.opends.server.util.CollectionUtils.newArrayList;
import static org.opends.server.util.ServerConstants.MBEAN_BASE_DOMAIN;
+import static org.opends.server.util.StaticUtils.byteToHex;
import static org.opends.server.util.StaticUtils.isAlpha;
import static org.opends.server.util.StaticUtils.isDigit;
@@ -95,40 +96,16 @@
{
try
{
- String typeStr = null;
- String dnString = configEntryDN.toString();
- if (dnString != null && dnString.length() != 0)
+ StringBuilder buffer = new StringBuilder();
+ // Walk the RDNs from the root, rather than splitting the DN string at every comma.
+ for (int j = configEntryDN.size() - 1; j >= 0; j--)
{
- StringBuilder buffer = new StringBuilder(dnString.length());
- String rdns[] = dnString.replace(',', ';').split(";");
- for (int j = rdns.length - 1; j >= 0; j--)
- {
- int rdnIndex = rdns.length - j;
- buffer.append(",Rdn").append(rdnIndex).append("=") ;
- for (int i = 0; i < rdns[j].length(); i++)
- {
- char c = rdns[j].charAt(i);
- if (isAlpha(c) || isDigit(c))
- {
- buffer.append(c);
- } else
- {
- switch (c)
- {
- case ' ':
- buffer.append("_");
- break;
- case '=':
- buffer.append("-");
- }
- }
- }
- }
-
- typeStr = buffer.toString();
+ int rdnIndex = configEntryDN.size() - j;
+ buffer.append(",Rdn").append(rdnIndex).append("=");
+ appendJmxRdn(buffer, configEntryDN.parent(j).rdn());
}
-
- return MBEAN_BASE_DOMAIN + ":" + "Name=rootDSE" + typeStr;
+ // The root DN keeps the name it always had, which ends with "null".
+ return MBEAN_BASE_DOMAIN + ":" + "Name=rootDSE" + (buffer.length() != 0 ? buffer : "null");
} catch (Exception e)
{
logger.traceException(e);
@@ -138,6 +115,76 @@
}
/**
+ * Appends the JMX form of an RDN to the provided buffer. The attribute name keeps only its letters and
+ * digits, and is followed by '-' and the value. A value made of letters, digits and spaces is written as it
+ * always was, with '_' for a space. Any other value would lose characters that way, and two DNs would share
+ * a name, so it is percent-encoded instead: its letters and digits are kept, a space is still written as '_',
+ * and every other character, '_' included, is written as the '%' encoded bytes of its UTF-8 form. The SNMP
+ * extension relies on the '_': it finds the connection handlers, whose names hold an IP address, by
+ * "Connection_Handler" and their statistics by "_Statistics". The AVAs of a multi-valued RDN are joined
+ * with '+'.
+ */
+ private static void appendJmxRdn(StringBuilder buffer, RDN rdn)
+ {
+ boolean first = true;
+ for (AVA ava : rdn)
+ {
+ if (!first)
+ {
+ buffer.append('+');
+ }
+ first = false;
+ String name = ava.getAttributeName();
+ for (int i = 0; i < name.length(); i++)
+ {
+ char c = name.charAt(i);
+ if (isAlpha(c) || isDigit(c))
+ {
+ buffer.append(c);
+ }
+ }
+ buffer.append('-');
+ String value = ava.getAttributeValue().toString();
+ if (isPlainJmxValue(value))
+ {
+ buffer.append(value.replace(' ', '_'));
+ }
+ else
+ {
+ for (byte b : ava.getAttributeValue().toByteArray())
+ {
+ char c = (char) (b & 0xFF);
+ if (c == ' ')
+ {
+ buffer.append('_');
+ }
+ else if (c < 0x80 && (isAlpha(c) || isDigit(c)))
+ {
+ buffer.append(c);
+ }
+ else
+ {
+ buffer.append('%').append(byteToHex(b));
+ }
+ }
+ }
+ }
+ }
+
+ private static boolean isPlainJmxValue(String value)
+ {
+ for (int i = 0; i < value.length(); i++)
+ {
+ char c = value.charAt(i);
+ if (!isAlpha(c) && !isDigit(c) && c != ' ')
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
* Creates a new dynamic JMX MBean for use with the Directory Server.
*
* @param configEntryDN The DN of the configuration entry with which this
--
Gitblit v1.10.0