001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2006-2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.core;
028 import org.opends.messages.Message;
029
030 import java.util.ArrayList;
031 import java.util.List;
032
033 import org.opends.server.admin.server.ConfigurationChangeListener;
034 import org.opends.server.admin.std.server.PasswordPolicyCfg;
035 import org.opends.server.config.ConfigException;
036 import org.opends.server.types.ConfigChangeResult;
037 import org.opends.server.types.InitializationException;
038 import org.opends.server.types.ResultCode;
039
040 import static org.opends.server.loggers.debug.DebugLogger.*;
041 import org.opends.server.loggers.debug.DebugTracer;
042 import org.opends.server.types.DebugLogLevel;
043 import static org.opends.messages.CoreMessages.*;
044
045
046 /**
047 This class is the interface between the password policy configurable component
048 and a password policy state object. When a password policy entry is added to
049 the configuration, an instance of this class is created and registered to
050 manage subsequent modification to that configuration entry, including
051 valiadating any proposed modification and applying an accepted modification.
052 */
053 public class PasswordPolicyConfig
054 implements ConfigurationChangeListener<PasswordPolicyCfg>
055 {
056 /**
057 * The tracer object for the debug logger.
058 */
059 private static final DebugTracer TRACER = getTracer();
060
061
062 /**
063 * The password policy object corresponding to the configuration entry. The
064 * policy referenced by this field is assumed to be valid, hence any
065 * changes resulting from a modification of the configuration entry must be
066 * applied to a newly allocated instance and validated before updating this
067 * reference to point to the new policy instance.
068 */
069 private PasswordPolicy currentPolicy;
070
071
072 /**
073 * Creates a new password policy configurable component to manage the provided
074 * password policy object.
075 *
076 * @param policy The password policy object this object will manage.
077 */
078 public PasswordPolicyConfig(PasswordPolicy policy)
079 {
080 this.currentPolicy = policy;
081 }
082
083
084 /**
085 * {@inheritDoc}
086 */
087 public boolean isConfigurationChangeAcceptable(
088 PasswordPolicyCfg configuration, List<Message> unacceptableReasons)
089 {
090 assert configuration.dn().equals(this.currentPolicy.getConfigEntryDN() )
091 : "Internal Error: mismatch between DN of configuration entry and"
092 + "DN of current password policy." ;
093
094 try
095 {
096 new PasswordPolicy(configuration);
097 }
098 catch (ConfigException ce)
099 {
100 if (debugEnabled())
101 {
102 TRACER.debugCaught(DebugLogLevel.ERROR, ce);
103 }
104
105 unacceptableReasons.add(ce.getMessageObject());
106 return false;
107 }
108 catch (InitializationException ie)
109 {
110 if (debugEnabled())
111 {
112 TRACER.debugCaught(DebugLogLevel.ERROR, ie);
113 }
114
115 unacceptableReasons.add(ie.getMessageObject());
116 return false;
117 }
118
119 // If we made it here, then the configuration is acceptable.
120 return true;
121 }
122
123
124
125 /**
126 * {@inheritDoc}
127 */
128 public ConfigChangeResult applyConfigurationChange(
129 PasswordPolicyCfg configuration)
130 {
131 assert configuration.dn().equals(this.currentPolicy.getConfigEntryDN() )
132 : "Internal Error: mismatch between DN of configuration entry and"
133 + "DN of current password policy." ;
134
135 PasswordPolicy p;
136
137 try
138 {
139 p = new PasswordPolicy(configuration);
140 }
141 catch (ConfigException ce)
142 {
143 if (debugEnabled())
144 {
145 TRACER.debugCaught(DebugLogLevel.ERROR, ce);
146 }
147 ArrayList<Message> messages = new ArrayList<Message>();
148 messages.add(ce.getMessageObject());
149 return new ConfigChangeResult(
150 DirectoryServer.getServerErrorResultCode(),
151 /*adminActionRequired*/ true, messages);
152 }
153 catch (InitializationException ie)
154 {
155 if (debugEnabled())
156 {
157 TRACER.debugCaught(DebugLogLevel.ERROR, ie);
158 }
159 ArrayList<Message> messages = new ArrayList<Message>();
160 messages.add(ie.getMessageObject());
161 return new ConfigChangeResult(
162 DirectoryServer.getServerErrorResultCode(),
163 /*adminActionRequired*/ true, messages);
164 }
165
166 // If we've made it here, then everything is acceptable. Apply the new
167 // configuration.
168 ArrayList<Message> messages = new ArrayList<Message>();
169 messages.add(INFO_PWPOLICY_UPDATED_POLICY.get(
170 String.valueOf(p.getConfigEntryDN())));
171 this.currentPolicy = p;
172
173 return new ConfigChangeResult(ResultCode.SUCCESS,
174 /*adminActionRequired*/ false, messages);
175 }
176
177 /**
178 * Retrieves the PasswordPolicy object representing the configuration entry
179 * managed by this object.
180 *
181 * @return The PasswordPolicy object.
182 */
183 public PasswordPolicy getPolicy()
184 {
185 return currentPolicy;
186 }
187 }