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 }