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.extensions; 028 import org.opends.messages.Message; 029 030 031 032 import static org.opends.server.loggers.ErrorLogger.logError; 033 import static org.opends.messages.ExtensionMessages.*; 034 035 036 import java.util.ArrayList; 037 import java.util.HashSet; 038 import java.util.List; 039 040 import org.opends.server.admin.server.ConfigurationChangeListener; 041 import org.opends.server.admin.std.meta. 042 ErrorLogAccountStatusNotificationHandlerCfgDefn; 043 import org.opends.server.admin.std.server.AccountStatusNotificationHandlerCfg; 044 import org.opends.server.admin.std.server. 045 ErrorLogAccountStatusNotificationHandlerCfg; 046 import org.opends.server.api.AccountStatusNotificationHandler; 047 import org.opends.server.config.ConfigException; 048 import org.opends.server.types.AccountStatusNotification; 049 import org.opends.server.types.AccountStatusNotificationType; 050 import org.opends.server.types.ConfigChangeResult; 051 import org.opends.server.types.DN; 052 import org.opends.server.types.InitializationException; 053 import org.opends.server.types.ResultCode; 054 055 056 057 /** 058 * This class defines an account status notification handler that will write 059 * information about status notifications using the Directory Server's error 060 * logging facility. 061 */ 062 public class ErrorLogAccountStatusNotificationHandler 063 extends 064 AccountStatusNotificationHandler 065 <ErrorLogAccountStatusNotificationHandlerCfg> 066 implements 067 ConfigurationChangeListener 068 <ErrorLogAccountStatusNotificationHandlerCfg> 069 { 070 /** 071 * The set of names for the account status notification types that may be 072 * logged by this notification handler. 073 */ 074 private static final HashSet<String> NOTIFICATION_TYPE_NAMES = 075 new HashSet<String>(); 076 077 static 078 { 079 for (AccountStatusNotificationType t : 080 AccountStatusNotificationType.values()) 081 { 082 NOTIFICATION_TYPE_NAMES.add(t.getName()); 083 } 084 } 085 086 087 // The DN of the configuration entry for this notification handler. 088 private DN configEntryDN; 089 090 // The set of notification types that should generate log messages. 091 private HashSet<AccountStatusNotificationType> notificationTypes; 092 093 094 095 /** 096 * {@inheritDoc} 097 */ 098 public void initializeStatusNotificationHandler( 099 ErrorLogAccountStatusNotificationHandlerCfg configuration 100 ) 101 throws ConfigException, InitializationException 102 { 103 configuration.addErrorLogChangeListener (this); 104 configEntryDN = configuration.dn(); 105 106 // Read configuration and apply changes. 107 boolean applyChanges = true; 108 processNotificationHandlerConfig (configuration, applyChanges); 109 } 110 111 112 113 /** 114 * {@inheritDoc} 115 */ 116 public void handleStatusNotification( 117 AccountStatusNotification notification) 118 { 119 logError(NOTE_ERRORLOG_ACCTNOTHANDLER_NOTIFICATION.get( 120 notification.getNotificationType().getName(), 121 String.valueOf(notification.getUserDN()), 122 notification.getMessage().getDescriptor().getId(), 123 notification.getMessage())); 124 } 125 126 127 128 /** 129 * {@inheritDoc} 130 */ 131 @Override() 132 public boolean isConfigurationAcceptable( 133 AccountStatusNotificationHandlerCfg configuration, 134 List<Message> unacceptableReasons) 135 { 136 ErrorLogAccountStatusNotificationHandlerCfg config = 137 (ErrorLogAccountStatusNotificationHandlerCfg) configuration; 138 return isConfigurationChangeAcceptable(config, unacceptableReasons); 139 } 140 141 142 143 /** 144 * {@inheritDoc} 145 */ 146 public boolean isConfigurationChangeAcceptable( 147 ErrorLogAccountStatusNotificationHandlerCfg configuration, 148 List<Message> unacceptableReasons 149 ) 150 { 151 // Make sure that we can process the defined notification handler. 152 // If so, then we'll accept the new configuration. 153 boolean applyChanges = false; 154 boolean isAcceptable = processNotificationHandlerConfig ( 155 configuration, applyChanges 156 ); 157 158 return isAcceptable; 159 } 160 161 162 163 /** 164 * Makes a best-effort attempt to apply the configuration contained in the 165 * provided entry. Information about the result of this processing should be 166 * added to the provided message list. Information should always be added to 167 * this list if a configuration change could not be applied. If detailed 168 * results are requested, then information about the changes applied 169 * successfully (and optionally about parameters that were not changed) should 170 * also be included. 171 * 172 * @param configuration The entry containing the new configuration to 173 * apply for this component. 174 * @param detailedResults Indicates whether detailed information about the 175 * processing should be added to the list. 176 * 177 * @return Information about the result of the configuration update. 178 */ 179 public ConfigChangeResult applyConfigurationChange ( 180 ErrorLogAccountStatusNotificationHandlerCfg configuration, 181 boolean detailedResults 182 ) 183 { 184 ConfigChangeResult changeResult = applyConfigurationChange (configuration); 185 return changeResult; 186 } 187 188 189 190 /** 191 * {@inheritDoc} 192 */ 193 public ConfigChangeResult applyConfigurationChange ( 194 ErrorLogAccountStatusNotificationHandlerCfg configuration 195 ) 196 { 197 ResultCode resultCode = ResultCode.SUCCESS; 198 boolean adminActionRequired = false; 199 ArrayList<Message> messages = new ArrayList<Message>(); 200 ConfigChangeResult changeResult = new ConfigChangeResult( 201 resultCode, adminActionRequired, messages 202 ); 203 204 // Initialize the set of notification types that should generate log 205 // messages. 206 boolean applyChanges = false; 207 processNotificationHandlerConfig ( 208 configuration, applyChanges 209 ); 210 211 return changeResult; 212 } 213 214 215 /** 216 * Parses the provided configuration and configure the notification handler. 217 * 218 * @param configuration The new configuration containing the changes. 219 * @param applyChanges If true then take into account the new configuration. 220 * 221 * @return The mapping between strings of character set values and the 222 * minimum number of characters required from those sets. 223 */ 224 public boolean processNotificationHandlerConfig( 225 ErrorLogAccountStatusNotificationHandlerCfg configuration, 226 boolean applyChanges 227 ) 228 { 229 // false if the configuration is not acceptable 230 boolean isAcceptable = true; 231 232 // The set of notification types that should generate log messages. 233 HashSet<AccountStatusNotificationType> newNotificationTypes = 234 new HashSet<AccountStatusNotificationType>(); 235 236 // Initialize the set of notification types that should generate log 237 // messages. 238 for (ErrorLogAccountStatusNotificationHandlerCfgDefn. 239 AccountStatusNotificationType configNotificationType: 240 configuration.getAccountStatusNotificationType()) 241 { 242 newNotificationTypes.add (getNotificationType (configNotificationType)); 243 } 244 245 if (applyChanges && isAcceptable) 246 { 247 notificationTypes = newNotificationTypes; 248 } 249 250 return isAcceptable; 251 } 252 253 254 /** 255 * Gets the OpenDS notification type object that corresponds to the 256 * configuration counterpart. 257 * 258 * @param configNotificationType The configuration notification type for 259 * which to retrieve the OpenDS notification 260 * type. 261 */ 262 private AccountStatusNotificationType getNotificationType( 263 ErrorLogAccountStatusNotificationHandlerCfgDefn. 264 AccountStatusNotificationType configNotificationType 265 ) 266 { 267 AccountStatusNotificationType nt = null; 268 269 switch (configNotificationType) 270 { 271 case ACCOUNT_TEMPORARILY_LOCKED: 272 nt = AccountStatusNotificationType.ACCOUNT_TEMPORARILY_LOCKED; 273 break; 274 case ACCOUNT_PERMANENTLY_LOCKED: 275 nt = AccountStatusNotificationType.ACCOUNT_PERMANENTLY_LOCKED; 276 break; 277 case ACCOUNT_UNLOCKED: 278 nt = AccountStatusNotificationType.ACCOUNT_UNLOCKED; 279 break; 280 case ACCOUNT_IDLE_LOCKED: 281 nt = AccountStatusNotificationType.ACCOUNT_IDLE_LOCKED; 282 break; 283 case ACCOUNT_RESET_LOCKED: 284 nt = AccountStatusNotificationType.ACCOUNT_RESET_LOCKED; 285 break; 286 case ACCOUNT_DISABLED: 287 nt = AccountStatusNotificationType.ACCOUNT_DISABLED; 288 break; 289 case ACCOUNT_ENABLED: 290 nt = AccountStatusNotificationType.ACCOUNT_ENABLED; 291 break; 292 case ACCOUNT_EXPIRED: 293 nt = AccountStatusNotificationType.ACCOUNT_EXPIRED; 294 break; 295 case PASSWORD_EXPIRED: 296 nt = AccountStatusNotificationType.PASSWORD_EXPIRED; 297 break; 298 case PASSWORD_EXPIRING: 299 nt = AccountStatusNotificationType.PASSWORD_EXPIRING; 300 break; 301 case PASSWORD_RESET: 302 nt = AccountStatusNotificationType.PASSWORD_RESET; 303 break; 304 case PASSWORD_CHANGED: 305 nt = AccountStatusNotificationType.PASSWORD_CHANGED; 306 break; 307 } 308 309 return nt; 310 } 311 312 } 313