From 214f451ba73df3e9233471a0dbe636314f5cb3bb Mon Sep 17 00:00:00 2001
From: Violette Roche-Montane <violette.roche-montane@forgerock.com>
Date: Thu, 23 Jan 2014 10:47:40 +0000
Subject: [PATCH] OPENDJ-1284 CryptoManager error when starting server after an upgrade
---
opends/src/server/org/opends/server/tools/upgrade/UpgradeTasks.java | 41 ++++----
opends/src/messages/messages/tools.properties | 9 +
opends/src/server/org/opends/server/tools/upgrade/UpgradeUtils.java | 205 +++++++++++++++++++++++-----------------
opends/src/server/org/opends/server/tools/upgrade/Upgrade.java | 23 +++-
4 files changed, 162 insertions(+), 116 deletions(-)
diff --git a/opends/src/messages/messages/tools.properties b/opends/src/messages/messages/tools.properties
index f6cdcd6..7f2d49d 100644
--- a/opends/src/messages/messages/tools.properties
+++ b/opends/src/messages/messages/tools.properties
@@ -20,7 +20,7 @@
# CDDL HEADER END
#
# Copyright 2006-2010 Sun Microsystems, Inc.
-# Portions Copyright 2011-2013 ForgeRock AS
+# Portions Copyright 2011-2014 ForgeRock AS
@@ -2498,8 +2498,8 @@
INFO_UPGRADE_DISPLAY_CONFIRM_START_1814=The upgrade is ready to proceed. Do you \
wish to continue?
INFO_UPGRADE_ABORTED_BY_USER_1815=The upgrade has been canceled
-SEVERE_ERR_UPGRADE_UNKNOWN_OC_ATT_1816=The %s %s doesn't exist \
-in the template configuration (possible typo or template corruption)
+SEVERE_ERR_UPGRADE_UNKNOWN_OC_ATT_1816=No %s with OID %s exists in \
+the schema
SEVERE_ERR_UPGRADE_CONFIG_ERROR_UPGRADE_FOLDER_1817=An error occurred when \
trying to upgrade the config/upgrade folder: %s
INFO_UPGRADE_REQUIREMENTS_1818=Preparing to upgrade
@@ -2580,3 +2580,6 @@
regression in the ds-sync-hist ordering index. This index has to be rebuilt and this could take a long time \
to proceed. Do you want to launch this process at automatically at the end of the upgrade?
SEVERE_ERR_TASK_TOOL_LDAP_ERROR_10020=ERROR: The server rejected the task for the following reason: %s
+INFO_UPGRADE_TASK_10133_1_SUMMARY_10021=Changing matching rule for 'userCertificate' and \
+ 'caCertificate' to CertificateExactMatch
+INFO_UPGRADE_TASK_10133_2_SUMMARY_10022=Configuring 'CertificateExactMatch' matching rule
diff --git a/opends/src/server/org/opends/server/tools/upgrade/Upgrade.java b/opends/src/server/org/opends/server/tools/upgrade/Upgrade.java
index 215a039..396b02f 100644
--- a/opends/src/server/org/opends/server/tools/upgrade/Upgrade.java
+++ b/opends/src/server/org/opends/server/tools/upgrade/Upgrade.java
@@ -21,7 +21,7 @@
* CDDL HEADER END
*
*
- * Copyright 2013 ForgeRock AS
+ * Copyright 2013-2014 ForgeRock AS
*/
package org.opends.server.tools.upgrade;
@@ -134,7 +134,7 @@
register("2.5.0.7748",
newAttributeTypes(INFO_UPGRADE_TASK_7748_1_SUMMARY.get(),
- "00-core.ldif", "etag"),
+ "00-core.ldif", "1.3.6.1.4.1.36733.2.1.1.59"), //etag
addConfigEntry(INFO_UPGRADE_TASK_7748_2_SUMMARY.get(),
"dn: cn=etag,cn=Virtual Attributes,cn=config",
"changetype: add",
@@ -279,7 +279,7 @@
register("2.5.0.8985",
newAttributeTypes(INFO_UPGRADE_TASK_8985_1_SUMMARY.get(),
- "00-core.ldif", "emailAddress"),
+ "00-core.ldif", "1.2.840.113549.1.9.1"), // emailAddress
modifyConfigEntry(INFO_UPGRADE_TASK_8985_2_SUMMARY.get(),
"&(ds-cfg-java-class=org.opends.server.extensions." +
"SubjectAttributeToUserAttributeCertificateMapper)" +
@@ -290,13 +290,26 @@
"add:ds-cfg-subject-attribute-mapping",
"ds-cfg-subject-attribute-mapping: emailAddress:mail"));
- /* See OPENDJ-992 */
+ /** See OPENDJ-992 */
register("2.5.0.9013",
regressionInVersion("2.5.0.7640",
rebuildSingleIndex(INFO_UPGRADE_TASK_9013_DESCRIPTION.get(),
"ds-sync-hist")));
-
+ /** See OPENDJ-1284*/
+ register("2.7.0.10133", // userCertificate OID / cACertificate OID
+ newAttributeTypes(INFO_UPGRADE_TASK_10133_1_SUMMARY.get(),
+ "00-core.ldif", "2.5.4.36", "2.5.4.37"),
+ addConfigEntry(INFO_UPGRADE_TASK_10133_2_SUMMARY.get(),
+ "dn: cn=Certificate Exact Matching Rule,cn=Matching Rules,cn=config",
+ "changetype: add",
+ "objectClass: top",
+ "objectClass: ds-cfg-matching-rule",
+ "objectClass: ds-cfg-equality-matching-rule",
+ "cn: Certificate Exact Matching Rule",
+ "ds-cfg-java-class: "
+ + "org.opends.server.schema.CertificateExactMatchingRuleFactory",
+ "ds-cfg-enabled: true"));
/*
* All upgrades will refresh the server configuration schema and generate
diff --git a/opends/src/server/org/opends/server/tools/upgrade/UpgradeTasks.java b/opends/src/server/org/opends/server/tools/upgrade/UpgradeTasks.java
index d668e7b..9b9cef9 100644
--- a/opends/src/server/org/opends/server/tools/upgrade/UpgradeTasks.java
+++ b/opends/src/server/org/opends/server/tools/upgrade/UpgradeTasks.java
@@ -21,7 +21,7 @@
* CDDL HEADER END
*
*
- * Copyright 2013 ForgeRock AS
+ * Copyright 2013-2014 ForgeRock AS
*/
package org.opends.server.tools.upgrade;
@@ -47,7 +47,6 @@
import javax.security.auth.callback.TextOutputCallback;
import org.forgerock.opendj.ldap.Filter;
-import org.forgerock.opendj.ldap.schema.UnknownSchemaElementException;
import org.opends.messages.Message;
import org.opends.server.tools.ClientException;
import org.opends.server.tools.RebuildIndex;
@@ -257,22 +256,23 @@
* <pre>
* register("2.5.0.7192",
* newAttributeTypes(Message.raw("New attribute etag"),
- * false, "00-core.ldif", "etag"));
+ * false, "00-core.ldif",
+ * "1.3.6.1.4.1.36733.2.1.1.59"));
* </pre>
*
* @param summary
* The summary of the task.
* @param fileName
* The file where to add the new attribute types. This file must be
- * contained in the config/schema folder.
- * @param names
- * The names of the new attributes to add to.
+ * contained in the configuration/schema folder.
+ * @param attributeOids
+ * The OIDs of the new attributes to add to.
* @return An upgrade task which adds new attribute types, defined previously
- * in the config template files, reads the definition and adds it onto
- * the specified file in parameter.
+ * in the configuration template files, reads the definition
+ * and adds it onto the specified file in parameter.
*/
public static UpgradeTask newAttributeTypes(final Message summary,
- final String fileName, final String... names)
+ final String fileName, final String... attributeOids)
{
return new AbstractUpgradeTask()
{
@@ -293,7 +293,7 @@
{
final int changeCount =
updateSchemaFile(schemaFileTemplate, pathDestination,
- names, null);
+ attributeOids, null);
displayChangeCount(pathDestination.getPath(), changeCount);
@@ -304,7 +304,7 @@
manageTaskException(context, ERR_UPGRADE_ADDATTRIBUTE_FAILS.get(
schemaFileTemplate.getName(), e.getMessage()), pnc);
}
- catch (final UnknownSchemaElementException e)
+ catch (final IllegalStateException e)
{
manageTaskException(context, ERR_UPGRADE_ADDATTRIBUTE_FAILS.get(
schemaFileTemplate.getName(), e.getMessage()), pnc);
@@ -322,15 +322,16 @@
* The summary of the task.
* @param fileName
* The file where to add the new object classes. This file must be
- * contained in the config/schema folder.
- * @param names
- * The names of the new object classes to add to.
+ * contained in the configuration/schema folder.
+ * @param objectClassesOids
+ * The OIDs of the new object classes to add to.
* @return An upgrade task which adds new object classes, defined previously
- * in the config template files, reads the definition and adds it onto
- * the specified file in parameter.
+ * in the configuration template files,
+ * reads the definition and adds it onto the specified file in
+ * parameter.
*/
public static UpgradeTask newObjectClasses(final Message summary,
- final String fileName, final String... names)
+ final String fileName, final String... objectClassesOids)
{
return new AbstractUpgradeTask()
{
@@ -354,7 +355,7 @@
{
final int changeCount =
updateSchemaFile(schemaFileTemplate, pathDestination,
- null, names);
+ null, objectClassesOids);
displayChangeCount(pathDestination.getPath(), changeCount);
@@ -365,9 +366,9 @@
manageTaskException(context, ERR_UPGRADE_ADDOBJECTCLASS_FAILS.get(
schemaFileTemplate.getName(), e.getMessage()), pnc);
}
- catch (final UnknownSchemaElementException e)
+ catch (final IllegalStateException e)
{
- manageTaskException(context, ERR_UPGRADE_ADDOBJECTCLASS_FAILS.get(
+ manageTaskException(context, ERR_UPGRADE_ADDATTRIBUTE_FAILS.get(
schemaFileTemplate.getName(), e.getMessage()), pnc);
}
}
diff --git a/opends/src/server/org/opends/server/tools/upgrade/UpgradeUtils.java b/opends/src/server/org/opends/server/tools/upgrade/UpgradeUtils.java
index a46a23f..e5dd73c 100644
--- a/opends/src/server/org/opends/server/tools/upgrade/UpgradeUtils.java
+++ b/opends/src/server/org/opends/server/tools/upgrade/UpgradeUtils.java
@@ -21,7 +21,7 @@
* CDDL HEADER END
*
*
- * Copyright 2013 ForgeRock AS
+ * Copyright 2013-2014 ForgeRock AS
*/
package org.opends.server.tools.upgrade;
@@ -37,9 +37,9 @@
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.requests.SearchRequest;
import org.forgerock.opendj.ldap.schema.CoreSchema;
+import org.forgerock.opendj.ldap.schema.MatchingRule;
import org.forgerock.opendj.ldap.schema.Schema;
import org.forgerock.opendj.ldap.schema.SchemaBuilder;
-import org.forgerock.opendj.ldap.schema.UnknownSchemaElementException;
import org.forgerock.opendj.ldif.EntryReader;
import org.forgerock.opendj.ldif.LDIF;
import org.forgerock.opendj.ldif.LDIFEntryReader;
@@ -51,12 +51,11 @@
import org.opends.server.util.StaticUtils;
import static org.opends.messages.ConfigMessages.INFO_CONFIG_FILE_HEADER;
-import static org.opends.messages.ToolMessages.ERR_UPGRADE_UNKNOWN_OC_ATT;
import static org.opends.messages.ToolMessages.ERR_UPGRADE_CORRUPTED_TEMPLATE;
+import static org.opends.messages.ToolMessages.ERR_UPGRADE_UNKNOWN_OC_ATT;
import static org.opends.server.tools.upgrade.FileManager.deleteRecursively;
import static org.opends.server.tools.upgrade.FileManager.rename;
import static org.opends.server.tools.upgrade.Installation.*;
-import static org.opends.server.util.ServerConstants.EOL;
/**
* Common utility methods needed by the upgrade.
@@ -571,54 +570,52 @@
* is inserted successfully to the destination file.
* @throws IOException
* If an unexpected IO error occurred while reading the entry.
- * @throws UnknownSchemaElementException
+ * @throws IllegalStateException
* Failure to find an attribute in the template schema indicates
* either a programming error (e.g. typo in the attribute name) or
* template corruption. Upgrade should stop.
*/
static int updateSchemaFile(final File templateFile, final File destination,
final String[] attributes, final String[] objectClasses)
- throws IOException, UnknownSchemaElementException
+ throws IOException, IllegalStateException
{
int changeCount = 0;
- LDIFEntryReader reader = null;
- BufferedReader br = null;
- FileWriter fw = null;
+ LDIFEntryReader templateReader = null;
+ LDIFEntryReader destinationReader = null;
+ LDIFEntryWriter destinationWriter = null;
File copy = null;
try
{
- reader = new LDIFEntryReader(new FileInputStream(templateFile));
-
- if (!reader.hasNext())
+ templateReader = new LDIFEntryReader(new FileInputStream(templateFile));
+ if (!templateReader.hasNext())
{
// Unless template are corrupted, this should not happen.
throw new IOException(ERR_UPGRADE_CORRUPTED_TEMPLATE.get(
templateFile.getPath()).toString());
}
- final LinkedList<String> definitionsList = new LinkedList<String>();
+ final Entry templateSchemaEntry = templateReader.readEntry();
- final Entry schemaEntry = reader.readEntry();
+ destinationReader = new LDIFEntryReader(
+ new FileInputStream(destination));
+ if (!destinationReader.hasNext())
+ {
+ // Unless template are corrupted, this should not happen.
+ throw new IOException(ERR_UPGRADE_CORRUPTED_TEMPLATE.get(
+ destination.getPath()).toString());
+ }
+ final Entry destinationSchemaEntry = destinationReader.readEntry();
- Schema schema =
- new SchemaBuilder(Schema.getCoreSchema())
- .addSchema(schemaEntry, true).toSchema();
if (attributes != null)
{
for (final String att : attributes)
{
- try
- {
- final String definition =
- "attributeTypes: " + schema.getAttributeType(att);
- definitionsList.add(definition);
- LOG.log(Level.INFO, String.format("Added %s", definition));
- }
- catch (UnknownSchemaElementException e)
- {
- LOG.log(Level.SEVERE, ERR_UPGRADE_UNKNOWN_OC_ATT.get("attribute",
- att).toString());
- throw e;
- }
+ final ByteString attributeType =
+ getSchemaElement(templateSchemaEntry, "attributeTypes", att);
+ destinationSchemaEntry.getAttribute("attributeTypes").add(
+ attributeType);
+ changeCount++;
+ LOG.log(Level.INFO, String.format("Added %s", attributeType
+ .toString()));
}
}
@@ -626,50 +623,35 @@
{
for (final String oc : objectClasses)
{
- try
- {
- final String definition =
- "objectClasses: " + schema.getObjectClass(oc);
- definitionsList.add(definition);
- LOG.log(Level.INFO, String.format("Added %s", definition));
- }
- catch (UnknownSchemaElementException e)
- {
- LOG.log(Level.SEVERE, ERR_UPGRADE_UNKNOWN_OC_ATT.get(
- "object class", oc).toString());
- throw e;
- }
+ final ByteString objectClass =
+ getSchemaElement(templateSchemaEntry, "objectClasses", oc);
+ destinationSchemaEntry.getAttribute("objectClasses").add(objectClass);
+ changeCount++;
+ LOG.log(Level.INFO,
+ String.format("Added %s", objectClass.toString()));
}
}
- // Then, open the destination file and write the new attribute
- // or objectClass definitions
+
+ // Then writes the new schema entry.
copy =
File.createTempFile("copySchema", ".tmp",
destination.getParentFile());
- br = new BufferedReader(new FileReader(destination));
- fw = new FileWriter(copy);
- String line = br.readLine();
- while (line != null && !"".equals(line))
- {
- fw.write(line + EOL);
- line = br.readLine();
- }
- for (final String definition : definitionsList)
- {
- writeLine(fw, definition, 80);
- changeCount++;
- }
- // Must be ended with a blank line
- fw.write(EOL);
+ final FileOutputStream fos = new FileOutputStream(copy);
+ destinationWriter = new LDIFEntryWriter(fos);
+ destinationWriter.setWrapColumn(79);
+ // Copy comments to fos (get License and first comments only).
+ writeFileHeaderComments(templateFile, destinationWriter);
+ // Writes the entry after.
+ destinationWriter.writeEntry(destinationSchemaEntry);
}
finally
{
- // The reader and writer must be close before writing files.
+ // Readers and writer must be close before writing files.
// This causes exceptions under windows OS.
- StaticUtils.close(br, fw, reader);
+ StaticUtils.close(templateReader, destinationReader, destinationWriter);
}
- // Writes the schema file.
+ // Renames the copy to make it the new schema file.
try
{
rename(copy, destination);
@@ -685,6 +667,78 @@
}
/**
+ * Gets and writes the first comments of a file.
+ *
+ * @param file
+ * The selected file to get the comments.
+ * @param writer
+ * The writer which is going to write the comments.
+ * @throws IOException
+ * If an error occurred with the file.
+ */
+ private static void writeFileHeaderComments(final File file,
+ final LDIFEntryWriter writer) throws IOException
+ {
+ BufferedReader br = null;
+ try
+ {
+ br = new BufferedReader(new FileReader(file));
+ String comment = br.readLine();
+
+ while (comment != null && comment.startsWith("#"))
+ {
+ writer.writeComment(comment.replaceAll("# ", "").replaceAll("#", ""));
+ comment = br.readLine();
+ }
+ }
+ catch (IOException ex)
+ {
+ throw ex;
+ }
+ finally
+ {
+ StaticUtils.close(br);
+ }
+ }
+ /**
+ * Returns the definition of the selected attribute / object class OID.
+ *
+ * @param schemaEntry
+ * The selected schema entry to search on.
+ * @param type
+ * The type of the research. ("objectClasses" or "attributeTypes")
+ * @param oid
+ * The OID of the element to search for.
+ * @return The byte string definition of the element.
+ */
+ private static ByteString getSchemaElement(final Entry schemaEntry,
+ final String type, final String oid)
+ {
+ final Attribute attribute = schemaEntry.getAttribute(type);
+ final MatchingRule mrule =
+ CoreSchema.getObjectIdentifierFirstComponentMatchingRule();
+ Assertion assertion;
+ try
+ {
+ assertion = mrule.getAssertion(ByteString.valueOf(oid));
+ for (final ByteString value : attribute)
+ {
+ final ByteString nvalue = mrule.normalizeAttributeValue(value);
+ if (assertion.matches(nvalue).toBoolean())
+ {
+ return value;
+ }
+ }
+ }
+ catch (DecodeException e)
+ {
+ throw new IllegalStateException(e);
+ }
+ throw new IllegalStateException(ERR_UPGRADE_UNKNOWN_OC_ATT.get(type, oid)
+ .toString());
+ }
+
+ /**
* Creates a new file in the config/upgrade folder. The new file is a
* concatenation of entries of all files contained in the config/schema
* folder.
@@ -833,31 +887,6 @@
return modifiedLines;
}
- private static void writeLine(final FileWriter fw, final String line,
- final int wrapColumn) throws IOException
- {
- final int length = line.length();
- if (length > wrapColumn)
- {
- fw.write(line.subSequence(0, wrapColumn).toString());
- fw.write(EOL);
- int pos = wrapColumn;
- while (pos < length)
- {
- final int writeLength = Math.min(wrapColumn - 1, length - pos);
- fw.write(" ");
- fw.write(line.subSequence(pos, pos + writeLength).toString());
- fw.write(EOL);
- pos += wrapColumn - 1;
- }
- }
- else
- {
- fw.write(line);
- fw.write(EOL);
- }
- }
-
// Prevent instantiation.
private UpgradeUtils()
{
--
Gitblit v1.10.0