From 83db1555233d219fe0d8642a16ef64fc127ada54 Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Mon, 27 Jul 2026 13:22:06 +0000
Subject: [PATCH] Fix java/local-temp-file-or-directory-information-disclosure CodeQL alerts by using NIO temp file APIs (#763)

---
 opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java |    3 
 opendj-embedded/src/test/java/org/openidentityplatform/opendj/embedded/EmbeddedOpenDJTest.java   |   11 ++
 opendj-embedded/src/main/java/org/openidentityplatform/opendj/embedded/EmbeddedOpenDJ.java       |   37 +++++++-
 opendj-server-legacy/src/main/java/org/opends/quicksetup/TempLogFile.java                        |    4 
 opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/InstallerHelper.java          |    4 
 opendj-server-legacy/src/main/java/org/opends/server/tools/dsreplication/ReplicationCliMain.java |    4 
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ControlPanelLauncher.java    |    5 
 opendj-server-legacy/src/main/java/org/opends/server/tools/status/StatusCli.java                 |    4 
 opendj-server-legacy/src/main/java/org/opends/server/schema/SchemaFilesWriter.java               |   16 +++
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewBaseDNPanel.java       |    4 
 opendj-server-legacy/src/main/java/org/opends/server/admin/doc/ConfigGuideGeneration.java        |   17 ++--
 opendj-server-legacy/src/main/java/org/opends/server/util/SetupUtils.java                        |    4 
 opendj-server-legacy/src/main/java/org/opends/server/tools/LDAPAuthenticationHandler.java        |    4 
 opendj-server-legacy/src/test/java/org/opends/server/util/SetupUtilsTestCase.java                |   65 ++++++++++++++++
 14 files changed, 153 insertions(+), 29 deletions(-)

diff --git a/opendj-embedded/src/main/java/org/openidentityplatform/opendj/embedded/EmbeddedOpenDJ.java b/opendj-embedded/src/main/java/org/openidentityplatform/opendj/embedded/EmbeddedOpenDJ.java
index fc88890..d2ef004 100644
--- a/opendj-embedded/src/main/java/org/openidentityplatform/opendj/embedded/EmbeddedOpenDJ.java
+++ b/opendj-embedded/src/main/java/org/openidentityplatform/opendj/embedded/EmbeddedOpenDJ.java
@@ -11,7 +11,7 @@
  * Header, with the fields enclosed by brackets [] replaced by your own identifying
  * information: "Portions Copyright [year] [name of copyright owner]".
  *
- * Copyright 2024 3A Systems LLC.
+ * Copyright 2024-2026 3A Systems LLC.
  */
 
 package org.openidentityplatform.opendj.embedded;
@@ -60,6 +60,9 @@
 
     final Config config;
 
+    private final File instanceDirectory;
+    private final File rootDirectory;
+
     public EmbeddedOpenDJ() {
         this(new Config());
     }
@@ -69,13 +72,18 @@
         logger.info("Create embedded OpenDJ instance: {}", config);
 
         this.config = config;
-        File tempDirectory = new File(System.getProperty("java.io.tmpdir"));
-        File rootDirectory = new File(tempDirectory, "opendj");
+        File instanceDirectory = null;
         try {
-            if(rootDirectory.exists()) {
-                FileUtils.deleteDirectory(rootDirectory);
-            }
+            // Create a fresh per-instance parent directory, only accessible by the
+            // current user, instead of the fixed shared {java.io.tmpdir}/opendj
+            // directory. The server root inside it must be named "opendj" because
+            // setup from an archive requires the server root directory to match the
+            // root directory contained in the archive. The whole directory is
+            // deleted on close().
+            instanceDirectory = Files.createTempDirectory("opendj").toFile();
+            File rootDirectory = new File(instanceDirectory, "opendj");
             rootDirectory.mkdir();
+            logger.info("OpenDJ server root: {}", rootDirectory);
 
             File configDirectory = new File(rootDirectory, "config");
             File schemaDirectory = new File(configDirectory, "schema");
@@ -109,13 +117,25 @@
 
             copyFilesFromJar(schemaFiles, JAR_SCHEMA_DIRECTORY, schemaDirectory);
 
+            this.instanceDirectory = instanceDirectory;
+            this.rootDirectory = rootDirectory;
         }catch (Exception e) {
             logger.error("Error initializing OpenDJ");
+            FileUtils.deleteQuietly(instanceDirectory);
             throw new RuntimeException(e);
         }
         Runtime.getRuntime().addShutdownHook(new Thread(this::close));
     }
 
+    /**
+     * Returns the server root directory of this embedded instance.
+     *
+     * @return the server root directory
+     */
+    public File getServerRootDirectory() {
+        return rootDirectory;
+    }
+
     @Override
     public void run() {
         try {
@@ -145,13 +165,16 @@
 
     @Override
     public void close()  {
-        if (server.isRunning())
+        if (server.isRunning()) {
             try {
                 logger.info("Shutting down OpenDJ ...");
                 server.stop(this.getClass().getName(), LocalizableMessage.raw("Stopped after receiving Control-C"));
             }catch (Throwable e) {
                 logger.error("Error stopping OpenDJ", e);
             }
+        }
+        // close() is also registered as a shutdown hook, so deletion must stay idempotent
+        FileUtils.deleteQuietly(instanceDirectory);
     }
 
     private void copyFilesFromJar(List<String> jarFiles, String jarDirectory, File outputDirectory) throws IOException{
diff --git a/opendj-embedded/src/test/java/org/openidentityplatform/opendj/embedded/EmbeddedOpenDJTest.java b/opendj-embedded/src/test/java/org/openidentityplatform/opendj/embedded/EmbeddedOpenDJTest.java
index ece5c5c..d776d1e 100644
--- a/opendj-embedded/src/test/java/org/openidentityplatform/opendj/embedded/EmbeddedOpenDJTest.java
+++ b/opendj-embedded/src/test/java/org/openidentityplatform/opendj/embedded/EmbeddedOpenDJTest.java
@@ -11,7 +11,7 @@
  * Header, with the fields enclosed by brackets [] replaced by your own identifying
  * information: "Portions Copyright [year] [name of copyright owner]".
  *
- * Copyright 2024 3A Systems LLC.
+ * Copyright 2024-2026 3A Systems LLC.
  */
 
 package org.openidentityplatform.opendj.embedded;
@@ -54,6 +54,9 @@
         embeddedOpenDJ.run();
         assertTrue(embeddedOpenDJ.isRunning());
 
+        File serverRoot = embeddedOpenDJ.getServerRootDirectory();
+        assertTrue(serverRoot.isDirectory());
+
         //import ldif data from an input stream
         URI resUri = getClass().getClassLoader().getResource("opendj/data.ldif").toURI();
         byte[] bytes = Files.readAllBytes(Paths.get(resUri));
@@ -83,5 +86,9 @@
         //stop OpenDJ
         embeddedOpenDJ.close();
         assertFalse(embeddedOpenDJ.isRunning());
+
+        //the per-instance temporary directory is deleted on close
+        assertFalse(serverRoot.exists());
+        assertFalse(serverRoot.getParentFile().exists());
     }
-}
\ No newline at end of file
+}
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ControlPanelLauncher.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ControlPanelLauncher.java
index 153ba6f..269a265 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ControlPanelLauncher.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ControlPanelLauncher.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;
 
@@ -21,8 +22,8 @@
 import static org.opends.messages.AdminToolMessages.*;
 import static org.opends.messages.ToolMessages.*;
 
-import java.io.File;
 import java.io.PrintStream;
+import java.nio.file.Files;
 
 import javax.swing.SwingUtilities;
 
@@ -64,7 +65,7 @@
   {
     try {
       ControlPanelLog.initLogFileHandler(
-          File.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX));
+          Files.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX).toFile());
     } catch (Throwable t) {
       System.err.println("Unable to initialize log");
       t.printStackTrace();
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewBaseDNPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewBaseDNPanel.java
index 02ff31e..176eaf5 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewBaseDNPanel.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewBaseDNPanel.java
@@ -13,6 +13,7 @@
  *
  * Copyright 2008-2009 Sun Microsystems, Inc.
  * Portions Copyright 2011-2016 ForgeRock AS.
+ * Portions Copyright 2026 3A Systems, LLC.
  */
 package org.opends.guitools.controlpanel.ui;
 
@@ -28,6 +29,7 @@
 import java.awt.event.ItemListener;
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -1239,7 +1241,7 @@
       final TemplateFile generator = new TemplateFile(resourceDir.getAbsolutePath(), new Random(0));
       generator.parse(templateFile.getAbsolutePath(), Collections.<LocalizableMessage>emptyList());
 
-      final File tempFile = File.createTempFile("opendj-control-panel", ".ldif");
+      final File tempFile = Files.createTempFile("opendj-control-panel", ".ldif").toFile();
       tempFile.deleteOnExit();
       final String generatedLdifFilePath = tempFile.getAbsolutePath();
 
diff --git a/opendj-server-legacy/src/main/java/org/opends/quicksetup/TempLogFile.java b/opendj-server-legacy/src/main/java/org/opends/quicksetup/TempLogFile.java
index e17abd2..cd41826 100644
--- a/opendj-server-legacy/src/main/java/org/opends/quicksetup/TempLogFile.java
+++ b/opendj-server-legacy/src/main/java/org/opends/quicksetup/TempLogFile.java
@@ -13,12 +13,14 @@
  *
  * Copyright 2008-2010 Sun Microsystems, Inc.
  * Portions Copyright 2011-2016 ForgeRock AS.
+ * Portions Copyright 2026 3A Systems, LLC.
  */
 package org.opends.quicksetup;
 
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.nio.file.Files;
 import java.util.Date;
 import java.text.DateFormat;
 
@@ -51,7 +53,7 @@
   {
     try
     {
-      return new TempLogFile(File.createTempFile(prefix, ".log"));
+      return new TempLogFile(Files.createTempFile(prefix, ".log").toFile());
     }
     catch (final IOException e)
     {
diff --git a/opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/InstallerHelper.java b/opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/InstallerHelper.java
index 5b2e5e8..d4615d4 100644
--- a/opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/InstallerHelper.java
+++ b/opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/InstallerHelper.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;
 
@@ -33,6 +34,7 @@
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -272,7 +274,7 @@
     File ldifFile;
     try
     {
-      ldifFile = File.createTempFile("opendj-base-entry", ".ldif");
+      ldifFile = Files.createTempFile("opendj-base-entry", ".ldif").toFile();
       ldifFile.deleteOnExit();
     } catch (IOException ioe)
     {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/admin/doc/ConfigGuideGeneration.java b/opendj-server-legacy/src/main/java/org/opends/server/admin/doc/ConfigGuideGeneration.java
index 6e548e1..5e1e9b4 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/admin/doc/ConfigGuideGeneration.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/admin/doc/ConfigGuideGeneration.java
@@ -19,6 +19,7 @@
 
 import java.io.File;
 import java.io.PrintWriter;
+import java.nio.file.Files;
 import java.util.Collection;
 import java.util.Date;
 import java.util.Iterator;
@@ -98,7 +99,7 @@
    *
    * Properties:
    * GenerationDir - The directory where the doc is generated
-   *              (default is /var/tmp/[CONFIG_GUIDE_DIR&gt;])
+   *              (default is a fresh temporary directory, printed on startup)
    * LdapMapping - Presence means that the LDAP mapping section is to be
    *               generated (default is no)
    * OpenDJWiki - The URL of the OpenDJ Wiki
@@ -112,14 +113,14 @@
   public static void main(String[] args) {
     Properties properties = System.getProperties();
     generationDir = properties.getProperty("GenerationDir");
-    if (generationDir == null) {
-      // Default dir is prefixed by the system-dependent default temporary dir
-      generationDir = System.getProperty("java.io.tmpdir") + File.separator +
-        CONFIG_GUIDE_DIR;
-    }
-    // Create new dir if necessary
     try {
-      new File(generationDir).mkdir();
+      if (generationDir == null) {
+        // Default dir is a fresh temporary dir, only accessible by the current user
+        generationDir = Files.createTempDirectory(CONFIG_GUIDE_DIR).toString();
+      } else {
+        // Create new dir if necessary
+        new File(generationDir).mkdir();
+      }
     } catch (Exception e) {
       e.printStackTrace();
       System.exit(1);
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java
index 139076a..8624e84 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java
@@ -38,6 +38,7 @@
 import java.nio.MappedByteBuffer;
 import java.nio.channels.FileChannel;
 import java.nio.channels.FileChannel.MapMode;
+import java.nio.file.Files;
 import java.util.AbstractList;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -425,7 +426,7 @@
 
     private File exportBranches(List<DN> includeBranches, List<DN> excludeBranches) throws Exception
     {
-      final File migrationFile = File.createTempFile("import-migration-", ".ldif");
+      final File migrationFile = Files.createTempFile("import-migration-", ".ldif").toFile();
       final LDIFExportConfig exportConfig =
           new LDIFExportConfig(migrationFile.getAbsolutePath(), ExistingFileBehavior.OVERWRITE);
       exportConfig.setIncludeBranches(includeBranches);
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/schema/SchemaFilesWriter.java b/opendj-server-legacy/src/main/java/org/opends/server/schema/SchemaFilesWriter.java
index 010f881..8f74982 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/schema/SchemaFilesWriter.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/schema/SchemaFilesWriter.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.schema;
 
@@ -40,6 +41,7 @@
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.PosixFilePermission;
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -725,7 +727,7 @@
     }
 
     // Create a temporary file to which we can write the schema entry.
-    File tempFile = File.createTempFile(schemaFile, "temp");
+    File tempFile = Files.createTempFile(schemaFile, "temp").toFile();
     LDIFExportConfig exportConfig =
          new LDIFExportConfig(tempFile.getAbsolutePath(),
                               ExistingFileBehavior.OVERWRITE);
@@ -1064,11 +1066,23 @@
     // files.  If this fails, then try to restore the originals.
     try
     {
+      boolean posixSupported = schemaInstanceDir.toPath().getFileSystem()
+          .supportedFileAttributeViews().contains("posix");
       for (int i=0; i < installedFileList.size(); i++)
       {
         File installedFile = installedFileList.get(i);
         File tempFile      = tempFileList.get(i);
+        // The temporary file was created with owner-only permissions and Files.copy
+        // propagates the source permissions, so preserve the permissions of the
+        // previously installed schema file.
+        Set<PosixFilePermission> previousPermissions = posixSupported && installedFile.exists()
+            ? Files.getPosixFilePermissions(installedFile.toPath())
+            : null;
         Files.copy(tempFile.toPath(), installedFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
+        if (previousPermissions != null)
+        {
+          Files.setPosixFilePermissions(installedFile.toPath(), previousPermissions);
+        }
       }
     }
     catch (Exception e)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/tools/LDAPAuthenticationHandler.java b/opendj-server-legacy/src/main/java/org/opends/server/tools/LDAPAuthenticationHandler.java
index 6fe6ae3..a9704c2 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/tools/LDAPAuthenticationHandler.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/tools/LDAPAuthenticationHandler.java
@@ -13,6 +13,7 @@
  *
  * Copyright 2006-2009 Sun Microsystems, Inc.
  * Portions Copyright 2012-2016 ForgeRock AS.
+ * Portions Copyright 2026 3A Systems, LLC.
  */
 package org.opends.server.tools;
 
@@ -28,6 +29,7 @@
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
+import java.nio.file.Files;
 import java.security.MessageDigest;
 import java.security.PrivilegedExceptionAction;
 import java.security.SecureRandom;
@@ -1892,7 +1894,7 @@
     String configFileName;
     try
     {
-      File tempFile = File.createTempFile("login", "conf");
+      File tempFile = Files.createTempFile("login", "conf").toFile();
       configFileName = tempFile.getAbsolutePath();
       tempFile.deleteOnExit();
       try (BufferedWriter w = new BufferedWriter(new FileWriter(tempFile, false))) {
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 fa57322..07227ff 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
@@ -14,6 +14,7 @@
  * Copyright 2007-2010 Sun Microsystems, Inc.
  * Portions Copyright 2011-2016 ForgeRock AS.
  * Portions Copyright 2012 profiq s.r.o.
+ * Portions Copyright 2026 3A Systems, LLC.
  */
 package org.opends.server.tools.dsreplication;
 
@@ -46,6 +47,7 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintStream;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -364,7 +366,7 @@
     try
     {
       ControlPanelLog.initLogFileHandler(
-          File.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX));
+          Files.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX).toFile());
     } catch (Throwable t) {
       System.err.println("Unable to initialize log");
       t.printStackTrace();
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 40ba0d9..86a47b9 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
@@ -29,10 +29,10 @@
 import static org.opends.messages.QuickSetupMessages.INFO_NOT_AVAILABLE_LABEL;
 import static org.opends.messages.ToolMessages.*;
 
-import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintStream;
+import java.nio.file.Files;
 import java.security.GeneralSecurityException;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
@@ -166,7 +166,7 @@
 
     try {
       ControlPanelLog.initLogFileHandler(
-              File.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX));
+              Files.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX).toFile());
       ControlPanelLog.initPackage("org.opends.server.tools.status");
     } catch (Throwable t) {
       System.err.println("Unable to initialize log");
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/util/SetupUtils.java b/opendj-server-legacy/src/main/java/org/opends/server/util/SetupUtils.java
index 36cec85..f37eaac 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/util/SetupUtils.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/util/SetupUtils.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.util;
 
@@ -27,6 +28,7 @@
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.UnknownHostException;
+import java.nio.file.Files;
 import java.security.KeyStoreException;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateEncodingException;
@@ -149,7 +151,7 @@
       int numEntries)
          throws IOException
   {
-    File templateFile = File.createTempFile("opendj-install", ".template");
+    File templateFile = Files.createTempFile("opendj-install", ".template").toFile();
     templateFile.deleteOnExit();
 
     LinkedList<String> lines = new LinkedList<>();
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/util/SetupUtilsTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/util/SetupUtilsTestCase.java
new file mode 100644
index 0000000..ce97a35
--- /dev/null
+++ b/opendj-server-legacy/src/test/java/org/opends/server/util/SetupUtilsTestCase.java
@@ -0,0 +1,65 @@
+/*
+ * 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.opends.server.util;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.File;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.attribute.PosixFilePermission;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+
+import org.testng.SkipException;
+import org.testng.annotations.Test;
+
+/**
+ * A set of test cases for the SetupUtils class.
+ */
+public class SetupUtilsTestCase extends UtilTestCase
+{
+  /**
+   * Tests that temporary files are created readable and writable only by the
+   * owner on POSIX file systems.
+   *
+   * @throws Exception
+   *           If an unexpected problem occurs.
+   */
+  @Test
+  public void testCreateTemplateFileIsOwnerAccessOnly() throws Exception
+  {
+    if (!FileSystems.getDefault().supportedFileAttributeViews().contains("posix"))
+    {
+      throw new SkipException("POSIX file permissions are not supported on this platform");
+    }
+
+    File templateFile = SetupUtils.createTemplateFile(
+        Collections.singleton("dc=example,dc=com"), 1);
+    try
+    {
+      Set<PosixFilePermission> permissions =
+          Files.getPosixFilePermissions(templateFile.toPath());
+      assertEquals(permissions,
+          EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE));
+    }
+    finally
+    {
+      templateFile.delete();
+    }
+  }
+}

--
Gitblit v1.10.0