From 846b9829d2dc1a05e18cb11a7b13f7373f6a6a6b Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Thu, 03 May 2007 03:56:41 +0000
Subject: [PATCH] Implement support for config file change detection, which can detect external edits to the server configuration (e.g., manually updating the file in a text editor) with the server online. If the server detects that the configuration file has been externally modified when it needs to rewrite it to apply a change coming in through protocol, then it will attempt to copy the manually-edited file off to the side and will generate an administrative alert and write a log message to let administrators know what happened.
---
opendj-sdk/opends/src/server/org/opends/server/messages/ConfigMessages.java | 39 +++++++++++++
opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java | 73 ++++++++++++++++++++++++
opendj-sdk/opends/src/server/org/opends/server/util/ServerConstants.java | 50 ++++++++++++++++
3 files changed, 162 insertions(+), 0 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java b/opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java
index b6f1a2c..156a272 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java
@@ -1928,6 +1928,75 @@
// FIXME -- This needs support for encryption.
+ // Calculate an archive for the current server configuration file and see if
+ // it matches what we expect. If not, then the file has been manually
+ // edited with the server online which is a bad thing. In that case, we'll
+ // copy the current config off to the side before writing the new config
+ // so that the manual changes don't get lost but also don't get applied.
+ // Also, send an admin alert notifying administrators about the problem.
+ try
+ {
+ byte[] currentDigest = calculateConfigDigest();
+ if (! Arrays.equals(configurationDigest, currentDigest))
+ {
+ File existingCfg = new File(configFile);
+ File newConfigFile = new File(existingCfg.getParent(),
+ "config.manualedit-" +
+ TimeThread.getGMTTime() + ".ldif");
+ int counter = 2;
+ while (newConfigFile.exists())
+ {
+ newConfigFile = new File(newConfigFile.getAbsolutePath() + "." +
+ counter++);
+ }
+
+ FileInputStream inputStream = new FileInputStream(existingCfg);
+ FileOutputStream outputStream = new FileOutputStream(newConfigFile);
+ byte[] buffer = new byte[8192];
+ while (true)
+ {
+ int bytesRead = inputStream.read(buffer);
+ if (bytesRead < 0)
+ {
+ break;
+ }
+
+ outputStream.write(buffer, 0, bytesRead);
+ }
+
+ inputStream.close();
+ outputStream.close();
+
+ int msgID = MSGID_CONFIG_MANUAL_CHANGES_DETECTED;
+ String message = getMessage(msgID, configFile,
+ newConfigFile.getAbsolutePath());
+
+ logError(ErrorLogCategory.CONFIGURATION,
+ ErrorLogSeverity.SEVERE_WARNING, message, msgID);
+
+ DirectoryServer.sendAlertNotification(this,
+ ALERT_TYPE_MANUAL_CONFIG_EDIT_HANDLED, msgID, message);
+ }
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ int msgID = MSGID_CONFIG_MANUAL_CHANGES_LOST;
+ String message = getMessage(msgID, configFile,
+ stackTraceToSingleLineString(e));
+
+ logError(ErrorLogCategory.CONFIGURATION,
+ ErrorLogSeverity.SEVERE_ERROR, message, msgID);
+
+ DirectoryServer.sendAlertNotification(this,
+ ALERT_TYPE_MANUAL_CONFIG_EDIT_HANDLED, msgID, message);
+ }
+
+
// Write the new configuration to a temporary file.
String tempConfig = configFile + ".tmp";
try
@@ -3391,6 +3460,10 @@
alerts.put(ALERT_TYPE_CANNOT_WRITE_CONFIGURATION,
ALERT_DESCRIPTION_CANNOT_WRITE_CONFIGURATION);
+ alerts.put(ALERT_TYPE_MANUAL_CONFIG_EDIT_HANDLED,
+ ALERT_DESCRIPTION_MANUAL_CONFIG_EDIT_HANDLED);
+ alerts.put(ALERT_TYPE_MANUAL_CONFIG_EDIT_LOST,
+ ALERT_DESCRIPTION_MANUAL_CONFIG_EDIT_LOST);
return alerts;
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/ConfigMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/ConfigMessages.java
index e856107..94db4da 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/ConfigMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/ConfigMessages.java
@@ -6595,6 +6595,32 @@
/**
+ * The message ID for the message that will be used if the server detects that
+ * the configuration has been manually edited while the server is online, but
+ * that the manual edits have been copied off into another file before the
+ * configuration was updated by another change. This takes two arguments,
+ * which are the path to the live configuration file and the path to the file
+ * containing the manual edits.
+ */
+ public static final int MSGID_CONFIG_MANUAL_CHANGES_DETECTED =
+ CATEGORY_MASK_CONFIG | SEVERITY_MASK_SEVERE_WARNING | 655;
+
+
+
+ /**
+ * The message ID for the message that will be used if the server detects that
+ * the configuration may have been manually edited while the server is online,
+ * but a problem occurred that prevented the manual changes from being copied
+ * before the configuration was overwritten. This takes two arguments, which
+ * are the path to the live configuration file and a string representation of
+ * the exception that was caught.
+ */
+ public static final int MSGID_CONFIG_MANUAL_CHANGES_LOST =
+ CATEGORY_MASK_CONFIG | SEVERITY_MASK_SEVERE_ERROR | 656;
+
+
+
+ /**
* Associates a set of generic messages with the message IDs defined in this
* class.
*/
@@ -6917,6 +6943,19 @@
registerMessage(MSGID_CONFIG_FILE_CANNOT_WRITE_CONFIG_ARCHIVE,
"An error occurred while trying to write the current " +
"configuration to the configuration archive: %s");
+ registerMessage(MSGID_CONFIG_MANUAL_CHANGES_DETECTED,
+ "The Directory Server has detected that one or more " +
+ "external changes have been made to the configuration " +
+ "file %s while the server was online, but another change " +
+ "has caused the server configuration to be overwritten. " +
+ "The manual changes have not been applied, but they have " +
+ "been preserved in file %s");
+ registerMessage(MSGID_CONFIG_MANUAL_CHANGES_LOST,
+ "The Directory Server encountered an error while " +
+ "attempting to determine whether the configuration file " +
+ "%s has been externally edited with the server online, " +
+ "and/or trying to preserve such changes: %s. Any " +
+ "manual changes made to that file may have been lost");
registerMessage(MSGID_CONFIG_FILE_WRITE_CANNOT_EXPORT_NEW_CONFIG,
"An error occurred while attempting to export the new " +
"Directory Server configuration to file %s: %s");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/util/ServerConstants.java b/opendj-sdk/opends/src/server/org/opends/server/util/ServerConstants.java
index b8b39f9..50faed6 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/util/ServerConstants.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/util/ServerConstants.java
@@ -1326,6 +1326,56 @@
/**
* The description for the alert type that will be used for the alert
+ * notification generated if the server detects that the configuration has
+ * been manually edited with the server online and those edits would have been
+ * lost by an online config change.
+ */
+ public static final String ALERT_DESCRIPTION_MANUAL_CONFIG_EDIT_HANDLED =
+ "This alert type will be used to notify administrators if the " +
+ "Directory Server detects that its configuration has been manually " +
+ "edited with the server online and those changes were overwritten by " +
+ "another change made through the server. The manually-edited " +
+ "configuration will be copied off to another location.";
+
+
+
+ /**
+ * The alert type string that will be used for the alert notification
+ * generated if a problem occurs while attempting to write the Directory
+ * Server configuration to disk.
+ */
+ public static final String ALERT_TYPE_MANUAL_CONFIG_EDIT_HANDLED =
+ "org.opends.server.ManualConfigEditHandled";
+
+
+
+ /**
+ * The description for the alert type that will be used for the alert
+ * notification generated if the server detects that the configuration has
+ * been manually edited with the server online, but a problem occurred while
+ * trying to preserve the manual changes that may have caused them to be lost.
+ */
+ public static final String ALERT_DESCRIPTION_MANUAL_CONFIG_EDIT_LOST =
+ "This alert type will be used to notify administrators if the " +
+ "Directory Server detects that its configuration has been manually " +
+ "edited with the server online and those changes were overwritten by " +
+ "another change made through the server. The manually-edited " +
+ "configuration could not be preserved due to an unexpected error.";
+
+
+
+ /**
+ * The alert type string that will be used for the alert notification
+ * generated if a problem occurs while attempting to write the Directory
+ * Server configuration to disk.
+ */
+ public static final String ALERT_TYPE_MANUAL_CONFIG_EDIT_LOST =
+ "org.opends.server.ManualConfigEditLost";
+
+
+
+ /**
+ * The description for the alert type that will be used for the alert
* notification generated if an error occurs while attempting to write the
* tasks backing file.
*/
--
Gitblit v1.10.0