/* * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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-2012 ForgeRock AS. */ package org.opends.server.core; import org.opends.messages.Message; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Properties; import java.util.Set; import org.opends.server.admin.server.ConfigurationChangeListener; 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.admin.server.ServerManagementContext; 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) { int colonPos = server.indexOf(':'); if ((colonPos == 0) || (colonPos == (server.length()-1))) { Message message = ERR_CONFIG_CORE_INVALID_SMTP_SERVER.get(server); throw new ConfigException(message); } else if (colonPos > 0) { try { int port = Integer.parseInt(server.substring(colonPos+1)); if ((port < 1) || (port > 65535)) { Message message = ERR_CONFIG_CORE_INVALID_SMTP_SERVER.get(server); throw new ConfigException(message); } } catch (Exception 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()); ArrayList<Properties> mailServerProperties = new ArrayList<Properties>(); Set<String> smtpServers = globalConfig.getSMTPServer(); if ((smtpServers != null) && (! smtpServers.isEmpty())) { for (String smtpServer : smtpServers) { int colonPos = smtpServer.indexOf(':'); if (colonPos > 0) { String smtpHost = smtpServer.substring(0, colonPos); String smtpPort = smtpServer.substring(colonPos+1); Properties properties = new Properties(); properties.setProperty(SMTP_PROPERTY_HOST, smtpHost); properties.setProperty(SMTP_PROPERTY_PORT, smtpPort); properties.setProperty(SMTP_PROPERTY_CONNECTION_TIMEOUT, SMTP_DEFAULT_TIMEOUT_VALUE); properties.setProperty(SMTP_PROPERTY_IO_TIMEOUT, SMTP_DEFAULT_TIMEOUT_VALUE); mailServerProperties.add(properties); } else { Properties properties = new Properties(); 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} */ public boolean isConfigurationChangeAcceptable(GlobalCfg configuration, List<Message> unacceptableReasons) { boolean configAcceptable = true; Set<String> smtpServers = configuration.getSMTPServer(); if (smtpServers != null) { for (String server : smtpServers) { int colonPos = server.indexOf(':'); if ((colonPos == 0) || (colonPos == (server.length()-1))) { Message message = ERR_CONFIG_CORE_INVALID_SMTP_SERVER.get(server); unacceptableReasons.add(message); configAcceptable = false; } else if (colonPos > 0) { try { int port = Integer.parseInt(server.substring(colonPos+1)); if ((port < 1) || (port > 65535)) { Message message = ERR_CONFIG_CORE_INVALID_SMTP_SERVER.get(server); unacceptableReasons.add(message); configAcceptable = false; } } catch (Exception 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} */ public ConfigChangeResult applyConfigurationChange(GlobalCfg configuration) { ResultCode resultCode = ResultCode.SUCCESS; boolean adminActionRequired = false; ArrayList<Message> messages = new ArrayList<Message>(); applyGlobalConfiguration(configuration); return new ConfigChangeResult(resultCode, adminActionRequired, messages); } }