/*
|
* 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
|
* or http://forgerock.org/license/CDDLv1.0.html.
|
* 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-2010 Sun Microsystems, Inc.
|
* Portions copyright 2011-2013 ForgeRock AS.
|
*/
|
package org.opends.server.core;
|
|
import java.util.*;
|
|
import org.opends.messages.Message;
|
import org.opends.server.admin.server.ConfigurationChangeListener;
|
import org.opends.server.admin.server.ServerManagementContext;
|
import org.opends.server.admin.std.meta.GlobalCfgDefn;
|
import org.opends.server.admin.std.meta.GlobalCfgDefn.WorkflowConfigurationMode;
|
import org.opends.server.admin.std.server.GlobalCfg;
|
import org.opends.server.admin.std.server.RootCfg;
|
import org.opends.server.api.AuthenticationPolicy;
|
import org.opends.server.config.ConfigException;
|
import org.opends.server.types.*;
|
|
import static org.opends.messages.ConfigMessages.*;
|
import static org.opends.server.util.ServerConstants.*;
|
|
/**
|
* This class defines a utility that will be used to manage the set of core
|
* configuration attributes defined in the Directory Server. These
|
* configuration attributes appear in the "cn=config" configuration entry.
|
*/
|
public class CoreConfigManager
|
implements ConfigurationChangeListener<GlobalCfg>
|
{
|
/**
|
* Creates a new instance of this core config manager.
|
*/
|
public CoreConfigManager()
|
{
|
// No implementation is required.
|
}
|
|
|
|
/**
|
* Initializes the Directory Server's core configuration. This should only be
|
* called at server startup.
|
*
|
* @throws ConfigException If a configuration problem causes the identity
|
* mapper initialization process to fail.
|
*
|
* @throws InitializationException If a problem occurs while initializing
|
* the identity mappers that is not related
|
* to the server configuration.
|
*/
|
public void initializeCoreConfig()
|
throws ConfigException, InitializationException
|
{
|
// Get the root configuration object.
|
ServerManagementContext managementContext =
|
ServerManagementContext.getInstance();
|
RootCfg rootConfiguration =
|
managementContext.getRootConfiguration();
|
|
|
// Get the global configuration and register with it as a change listener.
|
GlobalCfg globalConfig = rootConfiguration.getGlobalConfiguration();
|
globalConfig.addChangeListener(this);
|
|
|
// If there are any STMP servers specified, then make sure that if the value
|
// contains a colon that the portion after it is an integer between 1 and
|
// 65535.
|
Set<String> smtpServers = globalConfig.getSMTPServer();
|
if (smtpServers != null)
|
{
|
for (String server : smtpServers)
|
{
|
try
|
{
|
// validate provided string
|
HostPort.valueOf(server);
|
}
|
catch (RuntimeException e)
|
{
|
Message message = ERR_CONFIG_CORE_INVALID_SMTP_SERVER.get(server);
|
throw new ConfigException(message, e);
|
}
|
}
|
}
|
|
|
// Apply the configuration to the server.
|
applyGlobalConfiguration(globalConfig);
|
}
|
|
|
|
/**
|
* Applies the settings in the provided configuration to the Directory Server.
|
*
|
* @param globalConfig The configuration settings to be applied.
|
*/
|
private static void applyGlobalConfiguration(GlobalCfg globalConfig)
|
{
|
DirectoryServer.setCheckSchema(globalConfig.isCheckSchema());
|
|
DirectoryServer.setDefaultPasswordPolicyDN(
|
globalConfig.getDefaultPasswordPolicyDN());
|
|
DirectoryServer.setAddMissingRDNAttributes(
|
globalConfig.isAddMissingRDNAttributes());
|
|
DirectoryServer.setAllowAttributeNameExceptions(
|
globalConfig.isAllowAttributeNameExceptions());
|
|
switch (globalConfig.getInvalidAttributeSyntaxBehavior())
|
{
|
case ACCEPT:
|
DirectoryServer.setSyntaxEnforcementPolicy(AcceptRejectWarn.ACCEPT);
|
break;
|
case WARN:
|
DirectoryServer.setSyntaxEnforcementPolicy(AcceptRejectWarn.WARN);
|
break;
|
case REJECT:
|
default:
|
DirectoryServer.setSyntaxEnforcementPolicy(AcceptRejectWarn.REJECT);
|
break;
|
}
|
|
DirectoryServer.setServerErrorResultCode(
|
ResultCode.valueOf(globalConfig.getServerErrorResultCode()));
|
|
switch (globalConfig.getSingleStructuralObjectclassBehavior())
|
{
|
case ACCEPT:
|
DirectoryServer.setSingleStructuralObjectClassPolicy(
|
AcceptRejectWarn.ACCEPT);
|
break;
|
case WARN:
|
DirectoryServer.setSingleStructuralObjectClassPolicy(
|
AcceptRejectWarn.WARN);
|
break;
|
case REJECT:
|
default:
|
DirectoryServer.setSingleStructuralObjectClassPolicy(
|
AcceptRejectWarn.REJECT);
|
break;
|
}
|
|
DirectoryServer.setNotifyAbandonedOperations(
|
globalConfig.isNotifyAbandonedOperations());
|
|
DirectoryServer.setSizeLimit(globalConfig.getSizeLimit());
|
|
DirectoryServer.setTimeLimit((int) globalConfig.getTimeLimit());
|
|
DirectoryServer.setProxiedAuthorizationIdentityMapperDN(
|
globalConfig.getProxiedAuthorizationIdentityMapperDN());
|
|
switch (globalConfig.getWritabilityMode())
|
{
|
case ENABLED:
|
DirectoryServer.setWritabilityMode(WritabilityMode.ENABLED);
|
break;
|
case INTERNAL_ONLY:
|
DirectoryServer.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
|
break;
|
case DISABLED:
|
default:
|
DirectoryServer.setWritabilityMode(WritabilityMode.DISABLED);
|
break;
|
}
|
|
DirectoryServer.setRejectUnauthenticatedRequests(
|
globalConfig.isRejectUnauthenticatedRequests());
|
|
DirectoryServer.setBindWithDNRequiresPassword(
|
globalConfig.isBindWithDNRequiresPassword());
|
|
DirectoryServer.setLookthroughLimit(globalConfig.getLookthroughLimit());
|
|
|
List<Properties> mailServerProperties = new ArrayList<Properties>();
|
Set<String> smtpServers = globalConfig.getSMTPServer();
|
if ((smtpServers != null) && (! smtpServers.isEmpty()))
|
{
|
for (String smtpServer : smtpServers)
|
{
|
final Properties properties = new Properties();
|
try
|
{
|
final HostPort hp = HostPort.valueOf(smtpServer);
|
|
properties.setProperty(SMTP_PROPERTY_HOST, hp.getHost());
|
properties.setProperty(SMTP_PROPERTY_PORT,
|
String.valueOf(hp.getPort()));
|
properties.setProperty(SMTP_PROPERTY_CONNECTION_TIMEOUT,
|
SMTP_DEFAULT_TIMEOUT_VALUE);
|
properties.setProperty(SMTP_PROPERTY_IO_TIMEOUT,
|
SMTP_DEFAULT_TIMEOUT_VALUE);
|
}
|
catch (RuntimeException e)
|
{
|
// no valid port provided
|
properties.setProperty(SMTP_PROPERTY_HOST, smtpServer);
|
}
|
mailServerProperties.add(properties);
|
}
|
}
|
DirectoryServer.setMailServerPropertySets(mailServerProperties);
|
|
DirectoryServer.setAllowedTasks(globalConfig.getAllowedTask());
|
|
|
HashSet<Privilege> disabledPrivileges = new HashSet<Privilege>();
|
Set<GlobalCfgDefn.DisabledPrivilege> configuredDisabledPrivs =
|
globalConfig.getDisabledPrivilege();
|
if (configuredDisabledPrivs != null)
|
{
|
for (GlobalCfgDefn.DisabledPrivilege p : configuredDisabledPrivs)
|
{
|
switch (p)
|
{
|
case BACKEND_BACKUP:
|
disabledPrivileges.add(Privilege.BACKEND_BACKUP);
|
break;
|
case BACKEND_RESTORE:
|
disabledPrivileges.add(Privilege.BACKEND_RESTORE);
|
break;
|
case BYPASS_ACL:
|
disabledPrivileges.add(Privilege.BYPASS_ACL);
|
break;
|
case CANCEL_REQUEST:
|
disabledPrivileges.add(Privilege.CANCEL_REQUEST);
|
break;
|
case CONFIG_READ:
|
disabledPrivileges.add(Privilege.CONFIG_READ);
|
break;
|
case CONFIG_WRITE:
|
disabledPrivileges.add(Privilege.CONFIG_WRITE);
|
break;
|
case DATA_SYNC:
|
disabledPrivileges.add(Privilege.DATA_SYNC);
|
break;
|
case DISCONNECT_CLIENT:
|
disabledPrivileges.add(Privilege.DISCONNECT_CLIENT);
|
break;
|
case JMX_NOTIFY:
|
disabledPrivileges.add(Privilege.JMX_NOTIFY);
|
break;
|
case JMX_READ:
|
disabledPrivileges.add(Privilege.JMX_READ);
|
break;
|
case JMX_WRITE:
|
disabledPrivileges.add(Privilege.JMX_WRITE);
|
break;
|
case LDIF_EXPORT:
|
disabledPrivileges.add(Privilege.LDIF_EXPORT);
|
break;
|
case LDIF_IMPORT:
|
disabledPrivileges.add(Privilege.LDIF_IMPORT);
|
break;
|
case MODIFY_ACL:
|
disabledPrivileges.add(Privilege.MODIFY_ACL);
|
break;
|
case PASSWORD_RESET:
|
disabledPrivileges.add(Privilege.PASSWORD_RESET);
|
break;
|
case PRIVILEGE_CHANGE:
|
disabledPrivileges.add(Privilege.PRIVILEGE_CHANGE);
|
break;
|
case PROXIED_AUTH:
|
disabledPrivileges.add(Privilege.PROXIED_AUTH);
|
break;
|
case SERVER_RESTART:
|
disabledPrivileges.add(Privilege.SERVER_RESTART);
|
break;
|
case SERVER_SHUTDOWN:
|
disabledPrivileges.add(Privilege.SERVER_SHUTDOWN);
|
break;
|
case UNINDEXED_SEARCH:
|
disabledPrivileges.add(Privilege.UNINDEXED_SEARCH);
|
break;
|
case UPDATE_SCHEMA:
|
disabledPrivileges.add(Privilege.UPDATE_SCHEMA);
|
break;
|
case SUBENTRY_WRITE:
|
disabledPrivileges.add(Privilege.SUBENTRY_WRITE);
|
break;
|
}
|
}
|
}
|
DirectoryServer.setDisabledPrivileges(disabledPrivileges);
|
|
DirectoryServer.setReturnBindErrorMessages(
|
globalConfig.isReturnBindErrorMessages());
|
|
DirectoryServer.setIdleTimeLimit(globalConfig.getIdleTimeLimit());
|
|
DirectoryServer.setSaveConfigOnSuccessfulStartup(
|
globalConfig.isSaveConfigOnSuccessfulStartup());
|
|
// If the workflow configuration mode has changed then reconfigure
|
// the workflows-only if the server is running. If the server is not
|
// running (ie. the server is starting up) simply update the workflow
|
// configuration mode as the workflow configuration is processed
|
// elsewhere.
|
WorkflowConfigurationMode oldMode =
|
DirectoryServer.getWorkflowConfigurationMode();
|
WorkflowConfigurationMode newMode =
|
globalConfig.getWorkflowConfigurationMode();
|
if (DirectoryServer.isRunning())
|
{
|
DirectoryServer.reconfigureWorkflows(oldMode, newMode);
|
}
|
else
|
{
|
DirectoryServer.setWorkflowConfigurationMode(newMode);
|
}
|
|
DirectoryServer.setUseNanoTime(globalConfig.getEtimeResolution() ==
|
GlobalCfgDefn.EtimeResolution.NANOSECONDS);
|
|
DirectoryServer.setMaxAllowedConnections(
|
globalConfig.getMaxAllowedClientConnections());
|
|
DirectoryServer.setMaxPersistentSearchLimit(
|
globalConfig.getMaxPsearches());
|
|
DirectoryServer.setMaxInternalBufferSize((int) globalConfig
|
.getMaxInternalBufferSize());
|
}
|
|
|
/**
|
* {@inheritDoc}
|
*/
|
@Override
|
public boolean isConfigurationChangeAcceptable(GlobalCfg configuration,
|
List<Message> unacceptableReasons)
|
{
|
boolean configAcceptable = true;
|
|
Set<String> smtpServers = configuration.getSMTPServer();
|
if (smtpServers != null)
|
{
|
for (String server : smtpServers)
|
{
|
try
|
{
|
// validate provided string
|
HostPort.valueOf(server);
|
}
|
catch (RuntimeException e)
|
{
|
Message message = ERR_CONFIG_CORE_INVALID_SMTP_SERVER.get(server);
|
unacceptableReasons.add(message);
|
configAcceptable = false;
|
}
|
}
|
}
|
|
// Ensure that the default password policy always points to a password
|
// policy and not another type of authentication policy.
|
DN defaultPasswordPolicyDN = configuration.getDefaultPasswordPolicyDN();
|
AuthenticationPolicy policy = DirectoryServer
|
.getAuthenticationPolicy(defaultPasswordPolicyDN);
|
if (!policy.isPasswordPolicy())
|
{
|
Message message =
|
ERR_CONFIG_PWPOLICY_CANNOT_CHANGE_DEFAULT_POLICY_WRONG_TYPE
|
.get(configuration.getDefaultPasswordPolicy());
|
unacceptableReasons.add(message);
|
configAcceptable = false;
|
}
|
|
return configAcceptable;
|
}
|
|
|
|
/**
|
* {@inheritDoc}
|
*/
|
@Override
|
public ConfigChangeResult applyConfigurationChange(GlobalCfg configuration)
|
{
|
ResultCode resultCode = ResultCode.SUCCESS;
|
boolean adminActionRequired = false;
|
List<Message> messages = new ArrayList<Message>();
|
|
applyGlobalConfiguration(configuration);
|
|
return new ConfigChangeResult(resultCode, adminActionRequired, messages);
|
}
|
}
|