From 8e8b6bd663f9c477b383e7f2aee2a42d62c96fda Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Thu, 30 Jul 2026 16:03:59 +0300 Subject: [PATCH 1/2] Fix CodeQL warning-severity alerts: dead checks, boxed locals and four null dereferences Tier 4 of the warning-severity CodeQL triage, covering the remaining sixteen rules. Of the 121 alerts, 64 are fixed here; the other 57 are left as they are for the reasons given at the end. Four of these turned out to be real defects rather than noise: * ModifyDNOperationBasis.getNewDN() checked for a null parent DN, set an UNWILLING_TO_PERFORM result, and then fell through to parentDN.child(), which throws NullPointerException. It now returns null once the error is recorded. The isRootDN() path is unchanged, since a child DN can still be built there. * RootContainer dereferenced highestID, which stays null when there is no base DN to open. Entry numbering now starts at 1 in that case. * ImportTask dereferenced the backend field in two places. With neither a backend ID nor an include branch resolving to a backend it stayed null, so a malformed import task failed with a NullPointerException instead of a diagnosable error. * BuildVersion.compareTo compared the rev field with ==, but rev is a String, so the comparison was by reference. AttributeFilter kept its iteration state in the Iterable rather than in the iterator, so a second traversal, including the one performed by toString(), yielded nothing. The state now belongs to the iterator. Dead checks removed (19 alerts). Each was verified in place and every removal preserves behaviour: a lower bound already implied by the enclosing test in ASCIICharProp and StringPrepProfile; a NUL comparison in the else branch of a c < ' ' test in AVA; a negative test on a value masked with 0x7F in PasswordPolicyResponseControl; an index test already implied by the loop bound in InetAddressValidator; three unreachable checks in SchemaUtils, where length is already 1 and the first character was validated by the enclosing isAlpha test; a length check already performed at the top of the method in UTCTimeSyntaxImpl; a negative array length in TemplateTag; a redundant second comparison in StaticUtils; and six null checks on fields initialised to a new collection. Mechanical fixes (41 alerts): fifteen boxed locals replaced by primitives; eight getClass().getResource calls replaced by the declaring class literal; seven int multiplications widened to long; three non-short-circuit operators rewritten into explicit locals, with a comment on why both sides must be evaluated; the two getFormatter calls in JDKLogging qualified with super, since they resolve to Handler rather than to the enclosing JDKLogging.getFormatter(); two per-call SecureRandom instances replaced by a shared one; an explicit interrupt check in the StatusCli refresh loop; and a dead assignment in replace.rb. Left as they are: * java/dereferenced-value-may-be-null, 37 alerts. All 42 were reviewed individually rather than dismissed as a group: four were real and are fixed above, one is already fixed by the Tier 1 change to AsynchronousTextWriter, and the rest are inferred from a guard on a different path. Resolving them would mean either adding redundant null checks or removing guards that may be needed. * java/inconsistent-compareto-and-equals, 12 alerts. Adding equals and hashCode would change collection semantics for classes that currently rely on identity in HashMap and HashSet. Task was checked as a representative: its compareTo falls back to comparing task IDs, so compareTo returns 0 only for the same task and its TreeSet usage is already correct. * java/constant-comparison, 6 alerts. Two are in DoubleMetaphone, a line-by-line port of the Double Metaphone algorithm where simplifying the conditions risks changing phonetic matching results. Four are retry loop conditions that are trivially true on their first evaluation. * java/iterator-remove-failure, 1 alert. The delegating remove() correctly propagates UnsupportedOperationException. --- .../opendj/config/dsconfig/BuildVersion.java | 3 ++- .../forgerock/opendj/util/ASCIICharProp.java | 5 +++-- .../opendj/util/StringPrepProfile.java | 3 ++- .../java/org/forgerock/opendj/ldap/AVA.java | 4 +++- .../opendj/ldap/AttributeFilter.java | 15 +++++++++++---- .../opendj/ldap/GeneralizedTime.java | 6 +++--- .../opendj/ldap/InetAddressValidator.java | 3 ++- .../PasswordPolicyResponseControl.java | 3 +-- .../opendj/ldap/schema/NameForm.java | 3 ++- .../opendj/ldap/schema/SchemaUtils.java | 19 +++++-------------- .../opendj/ldap/schema/UTCTimeSyntaxImpl.java | 13 +++---------- .../forgerock/opendj/ldif/TemplateTag.java | 3 ++- .../GenerateConfigurationReferenceMojo.java | 3 ++- .../org/opends/dsml/protocol/DSMLServlet.java | 2 +- .../opendj/maven/GenerateConfigMojo.java | 4 ++-- .../rest2ldap/Rest2LdapHttpApplication.java | 5 +++-- .../JsonQueryEqualityMatchingRuleImpl.java | 3 ++- opendj-server-legacy/replace.rb | 4 +++- .../controlpanel/ui/GenericDialog.java | 5 +---- .../guitools/controlpanel/util/Utilities.java | 5 +++-- .../quicksetup/installer/Installer.java | 5 +++-- .../authorization/dseecompat/BindRule.java | 8 +++----- .../opends/server/backends/LDIFBackend.java | 8 ++------ .../backends/pluggable/RootContainer.java | 4 +++- .../org/opends/server/core/MemoryQuota.java | 3 ++- .../server/core/ModifyDNOperationBasis.java | 6 ++++++ .../server/crypto/CryptoManagerImpl.java | 5 +++-- .../server/extensions/EntryCacheCommon.java | 7 ++++--- .../SaltedSHA1PasswordStorageScheme.java | 9 ++++++++- .../SaltedSHA512PasswordStorageScheme.java | 9 ++++++++- .../opends/server/loggers/CommonAudit.java | 3 ++- .../CommonAuditAccessLogPublisher.java | 3 ++- .../org/opends/server/loggers/JDKLogging.java | 9 ++++++--- .../replication/server/ServerHandler.java | 2 +- .../service/ReplicationBroker.java | 2 +- .../server/schema/GeneralizedTimeSyntax.java | 3 ++- .../org/opends/server/tasks/ImportTask.java | 14 ++++++++++++++ .../tasks/PurgeConflictsHistoricalTask.java | 11 +++++++---- .../dsreplication/ReplicationCliMain.java | 4 ++-- .../opends/server/tools/status/StatusCli.java | 7 ++++--- .../java/org/opends/server/types/Entry.java | 3 ++- .../server/util/CronExecutorService.java | 13 ++++++++++--- .../org/opends/server/util/StaticUtils.java | 11 +++++------ .../src/org/opends/server/snmp/DsMIBImpl.java | 6 ++---- .../server/core/ProductInformation.java | 3 ++- 45 files changed, 160 insertions(+), 109 deletions(-) diff --git a/opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/BuildVersion.java b/opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/BuildVersion.java index 7f33935fea..cd1620dfeb 100644 --- a/opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/BuildVersion.java +++ b/opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/BuildVersion.java @@ -13,6 +13,7 @@ * * Copyright 2008 Sun Microsystems, Inc. * Portions Copyright 2013-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.forgerock.opendj.config.dsconfig; @@ -191,7 +192,7 @@ public int compareTo(final BuildVersion version) { if (major == version.major) { if (minor == version.minor) { if (point == version.point) { - if (rev == version.rev) { + if (rev.equals(version.rev)) { return 0; } else if (rev.compareTo(version.rev) < 0) { return -1; diff --git a/opendj-core/src/main/java/com/forgerock/opendj/util/ASCIICharProp.java b/opendj-core/src/main/java/com/forgerock/opendj/util/ASCIICharProp.java index fc8816b64c..86ee0abe15 100644 --- a/opendj-core/src/main/java/com/forgerock/opendj/util/ASCIICharProp.java +++ b/opendj-core/src/main/java/com/forgerock/opendj/util/ASCIICharProp.java @@ -13,6 +13,7 @@ * * Copyright 2009 Sun Microsystems, Inc. * Portions copyright 2011-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package com.forgerock.opendj.util; @@ -110,7 +111,7 @@ private ASCIICharProp(final char c) { this.isKeyChar = true; this.isCompatKeyChar = true; this.decimalValue = -1; - if (c >= 'a' && c <= 'f') { + if (c <= 'f') { this.isHexChar = true; this.hexValue = c - 87; } else { @@ -127,7 +128,7 @@ private ASCIICharProp(final char c) { this.isKeyChar = true; this.isCompatKeyChar = true; this.decimalValue = -1; - if (c >= 'A' && c <= 'F') { + if (c <= 'F') { this.isHexChar = true; this.hexValue = c - 55; } else { diff --git a/opendj-core/src/main/java/com/forgerock/opendj/util/StringPrepProfile.java b/opendj-core/src/main/java/com/forgerock/opendj/util/StringPrepProfile.java index 7d2c291553..2ba8f1ca5c 100644 --- a/opendj-core/src/main/java/com/forgerock/opendj/util/StringPrepProfile.java +++ b/opendj-core/src/main/java/com/forgerock/opendj/util/StringPrepProfile.java @@ -13,6 +13,7 @@ * * Copyright 2010 Sun Microsystems, Inc. * Portions Copyright 2015 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package com.forgerock.opendj.util; @@ -462,7 +463,7 @@ public static void prepareUnicode(final StringBuilder buffer, final ByteSequence if (canMapToSpace(buffer, trim)) { buffer.append(SPACE_CHAR); } - } else if ((b >= '\u0000' && b <= '\u0008') || (b >= '\u000E' && b <= '\u001F') + } else if (b <= '\u0008' || (b >= '\u000E' && b <= '\u001F') || b == '\u007F') { // These characters are mapped to nothing and hence not // copied over.. diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java index 14ddecb1d7..4ec131b0ab 100644 --- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java +++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2010 Sun Microsystems, Inc. + * Portions Copyright 2026 3A Systems, LLC. * Portions copyright 2011-2016 ForgeRock AS. * Portions copyright 2021-2026 3A Systems, LLC */ @@ -166,9 +167,10 @@ static void escapeAttributeValue(final String str, final StringBuilder builder) builder.append(StaticUtils.byteToLowerHex(b)); } } else { + // NUL needs no test here: it is already handled by the c < ' ' branch above. if ((c == ' ' && si == length - 1) || (c == '"' || c == '+' || c == ',' || c == ';' || c == '<' - || c == '>' || c == '\\' || c == '\u0000' || c == '=')) { + || c == '>' || c == '\\' || c == '=')) { builder.append('\\'); } builder.append(c); diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeFilter.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeFilter.java index c207ed8468..345e9128e5 100644 --- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeFilter.java +++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeFilter.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2013-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.forgerock.opendj.ldap; @@ -163,13 +164,19 @@ public Iterable getAllAttributes() { * requested by the user. */ return new Iterable() { - private boolean hasNextMustIterate = true; - private final Iterator iterator = entry.getAllAttributes().iterator(); - private Attribute next = null; - @Override public Iterator iterator() { + /* + * The iteration state belongs to the iterator, not to this Iterable: + * keeping it here is what allows the Iterable to be iterated more than + * once, including by the toString() below. + */ return new Iterator() { + private boolean hasNextMustIterate = true; + private final Iterator iterator = + entry.getAllAttributes().iterator(); + private Attribute next; + @Override public boolean hasNext() { if (hasNextMustIterate) { diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/GeneralizedTime.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/GeneralizedTime.java index d58dbcfc91..ac11537e25 100644 --- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/GeneralizedTime.java +++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/GeneralizedTime.java @@ -836,9 +836,9 @@ private GeneralizedTime(final Calendar calendar, final Date date, final long tim @Override public int compareTo(final GeneralizedTime o) { - final Long timeMS1 = getTimeInMillis(); - final Long timeMS2 = o.getTimeInMillis(); - return timeMS1.compareTo(timeMS2); + final long timeMS1 = getTimeInMillis(); + final long timeMS2 = o.getTimeInMillis(); + return Long.compare(timeMS1, timeMS2); } @Override diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/InetAddressValidator.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/InetAddressValidator.java index ab2c845e63..ef2cd7ed2b 100644 --- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/InetAddressValidator.java +++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/InetAddressValidator.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Portions copyright 2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -184,7 +185,7 @@ public static boolean isValidInet6Address(String inet6Address) { if (!inet6Address.endsWith(octet)) { return false; } - if (index > octets.length - 1 || index > 6) { // CHECKSTYLE IGNORE MagicNumber + if (index > 6) { // CHECKSTYLE IGNORE MagicNumber // IPV4 occupies last two octets return false; } diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyResponseControl.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyResponseControl.java index 13e3d2fd8f..be39394f45 100644 --- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyResponseControl.java +++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/controls/PasswordPolicyResponseControl.java @@ -138,8 +138,7 @@ public PasswordPolicyResponseControl decodeControl(final Control control, // nested element. reader.readStartSequence(); final int warningChoiceValue = (0x7F & reader.peekType()); - if (warningChoiceValue < 0 - || warningChoiceValue >= PasswordPolicyWarningType.values().length) { + if (warningChoiceValue >= PasswordPolicyWarningType.values().length) { final LocalizableMessage message = ERR_PWPOLICYRES_INVALID_WARNING_TYPE.get(byteToHex(reader .peekType())); diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NameForm.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NameForm.java index 214bb0ca6d..2e651a4c53 100644 --- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NameForm.java +++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/NameForm.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2009 Sun Microsystems, Inc. + * Portions Copyright 2026 3A Systems, LLC. * Portions copyright 2011-2016 ForgeRock AS. */ package org.forgerock.opendj.ldap.schema; @@ -334,7 +335,7 @@ private NameForm(final Builder builder) { if (builder.structuralObjectClassOID == null || builder.structuralObjectClassOID.isEmpty()) { throw new IllegalArgumentException("A structural class OID must be specified."); } - if (builder.requiredAttributes == null || builder.requiredAttributes.isEmpty()) { + if (builder.requiredAttributes.isEmpty()) { throw new IllegalArgumentException("Required attribute must be specified."); } diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java index 5195e65be6..a83843e61f 100644 --- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java +++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java @@ -14,6 +14,7 @@ * Copyright 2009 Sun Microsystems, Inc. * Portions copyright 2011-2016 ForgeRock AS. * Portions Copyright 2024 3A Systems, LLC. + * Portions Copyright 2026 3A Systems, LLC. */ package org.forgerock.opendj.ldap.schema; @@ -229,11 +230,8 @@ static String readOID(final SubstringReader reader, final boolean allowCompatCha && (c = reader.read()) != ' ' && c != ')' && (c != '\'' || !enclosingQuote)) { - if (length == 0 && !isAlpha(c)) { - throw DecodeException.error( - ERR_ATTR_SYNTAX_ILLEGAL_CHAR_IN_STRING_OID1.get(c, reader.pos() - 1)); - } - + // The first character was already required to be alphabetic by the enclosing + // test, so only the key-character check is needed here. if (!isKeyChar(c, allowCompatChars)) { throw DecodeException.error( ERR_ATTR_SYNTAX_ILLEGAL_CHAR_IN_STRING_OID1.get(c, reader.pos() - 1)); @@ -327,10 +325,6 @@ static String readOIDLen(final SubstringReader reader, final boolean allowCompat length++; } - if (length == 0) { - throw DecodeException.error( - ERR_ATTR_SYNTAX_OID_NO_VALUE1.get(reader.pos() - 1)); - } } else if (isAlpha(c)) { // This must be an attribute description. In this case, we will // only accept alphabetic characters, numeric digits, and the hyphen. @@ -338,11 +332,8 @@ static String readOIDLen(final SubstringReader reader, final boolean allowCompat && c != ')' && c != '{' && (c != '\'' || !enclosingQuote)) { - if (length == 0 && !isAlpha(c)) { - throw DecodeException.error( - ERR_ATTR_SYNTAX_ILLEGAL_CHAR_IN_STRING_OID1.get(c, reader.pos() - 1)); - } - + // The first character was already required to be alphabetic by the enclosing + // test, so only the key-character check is needed here. if (!isKeyChar(c, allowCompatChars)) { throw DecodeException.error( ERR_ATTR_SYNTAX_ILLEGAL_CHAR_IN_STRING_OID1.get(c, reader.pos() - 1)); diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxImpl.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxImpl.java index 321e4cb72f..a19944618e 100644 --- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxImpl.java +++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/UTCTimeSyntaxImpl.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2009 Sun Microsystems, Inc. + * Portions Copyright 2026 3A Systems, LLC. * Portions copyright 2012-2016 ForgeRock AS. */ package org.forgerock.opendj.ldap.schema; @@ -399,16 +400,8 @@ public boolean valueIsAcceptable(final Schema schema, final ByteSequence value, case '3': case '4': case '5': - // There must be at least two more characters, and the next one - // must be a digit between 0 and 9. - if (length < 11) { - final LocalizableMessage message = - ERR_ATTR_SYNTAX_UTC_TIME_INVALID_CHAR.get(valueString, String.valueOf(m1), - 8); - invalidReason.append(message); - return false; - } - + // A length below 11 was already rejected at the top of this method, so the next + // character is present and must be a digit between 0 and 9. switch (valueString.charAt(9)) { case '0': case '1': diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldif/TemplateTag.java b/opendj-core/src/main/java/org/forgerock/opendj/ldif/TemplateTag.java index dfcabc926b..3df49c28b1 100644 --- a/opendj-core/src/main/java/org/forgerock/opendj/ldif/TemplateTag.java +++ b/opendj-core/src/main/java/org/forgerock/opendj/ldif/TemplateTag.java @@ -13,6 +13,7 @@ * * Copyright 2006-2009 Sun Microsystems, Inc. * Portions Copyright 2013-2015 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.forgerock.opendj.ldif; @@ -1322,7 +1323,7 @@ void initializeForTemplate(Schema schema, TemplateFile templateFile, Template te } private void initialize(String[] arguments, int lineNumber) throws DecodeException { - if (arguments.length < 0 || arguments.length > 2) { + if (arguments.length > 2) { throw DecodeException.fatalError(ERR_ENTRY_GENERATOR_TAG_INVALID_ARGUMENT_RANGE_COUNT.get( getName(), lineNumber, 0, 2, arguments.length)); } diff --git a/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateConfigurationReferenceMojo.java b/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateConfigurationReferenceMojo.java index 5618a9fc85..94311a9924 100644 --- a/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateConfigurationReferenceMojo.java +++ b/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateConfigurationReferenceMojo.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2015-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.forgerock.opendj.maven.doc; @@ -151,7 +152,7 @@ private void generateConfigRef() throws MojoExecutionException { */ private void copyResources() throws IOException { for (String file : resourceFiles) { - InputStream original = this.getClass().getResourceAsStream("/config-ref/" + file); + InputStream original = GenerateConfigurationReferenceMojo.class.getResourceAsStream("/config-ref/" + file); File copy = new File(outputDirectory, file); copyInputStreamToFile(original, copy); } diff --git a/opendj-dsml-servlet/src/main/java/org/opends/dsml/protocol/DSMLServlet.java b/opendj-dsml-servlet/src/main/java/org/opends/dsml/protocol/DSMLServlet.java index 3b2d725bb7..46630f4354 100644 --- a/opendj-dsml-servlet/src/main/java/org/opends/dsml/protocol/DSMLServlet.java +++ b/opendj-dsml-servlet/src/main/java/org/opends/dsml/protocol/DSMLServlet.java @@ -234,7 +234,7 @@ public void init(ServletConfig config) throws ServletException { // assign the DSMLv2 schema for validation if(schema==null) { - URL url = getClass().getResource("/resources/DSMLv2.xsd"); + URL url = DSMLServlet.class.getResource("/resources/DSMLv2.xsd"); if ( url != null ) { SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI); schema = sf.newSchema(url); diff --git a/opendj-maven-plugin/src/main/java/org/forgerock/opendj/maven/GenerateConfigMojo.java b/opendj-maven-plugin/src/main/java/org/forgerock/opendj/maven/GenerateConfigMojo.java index 6ab98dcc3a..94f87ec155 100644 --- a/opendj-maven-plugin/src/main/java/org/forgerock/opendj/maven/GenerateConfigMojo.java +++ b/opendj-maven-plugin/src/main/java/org/forgerock/opendj/maven/GenerateConfigMojo.java @@ -184,7 +184,7 @@ public void execute() throws MojoExecutionException { } else if (!isXMLPackageDirectoryValid()) { throw new MojoExecutionException("The XML definition directory \"" + getXMLPackageDirectory() + "\" does not exist."); - } else if (getClass().getResource(getStylesheetDirectory()) == null) { + } else if (GenerateConfigMojo.class.getResource(getStylesheetDirectory()) == null) { throw new MojoExecutionException("The XSLT stylesheet directory \"" + getStylesheetDirectory() + "\" does not exist."); } @@ -439,7 +439,7 @@ private boolean isXMLPackageDirectoryValid() { private Templates loadStylesheet(final String stylesheet) throws TransformerConfigurationException { final Source xslt = - new StreamSource(getClass().getResourceAsStream( + new StreamSource(GenerateConfigMojo.class.getResourceAsStream( getStylesheetDirectory() + "/" + stylesheet)); return stylesheetFactory.newTemplates(xslt); } diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LdapHttpApplication.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LdapHttpApplication.java index c70ec3247e..1cacf95405 100644 --- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LdapHttpApplication.java +++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LdapHttpApplication.java @@ -13,6 +13,7 @@ * * Copyright 2015-2016 ForgeRock AS. * Portions Copyright 2017 Rosie Applications, Inc. + * Portions Copyright 2026 3A Systems, LLC. */ package org.forgerock.opendj.rest2ldap; @@ -176,10 +177,10 @@ private static String listValues() { public Rest2LdapHttpApplication() { try { // The null check is required for unit test mocks because the resource does not exist. - final URL configUrl = getClass().getResource("/config.json"); + final URL configUrl = Rest2LdapHttpApplication.class.getResource("/config.json"); this.configDirectory = configUrl != null ? new File(configUrl.toURI()).getParentFile() : null; } catch (final URISyntaxException e) { - throw new IllegalStateException(""+getClass().getResource("/config.json"),e); + throw new IllegalStateException("" + Rest2LdapHttpApplication.class.getResource("/config.json"), e); } this.schema = Schema.getDefaultSchema(); } diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/schema/JsonQueryEqualityMatchingRuleImpl.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/schema/JsonQueryEqualityMatchingRuleImpl.java index 8e64239085..ee3600ce80 100644 --- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/schema/JsonQueryEqualityMatchingRuleImpl.java +++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/schema/JsonQueryEqualityMatchingRuleImpl.java @@ -12,6 +12,7 @@ * information: "Portions copyright [year] [name of copyright owner]". * * Copyright 2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.forgerock.opendj.rest2ldap.schema; @@ -430,7 +431,7 @@ private ByteSequence createIndexKey(final ByteString fieldKey, final Object valu if (value == null) { return createNullIndexKey(builder); } else if (value instanceof Number) { - final Double doubleValue = ((Number) value).doubleValue(); + final double doubleValue = ((Number) value).doubleValue(); return createNumberIndexKey(builder, BigDecimal.valueOf(doubleValue)); } else if (value instanceof Boolean) { final Boolean booleanValue = (Boolean) value; diff --git a/opendj-server-legacy/replace.rb b/opendj-server-legacy/replace.rb index a4b73e3339..8697a14ced 100755 --- a/opendj-server-legacy/replace.rb +++ b/opendj-server-legacy/replace.rb @@ -1,4 +1,7 @@ #!/usr/bin/env ruby +# +# Portions Copyright 2026 3A Systems, LLC. +# require 'fileutils' @@ -471,7 +474,6 @@ def replace_file(file, replacements) (0..replacements.size-1).step(2).each { |index| pattern, replace = replacements[index], replacements[index+1] replace = replace.gsub('{CLASSNAME}', classname(file)) - is_replaced = true #while is_replaced #puts "pattern: " + pattern.to_s is_replaced = contents.gsub!(pattern, replace) diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/GenericDialog.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/GenericDialog.java index e81c9954f9..f0dec5fb2d 100644 --- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/GenericDialog.java +++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/GenericDialog.java @@ -13,6 +13,7 @@ * * Copyright 2008-2009 Sun Microsystems, Inc. * Portions Copyright 2014-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.guitools.controlpanel.ui; @@ -200,10 +201,6 @@ public void setVisible(boolean visible) } if (visible && lastComponentWithFocus != null && lastComponentWithFocus.isVisible()) { - if (lastComponentWithFocus == null) - { - lastComponentWithFocus = panel.getPreferredFocusComponent(); - } lastComponentWithFocus.requestFocusInWindow(); } updateDefaultButton(panel); diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/Utilities.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/Utilities.java index 68fb0d6fcb..42a77c7a0f 100644 --- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/Utilities.java +++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/Utilities.java @@ -13,6 +13,7 @@ * * Copyright 2008-2010 Sun Microsystems, Inc. * Portions Copyright 2011-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.guitools.controlpanel.util; @@ -2411,7 +2412,7 @@ else if (attr.isNumericDate()) { return NO_VALUE_SET.toString(); } - Long l = Long.parseLong(monitoringValue); + long l = Long.parseLong(monitoringValue); Date date = new Date(l); return ConfigFromConnection.formatter.format(date); } @@ -2437,7 +2438,7 @@ else if (attr.isGMTDate()) } else if (attr.isValueInBytes()) { - Long l = Long.parseLong(monitoringValue); + long l = Long.parseLong(monitoringValue); long mb = l / (1024 * 1024); long kbs = (l - mb * 1024 * 1024) / 1024; return INFO_CTRL_PANEL_MEMORY_VALUE.get(mb, kbs).toString(); diff --git a/opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/Installer.java b/opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/Installer.java index b70df04eca..d6f7de187f 100644 --- a/opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/Installer.java +++ b/opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/Installer.java @@ -13,6 +13,7 @@ * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions Copyright 2011-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.quicksetup.installer; @@ -591,7 +592,7 @@ private void initMaps() int cumulatedTime = 0; for (InstallProgressStep s : steps) { - Integer statusTime = s.getRelativeDuration(); + int statusTime = s.getRelativeDuration(); hmRatio.put(s, (100 * cumulatedTime) / totalTime); cumulatedTime += statusTime; } @@ -2676,7 +2677,7 @@ else if (isSchema) { throw new ApplicationException(ReturnCode.APPLICATION_ERROR, pnfe.getMessageObject(), null); } - StaticUtils.sleep((5 - nTries) * 3000); + StaticUtils.sleep((5 - nTries) * 3000L); } nTries--; } 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 96bbef501c..245c133c3f 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 @@ -525,11 +525,9 @@ public String toString() { * should be appended. */ public final void toString(StringBuilder buffer) { - if (this.keywordRuleMap != null) { - for (KeywordBindRule rule : this.keywordRuleMap.values()) { - rule.toString(buffer); - buffer.append(";"); - } + for (KeywordBindRule rule : this.keywordRuleMap.values()) { + rule.toString(buffer); + buffer.append(";"); } } } diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/LDIFBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/LDIFBackend.java index 2d7ad26dec..bbcded9b1e 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/backends/LDIFBackend.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/LDIFBackend.java @@ -13,6 +13,7 @@ * * Copyright 2007-2008 Sun Microsystems, Inc. * Portions Copyright 2011-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.backends; @@ -366,12 +367,7 @@ public long getEntryCount() try { - if (entryMap != null) - { - return entryMap.size(); - } - - return -1; + return entryMap.size(); } finally { diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/RootContainer.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/RootContainer.java index e2fe9afb34..1adc22a057 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/RootContainer.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/RootContainer.java @@ -13,6 +13,7 @@ * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions Copyright 2011-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.backends.pluggable; @@ -229,7 +230,8 @@ private void openAndRegisterEntryContainers(WriteableTransaction txn, Set ba } } - nextEntryID = new AtomicLong(highestID.longValue() + 1); + // highestID is null when there was no base DN to open, in which case numbering starts at 1. + nextEntryID = new AtomicLong(highestID != null ? highestID.longValue() + 1 : 1); } /** diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/MemoryQuota.java b/opendj-server-legacy/src/main/java/org/opends/server/core/MemoryQuota.java index 32af3eb445..9503ef8e5d 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/core/MemoryQuota.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/core/MemoryQuota.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2015 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.core; @@ -132,7 +133,7 @@ public int memBytesToPercent(long size) */ public long memPercentToBytes(int percent) { - return (reservableMemory * percent / 100) * ONE_MEGABYTE; + return ((long) reservableMemory * percent / 100) * ONE_MEGABYTE; } /** diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyDNOperationBasis.java b/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyDNOperationBasis.java index baaa1f3b5d..ac5bbcbd17 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyDNOperationBasis.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyDNOperationBasis.java @@ -13,6 +13,7 @@ * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions Copyright 2011-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.core; @@ -531,6 +532,11 @@ public DN getNewDN() { setResultCode(ResultCode.UNWILLING_TO_PERFORM); appendErrorMessage(ERR_MODDN_NO_PARENT.get(entryDN)); + if (parentDN == null) + { + // Without a parent there is no new DN to build; the error set above is the outcome. + return null; + } } newDN = parentDN.child(getNewRDN()); } diff --git a/opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerImpl.java b/opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerImpl.java index 04f3347707..c2f0cb39e9 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerImpl.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerImpl.java @@ -14,6 +14,7 @@ * Copyright 2006-2010 Sun Microsystems, Inc. * Portions Copyright 2009 Parametric Technology Corporation (PTC) * Portions Copyright 2011-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.crypto; @@ -312,7 +313,7 @@ public boolean isConfigurationChangeAcceptable( // Requested encryption cipher validation. String requestedCipherTransformation = cfg.getCipherTransformation(); - Integer requestedCipherTransformationKeyLengthBits = cfg.getCipherKeyLength(); + int requestedCipherTransformationKeyLengthBits = cfg.getCipherKeyLength(); if (! requestedCipherTransformation.equals( this.preferredCipherTransformation) || requestedCipherTransformationKeyLengthBits != @@ -341,7 +342,7 @@ public boolean isConfigurationChangeAcceptable( // Requested MAC algorithm validation. String requestedMACAlgorithm = cfg.getMacAlgorithm(); - Integer requestedMACAlgorithmKeyLengthBits = cfg.getMacKeyLength(); + int requestedMACAlgorithmKeyLengthBits = cfg.getMacKeyLength(); if (!requestedMACAlgorithm.equals(this.preferredMACAlgorithm) || requestedMACAlgorithmKeyLengthBits != this.preferredMACAlgorithmKeyLengthBits) diff --git a/opendj-server-legacy/src/main/java/org/opends/server/extensions/EntryCacheCommon.java b/opendj-server-legacy/src/main/java/org/opends/server/extensions/EntryCacheCommon.java index bb06b58f69..b353c6b15a 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/extensions/EntryCacheCommon.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/extensions/EntryCacheCommon.java @@ -13,6 +13,7 @@ * * Copyright 2006-2008 Sun Microsystems, Inc. * Portions Copyright 2014-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.extensions; @@ -362,11 +363,11 @@ public static MonitorData getGenericMonitorData( // Cache misses is required to get cache tries and hit ratio. if (cacheMisses != null) { - Long cacheTries = cacheHits + cacheMisses; + long cacheTries = cacheHits + cacheMisses; attrs.add("entryCacheTries", cacheTries); - Double hitRatioRaw = cacheTries > 0 ? cacheHits.doubleValue() - / cacheTries.doubleValue() : cacheHits.doubleValue() / 1; + double hitRatioRaw = cacheTries > 0 ? cacheHits.doubleValue() + / cacheTries : cacheHits.doubleValue(); Double hitRatio = hitRatioRaw * 100D; attrs.add("entryCacheHitRatio", hitRatio); } diff --git a/opendj-server-legacy/src/main/java/org/opends/server/extensions/SaltedSHA1PasswordStorageScheme.java b/opendj-server-legacy/src/main/java/org/opends/server/extensions/SaltedSHA1PasswordStorageScheme.java index afb064c1e7..e417e1ca7d 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/extensions/SaltedSHA1PasswordStorageScheme.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/extensions/SaltedSHA1PasswordStorageScheme.java @@ -60,6 +60,13 @@ public class SaltedSHA1PasswordStorageScheme /** The number of bytes of random data to use as the salt when generating the hashes. */ private static final int NUM_SALT_BYTES = 8; + /** + * Source of randomness for the offline encoding, which has no access to the server's + * crypto manager. A single instance is shared because {@code SecureRandom} is thread-safe + * and reseeding it for every password would weaken it. + */ + private static final SecureRandom OFFLINE_RANDOM = new SecureRandom(); + /** The number of bytes SHA algorithm produces. */ private static final int SHA1_LENGTH = 20; @@ -423,7 +430,7 @@ public static String encodeOffline(byte[] passwordBytes) throws DirectoryException { byte[] saltBytes = new byte[NUM_SALT_BYTES]; - new SecureRandom().nextBytes(saltBytes); + OFFLINE_RANDOM.nextBytes(saltBytes); byte[] passwordPlusSalt = new byte[passwordBytes.length + NUM_SALT_BYTES]; System.arraycopy(passwordBytes, 0, passwordPlusSalt, 0, diff --git a/opendj-server-legacy/src/main/java/org/opends/server/extensions/SaltedSHA512PasswordStorageScheme.java b/opendj-server-legacy/src/main/java/org/opends/server/extensions/SaltedSHA512PasswordStorageScheme.java index 1fa32d94c4..23d969b71e 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/extensions/SaltedSHA512PasswordStorageScheme.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/extensions/SaltedSHA512PasswordStorageScheme.java @@ -60,6 +60,13 @@ public class SaltedSHA512PasswordStorageScheme /** The number of bytes of random data to use as the salt when generating the hashes. */ private static final int NUM_SALT_BYTES = 8; + /** + * Source of randomness for the offline encoding, which has no access to the server's + * crypto manager. A single instance is shared because {@code SecureRandom} is thread-safe + * and reseeding it for every password would weaken it. + */ + private static final SecureRandom OFFLINE_RANDOM = new SecureRandom(); + /** The size of the digest in bytes. */ private static final int SHA512_LENGTH = 512 / 8; @@ -427,7 +434,7 @@ public static String encodeOffline(byte[] passwordBytes) throws DirectoryException { byte[] saltBytes = new byte[NUM_SALT_BYTES]; - new SecureRandom().nextBytes(saltBytes); + OFFLINE_RANDOM.nextBytes(saltBytes); byte[] passwordPlusSalt = new byte[passwordBytes.length + NUM_SALT_BYTES]; System.arraycopy(passwordBytes, 0, passwordPlusSalt, 0, diff --git a/opendj-server-legacy/src/main/java/org/opends/server/loggers/CommonAudit.java b/opendj-server-legacy/src/main/java/org/opends/server/loggers/CommonAudit.java index 59240a4915..8445d97135 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/loggers/CommonAudit.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/loggers/CommonAudit.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2015-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.loggers; @@ -357,7 +358,7 @@ private AuditServiceProxy buildAuditService(AuditServiceSetup setup) throws IOException, AuditException, ConfigException { final JsonValue jsonConfig; - try (InputStream input = getClass().getResourceAsStream(AUDIT_SERVICE_JSON_CONFIGURATION_FILE)) + try (InputStream input = CommonAudit.class.getResourceAsStream(AUDIT_SERVICE_JSON_CONFIGURATION_FILE)) { jsonConfig = AuditJsonConfig.getJson(input); } diff --git a/opendj-server-legacy/src/main/java/org/opends/server/loggers/CommonAuditAccessLogPublisher.java b/opendj-server-legacy/src/main/java/org/opends/server/loggers/CommonAuditAccessLogPublisher.java index c0129b1626..d281050e9b 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/loggers/CommonAuditAccessLogPublisher.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/loggers/CommonAuditAccessLogPublisher.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2015-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.loggers; @@ -501,7 +502,7 @@ private String getTransactionIdFromControl(Operation operation) private Pair getExecutionTime(final Operation operation) { - Long etime = operation.getProcessingNanoTime(); + long etime = operation.getProcessingNanoTime(); // if not configured for nanos, use millis return etime <= -1 ? Pair.of(operation.getProcessingTime(), TimeUnit.MILLISECONDS) : diff --git a/opendj-server-legacy/src/main/java/org/opends/server/loggers/JDKLogging.java b/opendj-server-legacy/src/main/java/org/opends/server/loggers/JDKLogging.java index 5fbb17af46..51f0986e7e 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/loggers/JDKLogging.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/loggers/JDKLogging.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2014-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.loggers; @@ -112,14 +113,16 @@ private OpenDJHandler(final PrintStream out, final PrintStream err) @Override public void publish(LogRecord record) { - if (getFormatter() == null) + // These calls resolve to Handler's own formatter, not to the enclosing + // JDKLogging.getFormatter(); qualify them so that is unambiguous. + if (super.getFormatter() == null) { - setFormatter(new SimpleFormatter()); + super.setFormatter(new SimpleFormatter()); } try { - String message = getFormatter().format(record); + String message = super.getFormatter().format(record); if (record.getLevel().intValue() >= Level.WARNING.intValue()) { err.write(message.getBytes()); diff --git a/opendj-server-legacy/src/main/java/org/opends/server/replication/server/ServerHandler.java b/opendj-server-legacy/src/main/java/org/opends/server/replication/server/ServerHandler.java index ccb3ebdc85..8037b16cee 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/replication/server/ServerHandler.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/replication/server/ServerHandler.java @@ -791,7 +791,7 @@ public void lockDomainWithTimeout() throws DirectoryException, final Random random = new Random(); final int randomTime = random.nextInt(6); // Random from 0 to 5 // Wait at least 3 seconds + (0 to 5 seconds) - final long timeout = 3000 + randomTime * 1000; + final long timeout = 3000 + randomTime * 1000L; final boolean lockAcquired = replicationServerDomain.tryLock(timeout); if (!lockAcquired) { diff --git a/opendj-server-legacy/src/main/java/org/opends/server/replication/service/ReplicationBroker.java b/opendj-server-legacy/src/main/java/org/opends/server/replication/service/ReplicationBroker.java index 3015639a45..ce1e673aae 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/replication/service/ReplicationBroker.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/replication/service/ReplicationBroker.java @@ -1341,7 +1341,7 @@ Map getEvaluations() { if (foundBestRS()) { - final Integer bestRSServerId = getBestRS().getServerId(); + final int bestRSServerId = getBestRS().getServerId(); if (rsEvals.get(bestRSServerId) == null) { final LocalizableMessage eval = NOTE_BEST_RS.get(bestRSServerId, localServerId); diff --git a/opendj-server-legacy/src/main/java/org/opends/server/schema/GeneralizedTimeSyntax.java b/opendj-server-legacy/src/main/java/org/opends/server/schema/GeneralizedTimeSyntax.java index 4fc037c6b4..075f539fb3 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/schema/GeneralizedTimeSyntax.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/schema/GeneralizedTimeSyntax.java @@ -14,6 +14,7 @@ * Copyright 2006-2009 Sun Microsystems, Inc. * Portions Copyright 2009 D. J. Hagberg, Millibits Consulting, Inc. * Portions Copyright 2012-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.schema; @@ -1199,7 +1200,7 @@ private static long finishDecodingFraction(String value, int startPos, ResultCode.INVALID_ATTRIBUTE_SYNTAX, message); } - Double fractionValue = Double.parseDouble(fractionBuffer.toString()); + double fractionValue = Double.parseDouble(fractionBuffer.toString()); long additionalMilliseconds = Math.round(fractionValue * multiplier); try diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tasks/ImportTask.java b/opendj-server-legacy/src/main/java/org/opends/server/tasks/ImportTask.java index 648c97bc37..6830239204 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/tasks/ImportTask.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/tasks/ImportTask.java @@ -13,6 +13,7 @@ * * Copyright 2006-2009 Sun Microsystems, Inc. * Portions Copyright 2013-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.tasks; @@ -327,6 +328,12 @@ else if(backend != locatedBackend) } } + if (backend == null) + { + // Neither a backend ID nor an include branch identified a backend. + throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, ERR_LDIFIMPORT_NO_BACKENDS_FOR_ID.get()); + } + // Make sure the selected backend will handle all the include branches defaultIncludeBranches = new ArrayList<>(backend.getBaseDNs()); @@ -476,6 +483,13 @@ else if(backend != locatedBackend) } // Find backends with subordinate base DNs that should be excluded from the import. + if (backend == null) + { + // Neither a backend ID nor an include branch identified a backend. + logger.error(ERR_LDIFIMPORT_NO_BACKENDS_FOR_ID); + return TaskState.STOPPED_BY_ERROR; + } + defaultIncludeBranches = new HashSet<>(backend.getBaseDNs()); for (Backend subBackend : getServerContext().getBackendConfigManager().getSubordinateBackends(backend)) { diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tasks/PurgeConflictsHistoricalTask.java b/opendj-server-legacy/src/main/java/org/opends/server/tasks/PurgeConflictsHistoricalTask.java index 82affe6f79..e27421da03 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/tasks/PurgeConflictsHistoricalTask.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/tasks/PurgeConflictsHistoricalTask.java @@ -13,6 +13,7 @@ * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions Copyright 2013-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.tasks; @@ -123,18 +124,20 @@ public LocalizableMessage getDisplayName() { @Override protected TaskState runTask() { - Boolean purgeCompletedInTime = false; + boolean purgeCompletedInTime = false; logger.trace("PurgeConflictsHistoricalTask is starting on domain: %s max duration (sec): %d", domain.getBaseDN(), purgeTaskMaxDurationInSec); try { - replaceAttributeValue(ATTR_TASK_CONFLICTS_HIST_PURGE_COMPLETED_IN_TIME, purgeCompletedInTime.toString()); + replaceAttributeValue(ATTR_TASK_CONFLICTS_HIST_PURGE_COMPLETED_IN_TIME, + String.valueOf(purgeCompletedInTime)); // launch the task - domain.purgeConflictsHistorical(this, TimeThread.getTime() + purgeTaskMaxDurationInSec*1000); + domain.purgeConflictsHistorical(this, TimeThread.getTime() + purgeTaskMaxDurationInSec * 1000L); purgeCompletedInTime = true; - replaceAttributeValue(ATTR_TASK_CONFLICTS_HIST_PURGE_COMPLETED_IN_TIME, purgeCompletedInTime.toString()); + replaceAttributeValue(ATTR_TASK_CONFLICTS_HIST_PURGE_COMPLETED_IN_TIME, + String.valueOf(purgeCompletedInTime)); initState = TaskState.COMPLETED_SUCCESSFULLY; } diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tools/dsreplication/ReplicationCliMain.java b/opendj-server-legacy/src/main/java/org/opends/server/tools/dsreplication/ReplicationCliMain.java index 07227ffdd5..716009f9cd 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/tools/dsreplication/ReplicationCliMain.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/tools/dsreplication/ReplicationCliMain.java @@ -6595,7 +6595,7 @@ public void progressUpdate(ProgressUpdateEvent ev) ERR_REPLICATION_INITIALIZING_TRIES_COMPLETED.get( pnfe.getMessageObject()), INITIALIZING_TRIES_COMPLETED, pnfe); } - sleepCatchInterrupt((5 - nTries) * 3000); + sleepCatchInterrupt((5 - nTries) * 3000L); } catch (ApplicationException ae) { @@ -6648,7 +6648,7 @@ public void initializeAllSuffix(DN baseDN, ConnectionWrapper conn, boolean displ ERR_REPLICATION_INITIALIZING_TRIES_COMPLETED.get( pnfe.getMessageObject()), INITIALIZING_TRIES_COMPLETED, pnfe); } - sleepCatchInterrupt((5 - nTries) * 3000); + sleepCatchInterrupt((5 - nTries) * 3000L); } catch (ClientException ae) { diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tools/status/StatusCli.java b/opendj-server-legacy/src/main/java/org/opends/server/tools/status/StatusCli.java index 86a47b9388..be523b115f 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/tools/status/StatusCli.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/tools/status/StatusCli.java @@ -355,9 +355,10 @@ private void writeStatus(ControlPanelInfo controlInfo) writeStatus(controlInfo.getServerDescriptor()); int period = argParser.getRefreshPeriod(); boolean first = true; - while (period > 0) + // A positive refresh period means refreshing until the command is interrupted. + while (period > 0 && !Thread.currentThread().isInterrupted()) { - long timeToSleep = period * 1000; + long timeToSleep = period * 1000L; if (!first) { long t1 = System.currentTimeMillis(); @@ -1125,7 +1126,7 @@ private ManagementContext getManagementContextFromConnection( // Interact with the user though the console to get // LDAP connection information final String hostName = getHostNameForLdapUrl(ci.getHostName()); - final Integer portNumber = ci.getPortNumber(); + final int portNumber = ci.getPortNumber(); final DN bindDN = ci.getBindDN(); final String bindPassword = ci.getBindPassword(); TrustManager trustManager = ci.getTrustManager(); diff --git a/opendj-server-legacy/src/main/java/org/opends/server/types/Entry.java b/opendj-server-legacy/src/main/java/org/opends/server/types/Entry.java index c8087de18f..16a8590b13 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/types/Entry.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/types/Entry.java @@ -14,6 +14,7 @@ * Copyright 2006-2010 Sun Microsystems, Inc. * Portions Copyright 2011-2016 ForgeRock AS. * Portions Copyright 2023-2024 3A Systems, LLC. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.types; @@ -3357,7 +3358,7 @@ public static Entry decode(ByteSequenceReader entryBuffer, { // The first byte must be the entry version. If it's not one // we recognize, then that's an error. - Byte version = entryBuffer.readByte(); + byte version = entryBuffer.readByte(); if (version != 0x03 && version != 0x02 && version != 0x01) { LocalizableMessage message = ERR_ENTRY_DECODE_UNRECOGNIZED_VERSION.get( diff --git a/opendj-server-legacy/src/main/java/org/opends/server/util/CronExecutorService.java b/opendj-server-legacy/src/main/java/org/opends/server/util/CronExecutorService.java index 6b74dc87cc..22486eca46 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/util/CronExecutorService.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/util/CronExecutorService.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.util; @@ -90,8 +91,11 @@ public void setSchedulerFuture(Future schedulerFuture) @Override public boolean cancel(boolean mayInterruptIfRunning) { - return schedulerFuture.cancel(mayInterruptIfRunning) - | (executorFuture != null && executorFuture.cancel(mayInterruptIfRunning)); + // Both futures must be cancelled, so neither call may be short circuited. + final boolean schedulerCancelled = schedulerFuture.cancel(mayInterruptIfRunning); + final boolean executorCancelled = + executorFuture != null && executorFuture.cancel(mayInterruptIfRunning); + return schedulerCancelled || executorCancelled; } @Override @@ -351,7 +355,10 @@ public List> invokeAll(final Collection> tas @Override public boolean awaitTermination(final long timeout, final TimeUnit unit) throws InterruptedException { - return cronScheduler.awaitTermination(timeout, unit) & cronExecutorService.awaitTermination(timeout, unit); + // Both services must be awaited, so neither call may be short circuited. + final boolean schedulerTerminated = cronScheduler.awaitTermination(timeout, unit); + final boolean executorTerminated = cronExecutorService.awaitTermination(timeout, unit); + return schedulerTerminated && executorTerminated; } @Override diff --git a/opendj-server-legacy/src/main/java/org/opends/server/util/StaticUtils.java b/opendj-server-legacy/src/main/java/org/opends/server/util/StaticUtils.java index 5e344e8b61..e4d8c8eda5 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/util/StaticUtils.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/util/StaticUtils.java @@ -511,11 +511,7 @@ public static int compare(byte[] a, byte[] a2) { int firstByte = 0xFF & a[i]; int secondByte = 0xFF & a2[i]; if (firstByte != secondByte) { - if (firstByte < secondByte) { - return -1; - } else if (firstByte > secondByte) { - return 1; - } + return firstByte < secondByte ? -1 : 1; } } @@ -1795,7 +1791,10 @@ public static boolean recursiveDelete(File file) } } - return successful & file.delete(); + // The delete must be attempted even when a child could not be removed, so it is + // evaluated into a local before being combined with the running result. + final boolean deleted = file.delete(); + return successful && deleted; } return false; } diff --git a/opendj-server-legacy/src/snmp/src/org/opends/server/snmp/DsMIBImpl.java b/opendj-server-legacy/src/snmp/src/org/opends/server/snmp/DsMIBImpl.java index 204aaacdc8..d616140d92 100644 --- a/opendj-server-legacy/src/snmp/src/org/opends/server/snmp/DsMIBImpl.java +++ b/opendj-server-legacy/src/snmp/src/org/opends/server/snmp/DsMIBImpl.java @@ -238,8 +238,7 @@ private boolean addRowInDsTable() { this.mib, this.server, this.applIndex); // if the entry already exists nothing to do - if ((this.dsTableEntries.containsKey(entry.getObjectName())) || - (entry == null)) { + if (this.dsTableEntries.containsKey(entry.getObjectName())) { return true; } @@ -279,8 +278,7 @@ private boolean addRowInDsApplIfOpsTable(ObjectName connectionHandlerName) { this.applIndex, this.applIfOpsIndex); // If the entry already exists then nothing to do - if ((this.dsApplIfOpsTableEntries.containsKey(entry.getObjectName())) || - (entry == null)) { + if (this.dsApplIfOpsTableEntries.containsKey(entry.getObjectName())) { return true; } // Add the entry in the Table diff --git a/opendj-server/src/main/java/org/forgerock/opendj/server/core/ProductInformation.java b/opendj-server/src/main/java/org/forgerock/opendj/server/core/ProductInformation.java index 11b7d0a34c..0c81ec7096 100644 --- a/opendj-server/src/main/java/org/forgerock/opendj/server/core/ProductInformation.java +++ b/opendj-server/src/main/java/org/forgerock/opendj/server/core/ProductInformation.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2014-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.forgerock.opendj.server.core; @@ -43,7 +44,7 @@ public static ProductInformation getInstance() { private ProductInformation(final String productName) { final String resourceName = "/META-INF/product/" + productName + ".properties"; - final InputStream stream = getClass().getResourceAsStream(resourceName); + final InputStream stream = ProductInformation.class.getResourceAsStream(resourceName); if (stream == null) { throw new MissingResourceException("Can't find product information " + resourceName, From 25625bc90280cca408bfbf20fc971d80dcbf2603 Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Thu, 30 Jul 2026 17:55:53 +0300 Subject: [PATCH 2/2] Address review feedback on the tier 4 CodeQL cleanup StatusCli now sleeps with Thread.sleep and stops on interruption: StaticUtils.sleep discards the InterruptedException without restoring the flag, so the interrupt check added to the loop condition could never become true. ImportTask drops the null check in initializeTask(), which cannot be reached because that method already rejects a task carrying neither a backend ID nor an include branch. The check in runTask() stays, since that method does not re-validate and ignores an include branch resolving to no backend. ModifyDNOperationBasis remembers that the new DN has been computed, so a failed computation is neither repeated nor its error message appended twice, and it leaves the INVALID_DN_SYNTAX diagnosis of an unparseable entry DN in place. BuildVersion compares the revisions once instead of testing for equality first. Adds the tests the behaviour changes lacked: a filtered view can be iterated more than once, and versions differing only by an equal-valued but distinct revision string compare equal. Merges the duplicated 3A Systems copyright lines. --- .../opendj/config/dsconfig/BuildVersion.java | 7 +-- .../config/dsconfig/BuildVersionTest.java | 46 ++++++++++++++ .../java/org/forgerock/opendj/ldap/AVA.java | 1 - .../opendj/ldap/schema/SchemaUtils.java | 4 +- .../opendj/ldap/AttributeFilterTestCase.java | 63 +++++++++++++++++++ .../server/core/ModifyDNOperationBasis.java | 26 ++++++-- .../org/opends/server/tasks/ImportTask.java | 12 ++-- .../opends/server/tools/status/StatusCli.java | 13 +++- .../java/org/opends/server/types/Entry.java | 3 +- 9 files changed, 149 insertions(+), 26 deletions(-) create mode 100644 opendj-config/src/test/java/org/forgerock/opendj/config/dsconfig/BuildVersionTest.java create mode 100644 opendj-core/src/test/java/org/forgerock/opendj/ldap/AttributeFilterTestCase.java diff --git a/opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/BuildVersion.java b/opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/BuildVersion.java index cd1620dfeb..8dcd3e4024 100644 --- a/opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/BuildVersion.java +++ b/opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/BuildVersion.java @@ -192,11 +192,8 @@ public int compareTo(final BuildVersion version) { if (major == version.major) { if (minor == version.minor) { if (point == version.point) { - if (rev.equals(version.rev)) { - return 0; - } else if (rev.compareTo(version.rev) < 0) { - return -1; - } + // Compares the revisions as strings: they are VCS revisions, not numbers. + return Integer.signum(rev.compareTo(version.rev)); } else if (point < version.point) { return -1; } diff --git a/opendj-config/src/test/java/org/forgerock/opendj/config/dsconfig/BuildVersionTest.java b/opendj-config/src/test/java/org/forgerock/opendj/config/dsconfig/BuildVersionTest.java new file mode 100644 index 0000000000..305fd68f56 --- /dev/null +++ b/opendj-config/src/test/java/org/forgerock/opendj/config/dsconfig/BuildVersionTest.java @@ -0,0 +1,46 @@ +/* + * The contents of this file are subject to the terms of the Common Development and + * Distribution License (the License). You may not use this file except in compliance with the + * License. + * + * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the + * specific language governing permission and limitations under the License. + * + * When distributing Covered Software, include this CDDL Header Notice in each file and include + * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL + * Header, with the fields enclosed by brackets [] replaced by your own identifying + * information: "Portions copyright [year] [name of copyright owner]". + * + * Copyright 2026 3A Systems, LLC. + */ +package org.forgerock.opendj.config.dsconfig; + +import org.forgerock.testng.ForgeRockTestCase; +import org.testng.Assert; +import org.testng.annotations.Test; + +@Test(groups = { "precommit", "config" }) +public class BuildVersionTest extends ForgeRockTestCase { + + @Test + public void testEqualRevisionsCompareEqual() { + // Two distinct String instances holding the same revision: the revisions must be compared + // by value, not by reference. + final String rev = "abcdef"; + final String sameRev = new StringBuilder(rev).toString(); + Assert.assertEquals(new BuildVersion(4, 0, 0, rev).compareTo(new BuildVersion(4, 0, 0, sameRev)), 0); + } + + @Test + public void testRevisionsOrderVersionsWhichAreOtherwiseEqual() { + Assert.assertEquals(new BuildVersion(4, 0, 0, "aaa").compareTo(new BuildVersion(4, 0, 0, "bbb")), -1); + Assert.assertEquals(new BuildVersion(4, 0, 0, "bbb").compareTo(new BuildVersion(4, 0, 0, "aaa")), 1); + } + + @Test + public void testVersionNumbersTakePrecedenceOverRevisions() { + Assert.assertEquals(new BuildVersion(3, 9, 9, "zzz").compareTo(new BuildVersion(4, 0, 0, "aaa")), -1); + Assert.assertEquals(new BuildVersion(4, 1, 0, "aaa").compareTo(new BuildVersion(4, 0, 9, "zzz")), 1); + Assert.assertEquals(new BuildVersion(4, 0, 1, "aaa").compareTo(new BuildVersion(4, 0, 0, "zzz")), 1); + } +} diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java index 4ec131b0ab..7d8774c51a 100644 --- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java +++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java @@ -12,7 +12,6 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2010 Sun Microsystems, Inc. - * Portions Copyright 2026 3A Systems, LLC. * Portions copyright 2011-2016 ForgeRock AS. * Portions copyright 2021-2026 3A Systems, LLC */ diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java index a83843e61f..cb6bb24c7c 100644 --- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java +++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/schema/SchemaUtils.java @@ -13,8 +13,7 @@ * * Copyright 2009 Sun Microsystems, Inc. * Portions copyright 2011-2016 ForgeRock AS. - * Portions Copyright 2024 3A Systems, LLC. - * Portions Copyright 2026 3A Systems, LLC. + * Portions Copyright 2024-2026 3A Systems, LLC. */ package org.forgerock.opendj.ldap.schema; @@ -324,7 +323,6 @@ static String readOIDLen(final SubstringReader reader, final boolean allowCompat } length++; } - } else if (isAlpha(c)) { // This must be an attribute description. In this case, we will // only accept alphabetic characters, numeric digits, and the hyphen. diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/AttributeFilterTestCase.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/AttributeFilterTestCase.java new file mode 100644 index 0000000000..13f05b4937 --- /dev/null +++ b/opendj-core/src/test/java/org/forgerock/opendj/ldap/AttributeFilterTestCase.java @@ -0,0 +1,63 @@ +/* + * The contents of this file are subject to the terms of the Common Development and + * Distribution License (the License). You may not use this file except in compliance with the + * License. + * + * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the + * specific language governing permission and limitations under the License. + * + * When distributing Covered Software, include this CDDL Header Notice in each file and include + * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL + * Header, with the fields enclosed by brackets [] replaced by your own identifying + * information: "Portions copyright [year] [name of copyright owner]". + * + * Copyright 2026 3A Systems, LLC. + */ +package org.forgerock.opendj.ldap; + +import static org.fest.assertions.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.List; + +import org.testng.annotations.Test; + +/** + * Test {@code AttributeFilter}. + */ +@SuppressWarnings("javadoc") +public final class AttributeFilterTestCase extends SdkTestCase { + + @Test + public void testFilteredViewCanBeIteratedMoreThanOnce() { + final Iterable attributes = filteredView().getAllAttributes(); + + final List firstPass = namesOf(attributes); + assertThat(firstPass).isNotEmpty(); + assertThat(namesOf(attributes)).isEqualTo(firstPass); + } + + @Test + public void testFilteredViewCanBeIteratedAfterToString() { + final Iterable attributes = filteredView().getAllAttributes(); + + final List expected = namesOf(attributes); + attributes.toString(); + assertThat(namesOf(attributes)).isEqualTo(expected); + } + + private Entry filteredView() { + final Entry entry = + new LinkedHashMapEntry("dn: cn=test", "objectClass: top", "objectClass: person", + "cn: test", "sn: user"); + return new AttributeFilter().filteredViewOf(entry); + } + + private List namesOf(final Iterable attributes) { + final List names = new ArrayList<>(); + for (final Attribute attribute : attributes) { + names.add(attribute.getAttributeDescriptionAsString()); + } + return names; + } +} diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyDNOperationBasis.java b/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyDNOperationBasis.java index ac5bbcbd17..ac907e6f0c 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyDNOperationBasis.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyDNOperationBasis.java @@ -92,6 +92,12 @@ public class ModifyDNOperationBasis /** The new entry DN. */ private DN newDN; + /** + * Indicates whether the new entry DN has already been computed. The computation does not always + * yield a DN, and its failure is recorded on the operation, so it must not be repeated. + */ + private boolean newDNComputed; + /** * Creates a new modify DN operation with the provided information. * @@ -189,6 +195,9 @@ public final void setRawEntryDN(ByteString rawEntryDN) this.rawEntryDN = rawEntryDN; entryDN = null; + // The new DN is derived from the entry DN, so a failed computation must be allowed to run + // again. Any DN already computed is left in place, as it was before this flag existed. + newDNComputed = false; } @Override @@ -229,6 +238,7 @@ public final void setRawNewRDN(ByteString rawNewRDN) newRDN = null; newDN = null; + newDNComputed = false; } @Override @@ -276,6 +286,7 @@ public final void setRawNewSuperior(ByteString rawNewSuperior) newSuperior = null; newDN = null; + newDNComputed = false; } @Override @@ -511,17 +522,22 @@ public void setProxiedAuthorizationDN(DN dn) @Override public DN getNewDN() { - if (newDN == null) + if (newDN == null && !newDNComputed) { + newDNComputed = true; + // Construct the new DN to use for the entry. - DN parentDN = null; + DN parentDN; if (getNewSuperior() == null) { - if (getEntryDN() != null) + if (getEntryDN() == null) { - parentDN = DirectoryServer.getInstance().getServerContext().getBackendConfigManager() - .getParentDNInSuffix(entryDN); + // The raw DN could not be parsed and INVALID_DN_SYNTAX has already been recorded for it, + // so leave that diagnosis in place rather than replacing it with a less precise one. + return null; } + parentDN = DirectoryServer.getInstance().getServerContext().getBackendConfigManager() + .getParentDNInSuffix(entryDN); } else { diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tasks/ImportTask.java b/opendj-server-legacy/src/main/java/org/opends/server/tasks/ImportTask.java index 6830239204..f2f12a2d99 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/tasks/ImportTask.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/tasks/ImportTask.java @@ -328,12 +328,6 @@ else if(backend != locatedBackend) } } - if (backend == null) - { - // Neither a backend ID nor an include branch identified a backend. - throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, ERR_LDIFIMPORT_NO_BACKENDS_FOR_ID.get()); - } - // Make sure the selected backend will handle all the include branches defaultIncludeBranches = new ArrayList<>(backend.getBaseDNs()); @@ -482,14 +476,16 @@ else if(backend != locatedBackend) } } - // Find backends with subordinate base DNs that should be excluded from the import. if (backend == null) { - // Neither a backend ID nor an include branch identified a backend. + // Unlike initializeTask(), this method does not reject an include branch which resolves to no + // backend, so none of them having resolved leaves nothing to import into. The message of the + // backend ID case is reused here rather than adding a new one for a malformed task. logger.error(ERR_LDIFIMPORT_NO_BACKENDS_FOR_ID); return TaskState.STOPPED_BY_ERROR; } + // Find backends with subordinate base DNs that should be excluded from the import. defaultIncludeBranches = new HashSet<>(backend.getBaseDNs()); for (Backend subBackend : getServerContext().getBackendConfigManager().getSubordinateBackends(backend)) { diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tools/status/StatusCli.java b/opendj-server-legacy/src/main/java/org/opends/server/tools/status/StatusCli.java index be523b115f..ac59a1290d 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/tools/status/StatusCli.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/tools/status/StatusCli.java @@ -79,7 +79,6 @@ import org.opends.server.types.InitializationException; import org.opends.server.types.NullOutputStream; import org.opends.server.util.BuildVersion; -import org.opends.server.util.StaticUtils; import org.opends.server.util.cli.LDAPConnectionConsoleInteraction; import com.forgerock.opendj.cli.ArgumentException; @@ -370,7 +369,17 @@ private void writeStatus(ControlPanelInfo controlInfo) if (timeToSleep > 0) { - StaticUtils.sleep(timeToSleep); + try + { + // Not StaticUtils.sleep(): it discards the interruption, which would leave this loop + // running with no way for the caller to stop it. + Thread.sleep(timeToSleep); + } + catch (InterruptedException e) + { + Thread.currentThread().interrupt(); + break; + } } println(); println(LocalizableMessage.raw(" ---------------------")); diff --git a/opendj-server-legacy/src/main/java/org/opends/server/types/Entry.java b/opendj-server-legacy/src/main/java/org/opends/server/types/Entry.java index 16a8590b13..9bab17e04c 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/types/Entry.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/types/Entry.java @@ -13,8 +13,7 @@ * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions Copyright 2011-2016 ForgeRock AS. - * Portions Copyright 2023-2024 3A Systems, LLC. - * Portions Copyright 2026 3A Systems, LLC. + * Portions Copyright 2023-2026 3A Systems, LLC. */ package org.opends.server.types;