ConfigureDS.java revision a89f7014aeb71dba5c94404dfea7eb89e7eeee74
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2006-2009 Sun Microsystems, Inc.
* Portions Copyright 2012-2015 ForgeRock AS.
*/
/**
* This class provides a very basic tool that can be used to configure some of
* the most important settings in the Directory Server. This configuration is
* performed by editing the server's configuration files and therefore the
* Directory Server must be offline. This utility will be used during the
* Directory Server installation process.
* <BR><BR>
* The options that this tool can currently set include:
* <BR>
* <UL>
* <LI>The port on which the server will listen for LDAP communication</LI>
* <LI>The DN and password for the initial root user.
* <LI>The set of base DNs for user data</LI>
* </UL>
*/
public class ConfigureDS
{
private static final boolean WRONG_USAGE = true;
/** Private exception class to handle error message printing. */
@SuppressWarnings("serial")
private class ConfigureDSException extends Exception
{
private final int returnedErrorCode;
private final LocalizableMessage errorMessage;
private final boolean wrongUsage;
{
}
{
this(parentException, errorMessage, false);
}
{
}
final boolean showUsage)
{
}
final boolean wrongUsage, final int retCode)
{
super(parentException);
this.errorMessage = errorMessage;
this.wrongUsage = wrongUsage;
}
private LocalizableMessage getErrorMessage()
{
return errorMessage;
}
private boolean isWrongUsage()
{
return wrongUsage;
}
private int getErrorCode()
{
return returnedErrorCode;
}
}
//FIXME: Find a better way to do to prevent hardcoded ldif entries.
private static final String JCKES_KEY_MANAGER_LDIF_ENTRY =
+ "objectClass: top" + NEW_LINE
+ "objectClass: ds-cfg-key-manager-provider" + NEW_LINE
+ "objectClass: ds-cfg-file-based-key-manager-provider" + NEW_LINE
+ "cn: JCEKS" + NEW_LINE
+ "ds-cfg-java-class: org.opends.server.extensions.FileBasedKeyManagerProvider" + NEW_LINE
+ "ds-cfg-enabled: true" + NEW_LINE
+ "ds-cfg-key-store-type: JCEKS" + NEW_LINE
+ "ds-cfg-key-store-file: config/keystore.jceks" + NEW_LINE
+ "ds-cfg-key-store-pin-file: config/keystore.pin" + NEW_LINE;
private static final String JCKES_TRUST_MANAGER_DN = "cn=JCEKS,cn=Trust Manager Providers,cn=config";
private static final String JCKES_TRUST_MANAGER_LDIF_ENTRY =
+ "objectClass: top" + NEW_LINE
+ "objectClass: ds-cfg-trust-manager-provider" + NEW_LINE
+ "objectClass: ds-cfg-file-based-trust-manager-provider" + NEW_LINE
+ "cn: JCEKS" + NEW_LINE
+ "ds-cfg-java-class: org.opends.server.extensions.FileBasedTrustManagerProvider" + NEW_LINE
+ "ds-cfg-enabled: false" + NEW_LINE
+ "ds-cfg-trust-store-type: JCEKS" + NEW_LINE
+ "ds-cfg-trust-store-file: config/truststore" + NEW_LINE;
/** The fully-qualified name of this class. */
/** The DN of the configuration entry defining the LDAP connection handler. */
public static final String DN_LDAP_CONNECTION_HANDLER = "cn=LDAP Connection Handler," + DN_CONNHANDLER_BASE;
/** The DN of the configuration entry defining the Administration connector. */
/** The DN of the configuration entry defining the LDAPS connection handler. */
private static final String DN_LDAPS_CONNECTION_HANDLER = "cn=LDAPS Connection Handler," + DN_CONNHANDLER_BASE;
/** The DN of the configuration entry defining the JMX connection handler. */
private static final String DN_JMX_CONNECTION_HANDLER = "cn=JMX Connection Handler," + DN_CONNHANDLER_BASE;
/** The DN of the configuration entry defining the initial root user. */
/** The DN of the Crypto Manager. */
/** The DN of the DIGEST-MD5 SASL mechanism handler. */
public static final String DN_DIGEST_MD5_SASL_MECHANISM = "cn=DIGEST-MD5,cn=SASL Mechanisms,cn=config";
private static int SUCCESS = 0;
private static int ERROR = 1;
/**
* Provides the command-line arguments to the <CODE>configMain</CODE> method
* for processing.
*
* @param args The set of command-line arguments provided to this program.
*/
{
{
}
}
/**
* Parses the provided command-line arguments and makes the appropriate
* changes to the Directory Server configuration.
*
* @param args The command-line arguments provided to this program.
*
* @param outStream Output stream.
* @param errStream Error stream.
* @return The exit code from the configuration processing. A nonzero value
* indicates that there was some kind of problem during the
* configuration processing.
*/
public static int configMain(final String[] args, final OutputStream outStream, final OutputStream errStream)
{
}
private final PrintStream out;
private final PrintStream err;
private final ArgumentParser argParser;
private BooleanArgument showUsage;
private BooleanArgument enableStartTLS;
private FileBasedArgument rootPasswordFile;
private StringArgument hostName;
private IntegerArgument ldapPort;
private IntegerArgument adminConnectorPort;
private IntegerArgument ldapsPort;
private IntegerArgument jmxPort;
private StringArgument baseDNString;
private StringArgument configClass;
private StringArgument configFile;
private StringArgument rootDNString;
private StringArgument rootPassword;
private StringArgument keyManagerProviderDN;
private StringArgument trustManagerProviderDN;
private StringArgument certNickName;
private StringArgument keyManagerPath;
private StringArgument serverRoot;
private StringArgument backendType;
private ConfigHandler<?> configHandler;
private ConfigureDS(final String[] args, final OutputStream outStream, final OutputStream errStream)
{
}
private int run()
{
try
{
if (argParser.usageOrVersionDisplayed())
{
return SUCCESS;
}
// Get the Directory Server configuration handler and use it to make the
// appropriate configuration changes.
checkManagerProvider(keyManagerProviderDN, JCKES_KEY_MANAGER_DN, JCKES_KEY_MANAGER_LDIF_ENTRY, true);
checkManagerProvider(trustManagerProviderDN, JCKES_TRUST_MANAGER_DN, JCKES_TRUST_MANAGER_LDIF_ENTRY, false);
// Check that the keystore path values are valid.
{
throw new ConfigureDSException(message);
}
return SUCCESS;
}
catch (final ConfigureDSException e)
{
if (e.isWrongUsage())
{
}
return e.getErrorCode();
}
finally
{
}
}
private void initializeArguments() throws ConfigureDSException
{
try
{
configFile = new StringArgument(
"configfile", 'c', "configFile",
true, false, true, INFO_CONFIGFILE_PLACEHOLDER.get(),
configFile.setHidden(true);
configClass = new StringArgument(
false, false, true, INFO_CONFIGCLASS_PLACEHOLDER.get(),
configClass.setHidden(true);
try
{
}
catch (final Exception e)
{
// Not much we can do here.
defaultHostName = "localhost";
}
hostName = new StringArgument(
false, false, true, INFO_HOST_PLACEHOLDER.get(),
ldapPort = new IntegerArgument(
false, false, true, INFO_LDAPPORT_PLACEHOLDER.get(),
false, false, true, INFO_PORT_PLACEHOLDER.get(),
4444, "adminConnectorPort", true, 1, true, 65535, INFO_INSTALLDS_DESCRIPTION_ADMINCONNECTORPORT.get());
ldapsPort = new IntegerArgument(
"ldapsPort", 'P', "ldapsPort",
false, false, true, INFO_LDAPPORT_PLACEHOLDER.get(),
enableStartTLS = new BooleanArgument(
jmxPort = new IntegerArgument(
"jmxport", 'x', "jmxPort",
false, false, true, INFO_JMXPORT_PLACEHOLDER.get(),
CliConstants.DEFAULT_JMX_PORT, null, true, 1, true, 65535, INFO_CONFIGDS_DESCRIPTION_JMX_PORT.get());
"keymanagerproviderdn", 'k', "keyManagerProviderDN",
false, false, true, INFO_KEY_MANAGER_PROVIDER_DN_PLACEHOLDER.get(),
"trustmanagerproviderdn", 't', "trustManagerProviderDN",
false, false, true, INFO_TRUST_MANAGER_PROVIDER_DN_PLACEHOLDER.get(),
keyManagerPath = new StringArgument(
"keymanagerpath", 'm', "keyManagerPath",
false, false, true, INFO_KEY_MANAGER_PATH_PLACEHOLDER.get(),
certNickName = new StringArgument(
"certnickname", 'a', "certNickName",
false, false, true, INFO_NICKNAME_PLACEHOLDER.get(),
baseDNString = new StringArgument(
false, true, true, INFO_BASEDN_PLACEHOLDER.get(),
rootDNString = new StringArgument(
false, false, true, INFO_ROOT_USER_DN_PLACEHOLDER.get(),
rootPassword = new StringArgument(
false, false, true, INFO_ROOT_USER_PWD_PLACEHOLDER.get(),
false, false, INFO_FILE_PLACEHOLDER.get(),
serverRoot = new StringArgument(
false, false, true, INFO_SERVER_ROOT_DIR_PLACEHOLDER.get(),
serverRoot.setHidden(true);
backendType = new StringArgument(
false, false, true, INFO_INSTALLDS_BACKEND_TYPE_PLACEHOLDER.get(),
);
}
catch (final ArgumentException ae)
{
}
}
private int parseArguments() throws ConfigureDSException
{
try
{
return SUCCESS;
}
catch (final ArgumentException ae)
{
}
}
/** Make sure that the user actually tried to configure something. */
private void checkArgumentsConsistency() throws ConfigureDSException
{
if (!baseDNString.isPresent()
&& !rootDNString.isPresent())
{
}
}
private void checkPortArguments() throws ConfigureDSException
{
try
{
{
{
{
throw new ConfigureDSException(ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(portArg.getIntValue()), WRONG_USAGE);
}
}
}
}
catch (final ArgumentException ae)
{
}
}
private void initializeDirectoryServer() throws ConfigureDSException
{
if (serverRoot.isPresent()) {
try {
} catch (final InitializationException e) {
}
}
// Initialize the Directory Server configuration handler using the
// information that was provided.
try
{
}
catch (final Exception e)
{
final LocalizableMessage msg = ERR_CONFIGDS_CANNOT_INITIALIZE_JMX.get(configFile.getValue(), e.getMessage());
throw new ConfigureDSException(e, msg);
}
try
{
}
catch (final Exception e)
{
final LocalizableMessage msg = ERR_CONFIGDS_CANNOT_INITIALIZE_CONFIG.get(configFile.getValue(), e.getMessage());
throw new ConfigureDSException(e, msg);
}
try
{
}
catch (final Exception e)
{
final LocalizableMessage msg = ERR_CONFIGDS_CANNOT_INITIALIZE_SCHEMA.get(configFile.getValue(), e.getMessage());
throw new ConfigureDSException(e, msg);
}
}
/**
* Make sure that we can get an exclusive lock for the Directory Server, so
* that no other operation will be allowed while this is in progress.
*
* @throws ConfigureDSException
*/
private void tryAcquireExclusiveLocks() throws ConfigureDSException
{
{
throw new ConfigureDSException(ERR_CONFIGDS_CANNOT_ACQUIRE_SERVER_LOCK.get(serverLockFileName, failureReason));
}
}
{
if (baseDNString.isPresent())
{
{
try
{
}
catch (final Exception e)
{
}
}
}
return baseDNs;
}
{
if (rootDNString.isPresent())
{
try
{
}
catch (final DirectoryException de)
{
}
}
return rootDN;
}
{
if (rootDNString.isPresent())
{
if (rootPassword.isPresent())
{
}
else if (rootPasswordFile.isPresent())
{
}
else
{
}
}
return rootPW;
}
final boolean isKeyManager) throws ConfigureDSException
{
{
try
{
}
catch (final DirectoryException de)
{
final LocalizableMessage message =
}
{
try
{
{
}
}
catch (final Exception e)
{
final LocalizableMessage message = isKeyManager ? ERR_CONFIG_KEYMANAGER_CANNOT_CREATE_JCEKS_PROVIDER.get(e)
throw new ConfigureDSException(e, message);
}
finally
{
}
}
else
{
try
{
}
catch (final Exception e)
{
throw new ConfigureDSException(e, message);
}
}
}
}
@SuppressWarnings("unchecked")
private void updateBaseDNs(final List<org.forgerock.opendj.ldap.DN> baseDNs) throws ConfigureDSException
{
{
final ManagedObjectDefinition<?, ?> backend = backendTypeHelper.retrieveBackendTypeFromName(backendTypeName);
{
throw new ConfigureDSException(
ERR_CONFIGDS_BACKEND_TYPE_UNKNOWN.get(backendTypeName, backendTypeHelper.getPrintableBackendTypeNames()));
}
try
{
}
catch (Exception e)
{
}
}
}
private void updateLdapPort() throws ConfigureDSException
{
{
try
{
final ConfigEntry configEntry = configHandler.getConfigEntry(DN.valueOf(DN_LDAP_CONNECTION_HANDLER));
}
catch (final Exception e)
{
}
}
}
private void updateAdminConnectorPort() throws ConfigureDSException
{
if (adminConnectorPort.isPresent())
{
try
{
}
catch (final Exception e)
{
}
}
}
private void updateLdapSecurePort() throws ConfigureDSException
{
{
try
{
final ConfigEntry configEntry = configHandler.getConfigEntry(DN.valueOf(DN_LDAPS_CONNECTION_HANDLER));
}
catch (final Exception e)
{
}
}
}
private void updateJMXport() throws ConfigureDSException
{
{
try
{
final ConfigEntry configEntry = configHandler.getConfigEntry(DN.valueOf(DN_JMX_CONNECTION_HANDLER));
}
catch (final Exception e)
{
}
}
}
private void updateStartTLS() throws ConfigureDSException
{
if (enableStartTLS.isPresent())
{
try
{
final ConfigEntry configEntry = configHandler.getConfigEntry(DN.valueOf(DN_LDAP_CONNECTION_HANDLER));
}
catch (final Exception e)
{
}
}
}
private void updateKeyManager() throws ConfigureDSException
{
if (keyManagerProviderDN.isPresent())
{
{
try
{
// Enable the key manager
final ConfigEntry configEntry = configHandler.getConfigEntry(DN.valueOf(keyManagerProviderDN.getValue()));
}
catch (final Exception e)
{
}
}
if (keyManagerPath.isPresent())
{
try
{
true, true, true, keyManagerPath.getValue());
final ConfigEntry configEntry = configHandler.getConfigEntry(DN.valueOf(keyManagerProviderDN.getValue()));
}
catch (final Exception e)
{
}
}
}
}
throws ConfigureDSException
{
{
try
{
false, false, true, keyManagerProviderDN.getValue());
}
catch (final Exception e)
{
}
}
}
private void updateTrustManager() throws ConfigureDSException
{
if (trustManagerProviderDN.isPresent())
{
{
try
{
final ConfigEntry configEntry = configHandler.getConfigEntry(DN.valueOf(trustManagerProviderDN.getValue()));
}
catch (final Exception e)
{
}
}
}
if (certNickName.isPresent())
{
false, false, true, certNickName.getValue());
false, false, true, certNickName.getValue());
}
else
{
// Use the key manager specified for connection handlers
}
}
private void putTrustManagerAttribute(final Argument arg, final String attributeDN) throws ConfigureDSException
{
{
try
{
false, false, true, trustManagerProviderDN.getValue());
}
catch (final Exception e)
{
}
}
}
{
try
{
{
}
else
{
}
}
catch (final Exception e)
{
}
}
{
try
{
}
catch (final Exception e)
{
}
}
{
{
try
{
false, true, false, rootDN);
}
catch (final Exception e)
{
}
}
}
/** Set the FQDN for the DIGEST-MD5 SASL mechanism. */
private void addFQDNDigestMD5() throws ConfigureDSException
{
try
{
final ConfigEntry configEntry = configHandler.getConfigEntry(DN.valueOf(DN_DIGEST_MD5_SASL_MECHANISM));
}
catch (final Exception e)
{
}
}
/**
* Check that the cipher specified is supported. This is intended to fix
* issues with JVM that do not support the default cipher (see issue 3075 for
* instance).
*
* @throws ConfigureDSException
*/
private void updateCryptoCipher() throws ConfigureDSException
{
final StringPropertyDefinition prop = cryptoManager.getKeyWrappingTransformationPropertyDefinition();
if (p instanceof DefinedDefaultBehaviorProvider)
{
if (!defaultValues.isEmpty())
{
}
}
if (defaultCipher != null)
{
// Check that the default cipher is supported by the JVM.
try
{
}
catch (final GeneralSecurityException ex)
{
// The cipher is not supported: try to find an alternative one.
if (alternativeCipher != null)
{
try
{
false, false, true, alternativeCipher);
}
catch (final Exception e)
{
}
}
}
}
}
private void writeUpdatedConfiguration() throws ConfigureDSException
{
try
{
}
catch (final DirectoryException de)
{
throw new ConfigureDSException(de, ERR_CONFIGDS_CANNOT_WRITE_UPDATED_CONFIG.get(de.getMessageObject()));
}
}
/**
* Returns a cipher that is supported by the JVM we are running at.
* Returns <CODE>null</CODE> if no alternative cipher could be found.
* @return a cipher that is supported by the JVM we are running at.
*/
public static String getAlternativeCipher()
{
final String[] preferredAlternativeCiphers =
{
};
{
try
{
break;
}
catch (final Throwable t)
{
}
}
return alternativeCipher;
}
}