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 029 import org.opends.server.admin.ClassLoaderProvider; 030 import org.opends.server.admin.server.ServerManagementContext; 031 import org.opends.server.admin.std.meta.GlobalCfgDefn.WorkflowConfigurationMode; 032 import org.opends.server.admin.std.server.*; 033 import org.opends.server.api.AccountStatusNotificationHandler; 034 import org.opends.server.api.AlertGenerator; 035 import org.opends.server.api.AlertHandler; 036 import org.opends.server.api.ApproximateMatchingRule; 037 import org.opends.server.api.AttributeSyntax; 038 import org.opends.server.api.Backend; 039 import org.opends.server.api.BackendInitializationListener; 040 import org.opends.server.api.BackupTaskListener; 041 import org.opends.server.api.CertificateMapper; 042 import org.opends.server.api.ChangeNotificationListener; 043 import org.opends.server.api.ClientConnection; 044 import org.opends.server.api.CompressedSchema; 045 import org.opends.server.api.ConfigAddListener; 046 import org.opends.server.api.ConfigChangeListener; 047 import org.opends.server.api.ConfigDeleteListener; 048 import org.opends.server.api.ConfigHandler; 049 import org.opends.server.api.ConnectionHandler; 050 import org.opends.server.api.DirectoryServerMBean; 051 import org.opends.server.api.EntryCache; 052 import org.opends.server.api.EqualityMatchingRule; 053 import org.opends.server.api.ExportTaskListener; 054 import org.opends.server.api.ExtendedOperationHandler; 055 import org.opends.server.api.IdentityMapper; 056 import org.opends.server.api.ImportTaskListener; 057 import org.opends.server.api.InvokableComponent; 058 import org.opends.server.api.KeyManagerProvider; 059 import org.opends.server.api.MatchingRule; 060 import org.opends.server.api.MonitorProvider; 061 import org.opends.server.api.OrderingMatchingRule; 062 import org.opends.server.api.PasswordGenerator; 063 import org.opends.server.api.PasswordStorageScheme; 064 import org.opends.server.api.PasswordValidator; 065 import org.opends.server.api.RestoreTaskListener; 066 import org.opends.server.api.SASLMechanismHandler; 067 import org.opends.server.api.ServerShutdownListener; 068 import org.opends.server.api.SubstringMatchingRule; 069 import org.opends.server.api.SynchronizationProvider; 070 import org.opends.server.api.TrustManagerProvider; 071 import org.opends.server.api.WorkQueue; 072 import org.opends.server.api.AccessControlHandler; 073 import org.opends.server.api.plugin.PluginType; 074 import org.opends.server.api.plugin.PluginResult; 075 import org.opends.server.backends.RootDSEBackend; 076 import static org.opends.server.config.ConfigConstants.DN_MONITOR_ROOT; 077 import static org.opends.server.config.ConfigConstants.ENV_VAR_INSTANCE_ROOT; 078 import org.opends.server.config.ConfigEntry; 079 import org.opends.server.config.ConfigException; 080 import org.opends.server.config.JMXMBean; 081 import org.opends.server.controls.PasswordPolicyErrorType; 082 import org.opends.server.controls.PasswordPolicyResponseControl; 083 import org.opends.server.extensions.ConfigFileHandler; 084 import org.opends.server.extensions.JMXAlertHandler; 085 import static org.opends.server.loggers.AccessLogger.*; 086 import static org.opends.server.loggers.ErrorLogger.*; 087 import org.opends.server.loggers.*; 088 import static org.opends.server.loggers.debug.DebugLogger.*; 089 import org.opends.server.loggers.debug.DebugTracer; 090 import org.opends.server.loggers.debug.DebugLogger; 091 import org.opends.server.loggers.debug.TextDebugLogPublisher; 092 093 import org.opends.messages.MessageDescriptor; 094 import org.opends.messages.Message; 095 import static org.opends.messages.CoreMessages.*; 096 import static org.opends.messages.ToolMessages.*; 097 import org.opends.server.monitors.BackendMonitor; 098 import org.opends.server.monitors.ConnectionHandlerMonitor; 099 import org.opends.server.schema.AttributeTypeSyntax; 100 import org.opends.server.schema.BinarySyntax; 101 import org.opends.server.schema.BooleanEqualityMatchingRule; 102 import org.opends.server.schema.BooleanSyntax; 103 import org.opends.server.schema.CaseExactEqualityMatchingRule; 104 import org.opends.server.schema.CaseExactIA5EqualityMatchingRule; 105 import org.opends.server.schema.CaseExactIA5SubstringMatchingRule; 106 import org.opends.server.schema.CaseExactOrderingMatchingRule; 107 import org.opends.server.schema.CaseExactSubstringMatchingRule; 108 import org.opends.server.schema.CaseIgnoreEqualityMatchingRule; 109 import org.opends.server.schema.CaseIgnoreIA5EqualityMatchingRule; 110 import org.opends.server.schema.CaseIgnoreIA5SubstringMatchingRule; 111 import org.opends.server.schema.CaseIgnoreOrderingMatchingRule; 112 import org.opends.server.schema.CaseIgnoreSubstringMatchingRule; 113 import org.opends.server.schema.DirectoryStringSyntax; 114 import org.opends.server.schema.DistinguishedNameEqualityMatchingRule; 115 import org.opends.server.schema.DistinguishedNameSyntax; 116 import org.opends.server.schema.DoubleMetaphoneApproximateMatchingRule; 117 import org.opends.server.schema.GeneralizedTimeEqualityMatchingRule; 118 import org.opends.server.schema.GeneralizedTimeOrderingMatchingRule; 119 import org.opends.server.schema.GeneralizedTimeSyntax; 120 import org.opends.server.schema.IA5StringSyntax; 121 import org.opends.server.schema.IntegerEqualityMatchingRule; 122 import org.opends.server.schema.IntegerOrderingMatchingRule; 123 import org.opends.server.schema.IntegerSyntax; 124 import org.opends.server.schema.OIDSyntax; 125 import org.opends.server.schema.ObjectClassSyntax; 126 import org.opends.server.schema.ObjectIdentifierEqualityMatchingRule; 127 import org.opends.server.schema.OctetStringEqualityMatchingRule; 128 import org.opends.server.schema.OctetStringOrderingMatchingRule; 129 import org.opends.server.schema.OctetStringSubstringMatchingRule; 130 import static org.opends.server.schema.SchemaConstants.*; 131 import org.opends.server.schema.TelephoneNumberEqualityMatchingRule; 132 import org.opends.server.schema.TelephoneNumberSubstringMatchingRule; 133 import org.opends.server.schema.TelephoneNumberSyntax; 134 import org.opends.server.tools.ConfigureWindowsService; 135 import org.opends.server.types.AbstractOperation; 136 import org.opends.server.types.AcceptRejectWarn; 137 import org.opends.server.types.AttributeType; 138 import org.opends.server.types.AttributeUsage; 139 import org.opends.server.types.AttributeValue; 140 import org.opends.server.types.BackupConfig; 141 import org.opends.server.types.Control; 142 import org.opends.server.crypto.CryptoManagerImpl; 143 import org.opends.server.types.DITContentRule; 144 import org.opends.server.types.DITStructureRule; 145 import org.opends.server.types.DN; 146 import org.opends.server.types.DebugLogLevel; 147 import org.opends.server.types.DirectoryException; 148 import org.opends.server.types.Entry; 149 import org.opends.server.types.HostPort; 150 import org.opends.server.types.InitializationException; 151 import org.opends.server.types.LDIFExportConfig; 152 import org.opends.server.types.LDIFImportConfig; 153 import org.opends.server.types.MatchingRuleUse; 154 import org.opends.server.types.Modification; 155 import org.opends.server.types.NameForm; 156 import org.opends.server.types.ObjectClass; 157 import org.opends.server.types.ObjectClassType; 158 import org.opends.server.types.OperatingSystem; 159 import org.opends.server.types.OperationType; 160 import org.opends.server.types.Privilege; 161 import org.opends.server.types.RDN; 162 import org.opends.server.types.RestoreConfig; 163 import org.opends.server.types.ResultCode; 164 import org.opends.server.types.Schema; 165 import org.opends.server.types.VirtualAttributeRule; 166 import org.opends.server.types.WritabilityMode; 167 import org.opends.server.types.DirectoryEnvironmentConfig; 168 import org.opends.server.types.LockManager; 169 import static org.opends.server.util.DynamicConstants.*; 170 import static org.opends.server.util.ServerConstants.*; 171 import static org.opends.server.util.StaticUtils.*; 172 import static org.opends.server.util.Validator.ensureNotNull; 173 import org.opends.server.util.*; 174 import org.opends.server.util.args.ArgumentException; 175 import org.opends.server.util.args.ArgumentParser; 176 import org.opends.server.util.args.BooleanArgument; 177 import org.opends.server.util.args.StringArgument; 178 import org.opends.server.workflowelement.*; 179 import org.opends.server.workflowelement.localbackend.*; 180 import org.opends.server.protocols.internal.InternalConnectionHandler; 181 import org.opends.server.protocols.internal.InternalClientConnection; 182 import org.opends.server.crypto.CryptoManagerSync; 183 import static org.opends.messages.ConfigMessages.*; 184 185 import javax.management.MBeanServer; 186 import javax.management.MBeanServerFactory; 187 import java.io.File; 188 import java.io.FileOutputStream; 189 import java.io.IOException; 190 import java.io.OutputStream; 191 import java.io.PrintStream; 192 import java.net.InetAddress; 193 import java.text.DecimalFormat; 194 import java.util.*; 195 import java.util.concurrent.ConcurrentHashMap; 196 import java.util.concurrent.CopyOnWriteArrayList; 197 import java.util.concurrent.CopyOnWriteArraySet; 198 199 200 /** 201 * This class defines the core of the Directory Server. It manages the startup 202 * and shutdown processes and coordinates activities between all other 203 * components. 204 */ 205 public class DirectoryServer 206 implements Thread.UncaughtExceptionHandler, AlertGenerator 207 { 208 /** 209 * The tracer object for the debug logger. 210 */ 211 private static final DebugTracer TRACER = getTracer(); 212 213 /** 214 * The fully-qualified name of this class. 215 */ 216 private static final String CLASS_NAME = 217 "org.opends.server.core.DirectoryServer"; 218 219 220 /** 221 * The singleton Directory Server instance. 222 */ 223 private static DirectoryServer directoryServer = new DirectoryServer(); 224 225 226 227 /** 228 * Indicates whether the server currently holds an exclusive lock on the 229 * server lock fiie. 230 */ 231 private static boolean serverLocked = false; 232 233 234 /** 235 * Return codes used when the hidden option --checkStartability is used. 236 * NOTE: when checkstartability is specified is recommended not to allocate 237 * a lot of memory for the JVM (Using -Xms and -Xmx options) as there might 238 * be calls to Runtime.exec. 239 */ 240 /** 241 * Returned when the user specified the --checkStartability option with other 242 * options like printing the usage, dumping messages, displaying version, etc. 243 */ 244 private static int NOTHING_TO_DO = 0; 245 /** 246 * Returned when the user specified the --checkStartability option with 247 * some incompatible arguments. 248 */ 249 private static int CHECK_ERROR = 1; 250 /** 251 * The server is already started. 252 */ 253 private static int SERVER_ALREADY_STARTED = 98; 254 /** 255 * The server must be started as detached process. 256 */ 257 private static int START_AS_DETACH = 99; 258 /** 259 * The server must be started as a non-detached process. 260 */ 261 private static int START_AS_NON_DETACH = 100; 262 /** 263 * The server must be started as a window service. 264 */ 265 private static int START_AS_WINDOWS_SERVICE = 101; 266 /** 267 * The server must be started as detached and it is being called from the 268 * Windows Service. 269 */ 270 private static int START_AS_DETACH_CALLED_FROM_WINDOWS_SERVICE = 102; 271 /** 272 * The server must be started as detached process and should not produce any 273 * output. 274 */ 275 private static int START_AS_DETACH_QUIET = 103; 276 277 // The policy to use regarding single structural objectclass enforcement. 278 private AcceptRejectWarn singleStructuralClassPolicy; 279 280 // The policy to use regarding syntax enforcement. 281 private AcceptRejectWarn syntaxEnforcementPolicy; 282 283 // The account status notification handler config manager for the server. 284 private AccountStatusNotificationHandlerConfigManager 285 accountStatusNotificationHandlerConfigManager; 286 287 // The default syntax to use for binary attributes. 288 private AttributeSyntax<AttributeSyntaxCfg> defaultBinarySyntax; 289 290 // The default syntax to use for Boolean attributes. 291 private AttributeSyntax<AttributeSyntaxCfg> defaultBooleanSyntax; 292 293 // The default syntax to use for DN attributes. 294 private AttributeSyntax<AttributeSyntaxCfg> defaultDNSyntax; 295 296 // The default syntax to use for integer attributes. 297 private AttributeSyntax<AttributeSyntaxCfg> defaultIntegerSyntax; 298 299 // The default syntax to use for string attributes. 300 private AttributeSyntax<DirectoryStringAttributeSyntaxCfg> 301 defaultStringSyntax; 302 303 // The default attribute syntax to use for attributes with no defined syntax. 304 private AttributeSyntax<DirectoryStringAttributeSyntaxCfg> defaultSyntax; 305 306 // The attribute type used to reference the "objectclass" attribute. 307 private AttributeType objectClassAttributeType; 308 309 // The authenticated users manager for the server. 310 private AuthenticatedUsers authenticatedUsers; 311 312 // The configuration manager that will handle the server backends. 313 private BackendConfigManager backendConfigManager; 314 315 // Indicates whether to automatically add missing RDN attributes to entries 316 // during an add request. 317 private boolean addMissingRDNAttributes; 318 319 // Indicates whether to allow attribute name exceptions (i.e., attribute names 320 // can contain underscores and may start with a digit). 321 private boolean allowAttributeNameExceptions; 322 323 // Indicates whether a simple bind request containing a DN must also provide a 324 // password. 325 private boolean bindWithDNRequiresPassword; 326 327 // Indicates whether the Directory Server should perform schema checking for 328 // update operations. 329 private boolean checkSchema; 330 331 // Indicates whether the server has been bootstrapped. 332 private boolean isBootstrapped; 333 334 // Indicates whether the server has been bootstrapped for client use. 335 private boolean isClientBootstrapped; 336 337 // Indicates whether the server is currently online. 338 private boolean isRunning; 339 340 // Indicates whether the server is currently in "lockdown mode". 341 private boolean lockdownMode; 342 343 // Indicates whether the server should send a response to operations that have 344 // been abandoned. 345 private boolean notifyAbandonedOperations; 346 347 // Indicates whether to save a copy of the configuration on successful 348 // startup. 349 private boolean saveConfigOnSuccessfulStartup; 350 351 // Indicates whether the server is currently in the process of shutting down. 352 private boolean shuttingDown; 353 354 // Indicates whether the server should reject unauthenticated requests. 355 private boolean rejectUnauthenticatedRequests; 356 357 // Indicates whether bind responses should include failure reason messages. 358 private boolean returnBindErrorMessages; 359 360 // The configuration manager that will handle the certificate mapper. 361 private CertificateMapperConfigManager certificateMapperConfigManager; 362 363 // The class used to provide the config handler implementation. 364 private Class configClass; 365 366 // The configuration handler for the Directory Server. 367 private ConfigHandler configHandler; 368 369 // The set of account status notification handlers defined in the server. 370 private ConcurrentHashMap<DN,AccountStatusNotificationHandler> 371 accountStatusNotificationHandlers; 372 373 // The set of certificate mappers registered with the server. 374 private ConcurrentHashMap<DN,CertificateMapper> certificateMappers; 375 376 // The set of alternate bind DNs for the root users. 377 private ConcurrentHashMap<DN,DN> alternateRootBindDNs; 378 379 // The set of identity mappers registered with the server (mapped between 380 // the configuration entry Dn and the mapper). 381 private ConcurrentHashMap<DN,IdentityMapper> identityMappers; 382 383 // The set of JMX MBeans that have been registered with the server (mapped 384 // between the associated configuration entry DN and the MBean). 385 private ConcurrentHashMap<DN,JMXMBean> mBeans; 386 387 // The set of key manager providers registered with the server. 388 private ConcurrentHashMap<DN,KeyManagerProvider> keyManagerProviders; 389 390 // The set of password generators registered with the Directory Server, as a 391 // mapping between the DN of the associated configuration entry and the 392 // generator implementation. 393 private ConcurrentHashMap<DN,PasswordGenerator> passwordGenerators; 394 395 // The set of password policies registered with the Directory Server, as a 396 // mapping between the DN of the associated configuration entry and the policy 397 // implementation. 398 private ConcurrentHashMap<DN,PasswordPolicyConfig> passwordPolicies; 399 400 // The set of password validators registered with the Directory Server, as a 401 // mapping between the DN of the associated configuration entry and the 402 // validator implementation. 403 private ConcurrentHashMap<DN, 404 PasswordValidator<? extends PasswordValidatorCfg>> 405 passwordValidators; 406 407 // The set of trust manager providers registered with the server. 408 private ConcurrentHashMap<DN,TrustManagerProvider> trustManagerProviders; 409 410 // The set of log rotation policies registered with the Directory Server, as 411 // a mapping between the DN of the associated configuration entry and the 412 // policy implementation. 413 private ConcurrentHashMap<DN, RotationPolicy> rotationPolicies; 414 415 // The set of log retention policies registered with the Directory Server, as 416 // a mapping between the DN of the associated configuration entry and the 417 // policy implementation. 418 private ConcurrentHashMap<DN, RetentionPolicy> retentionPolicies; 419 420 // The set supported LDAP protocol versions. 421 private ConcurrentHashMap<Integer,List<ConnectionHandler>> 422 supportedLDAPVersions; 423 424 // The set of extended operation handlers registered with the server (mapped 425 // between the OID of the extended operation and the handler). 426 private ConcurrentHashMap<String,ExtendedOperationHandler> 427 extendedOperationHandlers; 428 429 // The set of monitor providers registered with the Directory Server, as a 430 // mapping between the monitor name and the corresponding implementation. 431 private ConcurrentHashMap<String, 432 MonitorProvider<? extends MonitorProviderCfg>> 433 monitorProviders; 434 435 // The set of password storage schemes defined in the server (mapped between 436 // the lowercase scheme name and the storage scheme) that support the 437 // authentication password syntax. 438 private ConcurrentHashMap<String,PasswordStorageScheme> 439 authPasswordStorageSchemes; 440 441 // The set of password storage schemes defined in the server (mapped between 442 // the lowercase scheme name and the storage scheme). 443 private ConcurrentHashMap<String,PasswordStorageScheme> 444 passwordStorageSchemes; 445 446 // The set of password storage schemes defined in the server (mapped between 447 // the DN of the configuration entry and the storage scheme). 448 private ConcurrentHashMap<DN,PasswordStorageScheme> 449 passwordStorageSchemesByDN; 450 451 // The set of SASL mechanism handlers registered with the server (mapped 452 // between the mechanism name and the handler). 453 private ConcurrentHashMap<String,SASLMechanismHandler> saslMechanismHandlers; 454 455 // The connection handler configuration manager for the Directory Server. 456 private ConnectionHandlerConfigManager connectionHandlerConfigManager; 457 458 // The set of alert handlers registered with the Directory Server. 459 private CopyOnWriteArrayList<AlertHandler> alertHandlers; 460 461 // The set of backup task listeners registered with the Directory Server. 462 private CopyOnWriteArrayList<BackupTaskListener> backupTaskListeners; 463 464 // The set of change notification listeners registered with the Directory 465 // Server. 466 private CopyOnWriteArrayList<ChangeNotificationListener> 467 changeNotificationListeners; 468 469 // The set of connection handlers registered with the Directory Server. 470 private CopyOnWriteArrayList<ConnectionHandler> connectionHandlers; 471 472 // The set of export task listeners registered with the Directory Server. 473 private CopyOnWriteArrayList<ExportTaskListener> exportTaskListeners; 474 475 // The set of import task listeners registered with the Directory Server. 476 private CopyOnWriteArrayList<ImportTaskListener> importTaskListeners; 477 478 // The set of persistent searches registered with the Directory Server. 479 private CopyOnWriteArrayList<PersistentSearch> persistentSearches; 480 481 // The set of restore task listeners registered with the Directory Server. 482 private CopyOnWriteArrayList<RestoreTaskListener> restoreTaskListeners; 483 484 // The set of shutdown listeners that have been registered with the Directory 485 // Server. 486 private CopyOnWriteArrayList<ServerShutdownListener> shutdownListeners; 487 488 // The set of synchronization providers that have been registered with the 489 // Directory Server. 490 private 491 CopyOnWriteArrayList<SynchronizationProvider<SynchronizationProviderCfg>> 492 synchronizationProviders; 493 494 // The set of virtual attributes defined in the server. 495 private CopyOnWriteArrayList<VirtualAttributeRule> virtualAttributes; 496 497 // The set of backend initialization listeners registered with the Directory 498 // Server. 499 private CopyOnWriteArraySet<BackendInitializationListener> 500 backendInitializationListeners; 501 502 // The set of root DNs registered with the Directory Server. 503 private CopyOnWriteArraySet<DN> rootDNs; 504 505 // The core configuration manager for the Directory Server. 506 private CoreConfigManager coreConfigManager; 507 508 // The crypto manager for the Directory Server. 509 private CryptoManagerImpl cryptoManager; 510 511 // The default compressed schema manager. 512 private DefaultCompressedSchema compressedSchema; 513 514 // The environment configuration for the Directory Server. 515 private DirectoryEnvironmentConfig environmentConfig; 516 517 // The shutdown hook that has been registered with the server. 518 private DirectoryServerShutdownHook shutdownHook; 519 520 // The DN of the default password policy configuration entry. 521 private DN defaultPasswordPolicyDN; 522 523 // The DN of the identity mapper that will be used to resolve authorization 524 // IDs contained in the proxied authorization V2 control. 525 private DN proxiedAuthorizationIdentityMapperDN; 526 527 // The DN of the entry containing the server schema definitions. 528 private DN schemaDN; 529 530 // The Directory Server entry cache. 531 private EntryCache entryCache; 532 533 // The configuration manager for the entry cache. 534 private EntryCacheConfigManager entryCacheConfigManager; 535 536 // The configuration manager for extended operation handlers. 537 private ExtendedOperationConfigManager extendedOperationConfigManager; 538 539 // The path to the file containing the Directory Server configuration, or the 540 // information needed to bootstrap the configuration handler. 541 private File configFile; 542 543 // The group manager for the Directory Server. 544 private GroupManager groupManager; 545 546 // The configuration manager for identity mappers. 547 private IdentityMapperConfigManager identityMapperConfigManager; 548 549 // The maximum number of entries that should be returned for a search unless 550 // overridden on a per-user basis. 551 private int sizeLimit; 552 553 // The maximum length of time in seconds that should be allowed for a search 554 // unless overridden on a per-user basis. 555 private int timeLimit; 556 557 // The maxiumum number of candidates that should be check for matches during 558 // a search. 559 private int lookthroughLimit; 560 561 // Whether to use collect operation processing times in nanosecond resolution 562 private boolean useNanoTime; 563 564 // The key manager provider configuration manager for the Directory Server. 565 private KeyManagerProviderConfigManager keyManagerProviderConfigManager; 566 567 // The set of connections that are currently established. 568 private LinkedHashSet<ClientConnection> establishedConnections; 569 570 // The sets of mail server properties 571 private List<Properties> mailServerPropertySets; 572 573 // The set of schema changes made by editing the schema configuration files 574 // with the server offline. 575 private List<Modification> offlineSchemaChanges; 576 577 // The log rotation policy config manager for the Directory Server. 578 private LogRotationPolicyConfigManager rotationPolicyConfigManager; 579 580 // The log retention policy config manager for the Directory Server. 581 private LogRetentionPolicyConfigManager retentionPolicyConfigManager; 582 583 // The logger configuration manager for the Directory Server. 584 private LoggerConfigManager loggerConfigManager; 585 586 // The number of connections currently established to the server. 587 private long currentConnections; 588 589 // The idle time limit for the server. 590 private long idleTimeLimit; 591 592 // The maximum number of connections that will be allowed at any given time. 593 private long maxAllowedConnections; 594 595 // The maximum number of connections established at one time. 596 private long maxConnections; 597 598 // The time that this Directory Server instance was started. 599 private long startUpTime; 600 601 // The total number of connections established since startup. 602 private long totalConnections; 603 604 // The MBean server used to handle JMX interaction. 605 private MBeanServer mBeanServer; 606 607 // The monitor config manager for the Directory Server. 608 private MonitorConfigManager monitorConfigManager; 609 610 // The operating system on which the server is running. 611 private OperatingSystem operatingSystem; 612 613 // The configuration handler used to manage the password generators. 614 private PasswordGeneratorConfigManager passwordGeneratorConfigManager; 615 616 // The default password policy for the Directory Server. 617 private PasswordPolicyConfig defaultPasswordPolicyConfig; 618 619 // The configuration handler used to manage the password policies. 620 private PasswordPolicyConfigManager passwordPolicyConfigManager; 621 622 // The configuration handler used to manage the password storage schemes. 623 private PasswordStorageSchemeConfigManager storageSchemeConfigManager; 624 625 // The configuration handler used to manage the password validators. 626 private PasswordValidatorConfigManager passwordValidatorConfigManager; 627 628 // The plugin config manager for the Directory Server. 629 private PluginConfigManager pluginConfigManager; 630 631 // The result code that should be used for internal "server" errors. 632 private ResultCode serverErrorResultCode; 633 634 // The special backend used for the Directory Server root DSE. 635 private RootDSEBackend rootDSEBackend; 636 637 // The root DN config manager for the server. 638 private RootDNConfigManager rootDNConfigManager; 639 640 // The SASL mechanism config manager for the Directory Server. 641 private SASLConfigManager saslConfigManager; 642 643 // The schema for the Directory Server. 644 private Schema schema; 645 646 // The schema configuration manager for the Directory Server. 647 private SchemaConfigManager schemaConfigManager; 648 649 // The set of disabled privileges. 650 private Set<Privilege> disabledPrivileges; 651 652 // The set of allowed task classes. 653 private Set<String> allowedTasks; 654 655 // The time that the server was started, formatted in UTC time. 656 private String startTimeUTC; 657 658 // The synchronization provider configuration manager for the Directory 659 // Server. 660 private SynchronizationProviderConfigManager 661 synchronizationProviderConfigManager; 662 663 // The thread group for all threads associated with the Directory Server. 664 private ThreadGroup directoryThreadGroup; 665 666 667 // Registry for base DN and naming context information. 668 private BaseDnRegistry baseDnRegistry; 669 670 671 // The set of backends registered with the server. 672 private TreeMap<String,Backend> backends; 673 674 // The mapping between backends and their unique indentifiers for their 675 // offline state, representing either checksum or other unique value to 676 // be used for detecting any offline modifications to a given backend. 677 private ConcurrentHashMap<String,Long> offlineBackendsStateIDs; 678 679 // The set of supported controls registered with the Directory Server. 680 private TreeSet<String> supportedControls; 681 682 // The set of supported feature OIDs registered with the Directory Server. 683 private TreeSet<String> supportedFeatures; 684 685 // The trust manager provider configuration manager for the Directory Server. 686 private TrustManagerProviderConfigManager trustManagerProviderConfigManager; 687 688 // The virtual attribute provider configuration manager for the Directory 689 // Server. 690 private VirtualAttributeConfigManager virtualAttributeConfigManager; 691 692 // The work queue that will be used to service client requests. 693 private WorkQueue workQueue; 694 695 // The writability mode for the Directory Server. 696 private WritabilityMode writabilityMode; 697 698 // The workflow configuration mode (auto or manual). 699 private WorkflowConfigurationMode workflowConfigurationMode; 700 701 // The network group config manager for the Directory Server. 702 // This config manager is used when the workflow configuration 703 // mode is 'manual'. 704 private NetworkGroupConfigManager networkGroupConfigManager; 705 706 // The workflow config manager for the Directory Server. 707 // This config manager is used when the workflow configuration 708 // mode is 'manual'. 709 private WorkflowConfigManager workflowConfigManager; 710 711 // The workflow element config manager for the Directory Server. 712 // This config manager is used when the workflow configuration 713 // mode is 'manual'. 714 private WorkflowElementConfigManager workflowElementConfigManager; 715 716 717 718 /** 719 * Creates a new instance of the Directory Server. This will allow only a 720 * single instance of the server per JVM. 721 */ 722 private DirectoryServer() 723 { 724 this(new DirectoryEnvironmentConfig()); 725 } 726 727 728 729 /** 730 * Creates a new instance of the Directory Server. This will allow only a 731 * single instance of the server per JVM. 732 * 733 * @param config The environment configuration to use for the Directory 734 * Server instance. 735 */ 736 private DirectoryServer(DirectoryEnvironmentConfig config) 737 { 738 environmentConfig = config; 739 isBootstrapped = false; 740 isClientBootstrapped = false; 741 isRunning = false; 742 shuttingDown = false; 743 lockdownMode = false; 744 serverErrorResultCode = ResultCode.OTHER; 745 746 operatingSystem = OperatingSystem.forName(System.getProperty("os.name")); 747 } 748 749 750 751 /** 752 * Retrieves the instance of the Directory Server that is associated with this 753 * JVM. 754 * 755 * @return The instance of the Directory Server that is associated with this 756 * JVM. 757 */ 758 public static DirectoryServer getInstance() 759 { 760 return directoryServer; 761 } 762 763 764 765 /** 766 * Creates a new instance of the Directory Server and replaces the static 767 * reference to it. This should only be used in the context of an in-core 768 * restart after the existing server has been shut down. 769 * 770 * @param config The environment configuration for the Directory Server. 771 * 772 * @return The new instance of the Directory Server that is associated with 773 * this JVM. 774 */ 775 private static DirectoryServer 776 getNewInstance(DirectoryEnvironmentConfig config) 777 { 778 synchronized (directoryServer) 779 { 780 return directoryServer = new DirectoryServer(config); 781 } 782 } 783 784 785 786 /** 787 * Retrieves the environment configuration for the Directory Server. 788 * 789 * @return The environment configuration for the Directory Server. 790 */ 791 public static DirectoryEnvironmentConfig getEnvironmentConfig() 792 { 793 return directoryServer.environmentConfig; 794 } 795 796 797 798 /** 799 * Sets the environment configuration for the Directory Server. This method 800 * may only be invoked when the server is not running. 801 * 802 * @param config The environment configuration for the Directory Server. 803 * 804 * @throws InitializationException If the Directory Server is currently 805 * running. 806 */ 807 public void setEnvironmentConfig(DirectoryEnvironmentConfig config) 808 throws InitializationException 809 { 810 if (isRunning) 811 { 812 throw new InitializationException( 813 ERR_CANNOT_SET_ENVIRONMENT_CONFIG_WHILE_RUNNING.get()); 814 } 815 816 environmentConfig = config; 817 } 818 819 820 821 /** 822 * Indicates whether the Directory Server is currently running. 823 * 824 * @return {@code true} if the server is currently running, or {@code false} 825 * if not. 826 */ 827 public static boolean isRunning() 828 { 829 return directoryServer.isRunning; 830 } 831 832 833 834 /** 835 * Bootstraps the appropriate Directory Server structures that may be needed 836 * by client-side tools. This is not intended for use in running the server 837 * itself. 838 */ 839 public static void bootstrapClient() 840 { 841 synchronized (directoryServer) 842 { 843 if (directoryServer.isClientBootstrapped) 844 { 845 return; 846 } 847 848 849 // Set default values for variables that may be needed during schema 850 // processing. 851 directoryServer.syntaxEnforcementPolicy = AcceptRejectWarn.REJECT; 852 853 854 // Create the server schema and initialize and register a minimal set of 855 // matching rules and attribute syntaxes. 856 directoryServer.schema = new Schema(); 857 directoryServer.bootstrapMatchingRules(); 858 directoryServer.bootstrapAttributeSyntaxes(); 859 860 861 // Perform any additional initialization that might be necessary before 862 // loading the configuration. 863 directoryServer.alertHandlers = new CopyOnWriteArrayList<AlertHandler>(); 864 directoryServer.passwordStorageSchemes = 865 new ConcurrentHashMap<String,PasswordStorageScheme>(); 866 directoryServer.passwordStorageSchemesByDN = 867 new ConcurrentHashMap<DN,PasswordStorageScheme>(); 868 directoryServer.passwordGenerators = 869 new ConcurrentHashMap<DN,PasswordGenerator>(); 870 directoryServer.authPasswordStorageSchemes = 871 new ConcurrentHashMap<String,PasswordStorageScheme>(); 872 directoryServer.passwordValidators = 873 new ConcurrentHashMap<DN, 874 PasswordValidator<? extends PasswordValidatorCfg>>(); 875 directoryServer.accountStatusNotificationHandlers = 876 new ConcurrentHashMap<DN,AccountStatusNotificationHandler>(); 877 directoryServer.rootDNs = new CopyOnWriteArraySet<DN>(); 878 directoryServer.alternateRootBindDNs = new ConcurrentHashMap<DN,DN>(); 879 directoryServer.keyManagerProviders = 880 new ConcurrentHashMap<DN,KeyManagerProvider>(); 881 directoryServer.trustManagerProviders = 882 new ConcurrentHashMap<DN,TrustManagerProvider>(); 883 directoryServer.rotationPolicies = 884 new ConcurrentHashMap<DN, RotationPolicy>(); 885 directoryServer.retentionPolicies = 886 new ConcurrentHashMap<DN, RetentionPolicy>(); 887 directoryServer.certificateMappers = 888 new ConcurrentHashMap<DN,CertificateMapper>(); 889 directoryServer.passwordPolicies = 890 new ConcurrentHashMap<DN,PasswordPolicyConfig>(); 891 directoryServer.defaultPasswordPolicyDN = null; 892 directoryServer.defaultPasswordPolicyConfig = null; 893 directoryServer.monitorProviders = 894 new ConcurrentHashMap<String, 895 MonitorProvider<? extends MonitorProviderCfg>>(); 896 directoryServer.backends = new TreeMap<String,Backend>(); 897 directoryServer.offlineBackendsStateIDs = 898 new ConcurrentHashMap<String,Long>(); 899 directoryServer.backendInitializationListeners = 900 new CopyOnWriteArraySet<BackendInitializationListener>(); 901 directoryServer.baseDnRegistry = new BaseDnRegistry(); 902 directoryServer.changeNotificationListeners = 903 new CopyOnWriteArrayList<ChangeNotificationListener>(); 904 directoryServer.persistentSearches = 905 new CopyOnWriteArrayList<PersistentSearch>(); 906 directoryServer.shutdownListeners = 907 new CopyOnWriteArrayList<ServerShutdownListener>(); 908 directoryServer.synchronizationProviders = 909 new CopyOnWriteArrayList<SynchronizationProvider 910 <SynchronizationProviderCfg>>(); 911 directoryServer.supportedControls = new TreeSet<String>(); 912 directoryServer.supportedFeatures = new TreeSet<String>(); 913 directoryServer.supportedLDAPVersions = 914 new ConcurrentHashMap<Integer,List<ConnectionHandler>>(); 915 directoryServer.virtualAttributes = 916 new CopyOnWriteArrayList<VirtualAttributeRule>(); 917 directoryServer.connectionHandlers = 918 new CopyOnWriteArrayList<ConnectionHandler>(); 919 directoryServer.identityMappers = 920 new ConcurrentHashMap<DN,IdentityMapper>(); 921 directoryServer.extendedOperationHandlers = 922 new ConcurrentHashMap<String,ExtendedOperationHandler>(); 923 directoryServer.saslMechanismHandlers = 924 new ConcurrentHashMap<String,SASLMechanismHandler>(); 925 directoryServer.authenticatedUsers = new AuthenticatedUsers(); 926 directoryServer.offlineSchemaChanges = new LinkedList<Modification>(); 927 directoryServer.backupTaskListeners = 928 new CopyOnWriteArrayList<BackupTaskListener>(); 929 directoryServer.restoreTaskListeners = 930 new CopyOnWriteArrayList<RestoreTaskListener>(); 931 directoryServer.exportTaskListeners = 932 new CopyOnWriteArrayList<ExportTaskListener>(); 933 directoryServer.importTaskListeners = 934 new CopyOnWriteArrayList<ImportTaskListener>(); 935 directoryServer.allowedTasks = new LinkedHashSet<String>(0); 936 directoryServer.disabledPrivileges = new LinkedHashSet<Privilege>(0); 937 directoryServer.returnBindErrorMessages = false; 938 directoryServer.idleTimeLimit = 0L; 939 } 940 } 941 942 943 944 /** 945 * Bootstraps the Directory Server by initializing all the necessary 946 * structures that should be in place before the configuration may be read. 947 * This step must be completed before the server may be started or the 948 * configuration is loaded, but it will not be allowed while the server is 949 * running. 950 * 951 * @throws InitializationException If a problem occurs while attempting to 952 * bootstrap the server. 953 */ 954 public void bootstrapServer() 955 throws InitializationException 956 { 957 // First, make sure that the server isn't currently running. If it isn't, 958 // then make sure that no other thread will try to start or bootstrap the 959 // server before this thread is done. 960 synchronized (directoryServer) 961 { 962 if (isRunning) 963 { 964 Message message = ERR_CANNOT_BOOTSTRAP_WHILE_RUNNING.get(); 965 throw new InitializationException(message); 966 } 967 968 isBootstrapped = false; 969 shuttingDown = false; 970 } 971 972 973 // Create the thread group that should be used for all Directory Server 974 // threads. 975 directoryThreadGroup = new ThreadGroup("Directory Server Thread Group"); 976 977 978 // Add a shutdown hook so that the server can be notified when the JVM 979 // starts shutting down. 980 shutdownHook = new DirectoryServerShutdownHook(); 981 Runtime.getRuntime().addShutdownHook(shutdownHook); 982 983 984 // Register this class as the default uncaught exception handler for the 985 // JVM. The uncaughtException method will be called if a thread dies 986 // because it did not properly handle an exception. 987 Thread.setDefaultUncaughtExceptionHandler(this); 988 989 990 // Create the MBean server that we will use for JMX interaction. 991 initializeJMX(); 992 993 994 logError(INFO_DIRECTORY_BOOTSTRAPPING.get()); 995 996 997 // Perform all the bootstrapping that is shared with the client-side 998 // processing. 999 bootstrapClient(); 1000 1001 1002 // Initialize the variables that will be used for connection tracking. 1003 establishedConnections = new LinkedHashSet<ClientConnection>(1000); 1004 currentConnections = 0; 1005 maxConnections = 0; 1006 totalConnections = 0; 1007 1008 1009 // Create the plugin config manager, but don't initialize it yet. This will 1010 // make it possible to process internal operations before the plugins have 1011 // been loaded. 1012 pluginConfigManager = new PluginConfigManager(); 1013 1014 1015 // If we have gotten here, then the configuration should be properly 1016 // bootstrapped. 1017 synchronized (directoryServer) 1018 { 1019 isBootstrapped = true; 1020 } 1021 } 1022 1023 1024 1025 /** 1026 * Performs a minimal set of JMX initialization. This may be used by the core 1027 * Directory Server or by command-line tools. 1028 * 1029 * @throws InitializationException If a problem occurs while attempting to 1030 * initialize the JMX subsystem. 1031 */ 1032 public static void initializeJMX() 1033 throws InitializationException 1034 { 1035 try 1036 { 1037 // FIXME -- Should we use the plaform Mbean Server or 1038 // should we use a private one ? 1039 directoryServer.mBeanServer = MBeanServerFactory.newMBeanServer(); 1040 // directoryServer.mBeanServer = 1041 // ManagementFactory.getPlatformMBeanServer(); 1042 1043 directoryServer.mBeans = new ConcurrentHashMap<DN,JMXMBean>(); 1044 registerAlertGenerator(directoryServer); 1045 } 1046 catch (Exception e) 1047 { 1048 if (debugEnabled()) 1049 { 1050 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1051 } 1052 1053 Message message = ERR_CANNOT_CREATE_MBEAN_SERVER.get(String.valueOf(e)); 1054 throw new InitializationException(message, e); 1055 } 1056 } 1057 1058 1059 1060 /** 1061 * Instantiates the configuration handler and loads the Directory Server 1062 * configuration. 1063 * 1064 * @param configClass The fully-qualified name of the Java class that will 1065 * serve as the configuration handler for the Directory 1066 * Server. 1067 * @param configFile The path to the file that will hold either the entire 1068 * server configuration or enough information to allow 1069 * the server to access the configuration in some other 1070 * repository. 1071 * 1072 * @throws InitializationException If a problem occurs while trying to 1073 * initialize the config handler. 1074 */ 1075 public void initializeConfiguration(String configClass, String configFile) 1076 throws InitializationException 1077 { 1078 Class cfgClass; 1079 try 1080 { 1081 cfgClass = Class.forName(configClass); 1082 } 1083 catch (Exception e) 1084 { 1085 if (debugEnabled()) 1086 { 1087 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1088 } 1089 1090 Message message = 1091 ERR_CANNOT_LOAD_CONFIG_HANDLER_CLASS.get( 1092 configClass, stackTraceToSingleLineString(e)); 1093 throw new InitializationException(message, e); 1094 } 1095 1096 File cfgFile = new File(configFile); 1097 1098 environmentConfig.setConfigClass(cfgClass); 1099 environmentConfig.setConfigFile(cfgFile); 1100 initializeConfiguration(); 1101 } 1102 1103 1104 1105 /** 1106 * Instantiates the configuration handler and loads the Directory Server 1107 * configuration. 1108 * 1109 * @throws InitializationException If a problem occurs while trying to 1110 * initialize the config handler. 1111 */ 1112 public void initializeConfiguration() 1113 throws InitializationException 1114 { 1115 this.configClass = environmentConfig.getConfigClass(); 1116 this.configFile = environmentConfig.getConfigFile(); 1117 1118 1119 // Make sure that administration framework definition classes are loaded. 1120 ClassLoaderProvider provider = ClassLoaderProvider.getInstance(); 1121 if (! provider.isEnabled()) 1122 { 1123 provider.enable(); 1124 } 1125 1126 1127 // Load and instantiate the configuration handler class. 1128 Class handlerClass = configClass; 1129 try 1130 { 1131 configHandler = (ConfigHandler) handlerClass.newInstance(); 1132 } 1133 catch (Exception e) 1134 { 1135 if (debugEnabled()) 1136 { 1137 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1138 } 1139 1140 Message message = 1141 ERR_CANNOT_INSTANTIATE_CONFIG_HANDLER.get( 1142 String.valueOf(configClass), 1143 e.getLocalizedMessage()); 1144 throw new InitializationException(message, e); 1145 } 1146 1147 1148 // Perform the handler-specific initialization. 1149 try 1150 { 1151 configHandler.initializeConfigHandler(configFile.getAbsolutePath(), 1152 false); 1153 } 1154 catch (InitializationException ie) 1155 { 1156 if (debugEnabled()) 1157 { 1158 TRACER.debugCaught(DebugLogLevel.ERROR, ie); 1159 } 1160 1161 throw ie; 1162 } 1163 catch (Exception e) 1164 { 1165 if (debugEnabled()) 1166 { 1167 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1168 } 1169 1170 Message message = 1171 ERR_CANNOT_INITIALIZE_CONFIG_HANDLER.get( 1172 String.valueOf(configClass), 1173 String.valueOf(configFile), 1174 e.getLocalizedMessage()); 1175 throw new InitializationException(message); 1176 } 1177 1178 } 1179 1180 1181 1182 /** 1183 * Retrieves the path to the configuration file used to initialize the 1184 * Directory Server. 1185 * 1186 * @return The path to the configuration file used to initialize the 1187 * Directory Server. 1188 */ 1189 public static String getConfigFile() 1190 { 1191 return directoryServer.configFile.getAbsolutePath(); 1192 } 1193 1194 1195 1196 /** 1197 * Starts up the Directory Server. It must have already been bootstrapped 1198 * and cannot be running. 1199 * 1200 * @throws ConfigException If there is a problem with the Directory Server 1201 * configuration that prevents a critical component 1202 * from being instantiated. 1203 * 1204 * @throws InitializationException If some other problem occurs while 1205 * attempting to initialize and start the 1206 * Directory Server. 1207 */ 1208 public void startServer() 1209 throws ConfigException, InitializationException 1210 { 1211 synchronized (directoryServer) 1212 { 1213 if (! isBootstrapped) 1214 { 1215 Message message = ERR_CANNOT_START_BEFORE_BOOTSTRAP.get(); 1216 throw new InitializationException(message); 1217 } 1218 1219 if (isRunning) 1220 { 1221 Message message = ERR_CANNOT_START_WHILE_RUNNING.get(); 1222 throw new InitializationException(message); 1223 } 1224 1225 1226 logError(NOTE_DIRECTORY_SERVER_STARTING.get(getVersionString(), 1227 BUILD_ID, REVISION_NUMBER)); 1228 1229 RuntimeInformation.logInfo(); 1230 // Acquire an exclusive lock for the Directory Server process. 1231 if (! serverLocked) 1232 { 1233 String lockFile = LockFileManager.getServerLockFileName(); 1234 try 1235 { 1236 StringBuilder failureReason = new StringBuilder(); 1237 if (! LockFileManager.acquireExclusiveLock(lockFile, failureReason)) 1238 { 1239 Message message = ERR_CANNOT_ACQUIRE_EXCLUSIVE_SERVER_LOCK.get( 1240 lockFile, String.valueOf(failureReason)); 1241 throw new InitializationException(message); 1242 } 1243 1244 serverLocked = true; 1245 } 1246 catch (InitializationException ie) 1247 { 1248 throw ie; 1249 } 1250 catch (Exception e) 1251 { 1252 if (debugEnabled()) 1253 { 1254 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1255 } 1256 1257 Message message = ERR_CANNOT_ACQUIRE_EXCLUSIVE_SERVER_LOCK.get( 1258 lockFile, stackTraceToSingleLineString(e)); 1259 throw new InitializationException(message, e); 1260 } 1261 } 1262 1263 1264 // Determine whether or not we should start the connection handlers. 1265 boolean startConnectionHandlers = 1266 (! environmentConfig.disableConnectionHandlers()); 1267 1268 1269 // Initialize all the schema elements. 1270 initializeSchema(); 1271 1272 1273 // Initialize the core Directory Server configuration. 1274 coreConfigManager = new CoreConfigManager(); 1275 coreConfigManager.initializeCoreConfig(); 1276 1277 1278 // Initialize the Directory Server crypto manager. 1279 initializeCryptoManager(); 1280 1281 1282 // Initialize the log rotation policies. 1283 rotationPolicyConfigManager = new LogRotationPolicyConfigManager(); 1284 rotationPolicyConfigManager.initializeLogRotationPolicyConfig(); 1285 1286 // Initialize the log retention policies. 1287 retentionPolicyConfigManager = new LogRetentionPolicyConfigManager(); 1288 retentionPolicyConfigManager.initializeLogRetentionPolicyConfig(); 1289 1290 1291 // Initialize the server loggers. 1292 loggerConfigManager = new LoggerConfigManager(); 1293 loggerConfigManager.initializeLoggerConfig(); 1294 1295 1296 // Initialize the server alert handlers. 1297 initializeAlertHandlers(); 1298 1299 1300 // Initialize the default entry cache. We have to have one before 1301 // <CODE>initializeBackends()</CODE> method kicks in further down. 1302 entryCacheConfigManager = new EntryCacheConfigManager(); 1303 entryCacheConfigManager.initializeDefaultEntryCache(); 1304 1305 1306 // Initialize the key manager provider. 1307 keyManagerProviderConfigManager = new KeyManagerProviderConfigManager(); 1308 keyManagerProviderConfigManager.initializeKeyManagerProviders(); 1309 1310 1311 // Initialize the trust manager provider. 1312 trustManagerProviderConfigManager = 1313 new TrustManagerProviderConfigManager(); 1314 trustManagerProviderConfigManager.initializeTrustManagerProviders(); 1315 1316 1317 // Initialize the certificate mapper. 1318 certificateMapperConfigManager = new CertificateMapperConfigManager(); 1319 certificateMapperConfigManager.initializeCertificateMappers(); 1320 1321 1322 // Initialize the identity mappers. 1323 initializeIdentityMappers(); 1324 1325 1326 // Initialize the root DNs. 1327 rootDNConfigManager = new RootDNConfigManager(); 1328 rootDNConfigManager.initializeRootDNs(); 1329 1330 1331 // Initialize the group manager. 1332 initializeGroupManager(); 1333 1334 // Initialize the access control handler. 1335 AccessControlConfigManager.getInstance().initializeAccessControl(); 1336 1337 // Initialize all the backends and their associated suffixes 1338 // and initialize the workflows when workflow configuration mode 1339 // is auto. 1340 initializeBackends(); 1341 1342 // When workflow configuration mode is manual, do configure the 1343 // workflows now, else just configure the remaining workflows 1344 // (rootDSE and config backend). 1345 if (workflowConfigurationModeIsAuto()) 1346 { 1347 createAndRegisterRemainingWorkflows(); 1348 } 1349 else 1350 { 1351 configureWorkflowsManual(); 1352 } 1353 1354 // Check for and initialize user configured entry cache if any, 1355 // if not stick with default entry cache initialized earlier. 1356 entryCacheConfigManager.initializeEntryCache(); 1357 1358 // Reset the map as we can no longer guarantee offline state. 1359 directoryServer.offlineBackendsStateIDs.clear(); 1360 1361 // Register the supported controls and supported features. 1362 initializeSupportedControls(); 1363 initializeSupportedFeatures(); 1364 1365 1366 // Initialize all the extended operation handlers. 1367 initializeExtendedOperations(); 1368 1369 1370 // Initialize all the SASL mechanism handlers. 1371 initializeSASLMechanisms(); 1372 1373 1374 // Initialize all the virtual attribute handlers. 1375 initializeVirtualAttributes(); 1376 1377 1378 // Initialize all the connection handlers. 1379 if (startConnectionHandlers) 1380 { 1381 initializeConnectionHandlers(); 1382 } 1383 1384 1385 // Initialize all the monitor providers. 1386 monitorConfigManager = new MonitorConfigManager(); 1387 monitorConfigManager.initializeMonitorProviders(); 1388 1389 1390 // Initialize all the password policy components. 1391 initializePasswordPolicyComponents(); 1392 1393 1394 // Load and initialize all the plugins, and then call the registered 1395 // startup plugins. 1396 initializePlugins(); 1397 1398 1399 // Initialize any synchronization providers that may be defined. 1400 synchronizationProviderConfigManager = 1401 new SynchronizationProviderConfigManager(); 1402 synchronizationProviderConfigManager.initializeSynchronizationProviders(); 1403 1404 1405 // Create and initialize the work queue. 1406 workQueue = new WorkQueueConfigManager().initializeWorkQueue(); 1407 1408 1409 PluginResult.Startup startupPluginResult = 1410 pluginConfigManager.invokeStartupPlugins(); 1411 if (! startupPluginResult.continueProcessing()) 1412 { 1413 Message message = ERR_STARTUP_PLUGIN_ERROR. 1414 get(startupPluginResult.getErrorMessage(), 1415 startupPluginResult.getErrorMessage().getDescriptor().getId()); 1416 throw new InitializationException(message); 1417 } 1418 1419 1420 if (startConnectionHandlers) 1421 { 1422 startConnectionHandlers(); 1423 new IdleTimeLimitThread().start(); 1424 } 1425 1426 1427 // Create an object to synchronize ADS with the crypto manager. 1428 new CryptoManagerSync(); 1429 1430 // If we should write a copy of the config on successful startup, then do 1431 // so now. 1432 if (saveConfigOnSuccessfulStartup) 1433 { 1434 configHandler.writeSuccessfulStartupConfig(); 1435 } 1436 1437 1438 // Mark the current time as the start time and indicate that the server is 1439 // now running. 1440 startUpTime = System.currentTimeMillis(); 1441 startTimeUTC = TimeThread.getGMTTime(); 1442 isRunning = true; 1443 1444 Message message = NOTE_DIRECTORY_SERVER_STARTED.get(); 1445 logError(message); 1446 sendAlertNotification(this, ALERT_TYPE_SERVER_STARTED, message); 1447 1448 // Force the root connection to be initialized. 1449 InternalClientConnection.getRootConnection(); 1450 1451 // If a server.starting file exists, then remove it. 1452 File serverStartingFile = 1453 new File(configHandler.getServerRoot() + File.separator + 1454 "logs" + File.separator + "server.starting"); 1455 if (serverStartingFile.exists()) 1456 { 1457 serverStartingFile.delete(); 1458 } 1459 } 1460 } 1461 1462 1463 1464 /** 1465 * Registers a basic set of matching rules with the server that should always 1466 * be available regardless of the server configuration and may be needed for 1467 * configuration processing. 1468 */ 1469 private void bootstrapMatchingRules() 1470 { 1471 try 1472 { 1473 ApproximateMatchingRule matchingRule = 1474 new DoubleMetaphoneApproximateMatchingRule(); 1475 matchingRule.initializeMatchingRule(null); 1476 registerApproximateMatchingRule(matchingRule, true); 1477 } 1478 catch (Exception e) 1479 { 1480 if (debugEnabled()) 1481 { 1482 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1483 } 1484 1485 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1486 get(DoubleMetaphoneApproximateMatchingRule.class.getName(), 1487 stackTraceToSingleLineString(e)); 1488 logError(message); 1489 } 1490 1491 1492 try 1493 { 1494 EqualityMatchingRule matchingRule = new BooleanEqualityMatchingRule(); 1495 matchingRule.initializeMatchingRule(null); 1496 registerEqualityMatchingRule(matchingRule, true); 1497 } 1498 catch (Exception e) 1499 { 1500 if (debugEnabled()) 1501 { 1502 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1503 } 1504 1505 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1506 get(BooleanEqualityMatchingRule.class.getName(), 1507 stackTraceToSingleLineString(e)); 1508 logError(message); 1509 } 1510 1511 1512 try 1513 { 1514 EqualityMatchingRule matchingRule = new CaseExactEqualityMatchingRule(); 1515 matchingRule.initializeMatchingRule(null); 1516 registerEqualityMatchingRule(matchingRule, true); 1517 } 1518 catch (Exception e) 1519 { 1520 if (debugEnabled()) 1521 { 1522 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1523 } 1524 1525 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1526 get(CaseExactEqualityMatchingRule.class.getName(), 1527 stackTraceToSingleLineString(e)); 1528 logError(message); 1529 } 1530 1531 1532 try 1533 { 1534 EqualityMatchingRule matchingRule = 1535 new CaseExactIA5EqualityMatchingRule(); 1536 matchingRule.initializeMatchingRule(null); 1537 registerEqualityMatchingRule(matchingRule, true); 1538 } 1539 catch (Exception e) 1540 { 1541 if (debugEnabled()) 1542 { 1543 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1544 } 1545 1546 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1547 get(CaseExactIA5EqualityMatchingRule.class.getName(), 1548 stackTraceToSingleLineString(e)); 1549 logError(message); 1550 } 1551 1552 1553 try 1554 { 1555 EqualityMatchingRule matchingRule = new CaseIgnoreEqualityMatchingRule(); 1556 matchingRule.initializeMatchingRule(null); 1557 registerEqualityMatchingRule(matchingRule, true); 1558 } 1559 catch (Exception e) 1560 { 1561 if (debugEnabled()) 1562 { 1563 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1564 } 1565 1566 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1567 get(CaseIgnoreEqualityMatchingRule.class.getName(), 1568 stackTraceToSingleLineString(e)); 1569 logError(message); 1570 } 1571 1572 1573 try 1574 { 1575 EqualityMatchingRule matchingRule = 1576 new CaseIgnoreIA5EqualityMatchingRule(); 1577 matchingRule.initializeMatchingRule(null); 1578 registerEqualityMatchingRule(matchingRule, true); 1579 } 1580 catch (Exception e) 1581 { 1582 if (debugEnabled()) 1583 { 1584 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1585 } 1586 1587 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1588 get(CaseIgnoreIA5EqualityMatchingRule.class.getName(), 1589 stackTraceToSingleLineString(e)); 1590 logError(message); 1591 } 1592 1593 1594 try 1595 { 1596 EqualityMatchingRule matchingRule = 1597 new DistinguishedNameEqualityMatchingRule(); 1598 matchingRule.initializeMatchingRule(null); 1599 registerEqualityMatchingRule(matchingRule, true); 1600 } 1601 catch (Exception e) 1602 { 1603 if (debugEnabled()) 1604 { 1605 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1606 } 1607 1608 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1609 get(DistinguishedNameEqualityMatchingRule.class.getName(), 1610 stackTraceToSingleLineString(e)); 1611 logError(message); 1612 } 1613 1614 1615 try 1616 { 1617 EqualityMatchingRule matchingRule = 1618 new GeneralizedTimeEqualityMatchingRule(); 1619 matchingRule.initializeMatchingRule(null); 1620 registerEqualityMatchingRule(matchingRule, true); 1621 } 1622 catch (Exception e) 1623 { 1624 if (debugEnabled()) 1625 { 1626 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1627 } 1628 1629 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1630 get(GeneralizedTimeEqualityMatchingRule.class.getName(), 1631 stackTraceToSingleLineString(e)); 1632 logError(message); 1633 } 1634 1635 1636 try 1637 { 1638 EqualityMatchingRule matchingRule = new IntegerEqualityMatchingRule(); 1639 matchingRule.initializeMatchingRule(null); 1640 registerEqualityMatchingRule(matchingRule, true); 1641 } 1642 catch (Exception e) 1643 { 1644 if (debugEnabled()) 1645 { 1646 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1647 } 1648 1649 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1650 get(IntegerEqualityMatchingRule.class.getName(), 1651 stackTraceToSingleLineString(e)); 1652 logError(message); 1653 } 1654 1655 1656 try 1657 { 1658 EqualityMatchingRule matchingRule = new OctetStringEqualityMatchingRule(); 1659 matchingRule.initializeMatchingRule(null); 1660 registerEqualityMatchingRule(matchingRule, true); 1661 } 1662 catch (Exception e) 1663 { 1664 if (debugEnabled()) 1665 { 1666 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1667 } 1668 1669 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1670 get(OctetStringEqualityMatchingRule.class.getName(), 1671 stackTraceToSingleLineString(e)); 1672 logError(message); 1673 } 1674 1675 1676 try 1677 { 1678 EqualityMatchingRule matchingRule = 1679 new ObjectIdentifierEqualityMatchingRule(); 1680 matchingRule.initializeMatchingRule(null); 1681 registerEqualityMatchingRule(matchingRule, true); 1682 } 1683 catch (Exception e) 1684 { 1685 if (debugEnabled()) 1686 { 1687 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1688 } 1689 1690 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1691 get(ObjectIdentifierEqualityMatchingRule.class.getName(), 1692 stackTraceToSingleLineString(e)); 1693 logError(message); 1694 } 1695 1696 1697 try 1698 { 1699 EqualityMatchingRule matchingRule = 1700 new TelephoneNumberEqualityMatchingRule(); 1701 matchingRule.initializeMatchingRule(null); 1702 registerEqualityMatchingRule(matchingRule, true); 1703 } 1704 catch (Exception e) 1705 { 1706 if (debugEnabled()) 1707 { 1708 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1709 } 1710 1711 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1712 get(TelephoneNumberEqualityMatchingRule.class.getName(), 1713 stackTraceToSingleLineString(e)); 1714 logError(message); 1715 } 1716 1717 1718 try 1719 { 1720 OrderingMatchingRule matchingRule = new CaseExactOrderingMatchingRule(); 1721 matchingRule.initializeMatchingRule(null); 1722 registerOrderingMatchingRule(matchingRule, true); 1723 } 1724 catch (Exception e) 1725 { 1726 if (debugEnabled()) 1727 { 1728 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1729 } 1730 1731 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1732 get(CaseExactOrderingMatchingRule.class.getName(), 1733 stackTraceToSingleLineString(e)); 1734 logError(message); 1735 } 1736 1737 1738 try 1739 { 1740 OrderingMatchingRule matchingRule = new CaseIgnoreOrderingMatchingRule(); 1741 matchingRule.initializeMatchingRule(null); 1742 registerOrderingMatchingRule(matchingRule, true); 1743 } 1744 catch (Exception e) 1745 { 1746 if (debugEnabled()) 1747 { 1748 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1749 } 1750 1751 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1752 get(CaseIgnoreOrderingMatchingRule.class.getName(), 1753 stackTraceToSingleLineString(e)); 1754 logError(message); 1755 } 1756 1757 1758 try 1759 { 1760 OrderingMatchingRule matchingRule = 1761 new GeneralizedTimeOrderingMatchingRule(); 1762 matchingRule.initializeMatchingRule(null); 1763 registerOrderingMatchingRule(matchingRule, true); 1764 } 1765 catch (Exception e) 1766 { 1767 if (debugEnabled()) 1768 { 1769 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1770 } 1771 1772 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1773 get(GeneralizedTimeOrderingMatchingRule.class.getName(), 1774 stackTraceToSingleLineString(e)); 1775 logError(message); 1776 } 1777 1778 1779 try 1780 { 1781 OrderingMatchingRule matchingRule = new IntegerOrderingMatchingRule(); 1782 matchingRule.initializeMatchingRule(null); 1783 registerOrderingMatchingRule(matchingRule, true); 1784 } 1785 catch (Exception e) 1786 { 1787 if (debugEnabled()) 1788 { 1789 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1790 } 1791 1792 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1793 get(IntegerOrderingMatchingRule.class.getName(), 1794 stackTraceToSingleLineString(e)); 1795 logError(message); 1796 } 1797 1798 1799 try 1800 { 1801 OrderingMatchingRule matchingRule = new OctetStringOrderingMatchingRule(); 1802 matchingRule.initializeMatchingRule(null); 1803 registerOrderingMatchingRule(matchingRule, true); 1804 } 1805 catch (Exception e) 1806 { 1807 if (debugEnabled()) 1808 { 1809 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1810 } 1811 1812 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1813 get(OctetStringOrderingMatchingRule.class.getName(), 1814 stackTraceToSingleLineString(e)); 1815 logError(message); 1816 } 1817 1818 1819 try 1820 { 1821 SubstringMatchingRule matchingRule = new CaseExactSubstringMatchingRule(); 1822 matchingRule.initializeMatchingRule(null); 1823 registerSubstringMatchingRule(matchingRule, true); 1824 } 1825 catch (Exception e) 1826 { 1827 if (debugEnabled()) 1828 { 1829 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1830 } 1831 1832 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1833 get(CaseExactSubstringMatchingRule.class.getName(), 1834 stackTraceToSingleLineString(e)); 1835 logError(message); 1836 } 1837 1838 1839 try 1840 { 1841 SubstringMatchingRule matchingRule = 1842 new CaseExactIA5SubstringMatchingRule(); 1843 matchingRule.initializeMatchingRule(null); 1844 registerSubstringMatchingRule(matchingRule, true); 1845 } 1846 catch (Exception e) 1847 { 1848 if (debugEnabled()) 1849 { 1850 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1851 } 1852 1853 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1854 get(CaseExactIA5SubstringMatchingRule.class.getName(), 1855 stackTraceToSingleLineString(e)); 1856 logError(message); 1857 } 1858 1859 1860 try 1861 { 1862 SubstringMatchingRule matchingRule = 1863 new CaseIgnoreSubstringMatchingRule(); 1864 matchingRule.initializeMatchingRule(null); 1865 registerSubstringMatchingRule(matchingRule, true); 1866 } 1867 catch (Exception e) 1868 { 1869 if (debugEnabled()) 1870 { 1871 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1872 } 1873 1874 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1875 get(CaseIgnoreSubstringMatchingRule.class.getName(), 1876 stackTraceToSingleLineString(e)); 1877 logError(message); 1878 } 1879 1880 1881 try 1882 { 1883 SubstringMatchingRule matchingRule = 1884 new CaseIgnoreIA5SubstringMatchingRule(); 1885 matchingRule.initializeMatchingRule(null); 1886 registerSubstringMatchingRule(matchingRule, true); 1887 } 1888 catch (Exception e) 1889 { 1890 if (debugEnabled()) 1891 { 1892 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1893 } 1894 1895 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1896 get(CaseIgnoreIA5SubstringMatchingRule.class.getName(), 1897 stackTraceToSingleLineString(e)); 1898 logError(message); 1899 } 1900 1901 1902 try 1903 { 1904 SubstringMatchingRule matchingRule = 1905 new OctetStringSubstringMatchingRule(); 1906 matchingRule.initializeMatchingRule(null); 1907 registerSubstringMatchingRule(matchingRule, true); 1908 } 1909 catch (Exception e) 1910 { 1911 if (debugEnabled()) 1912 { 1913 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1914 } 1915 1916 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1917 get(OctetStringSubstringMatchingRule.class.getName(), 1918 stackTraceToSingleLineString(e)); 1919 logError(message); 1920 } 1921 1922 1923 try 1924 { 1925 SubstringMatchingRule matchingRule = 1926 new TelephoneNumberSubstringMatchingRule(); 1927 matchingRule.initializeMatchingRule(null); 1928 registerSubstringMatchingRule(matchingRule, true); 1929 } 1930 catch (Exception e) 1931 { 1932 if (debugEnabled()) 1933 { 1934 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1935 } 1936 1937 Message message = ERR_CANNOT_BOOTSTRAP_MATCHING_RULE. 1938 get(TelephoneNumberSubstringMatchingRule.class.getName(), 1939 stackTraceToSingleLineString(e)); 1940 logError(message); 1941 } 1942 } 1943 1944 1945 1946 /** 1947 * Registers a basic set of attribute syntaxes with the server that should 1948 * always be available regardless of the server configuration and may be 1949 * needed for configuration processing. 1950 */ 1951 private void bootstrapAttributeSyntaxes() 1952 { 1953 try 1954 { 1955 AttributeTypeSyntax syntax = new AttributeTypeSyntax(); 1956 syntax.initializeSyntax(null); 1957 registerAttributeSyntax(syntax, true); 1958 } 1959 catch (Exception e) 1960 { 1961 if (debugEnabled()) 1962 { 1963 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1964 } 1965 1966 Message message = ERR_CANNOT_BOOTSTRAP_SYNTAX.get( 1967 AttributeTypeSyntax.class.getName(), stackTraceToSingleLineString(e)); 1968 logError(message); 1969 } 1970 1971 1972 try 1973 { 1974 defaultBinarySyntax = new BinarySyntax(); 1975 defaultBinarySyntax.initializeSyntax(null); 1976 registerAttributeSyntax(defaultBinarySyntax, true); 1977 } 1978 catch (Exception e) 1979 { 1980 if (debugEnabled()) 1981 { 1982 TRACER.debugCaught(DebugLogLevel.ERROR, e); 1983 } 1984 1985 Message message = ERR_CANNOT_BOOTSTRAP_SYNTAX.get( 1986 BinarySyntax.class.getName(), stackTraceToSingleLineString(e)); 1987 logError(message); 1988 } 1989 1990 1991 try 1992 { 1993 defaultBooleanSyntax = new BooleanSyntax(); 1994 defaultBooleanSyntax.initializeSyntax(null); 1995 registerAttributeSyntax(defaultBooleanSyntax, true); 1996 } 1997 catch (Exception e) 1998 { 1999 if (debugEnabled()) 2000 { 2001 TRACER.debugCaught(DebugLogLevel.ERROR, e); 2002 } 2003 2004 Message message = ERR_CANNOT_BOOTSTRAP_SYNTAX.get( 2005 BooleanSyntax.class.getName(), stackTraceToSingleLineString(e)); 2006 logError(message); 2007 } 2008 2009 2010 try 2011 { 2012 defaultStringSyntax = new DirectoryStringSyntax(); 2013 defaultStringSyntax.initializeSyntax(null); 2014 registerAttributeSyntax(defaultStringSyntax, true); 2015 defaultSyntax = defaultStringSyntax; 2016 } 2017 catch (Exception e) 2018 { 2019 if (debugEnabled()) 2020 { 2021 TRACER.debugCaught(DebugLogLevel.ERROR, e); 2022 } 2023 2024 Message message = ERR_CANNOT_BOOTSTRAP_SYNTAX. 2025 get(DirectoryStringSyntax.class.getName(), 2026 stackTraceToSingleLineString(e)); 2027 logError(message); 2028 } 2029 2030 2031 try 2032 { 2033 defaultDNSyntax = new DistinguishedNameSyntax(); 2034 defaultDNSyntax.initializeSyntax(null); 2035 registerAttributeSyntax(defaultDNSyntax, true); 2036 } 2037 catch (Exception e) 2038 { 2039 if (debugEnabled()) 2040 { 2041 TRACER.debugCaught(DebugLogLevel.ERROR, e); 2042 } 2043 2044 Message message = ERR_CANNOT_BOOTSTRAP_SYNTAX. 2045 get(DistinguishedNameSyntax.class.getName(), 2046 stackTraceToSingleLineString(e)); 2047 logError(message); 2048 } 2049 2050 2051 try 2052 { 2053 IA5StringSyntax syntax = new IA5StringSyntax(); 2054 syntax.initializeSyntax(null); 2055 registerAttributeSyntax(syntax, true); 2056 } 2057 catch (Exception e) 2058 { 2059 if (debugEnabled()) 2060 { 2061 TRACER.debugCaught(DebugLogLevel.ERROR, e); 2062 } 2063 2064 Message message = ERR_CANNOT_BOOTSTRAP_SYNTAX.get( 2065 IA5StringSyntax.class.getName(), stackTraceToSingleLineString(e)); 2066 logError(message); 2067 } 2068 2069 2070 try 2071 { 2072 defaultIntegerSyntax = new IntegerSyntax(); 2073 defaultIntegerSyntax.initializeSyntax(null); 2074 registerAttributeSyntax(defaultIntegerSyntax, true); 2075 } 2076 catch (Exception e) 2077 { 2078 if (debugEnabled()) 2079 { 2080 TRACER.debugCaught(DebugLogLevel.ERROR, e); 2081 } 2082 2083 Message message = ERR_CANNOT_BOOTSTRAP_SYNTAX.get( 2084 IntegerSyntax.class.getName(), stackTraceToSingleLineString(e)); 2085 logError(message); 2086 } 2087 2088 2089 try 2090 { 2091 GeneralizedTimeSyntax syntax = new GeneralizedTimeSyntax(); 2092 syntax.initializeSyntax(null); 2093 registerAttributeSyntax(syntax, true); 2094 } 2095 catch (Exception e) 2096 { 2097 if (debugEnabled()) 2098 { 2099 TRACER.debugCaught(DebugLogLevel.ERROR, e); 2100 } 2101 2102 Message message = ERR_CANNOT_BOOTSTRAP_SYNTAX. 2103 get(GeneralizedTimeSyntax.class.getName(), 2104 stackTraceToSingleLineString(e)); 2105 logError(message); 2106 } 2107 2108 2109 try 2110 { 2111 ObjectClassSyntax syntax = new ObjectClassSyntax(); 2112 syntax.initializeSyntax(null); 2113 registerAttributeSyntax(syntax, true); 2114 } 2115 catch (Exception e) 2116 { 2117 if (debugEnabled()) 2118 { 2119 TRACER.debugCaught(DebugLogLevel.ERROR, e); 2120 } 2121 2122 Message message = ERR_CANNOT_BOOTSTRAP_SYNTAX.get( 2123 ObjectClassSyntax.class.getName(), stackTraceToSingleLineString(e)); 2124 logError(message); 2125 } 2126 2127 2128 try 2129 { 2130 OIDSyntax syntax = new OIDSyntax(); 2131 syntax.initializeSyntax(null); 2132 registerAttributeSyntax(syntax, true); 2133 } 2134 catch (Exception e) 2135 { 2136 if (debugEnabled()) 2137 { 2138 TRACER.debugCaught(DebugLogLevel.ERROR, e); 2139 } 2140 2141 Message message = ERR_CANNOT_BOOTSTRAP_SYNTAX.get( 2142 OIDSyntax.class.getName(), stackTraceToSingleLineString(e)); 2143 logError(message); 2144 } 2145 2146 2147 try 2148 { 2149 TelephoneNumberSyntax syntax = new TelephoneNumberSyntax(); 2150 syntax.initializeSyntax(null); 2151 registerAttributeSyntax(syntax, true); 2152 } 2153 catch (Exception e) 2154 { 2155 if (debugEnabled()) 2156 { 2157 TRACER.debugCaught(DebugLogLevel.ERROR, e); 2158 } 2159 2160 Message message = ERR_CANNOT_BOOTSTRAP_SYNTAX. 2161 get(TelephoneNumberSyntax.class.getName(), 2162 stackTraceToSingleLineString(e)); 2163 logError(message); 2164 } 2165 } 2166 2167 2168 2169 /** 2170 * Retrieves the authenticated users manager for the Directory Server. 2171 * 2172 * @return The authenticated users manager for the Directory Server. 2173 */ 2174 public static AuthenticatedUsers getAuthenticatedUsers() 2175 { 2176 return directoryServer.authenticatedUsers; 2177 } 2178 2179 2180 2181 /** 2182 * Initializes the crypto manager for the Directory Server. 2183 * 2184 * @throws ConfigException If a configuration problem is identified while 2185 * initializing the crypto manager. 2186 * 2187 * @throws InitializationException If a problem occurs while initializing 2188 * the crypto manager that is not related 2189 * to the server configuration. 2190 */ 2191 public void initializeCryptoManager() 2192 throws ConfigException, InitializationException 2193 { 2194 RootCfg root = 2195 ServerManagementContext.getInstance().getRootConfiguration(); 2196 CryptoManagerCfg cryptoManagerCfg = root.getCryptoManager(); 2197 cryptoManager = new CryptoManagerImpl(cryptoManagerCfg); 2198 } 2199 2200 2201 2202 /** 2203 * Retrieves a reference to the Directory Server crypto manager. 2204 * 2205 * @return A reference to the Directory Server crypto manager. 2206 */ 2207 public static CryptoManagerImpl getCryptoManager() 2208 { 2209 return directoryServer.cryptoManager; 2210 } 2211 2212 2213 2214 /** 2215 * Indicates whether the Directory Server is configured with information about 2216 * one or more mail servers and may therefore be used to send e-mail messages. 2217 * 2218 * @return {@code true} if the Directory Server is configured to be able to 2219 * send e-mail messages, or {@code false} if not. 2220 */ 2221 public static boolean mailServerConfigured() 2222 { 2223 return ((directoryServer.mailServerPropertySets != null) && 2224 (! directoryServer.mailServerPropertySets.isEmpty())); 2225 } 2226 2227 2228 2229 /** 2230 * Specifies the set of mail server properties that should be used for SMTP 2231 * communication. 2232 * 2233 * @param mailServerPropertySets A list of {@code Properties} objects that 2234 * provide information that can be used to 2235 * communicate with SMTP servers. 2236 */ 2237 public static void setMailServerPropertySets(List<Properties> 2238 mailServerPropertySets) 2239 { 2240 directoryServer.mailServerPropertySets = mailServerPropertySets; 2241 } 2242 2243 2244 2245 /** 2246 * Retrieves the sets of information about the mail servers configured for use 2247 * by the Directory Server. 2248 * 2249 * @return The sets of information about the mail servers configured for use 2250 * by the Directory Server. 2251 */ 2252 public static List<Properties> getMailServerPropertySets() 2253 { 2254 return directoryServer.mailServerPropertySets; 2255 } 2256 2257 2258 2259 /** 2260 * Initializes the set of alert handlers defined in the Directory Server. 2261 * 2262 * @throws ConfigException If there is a configuration problem with any of 2263 * the alert handlers. 2264 * 2265 * @throws InitializationException If a problem occurs while initializing 2266 * the alert handlers that is not related to 2267 * the server configuration. 2268 */ 2269 private void initializeAlertHandlers() 2270 throws ConfigException, InitializationException 2271 { 2272 new AlertHandlerConfigManager().initializeAlertHandlers(); 2273 } 2274 2275 2276 2277 2278 /** 2279 * Initializes the schema elements for the Directory Server, including the 2280 * matching rules, attribute syntaxes, attribute types, and object classes. 2281 * 2282 * @throws ConfigException If there is a configuration problem with any of 2283 * the schema elements. 2284 * 2285 * @throws InitializationException If a problem occurs while initializing 2286 * the schema elements that is not related 2287 * to the server configuration. 2288 */ 2289 public void initializeSchema() 2290 throws ConfigException, InitializationException 2291 { 2292 // Create the schema configuration manager, and initialize the schema from 2293 // the configuration. 2294 schemaConfigManager = new SchemaConfigManager(); 2295 schema = schemaConfigManager.getSchema(); 2296 2297 schemaConfigManager.initializeMatchingRules(); 2298 schemaConfigManager.initializeAttributeSyntaxes(); 2299 schemaConfigManager.initializeSchemaFromFiles(); 2300 2301 // With server schema in place set compressed schema. 2302 compressedSchema = new DefaultCompressedSchema(); 2303 2304 // At this point we have a problem, because none of the configuration is 2305 // usable because it was all read before we had a schema (and therefore all 2306 // of the attribute types and objectclasses are bogus and won't let us find 2307 // anything). So we have to re-read the configuration so that we can 2308 // continue the necessary startup process. In the process, we want to 2309 // preserve any configuration add/delete/change listeners that might have 2310 // been registered with the old configuration (which will primarily be 2311 // schema elements) so they can be re-registered with the new configuration. 2312 LinkedHashMap<String,List<ConfigAddListener>> addListeners = 2313 new LinkedHashMap<String,List<ConfigAddListener>>(); 2314 LinkedHashMap<String,List<ConfigDeleteListener>> deleteListeners = 2315 new LinkedHashMap<String,List<ConfigDeleteListener>>(); 2316 LinkedHashMap<String,List<ConfigChangeListener>> changeListeners = 2317 new LinkedHashMap<String,List<ConfigChangeListener>>(); 2318 getChangeListeners(configHandler.getConfigRootEntry(), addListeners, 2319 deleteListeners, changeListeners); 2320 2321 try 2322 { 2323 configHandler.finalizeConfigHandler(); 2324 } 2325 catch (Exception e) 2326 { 2327 if (debugEnabled()) 2328 { 2329 TRACER.debugCaught(DebugLogLevel.ERROR, e); 2330 } 2331 } 2332 2333 try 2334 { 2335 configHandler.initializeConfigHandler(configFile.getAbsolutePath(), true); 2336 } 2337 catch (InitializationException ie) 2338 { 2339 if (debugEnabled()) 2340 { 2341 TRACER.debugCaught(DebugLogLevel.ERROR, ie); 2342 } 2343 2344 throw ie; 2345 } 2346 catch (Exception e) 2347 { 2348 if (debugEnabled()) 2349 { 2350 TRACER.debugCaught(DebugLogLevel.ERROR, e); 2351 } 2352 2353 Message message = 2354 ERR_CANNOT_INITIALIZE_CONFIG_HANDLER.get( 2355 String.valueOf(configClass), 2356 String.valueOf(configFile), 2357 e.getLocalizedMessage()); 2358 throw new InitializationException(message); 2359 } 2360 2361 2362 // Re-register all of the change listeners with the configuration. 2363 for (String dnStr : addListeners.keySet()) 2364 { 2365 try 2366 { 2367 DN dn = DN.decode(dnStr); 2368 for (ConfigAddListener listener : addListeners.get(dnStr)) 2369 { 2370 configHandler.getConfigEntry(dn).registerAddListener(listener); 2371 } 2372 } 2373 catch (DirectoryException de) 2374 { 2375 // This should never happen, so we'll just re-throw it. 2376 throw new InitializationException(de.getMessageObject()); 2377 } 2378 } 2379 2380 for (String dnStr : deleteListeners.keySet()) 2381 { 2382 try 2383 { 2384 DN dn = DN.decode(dnStr); 2385 for (ConfigDeleteListener listener : deleteListeners.get(dnStr)) 2386 { 2387 configHandler.getConfigEntry(dn).registerDeleteListener(listener); 2388 } 2389 } 2390 catch (DirectoryException de) 2391 { 2392 // This should never happen, so we'll just re-throw it. 2393 throw new InitializationException(de.getMessageObject()); 2394 } 2395 } 2396 2397 for (String dnStr : changeListeners.keySet()) 2398 { 2399 try 2400 { 2401 DN dn = DN.decode(dnStr); 2402 for (ConfigChangeListener listener : changeListeners.get(dnStr)) 2403 { 2404 configHandler.getConfigEntry(dn).registerChangeListener(listener); 2405 } 2406 } 2407 catch (DirectoryException de) 2408 { 2409 // This should never happen, so we'll just re-throw it. 2410 throw new InitializationException(de.getMessageObject()); 2411 } 2412 } 2413 } 2414 2415 2416 2417 /** 2418 * Retrieves the default compressed schema manager for the Directory Server. 2419 * 2420 * @return The default compressed schema manager for the Directory Server. 2421 */ 2422 public static CompressedSchema getDefaultCompressedSchema() 2423 { 2424 return directoryServer.compressedSchema; 2425 } 2426 2427 2428 2429 /** 2430 * Gets all of the add, delete, and change listeners from the provided 2431 * configuration entry and all of its descendants and puts them in the 2432 * appropriate lists. 2433 * 2434 * @param configEntry The configuration entry to be processed, along 2435 * with all of its descendants. 2436 * @param addListeners The set of add listeners mapped to the DN of the 2437 * corresponding configuration entry. 2438 * @param deleteListeners The set of delete listeners mapped to the DN of 2439 * the corresponding configuration entry. 2440 * @param changeListeners The set of change listeners mapped to the DN of 2441 * the corresponding configuration entry. 2442 */ 2443 private void getChangeListeners(ConfigEntry configEntry, 2444 LinkedHashMap<String,List<ConfigAddListener>> addListeners, 2445 LinkedHashMap<String,List<ConfigDeleteListener>> deleteListeners, 2446 LinkedHashMap<String,List<ConfigChangeListener>> changeListeners) 2447 { 2448 CopyOnWriteArrayList<ConfigAddListener> cfgAddListeners = 2449 configEntry.getAddListeners(); 2450 if ((cfgAddListeners != null) && (cfgAddListeners.size() > 0)) 2451 { 2452 addListeners.put(configEntry.getDN().toString(), cfgAddListeners); 2453 } 2454 2455 CopyOnWriteArrayList<ConfigDeleteListener> cfgDeleteListeners = 2456 configEntry.getDeleteListeners(); 2457 if ((cfgDeleteListeners != null) && (cfgDeleteListeners.size() > 0)) 2458 { 2459 deleteListeners.put(configEntry.getDN().toString(), cfgDeleteListeners); 2460 } 2461 2462 CopyOnWriteArrayList<ConfigChangeListener> cfgChangeListeners = 2463 configEntry.getChangeListeners(); 2464 if ((cfgChangeListeners != null) && (cfgChangeListeners.size() > 0)) 2465 { 2466 changeListeners.put(configEntry.getDN().toString(), cfgChangeListeners); 2467 } 2468 2469 for (ConfigEntry child : configEntry.getChildren().values()) 2470 { 2471 getChangeListeners(child, addListeners, deleteListeners, changeListeners); 2472 } 2473 } 2474 2475 2476 2477 /** 2478 * Retrieves the set of backend initialization listeners that have been 2479 * registered with the Directory Server. The contents of the returned set 2480 * must not be altered. 2481 * 2482 * @return The set of backend initialization listeners that have been 2483 * registered with the Directory Server. 2484 */ 2485 public static Set<BackendInitializationListener> 2486 getBackendInitializationListeners() 2487 { 2488 return directoryServer.backendInitializationListeners; 2489 } 2490 2491 2492 2493 /** 2494 * Registers the provided backend initialization listener with the Directory 2495 * Server. 2496 * 2497 * @param listener The backend initialization listener to register with the 2498 * Directory Server. 2499 */ 2500 public static void registerBackendInitializationListener( 2501 BackendInitializationListener listener) 2502 { 2503 directoryServer.backendInitializationListeners.add(listener); 2504 } 2505 2506 2507 2508 /** 2509 * Deegisters the provided backend initialization listener with the Directory 2510 * Server. 2511 * 2512 * @param listener The backend initialization listener to deregister with 2513 * the Directory Server. 2514 */ 2515 public static void deregisterBackendInitializationListener( 2516 BackendInitializationListener listener) 2517 { 2518 directoryServer.backendInitializationListeners.remove(listener); 2519 } 2520 2521 2522 2523 /** 2524 * Initializes the set of backends defined in the Directory Server. 2525 * 2526 * @throws ConfigException If there is a configuration problem with any of 2527 * the backends. 2528 * 2529 * @throws InitializationException If a problem occurs while initializing 2530 * the backends that is not related to the 2531 * server configuration. 2532 */ 2533 private void initializeBackends() 2534 throws ConfigException, InitializationException 2535 { 2536 backendConfigManager = new BackendConfigManager(); 2537 backendConfigManager.initializeBackendConfig(); 2538 2539 2540 // Make sure to initialize the root DSE backend separately after all other 2541 // backends. 2542 RootDSEBackendCfg rootDSECfg; 2543 try 2544 { 2545 RootCfg root = 2546 ServerManagementContext.getInstance().getRootConfiguration(); 2547 rootDSECfg = root.getRootDSEBackend(); 2548 } 2549 catch (Exception e) 2550 { 2551 if (debugEnabled()) 2552 { 2553 TRACER.debugCaught(DebugLogLevel.ERROR, e); 2554 } 2555 2556 Message message = ERR_CANNOT_GET_ROOT_DSE_CONFIG_ENTRY.get( 2557 stackTraceToSingleLineString(e)); 2558 throw new InitializationException(message, e); 2559 } 2560 2561 rootDSEBackend = new RootDSEBackend(); 2562 rootDSEBackend.configureBackend(rootDSECfg); 2563 rootDSEBackend.initializeBackend(); 2564 } 2565 2566 2567 /** 2568 * Deregisters a workflow with the default network group and 2569 * deregisters the workflow with the server. This method is 2570 * intended to be called when workflow configuration mode is 2571 * auto. 2572 * 2573 * @param baseDN the DN of the workflow to deregister 2574 */ 2575 private static void deregisterWorkflowWithDefaultNetworkGroup( 2576 DN baseDN 2577 ) 2578 { 2579 // Get the default network group and deregister all the workflows 2580 // being configured for the backend (there is one worklfow per 2581 // backend base DN). 2582 NetworkGroup defaultNetworkGroup = NetworkGroup.getDefaultNetworkGroup(); 2583 Workflow workflow = defaultNetworkGroup.deregisterWorkflow(baseDN); 2584 WorkflowImpl workflowImpl = (WorkflowImpl) workflow; 2585 workflowImpl.deregister(); 2586 } 2587 2588 2589 /** 2590 * Creates a set of workflows for a given backend and registers the 2591 * workflows with the default network group. There are as many workflows 2592 * as base DNs defined in the backend. This method is intended 2593 * to be called when workflow configuration mode is auto. 2594 * 2595 * @param backend the backend handled by the workflow 2596 * 2597 * @throws DirectoryException If the workflow ID for the provided 2598 * workflow conflicts with the workflow 2599 * ID of an existing workflow. 2600 */ 2601 public static void createAndRegisterWorkflowsWithDefaultNetworkGroup( 2602 Backend backend 2603 ) throws DirectoryException 2604 { 2605 // Create a worklfow for each backend base DN and register the workflow 2606 // with the default network group. 2607 for (DN curBaseDN: backend.getBaseDNs()) 2608 { 2609 WorkflowImpl workflowImpl = createWorkflow(curBaseDN, backend); 2610 registerWorkflowWithDefaultNetworkGroup(workflowImpl); 2611 } 2612 } 2613 2614 2615 /** 2616 * Creates one workflow for a given base DN in a backend. 2617 * 2618 * @param baseDN the base DN of the workflow to create 2619 * @param backend the backend handled by the workflow 2620 * 2621 * @return the newly created workflow 2622 * 2623 * @throws DirectoryException If the workflow ID for the provided 2624 * workflow conflicts with the workflow 2625 * ID of an existing workflow. 2626 */ 2627 public static WorkflowImpl createWorkflow( 2628 DN baseDN, 2629 Backend backend 2630 ) throws DirectoryException 2631 { 2632 String backendID = backend.getBackendID(); 2633 2634 // Create a root workflow element to encapsulate the backend 2635 LocalBackendWorkflowElement rootWE = 2636 LocalBackendWorkflowElement.createAndRegister(backendID, backend); 2637 2638 // The workflow ID is "backendID + baseDN". 2639 // We cannot use backendID as workflow identifier because a backend 2640 // may handle several base DNs. We cannot use baseDN either because 2641 // we might want to configure several workflows handling the same 2642 // baseDN through different network groups. So a mix of both 2643 // backendID and baseDN should be ok. 2644 String workflowID = backend.getBackendID() + "#" + baseDN.toString(); 2645 2646 // Create the worklfow for the base DN and register the workflow with 2647 // the server. 2648 WorkflowImpl workflowImpl = new WorkflowImpl( 2649 workflowID, baseDN, (WorkflowElement) rootWE); 2650 workflowImpl.register(); 2651 2652 return workflowImpl; 2653 } 2654 2655 2656 /** 2657 * Registers a workflow with the default network group. This method 2658 * is intended to be called when workflow configuration mode is auto. 2659 * 2660 * @param workflowImpl The workflow to register with the 2661 * default network group 2662 * 2663 * @throws DirectoryException If the workflow is already registered with 2664 * the default network group 2665 */ 2666 private static void registerWorkflowWithDefaultNetworkGroup( 2667 WorkflowImpl workflowImpl 2668 ) throws DirectoryException 2669 { 2670 NetworkGroup defaultNetworkGroup = NetworkGroup.getDefaultNetworkGroup(); 2671 defaultNetworkGroup.registerWorkflow(workflowImpl); 2672 } 2673 2674 2675 /** 2676 * Creates the missing workflows, one for the config backend and one for 2677 * the rootDSE backend. 2678 * 2679 * This method should be invoked whatever may be the workflow 2680 * configuration mode because config backend and rootDSE backend 2681 * will not have any configuration section, ever. 2682 * 2683 * @throws ConfigException If there is a configuration problem with any of 2684 * the workflows. 2685 */ 2686 private void createAndRegisterRemainingWorkflows() 2687 throws ConfigException 2688 { 2689 try 2690 { 2691 createAndRegisterWorkflowsWithDefaultNetworkGroup (configHandler); 2692 createAndRegisterWorkflowsWithDefaultNetworkGroup (rootDSEBackend); 2693 } 2694 catch (DirectoryException de) 2695 { 2696 throw new ConfigException(de.getMessageObject()); 2697 } 2698 } 2699 2700 2701 /** 2702 * Reconfigures the workflows when configuration mode has changed. 2703 * This method is invoked when workflows need to be reconfigured 2704 * while the server is running. If the reconfiguration is valid 2705 * then the method update the workflow configuration mode. 2706 * 2707 * @param oldMode the current workflow configuration mode 2708 * @param newMode the new workflow configuration mode 2709 */ 2710 public static void reconfigureWorkflows( 2711 WorkflowConfigurationMode oldMode, 2712 WorkflowConfigurationMode newMode) 2713 { 2714 if ((oldMode == WorkflowConfigurationMode.AUTO) 2715 && (newMode == WorkflowConfigurationMode.MANUAL)) 2716 { 2717 // move to manual mode 2718 try 2719 { 2720 directoryServer.configureWorkflowsManual(); 2721 setWorkflowConfigurationMode(newMode); 2722 } 2723 catch (Exception e) 2724 { 2725 // rollback to auto mode 2726 try 2727 { 2728 directoryServer.configureWorkflowsAuto(); 2729 } 2730 catch (Exception ee) 2731 { 2732 // rollback to auto mode is failing too!! 2733 // well, just log an error message and suggest the admin 2734 // to restart the server with the last valid config... 2735 Message message = ERR_CONFIG_WORKFLOW_CANNOT_CONFIGURE_MANUAL.get(); 2736 logError(message); 2737 } 2738 } 2739 } 2740 else if ((oldMode == WorkflowConfigurationMode.MANUAL) 2741 && (newMode == WorkflowConfigurationMode.AUTO)) 2742 { 2743 // move to auto mode 2744 try 2745 { 2746 directoryServer.configureWorkflowsAuto(); 2747 setWorkflowConfigurationMode(newMode); 2748 } 2749 catch (Exception e) 2750 { 2751 // rollback to manual mode 2752 try 2753 { 2754 directoryServer.configureWorkflowsManual(); 2755 } 2756 catch (Exception ee) 2757 { 2758 // rollback to auto mode is failing too!! 2759 // well, just log an error message and suggest the admin 2760 // to restart the server with the last valid config... 2761 Message message = ERR_CONFIG_WORKFLOW_CANNOT_CONFIGURE_AUTO.get(); 2762 logError(message); 2763 } 2764 } 2765 } 2766 } 2767 2768 2769 /** 2770 * Configures the workflows when configuration mode is manual. 2771 * 2772 * @throws ConfigException If there is a problem with the Directory Server 2773 * configuration that prevents a critical component 2774 * from being instantiated. 2775 * 2776 * @throws InitializationException If some other problem occurs while 2777 * attempting to initialize and start the 2778 * Directory Server. 2779 */ 2780 private void configureWorkflowsManual() 2781 throws ConfigException, InitializationException 2782 { 2783 // First of all re-initialize the current workflow configuration 2784 NetworkGroup.resetConfig(); 2785 WorkflowImpl.resetConfig(); 2786 WorkflowElement.resetConfig(); 2787 2788 // Then configure the workflows 2789 workflowElementConfigManager = new WorkflowElementConfigManager(); 2790 workflowElementConfigManager.initializeWorkflowElements(); 2791 2792 workflowConfigManager = new WorkflowConfigManager(); 2793 workflowConfigManager.initializeWorkflows(); 2794 2795 networkGroupConfigManager = new NetworkGroupConfigManager(); 2796 networkGroupConfigManager.initializeNetworkGroups(); 2797 2798 // We now need to complete the workflow creation for the 2799 // config backend and rootDSE backend. 2800 createAndRegisterRemainingWorkflows(); 2801 } 2802 2803 2804 /** 2805 * Configures the workflows when configuration mode is auto. 2806 * 2807 * @throws ConfigException If there is a problem with the Directory Server 2808 * configuration that prevents a critical component 2809 * from being instantiated. 2810 */ 2811 private void configureWorkflowsAuto() throws ConfigException 2812 { 2813 // First of all re-initialize the current workflow configuration 2814 NetworkGroup.resetConfig(); 2815 WorkflowImpl.resetConfig(); 2816 WorkflowElement.resetConfig(); 2817 2818 // For each base DN in a backend create a workflow and register 2819 // the workflow with the default network group 2820 Map<String, Backend> backends = getBackends(); 2821 for (String backendID: backends.keySet()) 2822 { 2823 Backend backend = backends.get(backendID); 2824 for (DN baseDN: backend.getBaseDNs()) 2825 { 2826 WorkflowImpl workflowImpl; 2827 try 2828 { 2829 workflowImpl = createWorkflow(baseDN, backend); 2830 registerWorkflowWithDefaultNetworkGroup(workflowImpl); 2831 } 2832 catch (DirectoryException e) 2833 { 2834 // TODO Auto-generated catch block 2835 throw new ConfigException(e.getMessageObject()); 2836 } 2837 } 2838 } 2839 2840 // We now need to complete the workflow creation for the 2841 // config backend and rootDSE backend. 2842 createAndRegisterRemainingWorkflows(); 2843 } 2844 2845 2846 /** 2847 * Initializes the Directory Server group manager. 2848 * 2849 * @throws ConfigException If there is a configuration problem with any of 2850 * the group implementations. 2851 * 2852 * @throws InitializationException If a problem occurs while initializing 2853 * the group manager that is not related to 2854 * the server configuration. 2855 */ 2856 public void initializeGroupManager() 2857 throws ConfigException, InitializationException 2858 { 2859 groupManager = new GroupManager(); 2860 groupManager.initializeGroupImplementations(); 2861 2862 // The configuration backend has already been registered by this point 2863 // so we need to handle it explicitly. 2864 groupManager.performBackendInitializationProcessing(configHandler); 2865 } 2866 2867 2868 2869 /** 2870 * Retrieves the Directory Server group manager. 2871 * 2872 * @return The Directory Server group manager. 2873 */ 2874 public static GroupManager getGroupManager() 2875 { 2876 return directoryServer.groupManager; 2877 } 2878 2879 2880 2881 /** 2882 * Initializes the set of supported controls for the Directory Server. 2883 * 2884 * @throws ConfigException If there is a configuration problem with the 2885 * list of supported controls. 2886 * 2887 * @throws InitializationException If a problem occurs while initializing 2888 * the set of supported controls that is not 2889 * related to the server configuration. 2890 */ 2891 private void initializeSupportedControls() 2892 throws ConfigException, InitializationException 2893 { 2894 supportedControls.add(OID_LDAP_ASSERTION); 2895 supportedControls.add(OID_LDAP_READENTRY_PREREAD); 2896 supportedControls.add(OID_LDAP_READENTRY_POSTREAD); 2897 supportedControls.add(OID_LDAP_NOOP_OPENLDAP_ASSIGNED); 2898 supportedControls.add(OID_PERSISTENT_SEARCH); 2899 supportedControls.add(OID_PROXIED_AUTH_V1); 2900 supportedControls.add(OID_PROXIED_AUTH_V2); 2901 supportedControls.add(OID_AUTHZID_REQUEST); 2902 supportedControls.add(OID_MATCHED_VALUES); 2903 supportedControls.add(OID_LDAP_SUBENTRIES); 2904 supportedControls.add(OID_PASSWORD_POLICY_CONTROL); 2905 supportedControls.add(OID_REAL_ATTRS_ONLY); 2906 supportedControls.add(OID_VIRTUAL_ATTRS_ONLY); 2907 supportedControls.add(OID_ACCOUNT_USABLE_CONTROL); 2908 } 2909 2910 2911 2912 /** 2913 * Initializes the set of supported features for the Directory Server. 2914 * 2915 * @throws ConfigException If there is a configuration problem with the 2916 * list of supported features. 2917 * 2918 * @throws InitializationException If a problem occurs while initializing 2919 * the set of supported features that is not 2920 * related to the server configuration. 2921 */ 2922 private void initializeSupportedFeatures() 2923 throws ConfigException, InitializationException 2924 { 2925 supportedFeatures.add(OID_ALL_OPERATIONAL_ATTRS_FEATURE); 2926 supportedFeatures.add(OID_MODIFY_INCREMENT_FEATURE); 2927 supportedFeatures.add(OID_TRUE_FALSE_FILTERS_FEATURE); 2928 } 2929 2930 2931 2932 /** 2933 * Initializes the set of identity mappers for the Directory Server. 2934 * 2935 * @throws ConfigException If there is a configuration problem with any of 2936 * the extended operation handlers. 2937 * 2938 * @throws InitializationException If a problem occurs while initializing 2939 * the extended operation handlers that is 2940 * not related to the server configuration. 2941 */ 2942 private void initializeIdentityMappers() 2943 throws ConfigException, InitializationException 2944 { 2945 identityMapperConfigManager = new IdentityMapperConfigManager(); 2946 identityMapperConfigManager.initializeIdentityMappers(); 2947 } 2948 2949 2950 2951 /** 2952 * Initializes the set of extended operation handlers for the Directory 2953 * Server. 2954 * 2955 * @throws ConfigException If there is a configuration problem with any of 2956 * the extended operation handlers. 2957 * 2958 * @throws InitializationException If a problem occurs while initializing 2959 * the extended operation handlers that is 2960 * not related to the server configuration. 2961 */ 2962 private void initializeExtendedOperations() 2963 throws ConfigException, InitializationException 2964 { 2965 extendedOperationConfigManager = new ExtendedOperationConfigManager(); 2966 extendedOperationConfigManager.initializeExtendedOperationHandlers(); 2967 } 2968 2969 2970 2971 /** 2972 * Initializes the set of SASL mechanism handlers for the Directory Server. 2973 * 2974 * @throws ConfigException If there is a configuration problem with any of 2975 * the SASL mechanism handlers. 2976 * 2977 * @throws InitializationException If a problem occurs while initializing 2978 * the SASL mechanism handlers that is not 2979 * related to the server configuration. 2980 */ 2981 private void initializeSASLMechanisms() 2982 throws ConfigException, InitializationException 2983 { 2984 saslConfigManager = new SASLConfigManager(); 2985 saslConfigManager.initializeSASLMechanismHandlers(); 2986 } 2987 2988 2989 2990 /** 2991 * Initializes the set of virtual attributes that should be defined in the 2992 * Directory Server. 2993 * 2994 * @throws ConfigException If there is a configuration problem with any of 2995 * the virtual attribute handlers. 2996 * 2997 * @throws InitializationException If a problem occurs while initializing 2998 * the virtual attribute handlers that is 2999 * not related to the server configuration. 3000 */ 3001 private void initializeVirtualAttributes() 3002 throws ConfigException, InitializationException 3003 { 3004 virtualAttributeConfigManager = new VirtualAttributeConfigManager(); 3005 virtualAttributeConfigManager.initializeVirtualAttributes(); 3006 } 3007 3008 3009 3010 /** 3011 * Initializes the set of connection handlers that should be defined in the 3012 * Directory Server. 3013 * 3014 * @throws ConfigException If there is a configuration problem with any of 3015 * the connection handlers. 3016 * 3017 * @throws InitializationException If a problem occurs while initializing 3018 * the connection handlers that is not 3019 * related to the server configuration. 3020 */ 3021 private void initializeConnectionHandlers() 3022 throws ConfigException, InitializationException 3023 { 3024 connectionHandlerConfigManager = new ConnectionHandlerConfigManager(); 3025 connectionHandlerConfigManager.initializeConnectionHandlerConfig(); 3026 } 3027 3028 3029 3030 /** 3031 * Initializes the set of password policy components for use by the Directory 3032 * Server. 3033 * 3034 * @throws ConfigException If there is a configuration problem with any of 3035 * the password policy components. 3036 * 3037 * @throws InitializationException If a problem occurs while initializing 3038 * the password policy components that is 3039 * not related to the server configuration. 3040 */ 3041 public void initializePasswordPolicyComponents() 3042 throws ConfigException, InitializationException 3043 { 3044 // Initialize all the password storage schemes. 3045 storageSchemeConfigManager = new PasswordStorageSchemeConfigManager(); 3046 storageSchemeConfigManager.initializePasswordStorageSchemes(); 3047 3048 3049 // Initialize all the password validators. 3050 passwordValidatorConfigManager = new PasswordValidatorConfigManager(); 3051 passwordValidatorConfigManager.initializePasswordValidators(); 3052 3053 3054 // Initialize all the password generators. 3055 passwordGeneratorConfigManager = new PasswordGeneratorConfigManager(); 3056 passwordGeneratorConfigManager.initializePasswordGenerators(); 3057 3058 3059 // Initialize the account status notification handlers. 3060 accountStatusNotificationHandlerConfigManager = 3061 new AccountStatusNotificationHandlerConfigManager(); 3062 accountStatusNotificationHandlerConfigManager. 3063 initializeNotificationHandlers(); 3064 3065 3066 // Initialize all the password policies. 3067 passwordPolicyConfigManager = new PasswordPolicyConfigManager(); 3068 passwordPolicyConfigManager.initializePasswordPolicies(); 3069 } 3070 3071 3072 3073 /** 3074 * Retrieves the operating system on which the Directory Server is running. 3075 * 3076 * @return The operating system on which the Directory Server is running. 3077 */ 3078 public static OperatingSystem getOperatingSystem() 3079 { 3080 return directoryServer.operatingSystem; 3081 } 3082 3083 3084 3085 /** 3086 * Retrieves the thread group that should be used by all threads associated 3087 * with the Directory Server. 3088 * 3089 * @return The thread group that should be used by all threads associated 3090 * with the Directory Server. 3091 */ 3092 public static ThreadGroup getDirectoryThreadGroup() 3093 { 3094 return directoryServer.directoryThreadGroup; 3095 } 3096 3097 3098 3099 /** 3100 * Retrieves a reference to the Directory Server configuration handler. 3101 * 3102 * @return A reference to the Directory Server configuration handler. 3103 */ 3104 public static ConfigHandler getConfigHandler() 3105 { 3106 return directoryServer.configHandler; 3107 } 3108 3109 3110 3111 /** 3112 * Initializes the set of plugins defined in the Directory Server. 3113 * 3114 * @throws ConfigException If there is a configuration problem with any of 3115 * the Directory Server plugins. 3116 * 3117 * @throws InitializationException If a problem occurs while initializing 3118 * the plugins that is not related to the 3119 * server configuration. 3120 */ 3121 public void initializePlugins() 3122 throws ConfigException, InitializationException 3123 { 3124 pluginConfigManager.initializePluginConfig(null); 3125 } 3126 3127 3128 3129 /** 3130 * Initializes the set of plugins defined in the Directory Server. Only the 3131 * specified types of plugins will be initialized. 3132 * 3133 * @param pluginTypes The set of plugin types for the plugins to 3134 * initialize. 3135 * 3136 * @throws ConfigException If there is a configuration problem with any of 3137 * the Directory Server plugins. 3138 * 3139 * @throws InitializationException If a problem occurs while initializing 3140 * the plugins that is not related to the 3141 * server configuration. 3142 */ 3143 public void initializePlugins(Set<PluginType> pluginTypes) 3144 throws ConfigException, InitializationException 3145 { 3146 pluginConfigManager = new PluginConfigManager(); 3147 pluginConfigManager.initializePluginConfig(pluginTypes); 3148 } 3149 3150 3151 3152 /** 3153 * Retrieves a reference to the Directory Server plugin configuration manager. 3154 * 3155 * @return A reference to the Directory Server plugin configuration manager. 3156 */ 3157 public static PluginConfigManager getPluginConfigManager() 3158 { 3159 return directoryServer.pluginConfigManager; 3160 } 3161 3162 3163 3164 /** 3165 * Retrieves the requested entry from the Directory Server configuration. 3166 * 3167 * @param entryDN The DN of the configuration entry to retrieve. 3168 * 3169 * @return The requested entry from the Directory Server configuration. 3170 * 3171 * @throws ConfigException If a problem occurs while trying to retrieve the 3172 * requested entry. 3173 */ 3174 public static ConfigEntry getConfigEntry(DN entryDN) 3175 throws ConfigException 3176 { 3177 return directoryServer.configHandler.getConfigEntry(entryDN); 3178 } 3179 3180 3181 3182 /** 3183 * Retrieves the path to the root directory for this instance of the Directory 3184 * Server. 3185 * 3186 * @return The path to the root directory for this instance of the Directory 3187 * Server. 3188 */ 3189 public static String getServerRoot() 3190 { 3191 if (directoryServer.configHandler == null) 3192 { 3193 File serverRoot = directoryServer.environmentConfig.getServerRoot(); 3194 if (serverRoot != null) 3195 { 3196 return serverRoot.getAbsolutePath(); 3197 } 3198 3199 // We don't know where the server root is, so we'll have to assume it's 3200 // the current working directory. 3201 return System.getProperty("user.dir"); 3202 } 3203 else 3204 { 3205 return directoryServer.configHandler.getServerRoot(); 3206 } 3207 } 3208 3209 /** 3210 * Retrieves the time that the Directory Server was started, in milliseconds 3211 * since the epoch. 3212 * 3213 * @return The time that the Directory Server was started, in milliseconds 3214 * since the epoch. 3215 */ 3216 public static long getStartTime() 3217 { 3218 return directoryServer.startUpTime; 3219 } 3220 3221 3222 3223 /** 3224 * Retrieves the time that the Directory Server was started, formatted in UTC. 3225 * 3226 * @return The time that the Directory Server was started, formatted in UTC. 3227 */ 3228 public static String getStartTimeUTC() 3229 { 3230 return directoryServer.startTimeUTC; 3231 } 3232 3233 3234 3235 /** 3236 * Retrieves a reference to the Directory Server schema. 3237 * 3238 * @return A reference to the Directory Server schema. 3239 */ 3240 public static Schema getSchema() 3241 { 3242 return directoryServer.schema; 3243 } 3244 3245 3246 3247 /** 3248 * Replaces the Directory Server schema with the provided schema. 3249 * 3250 * @param schema The new schema to use for the Directory Server. 3251 */ 3252 public static void setSchema(Schema schema) 3253 { 3254 directoryServer.schema = schema; 3255 } 3256 3257 3258 3259 /** 3260 * Retrieves a list of modifications detailing any schema changes that may 3261 * have been made with the server offline (e.g., by directly editing the 3262 * schema configuration files). Note that this information will not be 3263 * available until the server backends (and in particular, the schema backend) 3264 * have been initialized. 3265 * 3266 * @return A list of modifications detailing any schema changes that may have 3267 * been made with the server offline, or an empty list if no offline 3268 * schema changes have been detected. 3269 */ 3270 public static List<Modification> getOfflineSchemaChanges() 3271 { 3272 return directoryServer.offlineSchemaChanges; 3273 } 3274 3275 3276 3277 /** 3278 * Specifies a list of modifications detailing any schema changes that may 3279 * have been made with the server offline. 3280 * 3281 * @param offlineSchemaChanges A list of modifications detailing any schema 3282 * changes that may have been made with the 3283 * server offline. It must not be {@code null}. 3284 */ 3285 public static void setOfflineSchemaChanges(List<Modification> 3286 offlineSchemaChanges) 3287 { 3288 ensureNotNull(offlineSchemaChanges); 3289 3290 directoryServer.offlineSchemaChanges = offlineSchemaChanges; 3291 } 3292 3293 3294 3295 /** 3296 * Retrieves the set of matching rules registered with the Directory Server. 3297 * The mapping will be between the lowercase name or OID for each matching 3298 * rule and the matching rule implementation. The same matching rule instance 3299 * may be included multiple times with different keys. 3300 * 3301 * @return The set of matching rules registered with the Directory Server. 3302 */ 3303 public static ConcurrentHashMap<String,MatchingRule> getMatchingRules() 3304 { 3305 return directoryServer.schema.getMatchingRules(); 3306 } 3307 3308 3309 3310 /** 3311 * Retrieves the set of encoded matching rules that have been defined in the 3312 * Directory Server. 3313 * 3314 * @return The set of encoded matching rules that have been defined in the 3315 * Directory Server. 3316 */ 3317 public static LinkedHashSet<AttributeValue> getMatchingRuleSet() 3318 { 3319 return directoryServer.schema.getMatchingRuleSet(); 3320 } 3321 3322 3323 3324 /** 3325 * Retrieves the matching rule with the specified name or OID. 3326 * 3327 * @param lowerName The lowercase name or OID for the matching rule to 3328 * retrieve. 3329 * 3330 * @return The requested matching rule, or <CODE>null</CODE> if no such 3331 * matching rule has been defined in the server. 3332 */ 3333 public static MatchingRule getMatchingRule(String lowerName) 3334 { 3335 return directoryServer.schema.getMatchingRule(lowerName); 3336 } 3337 3338 3339 3340 /** 3341 * Registers the provided matching rule with the Directory Server. 3342 * 3343 * @param matchingRule The matching rule to register with the server. 3344 * @param overwriteExisting Indicates whether to overwrite an existing 3345 * mapping if there are any conflicts (i.e., 3346 * another matching rule with the same OID or 3347 * name). 3348 * 3349 * @throws DirectoryException If a conflict is encountered and the 3350 * <CODE>overwriteExisting</CODE> flag is set to 3351 * <CODE>false</CODE> 3352 */ 3353 public static void registerMatchingRule(MatchingRule matchingRule, 3354 boolean overwriteExisting) 3355 throws DirectoryException 3356 { 3357 directoryServer.schema.registerMatchingRule(matchingRule, 3358 overwriteExisting); 3359 } 3360 3361 3362 3363 /** 3364 * Deregisters the provided matching rule with the Directory Server. 3365 * 3366 * @param matchingRule The matching rule to deregister with the server. 3367 */ 3368 public static void deregisterMatchingRule(MatchingRule matchingRule) 3369 { 3370 directoryServer.schema.deregisterMatchingRule(matchingRule); 3371 } 3372 3373 3374 3375 /** 3376 * Retrieves the set of approximate matching rules registered with the 3377 * Directory Server. The mapping will be between the lowercase name or OID 3378 * for each approximate matching rule and the matching rule implementation. 3379 * The same approximate matching rule instance may be included multiple times 3380 * with different keys. 3381 * 3382 * @return The set of approximate matching rules registered with the 3383 * Directory Server. 3384 */ 3385 public static ConcurrentHashMap<String,ApproximateMatchingRule> 3386 getApproximateMatchingRules() 3387 { 3388 return directoryServer.schema.getApproximateMatchingRules(); 3389 } 3390 3391 3392 3393 /** 3394 * Retrieves the approximate matching rule with the specified name or OID. 3395 * 3396 * @param lowerName The lowercase name or OID for the approximate matching 3397 * rule to retrieve. 3398 * 3399 * @return The requested approximate matching rule, or <CODE>null</CODE> if 3400 * no such matching rule has been defined in the server. 3401 */ 3402 public static ApproximateMatchingRule 3403 getApproximateMatchingRule(String lowerName) 3404 { 3405 return directoryServer.schema.getApproximateMatchingRule(lowerName); 3406 } 3407 3408 3409 3410 /** 3411 * Registers the provided approximate matching rule with the Directory 3412 * Server. 3413 * 3414 * @param matchingRule The matching rule to register with the server. 3415 * @param overwriteExisting Indicates whether to overwrite an existing 3416 * mapping if there are any conflicts (i.e., 3417 * another matching rule with the same OID or 3418 * name). 3419 * 3420 * @throws DirectoryException If a conflict is encountered and the 3421 * <CODE>overwriteExisting</CODE> flag is set to 3422 * <CODE>false</CODE> 3423 */ 3424 public static void registerApproximateMatchingRule(ApproximateMatchingRule 3425 matchingRule, 3426 boolean overwriteExisting) 3427 throws DirectoryException 3428 { 3429 directoryServer.schema.registerApproximateMatchingRule(matchingRule, 3430 overwriteExisting); 3431 } 3432 3433 3434 3435 /** 3436 * Deregisters the provided approximate matching rule with the Directory 3437 * Server. 3438 * 3439 * @param matchingRule The matching rule to deregister with the server. 3440 */ 3441 public static void deregisterApproximateMatchingRule(ApproximateMatchingRule 3442 matchingRule) 3443 { 3444 directoryServer.schema.deregisterApproximateMatchingRule(matchingRule); 3445 } 3446 3447 3448 3449 /** 3450 * Retrieves the set of equality matching rules registered with the Directory 3451 * Server. The mapping will be between the lowercase name or OID for each 3452 * equality matching rule and the matching rule implementation. The same 3453 * equality matching rule instance may be included multiple times with 3454 * different keys. 3455 * 3456 * @return The set of equality matching rules registered with the Directory 3457 * Server. 3458 */ 3459 public static ConcurrentHashMap<String,EqualityMatchingRule> 3460 getEqualityMatchingRules() 3461 { 3462 return directoryServer.schema.getEqualityMatchingRules(); 3463 } 3464 3465 3466 3467 /** 3468 * Retrieves the equality matching rule with the specified name or OID. 3469 * 3470 * @param lowerName The lowercase name or OID for the equality matching rule 3471 * to retrieve. 3472 * 3473 * @return The requested equality matching rule, or <CODE>null</CODE> if no 3474 * such matching rule has been defined in the server. 3475 */ 3476 public static EqualityMatchingRule getEqualityMatchingRule(String lowerName) 3477 { 3478 return directoryServer.schema.getEqualityMatchingRule(lowerName); 3479 } 3480 3481 3482 3483 /** 3484 * Registers the provided equality matching rule with the Directory Server. 3485 * 3486 * @param matchingRule The matching rule to register with the server. 3487 * @param overwriteExisting Indicates whether to overwrite an existing 3488 * mapping if there are any conflicts (i.e., 3489 * another matching rule with the same OID or 3490 * name). 3491 * 3492 * @throws DirectoryException If a conflict is encountered and the 3493 * <CODE>overwriteExisting</CODE> flag is set to 3494 * <CODE>false</CODE> 3495 */ 3496 public static void registerEqualityMatchingRule(EqualityMatchingRule 3497 matchingRule, 3498 boolean overwriteExisting) 3499 throws DirectoryException 3500 { 3501 directoryServer.schema.registerEqualityMatchingRule(matchingRule, 3502 overwriteExisting); 3503 } 3504 3505 3506 3507 /** 3508 * Deregisters the provided equality matching rule with the Directory Server. 3509 * 3510 * @param matchingRule The matching rule to deregister with the server. 3511 */ 3512 public static void deregisterEqualityMatchingRule(EqualityMatchingRule 3513 matchingRule) 3514 { 3515 directoryServer.schema.deregisterEqualityMatchingRule(matchingRule); 3516 } 3517 3518 3519 3520 /** 3521 * Retrieves the set of ordering matching rules registered with the Directory 3522 * Server. The mapping will be between the lowercase name or OID for each 3523 * ordering matching rule and the matching rule implementation. The same 3524 * ordering matching rule instance may be included multiple times with 3525 * different keys. 3526 * 3527 * @return The set of ordering matching rules registered with the Directory 3528 * Server. 3529 */ 3530 public static ConcurrentHashMap<String,OrderingMatchingRule> 3531 getOrderingMatchingRules() 3532 { 3533 return directoryServer.schema.getOrderingMatchingRules(); 3534 } 3535 3536 3537 3538 /** 3539 * Retrieves the ordering matching rule with the specified name or OID. 3540 * 3541 * @param lowerName The lowercase name or OID for the ordering matching rule 3542 * to retrieve. 3543 * 3544 * @return The requested ordering matching rule, or <CODE>null</CODE> if no 3545 * such matching rule has been defined in the server. 3546 */ 3547 public static OrderingMatchingRule getOrderingMatchingRule(String lowerName) 3548 { 3549 return directoryServer.schema.getOrderingMatchingRule(lowerName); 3550 } 3551 3552 3553 3554 /** 3555 * Registers the provided ordering matching rule with the Directory Server. 3556 * 3557 * @param matchingRule The matching rule to register with the server. 3558 * @param overwriteExisting Indicates whether to overwrite an existing 3559 * mapping if there are any conflicts (i.e., 3560 * another matching rule with the same OID or 3561 * name). 3562 * 3563 * @throws DirectoryException If a conflict is encountered and the 3564 * <CODE>overwriteExisting</CODE> flag is set to 3565 * <CODE>false</CODE> 3566 */ 3567 public static void registerOrderingMatchingRule(OrderingMatchingRule 3568 matchingRule, 3569 boolean overwriteExisting) 3570 throws DirectoryException 3571 { 3572 directoryServer.schema.registerOrderingMatchingRule(matchingRule, 3573 overwriteExisting); 3574 } 3575 3576 3577 3578 /** 3579 * Deregisters the provided ordering matching rule with the Directory Server. 3580 * 3581 * @param matchingRule The matching rule to deregister with the server. 3582 */ 3583 public static void deregisterOrderingMatchingRule(OrderingMatchingRule 3584 matchingRule) 3585 { 3586 directoryServer.schema.deregisterOrderingMatchingRule(matchingRule); 3587 } 3588 3589 3590 3591 /** 3592 * Retrieves the set of substring matching rules registered with the Directory 3593 * Server. The mapping will be between the lowercase name or OID for each 3594 * substring matching rule and the matching rule implementation. The same 3595 * substring matching rule instance may be included multiple times with 3596 * different keys. 3597 * 3598 * @return The set of substring matching rules registered with the Directory 3599 * Server. 3600 */ 3601 public static ConcurrentHashMap<String,SubstringMatchingRule> 3602 getSubstringMatchingRules() 3603 { 3604 return directoryServer.schema.getSubstringMatchingRules(); 3605 } 3606 3607 3608 3609 /** 3610 * Retrieves the substring matching rule with the specified name or OID. 3611 * 3612 * @param lowerName The lowercase name or OID for the substring matching 3613 * rule to retrieve. 3614 * 3615 * @return The requested substring matching rule, or <CODE>null</CODE> if no 3616 * such matching rule has been defined in the server. 3617 */ 3618 public static SubstringMatchingRule getSubstringMatchingRule(String lowerName) 3619 { 3620 return directoryServer.schema.getSubstringMatchingRule(lowerName); 3621 } 3622 3623 3624 3625 /** 3626 * Registers the provided substring matching rule with the Directory Server. 3627 * 3628 * @param matchingRule The matching rule to register with the server. 3629 * @param overwriteExisting Indicates whether to overwrite an existing 3630 * mapping if there are any conflicts (i.e., 3631 * another matching rule with the same OID or 3632 * name). 3633 * 3634 * @throws DirectoryException If a conflict is encountered and the 3635 * <CODE>overwriteExisting</CODE> flag is set to 3636 * <CODE>false</CODE> 3637 */ 3638 public static void registerSubstringMatchingRule(SubstringMatchingRule 3639 matchingRule, 3640 boolean overwriteExisting) 3641 throws DirectoryException 3642 { 3643 directoryServer.schema.registerSubstringMatchingRule(matchingRule, 3644 overwriteExisting); 3645 } 3646 3647 3648 3649 /** 3650 * Deregisters the provided substring matching rule with the Directory Server. 3651 * 3652 * @param matchingRule The matching rule to deregister with the server. 3653 */ 3654 public static void deregisterSubstringMatchingRule(SubstringMatchingRule 3655 matchingRule) 3656 { 3657 directoryServer.schema.deregisterSubstringMatchingRule(matchingRule); 3658 } 3659 3660 3661 3662 /** 3663 * Retrieves the set of objectclasses defined in the Directory Server. 3664 * 3665 * @return The set of objectclasses defined in the Directory Server. 3666 */ 3667 public static ConcurrentHashMap<String,ObjectClass> getObjectClasses() 3668 { 3669 return directoryServer.schema.getObjectClasses(); 3670 } 3671 3672 3673 3674 /** 3675 * Retrieves the set of encoded objectclasses that have been defined in the 3676 * Directory Server. 3677 * 3678 * @return The set of encoded objectclasses that have been defined in the 3679 * Directory Server. 3680 */ 3681 public static LinkedHashSet<AttributeValue> getObjectClassSet() 3682 { 3683 return directoryServer.schema.getObjectClassSet(); 3684 } 3685 3686 3687 3688 /** 3689 * Retrieves the objectclass for the provided lowercase name or OID. 3690 * 3691 * @param lowerName The lowercase name or OID for the objectclass to 3692 * retrieve. 3693 * 3694 * @return The requested objectclass, or <CODE>null</CODE> if there is no 3695 * such objectclass defined in the server schema. 3696 */ 3697 public static ObjectClass getObjectClass(String lowerName) 3698 { 3699 return directoryServer.schema.getObjectClass(lowerName); 3700 } 3701 3702 3703 3704 /** 3705 * Retrieves the objectclass for the provided lowercase name or OID. It can 3706 * optionally return a generated "default" version if the requested 3707 * objectclass is not defined in the schema. 3708 * 3709 * @param lowerName The lowercase name or OID for the objectclass to 3710 * retrieve. 3711 * @param returnDefault Indicates whether to generate a default version if 3712 * the requested objectclass is not defined in the 3713 * server schema. 3714 * 3715 * @return The objectclass type, or <CODE>null</CODE> if there is no 3716 * objectclass with the specified name or OID defined in the server 3717 * schema and a default class should not be returned. 3718 */ 3719 public static ObjectClass getObjectClass(String lowerName, 3720 boolean returnDefault) 3721 { 3722 ObjectClass oc = directoryServer.schema.getObjectClass(lowerName); 3723 if (returnDefault && (oc == null)) 3724 { 3725 oc = getDefaultObjectClass(lowerName); 3726 } 3727 3728 return oc; 3729 } 3730 3731 3732 3733 /** 3734 * Registers the provided objectclass with the Directory Server. 3735 * 3736 * @param objectClass The objectclass instance to register with the 3737 * server. 3738 * @param overwriteExisting Indicates whether to overwrite an existing 3739 * mapping if there are any conflicts (i.e., 3740 * another objectclass with the same OID or 3741 * name). 3742 * 3743 * @throws DirectoryException If a conflict is encountered and the 3744 * <CODE>overwriteExisting</CODE> flag is set to 3745 * <CODE>false</CODE> 3746 */ 3747 public static void registerObjectClass(ObjectClass objectClass, 3748 boolean overwriteExisting) 3749 throws DirectoryException 3750 { 3751 directoryServer.schema.registerObjectClass(objectClass, overwriteExisting); 3752 } 3753 3754 3755 3756 /** 3757 * Deregisters the provided objectclass with the Directory Server. 3758 * 3759 * @param objectClass The objectclass instance to deregister with the 3760 * server. 3761 */ 3762 public static void deregisterObjectClass(ObjectClass objectClass) 3763 { 3764 directoryServer.schema.deregisterObjectClass(objectClass); 3765 } 3766 3767 3768 3769 /** 3770 * Retrieves the "top" objectClass, which should be the topmost objectclass in 3771 * the inheritance chain for most other objectclasses. If no such objectclass 3772 * could be found, then one will be constructed. 3773 * 3774 * @return The "top" objectClass. 3775 */ 3776 public static ObjectClass getTopObjectClass() 3777 { 3778 ObjectClass objectClass = 3779 directoryServer.schema.getObjectClass(TOP_OBJECTCLASS_NAME); 3780 if (objectClass == null) 3781 { 3782 String definition = 3783 "( 2.5.6.0 NAME 'top' ABSTRACT MUST objectClass " + 3784 "X-ORIGIN 'RFC 2256' )"; 3785 3786 objectClass = new ObjectClass(definition, TOP_OBJECTCLASS_NAME, 3787 Collections.singleton(TOP_OBJECTCLASS_NAME), 3788 TOP_OBJECTCLASS_OID, 3789 TOP_OBJECTCLASS_DESCRIPTION, null, null, 3790 null, ObjectClassType.ABSTRACT, false, 3791 null); 3792 } 3793 3794 return objectClass; 3795 } 3796 3797 3798 3799 /** 3800 * Causes the Directory Server to construct a new objectclass 3801 * definition with the provided name and with no required or allowed 3802 * attributes. This should only be used if there is no objectclass 3803 * for the specified name. It will not register the created 3804 * objectclass with the Directory Server. 3805 * 3806 * @param name 3807 * The name to use for the objectclass, as provided by the 3808 * user. 3809 * @return The constructed objectclass definition. 3810 */ 3811 public static ObjectClass getDefaultObjectClass(String name) 3812 { 3813 String lowerName = toLowerCase(name); 3814 ObjectClass objectClass = directoryServer.schema.getObjectClass(lowerName); 3815 if (objectClass == null) 3816 { 3817 String oid = lowerName + "-oid"; 3818 String definition = "( " + oid + " NAME '" + name + "' ABSTRACT )"; 3819 3820 objectClass = new ObjectClass(definition, name, 3821 Collections.singleton(name), oid, null, 3822 getTopObjectClass(), null, null, 3823 ObjectClassType.STRUCTURAL, false, null); 3824 } 3825 3826 return objectClass; 3827 } 3828 3829 3830 3831 /** 3832 * Causes the Directory Server to construct a new auxiliary objectclass 3833 * definition with the provided name and with no required or allowed 3834 * attributes. This should only be used if there is no objectclass for the 3835 * specified name. It will not register the created objectclass with the 3836 * Directory Server. 3837 * 3838 * @param name The name to use for the objectclass, as provided by the user. 3839 * 3840 * @return The constructed objectclass definition. 3841 */ 3842 public static ObjectClass getDefaultAuxiliaryObjectClass(String name) 3843 { 3844 String lowerName = toLowerCase(name); 3845 ObjectClass objectClass = directoryServer.schema.getObjectClass(lowerName); 3846 if (objectClass == null) 3847 { 3848 String oid = lowerName + "-oid"; 3849 String definition = "( " + oid + " NAME '" + name + "' ABSTRACT )"; 3850 3851 objectClass = new ObjectClass(definition, name, 3852 Collections.singleton(name), oid, null, 3853 getTopObjectClass(), null, null, 3854 ObjectClassType.AUXILIARY, false, null); 3855 } 3856 3857 return objectClass; 3858 } 3859 3860 3861 3862 /** 3863 * Retrieves the set of attribute type definitions that have been 3864 * defined in the Directory Server. 3865 * 3866 * @return The set of attribute type definitions that have been 3867 * defined in the Directory Server. 3868 */ 3869 public static ConcurrentHashMap<String,AttributeType> getAttributeTypes() 3870 { 3871 return directoryServer.schema.getAttributeTypes(); 3872 } 3873 3874 3875 3876 /** 3877 * Retrieves the set of encoded attribute types that have been defined in the 3878 * Directory Server. 3879 * 3880 * @return The set of encoded attribute types that have been defined in the 3881 * Directory Server. 3882 */ 3883 public static LinkedHashSet<AttributeValue> getAttributeTypeSet() 3884 { 3885 return directoryServer.schema.getAttributeTypeSet(); 3886 } 3887 3888 3889 3890 /** 3891 * Retrieves the attribute type for the provided lowercase name or OID. 3892 * 3893 * @param lowerName The lowercase attribute name or OID for the attribute 3894 * type to retrieve. 3895 * 3896 * @return The requested attribute type, or <CODE>null</CODE> if there is no 3897 * attribute with the specified type defined in the server schema. 3898 */ 3899 public static AttributeType getAttributeType(String lowerName) 3900 { 3901 return directoryServer.schema.getAttributeType(lowerName); 3902 } 3903 3904 3905 3906 /** 3907 * Retrieves the attribute type for the provided lowercase name or OID. It 3908 * can optionally return a generated "default" version if the requested 3909 * attribute type is not defined in the schema. 3910 * 3911 * @param lowerName The lowercase name or OID for the attribute type to 3912 * retrieve. 3913 * @param returnDefault Indicates whether to generate a default version if 3914 * the requested attribute type is not defined in the 3915 * server schema. 3916 * 3917 * @return The requested attribute type, or <CODE>null</CODE> if there is no 3918 * attribute with the specified type defined in the server schema and 3919 * a default type should not be returned. 3920 */ 3921 public static AttributeType getAttributeType(String lowerName, 3922 boolean returnDefault) 3923 { 3924 AttributeType type = directoryServer.schema.getAttributeType(lowerName); 3925 if (returnDefault && (type == null)) 3926 { 3927 type = getDefaultAttributeType(lowerName); 3928 } 3929 3930 return type; 3931 } 3932 3933 3934 3935 /** 3936 * Registers the provided attribute type with the Directory Server. 3937 * 3938 * @param attributeType The attribute type to register with the 3939 * Directory Server. 3940 * @param overwriteExisting Indicates whether to overwrite an existing 3941 * mapping if there are any conflicts (i.e., 3942 * another attribute type with the same OID or 3943 * name). 3944 * 3945 * @throws DirectoryException If a conflict is encountered and the 3946 * <CODE>overwriteExisting</CODE> flag is set to 3947 * <CODE>false</CODE> 3948 */ 3949 public static void registerAttributeType(AttributeType attributeType, 3950 boolean overwriteExisting) 3951 throws DirectoryException 3952 { 3953 directoryServer.schema.registerAttributeType(attributeType, 3954 overwriteExisting); 3955 } 3956 3957 3958 3959 /** 3960 * Deregisters the provided attribute type with the Directory Server. 3961 * 3962 * @param attributeType The attribute type to deregister with the Directory 3963 * Server. 3964 */ 3965 public static void deregisterAttributeType(AttributeType attributeType) 3966 { 3967 directoryServer.schema.deregisterAttributeType(attributeType); 3968 } 3969 3970 3971 3972 /** 3973 * Retrieves the attribute type for the "objectClass" attribute. 3974 * 3975 * @return The attribute type for the "objectClass" attribute. 3976 */ 3977 public static AttributeType getObjectClassAttributeType() 3978 { 3979 if (directoryServer.objectClassAttributeType == null) 3980 { 3981 directoryServer.objectClassAttributeType = 3982 directoryServer.schema.getAttributeType( 3983 OBJECTCLASS_ATTRIBUTE_TYPE_NAME); 3984 3985 if (directoryServer.objectClassAttributeType == null) 3986 { 3987 AttributeSyntax oidSyntax = 3988 directoryServer.schema.getSyntax(SYNTAX_OID_NAME); 3989 if (oidSyntax == null) 3990 { 3991 try 3992 { 3993 OIDSyntax newOIDSyntax = new OIDSyntax(); 3994 newOIDSyntax.initializeSyntax(null); 3995 oidSyntax = newOIDSyntax; 3996 directoryServer.schema.registerSyntax(oidSyntax, true); 3997 } 3998 catch (Exception e) 3999 { 4000 if (debugEnabled()) 4001 { 4002 TRACER.debugCaught(DebugLogLevel.ERROR, e); 4003 } 4004 } 4005 } 4006 4007 String definition = 4008 "( 2.5.4.0 NAME 'objectClass' EQUALITY objectIdentifierMatch " + 4009 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 X-ORIGIN 'RFC 2256' )"; 4010 4011 directoryServer.objectClassAttributeType = 4012 new AttributeType(definition, "objectClass", 4013 Collections.singleton("objectClass"), 4014 OBJECTCLASS_ATTRIBUTE_TYPE_OID, null, null, 4015 oidSyntax, AttributeUsage.USER_APPLICATIONS, 4016 false, false, false, false); 4017 try 4018 { 4019 directoryServer.schema.registerAttributeType( 4020 directoryServer.objectClassAttributeType, true); 4021 } 4022 catch (Exception e) 4023 { 4024 // This should never happen. 4025 if (debugEnabled()) 4026 { 4027 TRACER.debugCaught(DebugLogLevel.ERROR, e); 4028 } 4029 } 4030 } 4031 } 4032 4033 return directoryServer.objectClassAttributeType; 4034 } 4035 4036 4037 4038 /** 4039 * Causes the Directory Server to construct a new attribute type definition 4040 * with the provided name and using the default attribute syntax. This should 4041 * only be used if there is no real attribute type for the specified name. 4042 * 4043 * @param name The name to use for the attribute type, as provided by the 4044 * user. 4045 * 4046 * @return The constructed attribute type definition. 4047 */ 4048 public static AttributeType getDefaultAttributeType(String name) 4049 { 4050 return getDefaultAttributeType(name, getDefaultAttributeSyntax()); 4051 } 4052 4053 4054 4055 /** 4056 * Causes the Directory Server to construct a new attribute type definition 4057 * with the provided name and syntax. This should only be used if there is no 4058 * real attribute type for the specified name. 4059 * 4060 * @param name The name to use for the attribute type, as provided by the 4061 * user. 4062 * @param syntax The syntax to use for the attribute type. 4063 * 4064 * @return The constructed attribute type definition. 4065 */ 4066 public static AttributeType getDefaultAttributeType(String name, 4067 AttributeSyntax syntax) 4068 { 4069 String oid = toLowerCase(name) + "-oid"; 4070 String definition = "( " + oid + " NAME '" + name + "' SYNTAX " + 4071 syntax.getOID() + " )"; 4072 4073 return new AttributeType(definition, name, Collections.singleton(name), 4074 oid, null, null, syntax, 4075 AttributeUsage.USER_APPLICATIONS, false, false, 4076 false, false); 4077 } 4078 4079 4080 4081 /** 4082 * Retrieves the set of attribute syntaxes defined in the Directory Server. 4083 * 4084 * @return The set of attribute syntaxes defined in the Directory Server. 4085 */ 4086 public static ConcurrentHashMap<String,AttributeSyntax> getAttributeSyntaxes() 4087 { 4088 return directoryServer.schema.getSyntaxes(); 4089 } 4090 4091 4092 4093 /** 4094 * Retrieves the set of encoded attribute syntaxes that have been defined in 4095 * the Directory Server. 4096 * 4097 * @return The set of encoded attribute syntaxes that have been defined in 4098 * the Directory Server. 4099 */ 4100 public static LinkedHashSet<AttributeValue> getAttributeSyntaxSet() 4101 { 4102 return directoryServer.schema.getSyntaxSet(); 4103 } 4104 4105 4106 4107 /** 4108 * Retrieves the requested attribute syntax. 4109 * 4110 * @param oid The OID of the syntax to retrieve. 4111 * @param allowDefault Indicates whether to return the default attribute 4112 * syntax if the requested syntax is unknown. 4113 * 4114 * @return The requested attribute syntax, the default syntax if the 4115 * requested syntax is unknown and the caller has indicated that the 4116 * default is acceptable, or <CODE>null</CODE> otherwise. 4117 */ 4118 public static AttributeSyntax getAttributeSyntax(String oid, 4119 boolean allowDefault) 4120 { 4121 AttributeSyntax syntax = directoryServer.schema.getSyntax(oid); 4122 if ((syntax == null) && allowDefault) 4123 { 4124 return getDefaultAttributeSyntax(); 4125 } 4126 4127 return syntax; 4128 } 4129 4130 4131 4132 /** 4133 * Registers the provided attribute syntax with the Directory Server. 4134 * 4135 * @param syntax The attribute syntax to register with the 4136 * Directory Server. 4137 * @param overwriteExisting Indicates whether to overwrite an existing 4138 * mapping if there are any conflicts (i.e., 4139 * another attribute syntax with the same OID or 4140 * name). 4141 * 4142 * @throws DirectoryException If a conflict is encountered and the 4143 * <CODE>overwriteExisting</CODE> flag is set to 4144 * <CODE>false</CODE> 4145 */ 4146 public static void registerAttributeSyntax(AttributeSyntax syntax, 4147 boolean overwriteExisting) 4148 throws DirectoryException 4149 { 4150 directoryServer.schema.registerSyntax(syntax, overwriteExisting); 4151 } 4152 4153 4154 4155 /** 4156 * Deregisters the provided attribute syntax with the Directory Server. 4157 * 4158 * @param syntax The attribute syntax to deregister with the Directory 4159 * Server. 4160 */ 4161 public static void deregisterAttributeSyntax(AttributeSyntax syntax) 4162 { 4163 directoryServer.schema.deregisterSyntax(syntax); 4164 } 4165 4166 4167 4168 /** 4169 * Retrieves the default attribute syntax that should be used for attributes 4170 * that are not defined in the server schema. 4171 * 4172 * @return The default attribute syntax that should be used for attributes 4173 * that are not defined in the server schema. 4174 */ 4175 public static AttributeSyntax getDefaultAttributeSyntax() 4176 { 4177 return directoryServer.defaultSyntax; 4178 } 4179 4180 4181 4182 /** 4183 * Retrieves the default attribute syntax that should be used for attributes 4184 * that are not defined in the server schema and are meant to store binary 4185 * values. 4186 * 4187 * @return The default attribute syntax that should be used for attributes 4188 * that are not defined in the server schema and are meant to store 4189 * binary values. 4190 */ 4191 public static AttributeSyntax getDefaultBinarySyntax() 4192 { 4193 return directoryServer.defaultBinarySyntax; 4194 } 4195 4196 4197 4198 /** 4199 * Retrieves the default attribute syntax that should be used for attributes 4200 * that are not defined in the server schema and are meant to store Boolean 4201 * values. 4202 * 4203 * @return The default attribute syntax that should be used for attributes 4204 * that are not defined in the server schema and are meant to store 4205 * Boolean values. 4206 */ 4207 public static AttributeSyntax getDefaultBooleanSyntax() 4208 { 4209 return directoryServer.defaultBooleanSyntax; 4210 } 4211 4212 4213 4214 /** 4215 * Retrieves the default attribute syntax that should be used for attributes 4216 * that are not defined in the server schema and are meant to store DN values. 4217 * 4218 * @return The default attribute syntax that should be used for attributes 4219 * that are not defined in the server schema and are meant to store 4220 * DN values. 4221 */ 4222 public static AttributeSyntax getDefaultDNSyntax() 4223 { 4224 return directoryServer.defaultDNSyntax; 4225 } 4226 4227 4228 4229 /** 4230 * Retrieves the default attribute syntax that should be used for attributes 4231 * that are not defined in the server schema and are meant to store integer 4232 * values. 4233 * 4234 * @return The default attribute syntax that should be used for attributes 4235 * that are not defined in the server schema and are meant to store 4236 * integer values. 4237 */ 4238 public static AttributeSyntax getDefaultIntegerSyntax() 4239 { 4240 return directoryServer.defaultIntegerSyntax; 4241 } 4242 4243 4244 4245 /** 4246 * Retrieves the default attribute syntax that should be used for attributes 4247 * that are not defined in the server schema and are meant to store string 4248 * values. 4249 * 4250 * @return The default attribute syntax that should be used for attributes 4251 * that are not defined in the server schema and are meant to store 4252 * string values. 4253 */ 4254 public static AttributeSyntax getDefaultStringSyntax() 4255 { 4256 return directoryServer.defaultStringSyntax; 4257 } 4258 4259 4260 4261 /** 4262 * Retrieves the set of matching rule uses defined in the Directory Server. 4263 * 4264 * @return The set of matching rule uses defined in the Directory Server. 4265 */ 4266 public static ConcurrentHashMap<MatchingRule,MatchingRuleUse> 4267 getMatchingRuleUses() 4268 { 4269 return directoryServer.schema.getMatchingRuleUses(); 4270 } 4271 4272 4273 4274 /** 4275 * Retrieves the set of encoded matching rule uses that have been defined in 4276 * the Directory Server. 4277 * 4278 * @return The set of encoded matching rule uses that have been defined in 4279 * the Directory Server. 4280 */ 4281 public static LinkedHashSet<AttributeValue> getMatchingRuleUseSet() 4282 { 4283 return directoryServer.schema.getMatchingRuleUseSet(); 4284 } 4285 4286 4287 4288 /** 4289 * Retrieves the matching rule use associated with the provided matching rule. 4290 * 4291 * @param matchingRule The matching rule for which to retrieve the matching 4292 * rule use. 4293 * 4294 * @return The matching rule use for the provided matching rule, or 4295 * <CODE>null</CODE> if none is defined. 4296 */ 4297 public static MatchingRuleUse getMatchingRuleUse(MatchingRule matchingRule) 4298 { 4299 return directoryServer.schema.getMatchingRuleUse(matchingRule); 4300 } 4301 4302 4303 4304 /** 4305 * Registers the provided matching rule use with the Directory Server. 4306 * 4307 * @param matchingRuleUse The matching rule use to register with the 4308 * server. 4309 * @param overwriteExisting Indicates whether to overwrite an existing 4310 * mapping if there are any conflicts (i.e., 4311 * another matching rule use with the same matching 4312 * rule). 4313 * 4314 * @throws DirectoryException If a conflict is encountered and the 4315 * <CODE>overwriteExisting</CODE> flag is set to 4316 * <CODE>false</CODE> 4317 */ 4318 public static void registerMatchingRuleUse(MatchingRuleUse matchingRuleUse, 4319 boolean overwriteExisting) 4320 throws DirectoryException 4321 { 4322 directoryServer.schema.registerMatchingRuleUse(matchingRuleUse, 4323 overwriteExisting); 4324 } 4325 4326 4327 4328 /** 4329 * Deregisters the provided matching rule use with the Directory Server. 4330 * 4331 * @param matchingRuleUse The matching rule use to deregister with the 4332 * server. 4333 */ 4334 public static void deregisterMatchingRuleUse(MatchingRuleUse matchingRuleUse) 4335 { 4336 directoryServer.schema.deregisterMatchingRuleUse(matchingRuleUse); 4337 } 4338 4339 4340 4341 /** 4342 * Retrieves the set of DIT content rules defined in the Directory Server. 4343 * 4344 * @return The set of DIT content rules defined in the Directory Server. 4345 */ 4346 public static ConcurrentHashMap<ObjectClass,DITContentRule> 4347 getDITContentRules() 4348 { 4349 return directoryServer.schema.getDITContentRules(); 4350 } 4351 4352 4353 4354 /** 4355 * Retrieves the set of encoded DIT content rules that have been defined in 4356 * the Directory Server. 4357 * 4358 * @return The set of encoded DIT content rules that have been defined in the 4359 * Directory Server. 4360 */ 4361 public static LinkedHashSet<AttributeValue> getDITContentRuleSet() 4362 { 4363 return directoryServer.schema.getDITContentRuleSet(); 4364 } 4365 4366 4367 4368 /** 4369 * Retrieves the DIT content rule associated with the specified objectclass. 4370 * 4371 * @param objectClass The objectclass for which to retrieve the associated 4372 * DIT content rule. 4373 * 4374 * @return The requested DIT content rule, or <CODE>null</CODE> if no such 4375 * rule is defined in the schema. 4376 */ 4377 public static DITContentRule getDITContentRule(ObjectClass objectClass) 4378 { 4379 return directoryServer.schema.getDITContentRule(objectClass); 4380 } 4381 4382 4383 4384 /** 4385 * Registers the provided DIT content rule with the Directory Server. 4386 * 4387 * @param ditContentRule The DIT content rule to register with the 4388 * server. 4389 * @param overwriteExisting Indicates whether to overwrite an existing 4390 * mapping if there are any conflicts (i.e., 4391 * another DIT content rule with the same 4392 * structural objectclass). 4393 * 4394 * @throws DirectoryException If a conflict is encountered and the 4395 * <CODE>overwriteExisting</CODE> flag is set to 4396 * <CODE>false</CODE> 4397 */ 4398 public static void registerDITContentRule(DITContentRule ditContentRule, 4399 boolean overwriteExisting) 4400 throws DirectoryException 4401 { 4402 directoryServer.schema.registerDITContentRule(ditContentRule, 4403 overwriteExisting); 4404 } 4405 4406 4407 4408 /** 4409 * Deregisters the provided DIT content rule with the Directory Server. 4410 * 4411 * @param ditContentRule The DIT content rule to deregister with the server. 4412 */ 4413 public static void deregisterDITContentRule(DITContentRule ditContentRule) 4414 { 4415 directoryServer.schema.deregisterDITContentRule(ditContentRule); 4416 } 4417 4418 4419 4420 /** 4421 * Retrieves the set of DIT structure rules defined in the Directory Server. 4422 * 4423 * @return The set of DIT structure rules defined in the Directory Server. 4424 */ 4425 public static ConcurrentHashMap<NameForm,DITStructureRule> 4426 getDITStructureRules() 4427 { 4428 return directoryServer.schema.getDITStructureRulesByNameForm(); 4429 } 4430 4431 4432 4433 /** 4434 * Retrieves the set of encoded DIT structure rules that have been defined in 4435 * the Directory Server. 4436 * 4437 * @return The set of encoded DIT structure rules that have been defined in 4438 * the Directory Server. 4439 */ 4440 public static LinkedHashSet<AttributeValue> getDITStructureRuleSet() 4441 { 4442 return directoryServer.schema.getDITStructureRuleSet(); 4443 } 4444 4445 4446 4447 /** 4448 * Retrieves the DIT structure rule associated with the provided rule ID. 4449 * 4450 * @param ruleID The rule ID for which to retrieve the associated DIT 4451 * structure rule. 4452 * 4453 * @return The requested DIT structure rule, or <CODE>null</CODE> if no such 4454 * rule is defined. 4455 */ 4456 public static DITStructureRule getDITStructureRule(int ruleID) 4457 { 4458 return directoryServer.schema.getDITStructureRule(ruleID); 4459 } 4460 4461 4462 4463 /** 4464 * Retrieves the DIT structure rule associated with the provided name form. 4465 * 4466 * @param nameForm The name form for which to retrieve the associated DIT 4467 * structure rule. 4468 * 4469 * @return The requested DIT structure rule, or <CODE>null</CODE> if no such 4470 * rule is defined. 4471 */ 4472 public static DITStructureRule getDITStructureRule(NameForm nameForm) 4473 { 4474 return directoryServer.schema.getDITStructureRule(nameForm); 4475 } 4476 4477 4478 4479 /** 4480 * Registers the provided DIT structure rule with the Directory Server. 4481 * 4482 * @param ditStructureRule The DIT structure rule to register with the 4483 * server. 4484 * @param overwriteExisting Indicates whether to overwrite an existing 4485 * mapping if there are any conflicts (i.e., 4486 * another DIT structure rule with the same name 4487 * form). 4488 * 4489 * @throws DirectoryException If a conflict is encountered and the 4490 * <CODE>overwriteExisting</CODE> flag is set to 4491 * <CODE>false</CODE> 4492 */ 4493 public static void registerDITStructureRule(DITStructureRule ditStructureRule, 4494 boolean overwriteExisting) 4495 throws DirectoryException 4496 { 4497 directoryServer.schema.registerDITStructureRule(ditStructureRule, 4498 overwriteExisting); 4499 } 4500 4501 4502 4503 /** 4504 * Deregisters the provided DIT structure rule with the Directory Server. 4505 * 4506 * @param ditStructureRule The DIT structure rule to deregister with the 4507 * server. 4508 */ 4509 public static void deregisterDITStructureRule(DITStructureRule 4510 ditStructureRule) 4511 { 4512 directoryServer.schema.deregisterDITStructureRule(ditStructureRule); 4513 } 4514 4515 4516 4517 /** 4518 * Retrieves the set of name forms defined in the Directory Server. 4519 * 4520 * @return The set of name forms defined in the Directory Server. 4521 */ 4522 public static ConcurrentHashMap<ObjectClass,NameForm> getNameForms() 4523 { 4524 return directoryServer.schema.getNameFormsByObjectClass(); 4525 } 4526 4527 4528 4529 /** 4530 * Retrieves the set of encoded name forms that have been defined in the 4531 * Directory Server. 4532 * 4533 * @return The set of encoded name forms that have been defined in the 4534 * Directory Server. 4535 */ 4536 public static LinkedHashSet<AttributeValue> getNameFormSet() 4537 { 4538 return directoryServer.schema.getNameFormSet(); 4539 } 4540 4541 4542 4543 /** 4544 * Retrieves the name form associated with the specified objectclass. 4545 * 4546 * @param objectClass The objectclass for which to retrieve the associated 4547 * name form. 4548 * 4549 * @return The requested name form, or <CODE>null</CODE> if no such name form 4550 * is defined in the schema. 4551 */ 4552 public static NameForm getNameForm(ObjectClass objectClass) 4553 { 4554 return directoryServer.schema.getNameForm(objectClass); 4555 } 4556 4557 4558 4559 /** 4560 * Retrieves the name form associated with the specified name or OID. 4561 * 4562 * @param lowerName The name or OID of the name form to retrieve, formatted 4563 * in all lowercase characters. 4564 * 4565 * @return The requested name form, or <CODE>null</CODE> if no such name form 4566 * is defined in the schema. 4567 */ 4568 public static NameForm getNameForm(String lowerName) 4569 { 4570 return directoryServer.schema.getNameForm(lowerName); 4571 } 4572 4573 4574 4575 /** 4576 * Registers the provided name form with the Directory Server. 4577 * 4578 * @param nameForm The name form to register with the server. 4579 * @param overwriteExisting Indicates whether to overwrite an existing 4580 * mapping if there are any conflicts (i.e., 4581 * another name form with the same structural 4582 * objectclass). 4583 * 4584 * @throws DirectoryException If a conflict is encountered and the 4585 * <CODE>overwriteExisting</CODE> flag is set to 4586 * <CODE>false</CODE> 4587 */ 4588 public static void registerNameForm(NameForm nameForm, 4589 boolean overwriteExisting) 4590 throws DirectoryException 4591 { 4592 directoryServer.schema.registerNameForm(nameForm, overwriteExisting); 4593 } 4594 4595 4596 4597 /** 4598 * Deregisters the provided name form with the Directory Server. 4599 * 4600 * @param nameForm The name form to deregister with the server. 4601 */ 4602 public static void deregisterNameForm(NameForm nameForm) 4603 { 4604 directoryServer.schema.deregisterNameForm(nameForm); 4605 } 4606 4607 4608 4609 /** 4610 * Retrieves the set of virtual attribute rules registered with the Directory 4611 * Server. 4612 * 4613 * @return The set of virtual attribute rules registered with the Directory 4614 * Server. 4615 */ 4616 public static List<VirtualAttributeRule> getVirtualAttributes() 4617 { 4618 return directoryServer.virtualAttributes; 4619 } 4620 4621 4622 4623 /** 4624 * Retrieves the set of virtual attribute rules registered with the Directory 4625 * Server that are applicable to the provided entry. 4626 * 4627 * @param entry The entry for which to retrieve the applicable virtual 4628 * attribute rules. 4629 * 4630 * @return The set of virtual attribute rules registered with the Directory 4631 * Server that apply to the given entry. It may be an empty list if 4632 * there are no applicable virtual attribute rules. 4633 */ 4634 public static List<VirtualAttributeRule> getVirtualAttributes(Entry entry) 4635 { 4636 LinkedList<VirtualAttributeRule> ruleList = 4637 new LinkedList<VirtualAttributeRule>(); 4638 4639 for (VirtualAttributeRule rule : directoryServer.virtualAttributes) 4640 { 4641 if (rule.appliesToEntry(entry)) 4642 { 4643 ruleList.add(rule); 4644 } 4645 } 4646 4647 return ruleList; 4648 } 4649 4650 4651 4652 /** 4653 * Registers the provided virtual attribute rule with the Directory Server. 4654 * 4655 * @param rule The virtual attribute rule to be registered. 4656 */ 4657 public static void registerVirtualAttribute(VirtualAttributeRule rule) 4658 { 4659 synchronized (directoryServer.virtualAttributes) 4660 { 4661 directoryServer.virtualAttributes.add(rule); 4662 } 4663 } 4664 4665 4666 4667 /** 4668 * Deregisters the provided virtual attribute rule with the Directory Server. 4669 * 4670 * @param rule The virutal attribute rule to be deregistered. 4671 */ 4672 public static void deregisterVirtualAttribute(VirtualAttributeRule rule) 4673 { 4674 synchronized (directoryServer.virtualAttributes) 4675 { 4676 directoryServer.virtualAttributes.remove(rule); 4677 } 4678 } 4679 4680 4681 4682 /** 4683 * Replaces the specified virtual attribute rule in the set of virtual 4684 * attributes registered with the Directory Server. If the old rule cannot 4685 * be found in the list, then the set of registered virtual attributes is not 4686 * updated. 4687 * 4688 * @param oldRule The existing rule that should be replaced with the new 4689 * rule. 4690 * @param newRule The new rule that should be used in place of the existing 4691 * rule. 4692 * 4693 * @return {@code true} if the old rule was found and replaced with the new 4694 * version, or {@code false} if it was not. 4695 */ 4696 public static boolean replaceVirtualAttribute(VirtualAttributeRule oldRule, 4697 VirtualAttributeRule newRule) 4698 { 4699 synchronized (directoryServer.virtualAttributes) 4700 { 4701 int pos = directoryServer.virtualAttributes.indexOf(oldRule); 4702 if (pos >= 0) 4703 { 4704 directoryServer.virtualAttributes.set(pos, newRule); 4705 return true; 4706 } 4707 else 4708 { 4709 return false; 4710 } 4711 } 4712 } 4713 4714 4715 4716 /** 4717 * Retrieves a reference to the JMX MBean server that is associated with the 4718 * Directory Server. 4719 * 4720 * @return The JMX MBean server that is associated with the Directory Server. 4721 */ 4722 public static MBeanServer getJMXMBeanServer() 4723 { 4724 return directoryServer.mBeanServer; 4725 } 4726 4727 4728 4729 /** 4730 * Retrieves the set of JMX MBeans that are associated with the server. 4731 * 4732 * @return The set of JMX MBeans that are associated with the server. 4733 */ 4734 public static ConcurrentHashMap<DN,JMXMBean> getJMXMBeans() 4735 { 4736 return directoryServer.mBeans; 4737 } 4738 4739 4740 4741 /** 4742 * Retrieves the JMX MBean associated with the specified entry in the 4743 * Directory Server configuration. 4744 * 4745 * @param configEntryDN The DN of the configuration entry for which to 4746 * retrieve the associated JMX MBean. 4747 * 4748 * @return The JMX MBean associated with the specified entry in the Directory 4749 * Server configuration, or <CODE>null</CODE> if there is no MBean 4750 * for the specified entry. 4751 */ 4752 public static JMXMBean getJMXMBean(DN configEntryDN) 4753 { 4754 return directoryServer.mBeans.get(configEntryDN); 4755 } 4756 4757 4758 4759 /** 4760 * Registers the provided invokable component with the Directory Server. 4761 * 4762 * @param component The invokable component to register. 4763 */ 4764 public static void registerInvokableComponent(InvokableComponent component) 4765 { 4766 DN componentDN = component.getInvokableComponentEntryDN(); 4767 JMXMBean mBean = directoryServer.mBeans.get(componentDN); 4768 if (mBean == null) 4769 { 4770 mBean = new JMXMBean(componentDN); 4771 mBean.addInvokableComponent(component); 4772 directoryServer.mBeans.put(componentDN, mBean); 4773 } 4774 else 4775 { 4776 mBean.addInvokableComponent(component); 4777 } 4778 } 4779 4780 4781 4782 /** 4783 * Deregisters the provided invokable component with the Directory Server. 4784 * 4785 * @param component The invokable component to deregister. 4786 */ 4787 public static void deregisterInvokableComponent(InvokableComponent component) 4788 { 4789 DN componentDN = component.getInvokableComponentEntryDN(); 4790 JMXMBean mBean = directoryServer.mBeans.get(componentDN); 4791 if (mBean != null) 4792 { 4793 mBean.removeInvokableComponent(component); 4794 } 4795 } 4796 4797 4798 4799 /** 4800 * Registers the provided alert generator with the Directory Server. 4801 * 4802 * @param alertGenerator The alert generator to register. 4803 */ 4804 public static void registerAlertGenerator(AlertGenerator alertGenerator) 4805 { 4806 DN componentDN = alertGenerator.getComponentEntryDN(); 4807 JMXMBean mBean = directoryServer.mBeans.get(componentDN); 4808 if (mBean == null) 4809 { 4810 mBean = new JMXMBean(componentDN); 4811 mBean.addAlertGenerator(alertGenerator); 4812 directoryServer.mBeans.put(componentDN, mBean); 4813 } 4814 else 4815 { 4816 mBean.addAlertGenerator(alertGenerator); 4817 } 4818 } 4819 4820 4821 4822 /** 4823 * Deregisters the provided alert generator with the Directory Server. 4824 * 4825 * @param alertGenerator The alert generator to deregister. 4826 */ 4827 public static void deregisterAlertGenerator(AlertGenerator alertGenerator) 4828 { 4829 DN componentDN = alertGenerator.getComponentEntryDN(); 4830 JMXMBean mBean = directoryServer.mBeans.get(componentDN); 4831 if (mBean != null) 4832 { 4833 mBean.removeAlertGenerator(alertGenerator); 4834 } 4835 } 4836 4837 4838 4839 /** 4840 * Retrieves the set of alert handlers that have been registered with the 4841 * Directory Server. 4842 * 4843 * @return The set of alert handlers that have been registered with the 4844 * Directory Server. 4845 */ 4846 public static CopyOnWriteArrayList<AlertHandler> getAlertHandlers() 4847 { 4848 return directoryServer.alertHandlers; 4849 } 4850 4851 4852 4853 /** 4854 * Registers the provided alert handler with the Directory Server. 4855 * 4856 * @param alertHandler The alert handler to register. 4857 */ 4858 public static void registerAlertHandler(AlertHandler alertHandler) 4859 { 4860 directoryServer.alertHandlers.add(alertHandler); 4861 } 4862 4863 4864 4865 /** 4866 * Deregisters the provided alert handler with the Directory Server. 4867 * 4868 * @param alertHandler The alert handler to deregister. 4869 */ 4870 public static void deregisterAlertHandler(AlertHandler alertHandler) 4871 { 4872 directoryServer.alertHandlers.remove(alertHandler); 4873 } 4874 4875 4876 4877 /** 4878 * Sends an alert notification with the provided information. 4879 * 4880 * @param generator The alert generator that created the alert. 4881 * @param alertType The alert type name for this alert. 4882 * @param alertMessage A message (possibly <CODE>null</CODE>) that can 4883 */ 4884 public static void sendAlertNotification(AlertGenerator generator, 4885 String alertType, 4886 Message alertMessage) 4887 { 4888 if ((directoryServer.alertHandlers == null) || 4889 directoryServer.alertHandlers.isEmpty()) 4890 { 4891 // If the Directory Server is still in the process of starting up, then 4892 // create a JMX alert handler to use for this notification. 4893 if (! directoryServer.isRunning) 4894 { 4895 try 4896 { 4897 JMXAlertHandler alertHandler = new JMXAlertHandler(); 4898 alertHandler.initializeAlertHandler(null); 4899 alertHandler.sendAlertNotification(generator, alertType, 4900 alertMessage); 4901 } 4902 catch (Exception e) 4903 { 4904 if (debugEnabled()) 4905 { 4906 TRACER.debugCaught(DebugLogLevel.ERROR, e); 4907 } 4908 } 4909 } 4910 } 4911 else 4912 { 4913 for (AlertHandler alertHandler : directoryServer.alertHandlers) 4914 { 4915 AlertHandlerCfg config = alertHandler.getAlertHandlerConfiguration(); 4916 Set<String> enabledAlerts = config.getEnabledAlertType(); 4917 Set<String> disabledAlerts = config.getDisabledAlertType(); 4918 if ((enabledAlerts == null) || enabledAlerts.isEmpty()) 4919 { 4920 if ((disabledAlerts != null) && disabledAlerts.contains(alertType)) 4921 { 4922 continue; 4923 } 4924 } 4925 else 4926 { 4927 if (enabledAlerts.contains(alertType)) 4928 { 4929 if ((disabledAlerts != null) && disabledAlerts.contains(alertType)) 4930 { 4931 continue; 4932 } 4933 } 4934 else 4935 { 4936 continue; 4937 } 4938 } 4939 4940 alertHandler.sendAlertNotification(generator, alertType, alertMessage); 4941 } 4942 } 4943 4944 4945 Message message = NOTE_SENT_ALERT_NOTIFICATION.get( 4946 generator.getClassName(), alertType, 4947 alertMessage != null ? 4948 String.valueOf(alertMessage.getDescriptor().getId()) : 4949 String.valueOf(MessageDescriptor.NULL_ID), 4950 alertMessage); 4951 logError(message); 4952 } 4953 4954 4955 4956 /** 4957 * Retrieves the password storage scheme defined in the specified 4958 * configuration entry. 4959 * 4960 * @param configEntryDN The DN of the configuration entry that defines the 4961 * password storage scheme to retrieve. 4962 * 4963 * @return The requested password storage scheme, or {@code null} if no such 4964 * scheme is defined. 4965 */ 4966 public static PasswordStorageScheme getPasswordStorageScheme(DN configEntryDN) 4967 { 4968 return directoryServer.passwordStorageSchemesByDN.get(configEntryDN); 4969 } 4970 4971 4972 4973 /** 4974 * Retrieves the set of password storage schemes defined in the Directory 4975 * Server, as a mapping between the all-lowercase scheme name and the 4976 * corresponding implementation. 4977 * 4978 * @return The set of password storage schemes defined in the Directory 4979 * Server. 4980 */ 4981 public static ConcurrentHashMap<String,PasswordStorageScheme> 4982 getPasswordStorageSchemes() 4983 { 4984 return directoryServer.passwordStorageSchemes; 4985 } 4986 4987 4988 4989 /** 4990 * Retrieves the specified password storage scheme. 4991 * 4992 * @param lowerName The name of the password storage scheme to retrieve, 4993 * formatted in all lowercase characters. 4994 * 4995 * @return The requested password storage scheme, or <CODE>null</CODE> if no 4996 * such scheme is defined. 4997 */ 4998 public static PasswordStorageScheme getPasswordStorageScheme(String lowerName) 4999 { 5000 return directoryServer.passwordStorageSchemes.get(lowerName); 5001 } 5002 5003 5004 5005 /** 5006 * Retrieves the set of authentication password storage schemes defined in the 5007 * Directory Server, as a mapping between the scheme name and the 5008 * corresponding implementation. 5009 * 5010 * @return The set of authentication password storage schemes defined in the 5011 * Directory Server. 5012 */ 5013 public static ConcurrentHashMap<String,PasswordStorageScheme> 5014 getAuthPasswordStorageSchemes() 5015 { 5016 return directoryServer.authPasswordStorageSchemes; 5017 } 5018 5019 5020 5021 /** 5022 * Retrieves the specified authentication password storage scheme. 5023 * 5024 * @param name The case-sensitive name of the authentication password 5025 * storage scheme to retrieve. 5026 * 5027 * @return The requested authentication password storage scheme, or 5028 * <CODE>null</CODE> if no such scheme is defined. 5029 */ 5030 public static PasswordStorageScheme getAuthPasswordStorageScheme(String name) 5031 { 5032 return directoryServer.authPasswordStorageSchemes.get(name); 5033 } 5034 5035 5036 5037 /** 5038 * Registers the provided password storage scheme with the Directory Server. 5039 * If an existing password storage scheme is registered with the same name, 5040 * then it will be replaced with the provided scheme. 5041 * 5042 * @param configEntryDN The DN of the configuration entry that defines the 5043 * password storage scheme. 5044 * @param scheme The password storage scheme to register with the 5045 * Directory Server. 5046 */ 5047 public static void registerPasswordStorageScheme(DN configEntryDN, 5048 PasswordStorageScheme scheme) 5049 { 5050 directoryServer.passwordStorageSchemesByDN.put(configEntryDN, scheme); 5051 5052 String name = toLowerCase(scheme.getStorageSchemeName()); 5053 directoryServer.passwordStorageSchemes.put(name, scheme); 5054 5055 if (scheme.supportsAuthPasswordSyntax()) 5056 { 5057 directoryServer.authPasswordStorageSchemes.put( 5058 scheme.getAuthPasswordSchemeName(), scheme); 5059 } 5060 } 5061 5062 5063 5064 /** 5065 * Deregisters the specified password storage scheme with the Directory 5066 * Server. If no scheme is registered with the specified name, then no action 5067 * will be taken. 5068 * 5069 * @param configEntryDN The DN of the configuration entry that defines the 5070 * password storage scheme. 5071 */ 5072 public static void deregisterPasswordStorageScheme(DN configEntryDN) 5073 { 5074 PasswordStorageScheme scheme = 5075 directoryServer.passwordStorageSchemesByDN.remove(configEntryDN); 5076 5077 if (scheme != null) 5078 { 5079 directoryServer.passwordStorageSchemes.remove( 5080 toLowerCase(scheme.getStorageSchemeName())); 5081 5082 if (scheme.supportsAuthPasswordSyntax()) 5083 { 5084 directoryServer.authPasswordStorageSchemes.remove( 5085 scheme.getAuthPasswordSchemeName()); 5086 } 5087 } 5088 } 5089 5090 5091 5092 /** 5093 * Retrieves the set of password validators that have been registered for use 5094 * with the Directory Server as a mapping between the DN of the associated 5095 * validator configuration entry and the validator implementation. 5096 * 5097 * @return The set of password validators that have been registered for use 5098 * with the Directory Server. 5099 */ 5100 public static 5101 ConcurrentHashMap<DN, 5102 PasswordValidator<? extends PasswordValidatorCfg>> 5103 getPasswordValidators() 5104 { 5105 return directoryServer.passwordValidators; 5106 } 5107 5108 5109 5110 /** 5111 * Retrieves the password validator registered with the provided configuration 5112 * entry DN. 5113 * 5114 * @param configEntryDN The DN of the configuration entry for which to 5115 * retrieve the associated password validator. 5116 * 5117 * @return The requested password validator, or <CODE>null</CODE> if no such 5118 * validator is defined. 5119 */ 5120 public static PasswordValidator<? extends PasswordValidatorCfg> 5121 getPasswordValidator(DN configEntryDN) 5122 { 5123 return directoryServer.passwordValidators.get(configEntryDN); 5124 } 5125 5126 5127 5128 /** 5129 * Registers the provided password validator for use with the Directory 5130 * Server. 5131 * 5132 * @param configEntryDN The DN of the configuration entry that defines the 5133 * specified password validator. 5134 * @param validator The password validator to register with the 5135 * Directory Server. 5136 */ 5137 public static void 5138 registerPasswordValidator(DN configEntryDN, 5139 PasswordValidator<? extends PasswordValidatorCfg> 5140 validator) 5141 { 5142 directoryServer.passwordValidators.put(configEntryDN, validator); 5143 } 5144 5145 5146 5147 /** 5148 * Deregisters the provided password validator for use with the Directory 5149 * Server. 5150 * 5151 * @param configEntryDN The DN of the configuration entry that defines the 5152 * password validator to deregister. 5153 */ 5154 public static void deregisterPasswordValidator(DN configEntryDN) 5155 { 5156 directoryServer.passwordValidators.remove(configEntryDN); 5157 } 5158 5159 5160 5161 /** 5162 * Retrieves the set of account status notification handlers defined in the 5163 * Directory Server, as a mapping between the DN of the configuration entry 5164 * and the notification handler implementation. 5165 * 5166 * @return The set of account status notification handlers defined in the 5167 * Directory Server. 5168 */ 5169 public static ConcurrentHashMap<DN,AccountStatusNotificationHandler> 5170 getAccountStatusNotificationHandlers() 5171 { 5172 return directoryServer.accountStatusNotificationHandlers; 5173 } 5174 5175 5176 5177 /** 5178 * Retrieves the account status notification handler with the specified 5179 * configuration entry DN. 5180 * 5181 * @param handlerDN The DN of the configuration entry associated with the 5182 * account status notification handler to retrieve. 5183 * 5184 * @return The requested account status notification handler, or 5185 * <CODE>null</CODE> if no such handler is defined in the server. 5186 */ 5187 public static AccountStatusNotificationHandler 5188 getAccountStatusNotificationHandler(DN handlerDN) 5189 { 5190 return directoryServer.accountStatusNotificationHandlers.get(handlerDN); 5191 } 5192 5193 5194 5195 /** 5196 * Registers the provided account status notification handler with the 5197 * Directory Server. 5198 * 5199 * @param handlerDN The DN of the configuration entry that defines the 5200 * provided account status notification handler. 5201 * @param handler The account status notification handler to register with 5202 * the Directory Server. 5203 */ 5204 public static void registerAccountStatusNotificationHandler(DN handlerDN, 5205 AccountStatusNotificationHandler handler) 5206 { 5207 directoryServer.accountStatusNotificationHandlers.put(handlerDN, handler); 5208 } 5209 5210 5211 5212 /** 5213 * Deregisters the specified account status notification handler with the 5214 * Directory Server. 5215 * 5216 * @param handlerDN The DN of the configuration entry for the account status 5217 * notification handler to deregister. 5218 */ 5219 public static void deregisterAccountStatusNotificationHandler(DN handlerDN) 5220 { 5221 directoryServer.accountStatusNotificationHandlers.remove(handlerDN); 5222 } 5223 5224 5225 5226 5227 /** 5228 * Retrieves the set of password generators that have been registered for use 5229 * with the Directory Server as a mapping between the DN of the associated 5230 * generator configuration entry and the generator implementation. 5231 * 5232 * @return The set of password generators that have been registered for use 5233 * with the Directory Server. 5234 */ 5235 public static ConcurrentHashMap<DN,PasswordGenerator> getPasswordGenerators() 5236 { 5237 return directoryServer.passwordGenerators; 5238 } 5239 5240 5241 5242 /** 5243 * Retrieves the password generator registered with the provided configuration 5244 * entry DN. 5245 * 5246 * @param configEntryDN The DN of the configuration entry for which to 5247 * retrieve the associated password generator. 5248 * 5249 * @return The requested password generator, or <CODE>null</CODE> if no such 5250 * generator is defined. 5251 */ 5252 public static PasswordGenerator getPasswordGenerator(DN configEntryDN) 5253 { 5254 return directoryServer.passwordGenerators.get(configEntryDN); 5255 } 5256 5257 5258 5259 /** 5260 * Registers the provided password generator for use with the Directory 5261 * Server. 5262 * 5263 * @param configEntryDN The DN of the configuration entry that defines the 5264 * specified password generator. 5265 * @param generator The password generator to register with the 5266 * Directory Server. 5267 */ 5268 public static void registerPasswordGenerator(DN configEntryDN, 5269 PasswordGenerator generator) 5270 { 5271 directoryServer.passwordGenerators.put(configEntryDN, generator); 5272 } 5273 5274 5275 5276 /** 5277 * Deregisters the provided password generator for use with the Directory 5278 * Server. 5279 * 5280 * @param configEntryDN The DN of the configuration entry that defines the 5281 * password generator to deregister. 5282 */ 5283 public static void deregisterPasswordGenerator(DN configEntryDN) 5284 { 5285 directoryServer.passwordGenerators.remove(configEntryDN); 5286 } 5287 5288 5289 5290 /** 5291 * Retrieves the set of password policies registered with the Directory 5292 * Server. The references returned are to the actual password policy objects 5293 * currently in use by the directory server and the referenced objects must 5294 * not be modified. 5295 * 5296 * @return The set of password policies registered with the Directory Server. 5297 */ 5298 public static PasswordPolicy[] getPasswordPolicies() 5299 { 5300 // The password policy objects are returned in an array to prevent the 5301 // caller from modifying the map structure. 5302 PasswordPolicyConfig[] values = directoryServer.passwordPolicies.values() 5303 .toArray(new PasswordPolicyConfig[0]); 5304 PasswordPolicy[] policies = new PasswordPolicy[values.length]; 5305 for( int i = 0 ; i < values.length; ++i) 5306 { 5307 policies[i] = values[i].getPolicy(); 5308 } 5309 5310 return policies; 5311 } 5312 5313 5314 5315 /** 5316 * Retrieves the password policy registered for the provided configuration 5317 * entry. 5318 * 5319 * @param configEntryDN The DN of the configuration entry for which to 5320 * retrieve the associated password policy. 5321 * 5322 * @return The password policy registered for the provided configuration 5323 * entry, or <CODE>null</CODE> if there is no such policy. 5324 */ 5325 public static PasswordPolicy getPasswordPolicy(DN configEntryDN) 5326 { 5327 Validator.ensureNotNull(configEntryDN); 5328 5329 PasswordPolicyConfig config 5330 = directoryServer.passwordPolicies.get(configEntryDN); 5331 return (null == config) ? null : config.getPolicy(); 5332 } 5333 5334 5335 /** 5336 * Retrieves the password policy registered for the provided configuration 5337 * entry. 5338 * 5339 * @param configEntryDN The DN of the configuration entry for which to 5340 * retrieve the associated password policy. 5341 * 5342 * @return The password policy config registered for the provided 5343 * configuration entry, or <CODE>null</CODE> if there is 5344 * no such policy. 5345 */ 5346 public static PasswordPolicyConfig getPasswordPolicyConfig(DN configEntryDN) 5347 { 5348 Validator.ensureNotNull(configEntryDN); 5349 5350 return directoryServer.passwordPolicies.get(configEntryDN); 5351 } 5352 5353 5354 /** 5355 * Registers the provided password policy with the Directory Server. If a 5356 * policy is already registered for the provided configuration entry DN, then 5357 * it will be replaced. 5358 * 5359 * @param configEntryDN The DN of the configuration entry that defines the 5360 * password policy. 5361 * @param config The password policy config to register with the 5362 * server. 5363 */ 5364 public static void registerPasswordPolicy(DN configEntryDN, 5365 PasswordPolicyConfig config) 5366 { 5367 Validator.ensureNotNull(configEntryDN, config); 5368 5369 directoryServer.passwordPolicies.put(configEntryDN, config); 5370 } 5371 5372 5373 5374 /** 5375 * Deregisters the provided password policy with the Directory Server. If no 5376 * such policy is registered, then no action will be taken. 5377 * 5378 * @param configEntryDN The DN of the configuration entry that defines the 5379 * password policy to deregister. 5380 */ 5381 public static void deregisterPasswordPolicy(DN configEntryDN) 5382 { 5383 Validator.ensureNotNull(configEntryDN); 5384 5385 if (directoryServer.defaultPasswordPolicyDN.equals(configEntryDN)) 5386 { 5387 directoryServer.defaultPasswordPolicyConfig = null; 5388 } 5389 5390 PasswordPolicyConfig config 5391 = directoryServer.passwordPolicies.remove(configEntryDN); 5392 } 5393 5394 5395 5396 /** 5397 * Retrieves the DN of the configuration entry for the default password policy 5398 * for the Directory Server. 5399 * 5400 * @return The DN of the configuration entry for the default password policy 5401 * for the Directory Server. 5402 */ 5403 public static DN getDefaultPasswordPolicyDN() 5404 { 5405 return directoryServer.defaultPasswordPolicyDN; 5406 } 5407 5408 5409 5410 /** 5411 * Specifies the DN of the configuration entry for the default password policy 5412 * for the Directory Server. This routine does not check the registered 5413 * password policies for the specified DN, since in the case of server 5414 * initialization, the password policy entries will not yet have been loaded 5415 * from the configuration backend. 5416 * 5417 * @param defaultPasswordPolicyDN The DN of the configuration entry for the 5418 * default password policy for the Directory 5419 * Server. 5420 */ 5421 public static void setDefaultPasswordPolicyDN(DN defaultPasswordPolicyDN) 5422 { 5423 directoryServer.defaultPasswordPolicyDN = defaultPasswordPolicyDN; 5424 directoryServer.defaultPasswordPolicyConfig = null; 5425 } 5426 5427 5428 5429 /** 5430 * Retrieves the default password policy for the Directory Server. This method 5431 * is equivalent to invoking <CODE>getPasswordPolicy</CODE> on the DN returned 5432 * from <CODE>DirectoryServer.getDefaultPasswordPolicyDN()</CODE>. 5433 * 5434 * @return The default password policy for the Directory Server. 5435 */ 5436 public static PasswordPolicy getDefaultPasswordPolicy() 5437 { 5438 assert null != directoryServer.passwordPolicies.get( 5439 directoryServer.defaultPasswordPolicyDN) 5440 : "Internal Error: no default password policy defined." ; 5441 5442 if ((directoryServer.defaultPasswordPolicyConfig == null) && 5443 (directoryServer.defaultPasswordPolicyDN != null)) 5444 { 5445 directoryServer.defaultPasswordPolicyConfig = 5446 directoryServer.passwordPolicies.get( 5447 directoryServer.defaultPasswordPolicyDN); 5448 } 5449 assert directoryServer.passwordPolicies.get( 5450 directoryServer.defaultPasswordPolicyDN) 5451 == directoryServer.defaultPasswordPolicyConfig 5452 : "Internal Error: inconsistency between defaultPasswordPolicyConfig" 5453 + " cache and value in passwordPolicies map."; 5454 return directoryServer.defaultPasswordPolicyConfig.getPolicy(); 5455 } 5456 5457 5458 /** 5459 * Retrieves the log rotation policy registered for the provided configuration 5460 * entry. 5461 * 5462 * @param configEntryDN The DN of the configuration entry for which to 5463 * retrieve the associated rotation policy. 5464 * 5465 * @return The rotation policy registered for the provided configuration 5466 * entry, or <CODE>null</CODE> if there is no such policy. 5467 */ 5468 public static RotationPolicy getRotationPolicy(DN configEntryDN) 5469 { 5470 Validator.ensureNotNull(configEntryDN); 5471 5472 return directoryServer.rotationPolicies.get(configEntryDN); 5473 } 5474 5475 /** 5476 * Registers the provided log rotation policy with the Directory Server. If a 5477 * policy is already registered for the provided configuration entry DN, then 5478 * it will be replaced. 5479 * 5480 * @param configEntryDN The DN of the configuration entry that defines the 5481 * password policy. 5482 * @param policy The rotation policy to register with the server. 5483 */ 5484 public static void registerRotationPolicy(DN configEntryDN, 5485 RotationPolicy policy) 5486 { 5487 Validator.ensureNotNull(configEntryDN, policy); 5488 5489 directoryServer.rotationPolicies.put(configEntryDN, policy); 5490 } 5491 5492 5493 5494 /** 5495 * Deregisters the provided log rotation policy with the Directory Server. 5496 * If no such policy is registered, then no action will be taken. 5497 * 5498 * @param configEntryDN The DN of the configuration entry that defines the 5499 * rotation policy to deregister. 5500 */ 5501 public static void deregisterRotationPolicy(DN configEntryDN) 5502 { 5503 Validator.ensureNotNull(configEntryDN); 5504 5505 directoryServer.rotationPolicies.remove(configEntryDN); 5506 } 5507 5508 /** 5509 * Retrieves the log retention policy registered for the provided 5510 * configuration entry. 5511 * 5512 * @param configEntryDN The DN of the configuration entry for which to 5513 * retrieve the associated retention policy. 5514 * 5515 * @return The retention policy registered for the provided configuration 5516 * entry, or <CODE>null</CODE> if there is no such policy. 5517 */ 5518 public static RetentionPolicy getRetentionPolicy(DN configEntryDN) 5519 { 5520 Validator.ensureNotNull(configEntryDN); 5521 5522 return directoryServer.retentionPolicies.get(configEntryDN); 5523 } 5524 5525 /** 5526 * Registers the provided log retention policy with the Directory Server. 5527 * If a policy is already registered for the provided configuration entry DN, 5528 * then it will be replaced. 5529 * 5530 * @param configEntryDN The DN of the configuration entry that defines the 5531 * password policy. 5532 * @param policy The retention policy to register with the server. 5533 */ 5534 public static void registerRetentionPolicy(DN configEntryDN, 5535 RetentionPolicy policy) 5536 { 5537 Validator.ensureNotNull(configEntryDN, policy); 5538 5539 directoryServer.retentionPolicies.put(configEntryDN, policy); 5540 } 5541 5542 5543 5544 /** 5545 * Deregisters the provided log retention policy with the Directory Server. 5546 * If no such policy is registered, then no action will be taken. 5547 * 5548 * @param configEntryDN The DN of the configuration entry that defines the 5549 * retention policy to deregister. 5550 */ 5551 public static void deregisterRetentionPolicy(DN configEntryDN) 5552 { 5553 Validator.ensureNotNull(configEntryDN); 5554 5555 directoryServer.retentionPolicies.remove(configEntryDN); 5556 } 5557 5558 /** 5559 * Retrieves the set of monitor providers that have been registered with the 5560 * Directory Server, as a mapping between the monitor name (in all lowercase 5561 * characters) and the monitor implementation. 5562 * 5563 * @return The set of monitor providers that have been registered with the 5564 * Directory Server. 5565 */ 5566 public static ConcurrentHashMap<String, 5567 MonitorProvider<? extends MonitorProviderCfg>> 5568 getMonitorProviders() 5569 { 5570 return directoryServer.monitorProviders; 5571 } 5572 5573 5574 5575 /** 5576 * Retrieves the monitor provider with the specified name. 5577 * 5578 * @param lowerName The name of the monitor provider to retrieve, in all 5579 * lowercase characters. 5580 * 5581 * @return The requested resource monitor, or <CODE>null</CODE> if none 5582 * exists with the specified name. 5583 */ 5584 public static MonitorProvider<? extends MonitorProviderCfg> 5585 getMonitorProvider(String lowerName) 5586 { 5587 return directoryServer.monitorProviders.get(lowerName); 5588 } 5589 5590 5591 5592 /** 5593 * Registers the provided monitor provider with the Directory Server. Note 5594 * that if a monitor provider is already registered with the specified name, 5595 * then it will be replaced with the provided implementation. 5596 * 5597 * @param monitorProvider The monitor provider to register with the 5598 * Directory Server. 5599 */ 5600 public static void registerMonitorProvider( 5601 MonitorProvider<? extends MonitorProviderCfg> 5602 monitorProvider) 5603 { 5604 String lowerName = toLowerCase(monitorProvider.getMonitorInstanceName()); 5605 directoryServer.monitorProviders.put(lowerName, monitorProvider); 5606 5607 5608 // Try to register this monitor provider with an appropriate JMX MBean. 5609 try 5610 { 5611 DN monitorDN = getMonitorProviderDN(monitorProvider); 5612 JMXMBean mBean = directoryServer.mBeans.get(monitorDN); 5613 if (mBean == null) 5614 { 5615 mBean = new JMXMBean(monitorDN); 5616 mBean.addMonitorProvider(monitorProvider); 5617 directoryServer.mBeans.put(monitorDN, mBean); 5618 } 5619 else 5620 { 5621 mBean.addMonitorProvider(monitorProvider); 5622 } 5623 } 5624 catch (Exception e) 5625 { 5626 if (debugEnabled()) 5627 { 5628 TRACER.debugCaught(DebugLogLevel.ERROR, e); 5629 } 5630 } 5631 } 5632 5633 5634 5635 /** 5636 * Deregisters the specified monitor provider from the Directory Server. If 5637 * no such monitor provider is registered, no action will be taken. 5638 * 5639 * @param lowerName The name of the monitor provider to deregister, in all 5640 * lowercase characters. 5641 */ 5642 public static void deregisterMonitorProvider(String lowerName) 5643 { 5644 MonitorProvider provider = 5645 directoryServer.monitorProviders.remove(toLowerCase(lowerName)); 5646 5647 5648 // Try to deregister the monitor provider as an MBean. 5649 if (provider != null) 5650 { 5651 try 5652 { 5653 DN monitorDN = getMonitorProviderDN(provider); 5654 JMXMBean mBean = directoryServer.mBeans.get(monitorDN); 5655 if (mBean != null) 5656 { 5657 mBean.removeMonitorProvider(provider); 5658 } 5659 } 5660 catch (Exception e) 5661 { 5662 if (debugEnabled()) 5663 { 5664 TRACER.debugCaught(DebugLogLevel.ERROR, e); 5665 } 5666 } 5667 } 5668 } 5669 5670 5671 5672 /** 5673 * Retrieves the entry cache for the Directory Server. 5674 * 5675 * @return The entry cache for the Directory Server. 5676 */ 5677 public static EntryCache getEntryCache() 5678 { 5679 return directoryServer.entryCache; 5680 } 5681 5682 5683 5684 /** 5685 * Specifies the entry cache that should be used by the Directory Server. 5686 * This should only be called by the entry cache configuration manager. 5687 * 5688 * @param entryCache The entry cache for the Directory Server. 5689 */ 5690 public static void setEntryCache(EntryCache entryCache) 5691 { 5692 synchronized (directoryServer) 5693 { 5694 directoryServer.entryCache = entryCache; 5695 } 5696 } 5697 5698 5699 5700 /** 5701 * Retrieves the set of key manager providers registered with the Directory 5702 * Server. 5703 * 5704 * @return The set of key manager providers registered with the Directory 5705 * Server. 5706 */ 5707 public static Map<DN,KeyManagerProvider> getKeyManagerProviders() 5708 { 5709 return directoryServer.keyManagerProviders; 5710 } 5711 5712 5713 5714 /** 5715 * Retrieves the key manager provider registered with the provided entry DN. 5716 * 5717 * @param providerDN The DN with which the key manager provider is 5718 * registered. 5719 * 5720 * @return The key manager provider registered with the provided entry DN, or 5721 * {@code null} if there is no such key manager provider registered 5722 * with the server. 5723 */ 5724 public static KeyManagerProvider getKeyManagerProvider(DN providerDN) 5725 { 5726 return directoryServer.keyManagerProviders.get(providerDN); 5727 } 5728 5729 5730 5731 /** 5732 * Registers the provided key manager provider with the Directory Server. 5733 * 5734 * @param providerDN The DN with which to register the key manager provider. 5735 * @param provider The key manager provider to register with the server. 5736 */ 5737 public static void registerKeyManagerProvider(DN providerDN, 5738 KeyManagerProvider provider) 5739 { 5740 directoryServer.keyManagerProviders.put(providerDN, provider); 5741 } 5742 5743 5744 5745 /** 5746 * Deregisters the specified key manager provider with the Directory Server. 5747 * 5748 * @param providerDN The DN with which the key manager provider is 5749 * registered. 5750 */ 5751 public static void deregisterKeyManagerProvider(DN providerDN) 5752 { 5753 directoryServer.keyManagerProviders.remove(providerDN); 5754 } 5755 5756 5757 5758 /** 5759 * Retrieves the set of trust manager providers registered with the Directory 5760 * Server. 5761 * 5762 * @return The set of trust manager providers registered with the Directory 5763 * Server. 5764 */ 5765 public static Map<DN,TrustManagerProvider> getTrustManagerProviders() 5766 { 5767 return directoryServer.trustManagerProviders; 5768 } 5769 5770 5771 5772 /** 5773 * Retrieves the trust manager provider registered with the provided entry DN. 5774 * 5775 * @param providerDN The DN with which the trust manager provider is 5776 * registered. 5777 * 5778 * @return The trust manager provider registered with the provided entry DN, 5779 * or {@code null} if there is no such trust manager provider 5780 * registered with the server. 5781 */ 5782 public static TrustManagerProvider getTrustManagerProvider(DN providerDN) 5783 { 5784 return directoryServer.trustManagerProviders.get(providerDN); 5785 } 5786 5787 5788 5789 /** 5790 * Registers the provided trust manager provider with the Directory Server. 5791 * 5792 * @param providerDN The DN with which to register the trust manager 5793 * provider. 5794 * @param provider The trust manager provider to register with the server. 5795 */ 5796 public static void registerTrustManagerProvider(DN providerDN, 5797 TrustManagerProvider provider) 5798 { 5799 directoryServer.trustManagerProviders.put(providerDN, provider); 5800 } 5801 5802 5803 5804 /** 5805 * Deregisters the specified trust manager provider with the Directory Server. 5806 * 5807 * @param providerDN The DN with which the trust manager provider is 5808 * registered. 5809 */ 5810 public static void deregisterTrustManagerProvider(DN providerDN) 5811 { 5812 directoryServer.trustManagerProviders.remove(providerDN); 5813 } 5814 5815 5816 5817 /** 5818 * Retrieves the set of certificate mappers registered with the Directory 5819 * Server. 5820 * 5821 * @return The set of certificate mappers registered with the Directory 5822 * Server. 5823 */ 5824 public static Map<DN,CertificateMapper> getCertificateMappers() 5825 { 5826 return directoryServer.certificateMappers; 5827 } 5828 5829 5830 5831 /** 5832 * Retrieves the certificate mapper registered with the provided entry DN. 5833 * 5834 * @param mapperDN The DN with which the certificate mapper is registered. 5835 * 5836 * @return The certificate mapper registered with the provided entry DN, or 5837 * {@code null} if there is no such certificate mapper registered 5838 * with the server. 5839 */ 5840 public static CertificateMapper getCertificateMapper(DN mapperDN) 5841 { 5842 return directoryServer.certificateMappers.get(mapperDN); 5843 } 5844 5845 5846 5847 /** 5848 * Registers the provided certificate mapper with the Directory Server. 5849 * 5850 * @param mapperDN The DN with which to register the certificate mapper. 5851 * @param mapper The certificate mapper to register with the server. 5852 */ 5853 public static void registerCertificateMapper(DN mapperDN, 5854 CertificateMapper mapper) 5855 { 5856 directoryServer.certificateMappers.put(mapperDN, mapper); 5857 } 5858 5859 5860 5861 /** 5862 * Deregisters the specified certificate mapper with the Directory Server. 5863 * 5864 * @param mapperDN The DN with which the certificate mapper is registered. 5865 */ 5866 public static void deregisterCertificateMapper(DN mapperDN) 5867 { 5868 directoryServer.certificateMappers.remove(mapperDN); 5869 } 5870 5871 5872 5873 5874 /** 5875 * Retrieves the set of privileges that should automatically be granted to 5876 * root users when they authenticate. 5877 * 5878 * @return The set of privileges that should automatically be granted to root 5879 * users when they authenticate. 5880 */ 5881 public static Set<Privilege> getRootPrivileges() 5882 { 5883 return directoryServer.rootDNConfigManager.getRootPrivileges(); 5884 } 5885 5886 5887 5888 /** 5889 * Retrieves the DNs for the root users configured in the Directory Server. 5890 * Note that this set should only contain the actual DNs for the root users 5891 * and not any alternate DNs. Also, the contents of the returned set must not 5892 * be altered by the caller. 5893 * 5894 * @return The DNs for the root users configured in the Directory Server. 5895 */ 5896 public static CopyOnWriteArraySet<DN> getRootDNs() 5897 { 5898 return directoryServer.rootDNs; 5899 } 5900 5901 5902 5903 /** 5904 * Indicates whether the provided DN is the DN for one of the root users 5905 * configured in the Directory Server. 5906 * 5907 * @param userDN The user DN for which to make the determination. 5908 * 5909 * @return <CODE>true</CODE> if the provided user DN is a Directory Server 5910 * root DN, or <CODE>false</CODE> if not. 5911 */ 5912 public static boolean isRootDN(DN userDN) 5913 { 5914 return directoryServer.rootDNs.contains(userDN); 5915 } 5916 5917 5918 5919 /** 5920 * Registers the provided root DN with the Directory Server. 5921 * 5922 * @param rootDN The root DN to register with the Directory Server. 5923 */ 5924 public static void registerRootDN(DN rootDN) 5925 { 5926 directoryServer.rootDNs.add(rootDN); 5927 } 5928 5929 5930 5931 /** 5932 * Deregisters the provided root DN with the Directory Server. This will have 5933 * no effect if the provided DN is not registered as a root DN. 5934 * 5935 * @param rootDN The root DN to deregister. 5936 */ 5937 public static void deregisterRootDN(DN rootDN) 5938 { 5939 directoryServer.rootDNs.remove(rootDN); 5940 } 5941 5942 5943 5944 /** 5945 * Retrieves the set of alternate bind DNs for root users, mapped between the 5946 * alternate DN and the real DN. The contents of the returned map must not be 5947 * altered by the caller. 5948 * 5949 * @return The set of alternate bind DNs for root users, mapped between the 5950 * alternate DN and the real DN. 5951 */ 5952 public static ConcurrentHashMap<DN,DN> getAlternateRootBindDNs() 5953 { 5954 return directoryServer.alternateRootBindDNs; 5955 } 5956 5957 5958 5959 /** 5960 * Retrieves the real entry DN for the root user with the provided alternate 5961 * bind DN. 5962 * 5963 * @param alternateRootBindDN The alternate root bind DN for which to 5964 * retrieve the real entry DN. 5965 * 5966 * @return The real entry DN for the root user with the provided alternate 5967 * bind DN, or <CODE>null</CODE> if no such mapping has been defined. 5968 */ 5969 public static DN getActualRootBindDN(DN alternateRootBindDN) 5970 { 5971 return directoryServer.alternateRootBindDNs.get(alternateRootBindDN); 5972 } 5973 5974 5975 5976 /** 5977 * Registers an alternate root bind DN using the provided information. 5978 * 5979 * @param actualRootEntryDN The actual DN for the root user's entry. 5980 * @param alternateRootBindDN The alternate DN that should be interpreted as 5981 * if it were the provided actual root entry DN. 5982 * 5983 * @throws DirectoryException If the provided alternate bind DN is already 5984 * in use for another root user. 5985 */ 5986 public static void registerAlternateRootDN(DN actualRootEntryDN, 5987 DN alternateRootBindDN) 5988 throws DirectoryException 5989 { 5990 DN existingRootEntryDN = 5991 directoryServer.alternateRootBindDNs.putIfAbsent(alternateRootBindDN, 5992 actualRootEntryDN); 5993 if ((existingRootEntryDN != null) && 5994 (! existingRootEntryDN.equals(actualRootEntryDN))) 5995 { 5996 Message message = ERR_CANNOT_REGISTER_DUPLICATE_ALTERNATE_ROOT_BIND_DN. 5997 get(String.valueOf(alternateRootBindDN), 5998 String.valueOf(existingRootEntryDN)); 5999 throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message); 6000 } 6001 } 6002 6003 6004 6005 /** 6006 * Deregisters the provided alternate root bind DN from the server. This will 6007 * have no effect if there was no mapping defined for the provided alternate 6008 * root bind DN. 6009 * 6010 * @param alternateRootBindDN The alternate root bind DN to be deregistered. 6011 * 6012 * @return The actual root entry DN to which the provided alternate bind DN 6013 * was mapped, or <CODE>null</CODE> if there was no mapping for the 6014 * provided DN. 6015 */ 6016 public static DN deregisterAlternateRootBindDN(DN alternateRootBindDN) 6017 { 6018 return directoryServer.alternateRootBindDNs.remove(alternateRootBindDN); 6019 } 6020 6021 6022 6023 /** 6024 * Retrieves the result code that should be used when the Directory Server 6025 * encounters an internal server error. 6026 * 6027 * @return The result code that should be used when the Directory Server 6028 * encounters an internal server error. 6029 */ 6030 public static ResultCode getServerErrorResultCode() 6031 { 6032 return directoryServer.serverErrorResultCode; 6033 } 6034 6035 6036 6037 /** 6038 * Specifies the result code that should be used when the Directory Server 6039 * encounters an internal server error. 6040 * 6041 * @param serverErrorResultCode The result code that should be used when the 6042 * Directory Server encounters an internal 6043 * server error. 6044 */ 6045 public static void setServerErrorResultCode(ResultCode serverErrorResultCode) 6046 { 6047 directoryServer.serverErrorResultCode = serverErrorResultCode; 6048 } 6049 6050 6051 6052 /** 6053 * Indicates whether the Directory Server should automatically add missing RDN 6054 * attributes to an entry whenever it is added. 6055 * 6056 * @return <CODE>true</CODE> if the Directory Server should automatically add 6057 * missing RDN attributes to an entry, or <CODE>false</CODE> if it 6058 * should return an error to the client. 6059 */ 6060 public static boolean addMissingRDNAttributes() 6061 { 6062 return directoryServer.addMissingRDNAttributes; 6063 } 6064 6065 6066 6067 /** 6068 * Specifies whether the Directory Server should automatically add missing RDN 6069 * attributes to an entry whenever it is added. 6070 * 6071 * @param addMissingRDNAttributes Specifies whether the Directory Server 6072 * should automatically add missing RDN 6073 * attributes to an entry whenever it is 6074 * added. 6075 */ 6076 public static void setAddMissingRDNAttributes(boolean addMissingRDNAttributes) 6077 { 6078 directoryServer.addMissingRDNAttributes = addMissingRDNAttributes; 6079 } 6080 6081 6082 6083 /** 6084 * Indicates whether to be more flexible in the set of characters allowed for 6085 * attribute names. The standard requires that only ASCII alphabetic letters, 6086 * numeric digits, and hyphens be allowed, and that the name start with a 6087 * letter. If attribute name exceptions are enabled, then underscores will 6088 * also be allowed, and the name will be allowed to start with a digit. 6089 * 6090 * @return <CODE>true</CODE> if the server should use a more flexible 6091 * syntax for attribute names, or <CODE>false</CODE> if not. 6092 */ 6093 public static boolean allowAttributeNameExceptions() 6094 { 6095 return directoryServer.allowAttributeNameExceptions; 6096 } 6097 6098 6099 6100 /** 6101 * Specifies whether to be more flexible in the set of characters allowed for 6102 * attribute names. 6103 * 6104 * @param allowAttributeNameExceptions Specifies whether to be more flexible 6105 * in the set of characters allowed for 6106 * attribute names. 6107 */ 6108 public static void setAllowAttributeNameExceptions( 6109 boolean allowAttributeNameExceptions) 6110 { 6111 directoryServer.allowAttributeNameExceptions = allowAttributeNameExceptions; 6112 } 6113 6114 6115 6116 /** 6117 * Indicates whether the Directory Server should perform schema checking. 6118 * 6119 * @return <CODE>true</CODE> if the Directory Server should perform schema 6120 * checking, or <CODE>false</CODE> if not. 6121 */ 6122 public static boolean checkSchema() 6123 { 6124 return directoryServer.checkSchema; 6125 } 6126 6127 6128 6129 /** 6130 * Specifies whether the Directory Server should perform schema checking. 6131 * 6132 * @param checkSchema Specifies whether the Directory Server should perform 6133 * schema checking. 6134 */ 6135 public static void setCheckSchema(boolean checkSchema) 6136 { 6137 directoryServer.checkSchema = checkSchema; 6138 } 6139 6140 6141 6142 /** 6143 * Retrieves the policy that should be used regarding enforcement of a single 6144 * structural objectclass per entry. 6145 * 6146 * @return The policy that should be used regarding enforcement of a single 6147 * structural objectclass per entry. 6148 */ 6149 public static AcceptRejectWarn getSingleStructuralObjectClassPolicy() 6150 { 6151 return directoryServer.singleStructuralClassPolicy; 6152 } 6153 6154 6155 6156 /** 6157 * Specifies the policy that should be used regarding enforcement of a single 6158 * structural objectclass per entry. 6159 * 6160 * @param singleStructuralClassPolicy The policy that should be used 6161 * regarding enforcement of a single 6162 * structural objectclass per entry. 6163 */ 6164 public static void setSingleStructuralObjectClassPolicy( 6165 AcceptRejectWarn singleStructuralClassPolicy) 6166 { 6167 directoryServer.singleStructuralClassPolicy = singleStructuralClassPolicy; 6168 } 6169 6170 6171 6172 /** 6173 * Retrieves the policy that should be used when an attribute value is found 6174 * that is not valid according to the associated attribute syntax. 6175 * 6176 * @return The policy that should be used when an attribute value is found 6177 * that is not valid according to the associated attribute syntax. 6178 */ 6179 public static AcceptRejectWarn getSyntaxEnforcementPolicy() 6180 { 6181 return directoryServer.syntaxEnforcementPolicy; 6182 } 6183 6184 6185 6186 /** 6187 * Retrieves the policy that should be used when an attribute value is found 6188 * that is not valid according to the associated attribute syntax. 6189 * 6190 * @param syntaxEnforcementPolicy The policy that should be used when an 6191 * attribute value is found that is not valid 6192 * according to the associated attribute 6193 * syntax. 6194 */ 6195 public static void setSyntaxEnforcementPolicy( 6196 AcceptRejectWarn syntaxEnforcementPolicy) 6197 { 6198 directoryServer.syntaxEnforcementPolicy = syntaxEnforcementPolicy; 6199 } 6200 6201 6202 6203 /** 6204 * Indicates whether the Directory Server should send a response to an 6205 * operation that has been abandoned. Sending such a response is technically 6206 * a violation of the LDAP protocol specification, but not doing so in that 6207 * case can cause problems with clients that are expecting a response and may 6208 * hang until they get one. 6209 * 6210 * @return <CODE>true</CODE> if the Directory Server should send a response 6211 * to an operation that has been abandoned, or <CODE>false</CODE> if 6212 * not. 6213 */ 6214 public static boolean notifyAbandonedOperations() 6215 { 6216 return directoryServer.notifyAbandonedOperations; 6217 } 6218 6219 6220 6221 /** 6222 * Specifies whether the Directory Server should send a response to an 6223 * operation that has been abandoned. Sending such a response is technically 6224 * a violation of the LDAP protocol specification, but not doing so in that 6225 * case can cause problems with clients that are expecting a response and may 6226 * hang until they get one. 6227 * 6228 * @param notifyAbandonedOperations Indicates whether the Directory Server 6229 * should send a response to an operation 6230 * that has been abandoned. 6231 */ 6232 public static void setNotifyAbandonedOperations( 6233 boolean notifyAbandonedOperations) 6234 { 6235 directoryServer.notifyAbandonedOperations = notifyAbandonedOperations; 6236 } 6237 6238 6239 6240 /** 6241 * Retrieves the set of backends that have been registered with the Directory 6242 * Server, as a mapping between the backend ID and the corresponding backend. 6243 * 6244 * @return The set of backends that have been registered with the Directory 6245 * Server. 6246 */ 6247 public static Map<String,Backend> getBackends() 6248 { 6249 return directoryServer.backends; 6250 } 6251 6252 6253 6254 /** 6255 * Retrieves the backend with the specified backend ID. 6256 * 6257 * @param backendID The backend ID of the backend to retrieve. 6258 * 6259 * @return The backend with the specified backend ID, or {@code null} if 6260 * there is none. 6261 */ 6262 public static Backend getBackend(String backendID) 6263 { 6264 return directoryServer.backends.get(backendID); 6265 } 6266 6267 6268 6269 /** 6270 * Indicates whether the Directory Server has a backend with the specified 6271 * backend ID. 6272 * 6273 * @param backendID The backend ID for which to make the determination. 6274 * 6275 * @return {@code true} if the Directory Server has a backend with the 6276 * specified backend ID, or {@code false} if not. 6277 */ 6278 public static boolean hasBackend(String backendID) 6279 { 6280 return directoryServer.backends.containsKey(backendID); 6281 } 6282 6283 6284 6285 /** 6286 * Registers the provided backend with the Directory Server. Note that this 6287 * will not register the set of configured suffixes with the server, as that 6288 * must be done by the backend itself. 6289 * 6290 * @param backend The backend to register with the server. Neither the 6291 * backend nor its backend ID may be null. 6292 * 6293 * @throws DirectoryException If the backend ID for the provided backend 6294 * conflicts with the backend ID of an existing 6295 * backend. 6296 */ 6297 public static void registerBackend(Backend backend) 6298 throws DirectoryException 6299 { 6300 ensureNotNull(backend); 6301 6302 String backendID = backend.getBackendID(); 6303 ensureNotNull(backendID); 6304 6305 synchronized (directoryServer) 6306 { 6307 TreeMap<String, Backend> newBackends = 6308 new TreeMap<String, Backend>(directoryServer.backends); 6309 if (newBackends.containsKey(backendID)) 6310 { 6311 Message message = ERR_REGISTER_BACKEND_ALREADY_EXISTS.get(backendID); 6312 throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); 6313 } 6314 else 6315 { 6316 newBackends.put(backendID, backend); 6317 directoryServer.backends = newBackends; 6318 6319 for (String oid : backend.getSupportedControls()) 6320 { 6321 registerSupportedControl(oid); 6322 } 6323 6324 for (String oid : backend.getSupportedFeatures()) 6325 { 6326 registerSupportedFeature(oid); 6327 } 6328 6329 BackendMonitor monitor = new BackendMonitor(backend); 6330 monitor.initializeMonitorProvider(null); 6331 backend.setBackendMonitor(monitor); 6332 registerMonitorProvider(monitor); 6333 } 6334 } 6335 } 6336 6337 6338 6339 /** 6340 * Deregisters the provided backend with the Directory Server. Note that this 6341 * will not deregister the set of configured suffixes with the server, as that 6342 * must be done by the backend itself. 6343 * 6344 * @param backend The backend to deregister with the server. It must not be 6345 * {@code null}. 6346 */ 6347 public static void deregisterBackend(Backend backend) 6348 { 6349 ensureNotNull(backend); 6350 6351 synchronized (directoryServer) 6352 { 6353 TreeMap<String,Backend> newBackends = 6354 new TreeMap<String,Backend>(directoryServer.backends); 6355 newBackends.remove(backend.getBackendID()); 6356 6357 directoryServer.backends = newBackends; 6358 6359 // Don't need anymore the local backend workflow element so we 6360 // can remove it. We do remove the workflow element only when 6361 // the workflow configuration mode is auto because in manual 6362 // mode the config manager is doing the job. 6363 if (workflowConfigurationModeIsAuto()) 6364 { 6365 LocalBackendWorkflowElement.remove(backend.getBackendID()); 6366 } 6367 6368 6369 BackendMonitor monitor = backend.getBackendMonitor(); 6370 if (monitor != null) 6371 { 6372 String instanceName = toLowerCase(monitor.getMonitorInstanceName()); 6373 deregisterMonitorProvider(instanceName); 6374 monitor.finalizeMonitorProvider(); 6375 backend.setBackendMonitor(null); 6376 } 6377 } 6378 } 6379 6380 6381 6382 /** 6383 * This method returns a map that contains a unique offline state id, 6384 * such as checksum, for every server backend that has registered one. 6385 * 6386 * @return <CODE>Map</CODE> backend to checksum map for offline state. 6387 */ 6388 public static Map<String,Long> getOfflineBackendsStateIDs() { 6389 return Collections.unmodifiableMap(directoryServer.offlineBackendsStateIDs); 6390 } 6391 6392 6393 6394 /** 6395 * This method allows any server backend to register its unique offline 6396 * state, such as checksum, in a global map other server components can 6397 * access to determine if any changes were made to given backend while 6398 * offline. 6399 * 6400 * @param backend As returned by <CODE>getBackendID()</CODE> method. 6401 * 6402 * @param id Unique offline state identifier such as checksum. 6403 */ 6404 public static void registerOfflineBackendStateID(String backend, long id) { 6405 // Zero means failed checksum so just skip it. 6406 if (id != 0) { 6407 directoryServer.offlineBackendsStateIDs.put(backend, id); 6408 } 6409 } 6410 6411 6412 6413 /** 6414 * Retrieves the entire set of base DNs registered with the Directory Server, 6415 * mapped from the base DN to the backend responsible for that base DN. The 6416 * same backend may be present multiple times, mapped from different base DNs. 6417 * 6418 * @return The entire set of base DNs registered with the Directory Server. 6419 */ 6420 public static Map<DN,Backend> getBaseDNs() 6421 { 6422 return directoryServer.baseDnRegistry.getBaseDnMap(); 6423 } 6424 6425 6426 6427 /** 6428 * Retrieves the backend with the specified base DN. 6429 * 6430 * @param baseDN The DN that is registered as one of the base DNs for the 6431 * backend to retrieve. 6432 * 6433 * @return The backend with the specified base DN, or {@code null} if there 6434 * is no backend registered with the specified base DN. 6435 */ 6436 public static Backend getBackendWithBaseDN(DN baseDN) 6437 { 6438 return directoryServer.baseDnRegistry.getBaseDnMap().get(baseDN); 6439 } 6440 6441 6442 6443 /** 6444 * Retrieves the backend that should be used to handle operations on the 6445 * specified entry. 6446 * 6447 * @param entryDN The DN of the entry for which to retrieve the 6448 * corresponding backend. 6449 * 6450 * @return The backend that should be used to handle operations on the 6451 * specified entry, or {@code null} if no appropriate backend is 6452 * registered with the server. 6453 */ 6454 public static Backend getBackend(DN entryDN) 6455 { 6456 if (entryDN.isNullDN()) 6457 { 6458 return directoryServer.rootDSEBackend; 6459 } 6460 6461 Map<DN,Backend> baseDNs = directoryServer.baseDnRegistry.getBaseDnMap(); 6462 Backend b = baseDNs.get(entryDN); 6463 while (b == null) 6464 { 6465 entryDN = entryDN.getParent(); 6466 if (entryDN == null) 6467 { 6468 return null; 6469 } 6470 6471 b = baseDNs.get(entryDN); 6472 } 6473 6474 return b; 6475 } 6476 6477 6478 /** 6479 * Obtains a copy of the server's base DN registry. The copy can be used 6480 * to test registration/deregistration of base DNs but cannot be used to 6481 * modify the backends. To modify the server's live base DN to backend 6482 * mappings use {@link #registerBaseDN(DN, Backend, boolean)} and 6483 * {@link #deregisterBaseDN(DN)}. 6484 * 6485 * @return copy of the base DN regsitry 6486 */ 6487 public static BaseDnRegistry copyBaseDnRegistry() 6488 { 6489 return directoryServer.baseDnRegistry.copy(); 6490 } 6491 6492 6493 /** 6494 * Registers the provided base DN with the server. 6495 * 6496 * @param baseDN The base DN to register with the server. It must not be 6497 * {@code null}. 6498 * @param backend The backend responsible for the provided base DN. It 6499 * must not be {@code null}. 6500 * @param isPrivate Indicates whether the base DN should be considered a 6501 * private base DN. If the provided base DN is a naming 6502 * context, then this controls whether it is public or 6503 * private. 6504 * 6505 * @throws DirectoryException If a problem occurs while attempting to 6506 * register the provided base DN. 6507 */ 6508 public static void registerBaseDN(DN baseDN, Backend backend, 6509 boolean isPrivate) 6510 throws DirectoryException 6511 { 6512 ensureNotNull(baseDN, backend); 6513 6514 synchronized (directoryServer) 6515 { 6516 List<Message> warnings = 6517 directoryServer.baseDnRegistry.registerBaseDN( 6518 baseDN, backend, isPrivate); 6519 6520 // Since we've committed the changes we need to log any issues 6521 // that this registration has caused 6522 if (warnings != null) { 6523 for (Message warning : warnings) { 6524 logError(warning); 6525 } 6526 } 6527 6528 // When a new baseDN is registered with the server we have to create 6529 // a new workflow to handle the base DN. We do not need to create 6530 // the workflow in manual mode because in that case the workflows 6531 // are created explicitely. 6532 if (workflowConfigurationModeIsAuto()) 6533 { 6534 // Now create a workflow for the registered baseDN and register 6535 // the workflow with the default network group, but don't register 6536 // the workflow if the backend happens to be the configuration 6537 // backend because it's too soon for the config backend. 6538 if (! baseDN.equals(DN.decode("cn=config"))) 6539 { 6540 WorkflowImpl workflowImpl = createWorkflow(baseDN, backend); 6541 registerWorkflowWithDefaultNetworkGroup(workflowImpl); 6542 } 6543 } 6544 } 6545 } 6546 6547 6548 6549 /** 6550 * Deregisters the provided base DN with the server. 6551 * 6552 * @param baseDN The base DN to deregister with the server. It must not 6553 * be {@code null}. 6554 * 6555 * @throws DirectoryException If a problem occurs while attempting to 6556 * deregister the provided base DN. 6557 */ 6558 public static void deregisterBaseDN(DN baseDN) 6559 throws DirectoryException 6560 { 6561 ensureNotNull(baseDN); 6562 6563 synchronized(directoryServer) { 6564 6565 List<Message> warnings = 6566 directoryServer.baseDnRegistry.deregisterBaseDN(baseDN); 6567 6568 // Since we've committed the changes we need to log any issues 6569 // that this registration has caused 6570 if (warnings != null) { 6571 for (Message error : warnings) { 6572 logError(error); 6573 } 6574 } 6575 6576 // Now we need to deregister the workflow that was associated with 6577 // the base DN but we can do it only when the workflow configuration 6578 // mode is auto, because in manual mode the deregistration is done 6579 // by the workflow config manager. 6580 if (workflowConfigurationModeIsAuto()) 6581 { 6582 deregisterWorkflowWithDefaultNetworkGroup(baseDN); 6583 } 6584 } 6585 } 6586 6587 6588 6589 /** 6590 * Retrieves the set of public naming contexts defined in the Directory 6591 * Server, mapped from the naming context DN to the corresponding backend. 6592 * 6593 * @return The set of public naming contexts defined in the Directory Server. 6594 */ 6595 public static Map<DN,Backend> getPublicNamingContexts() 6596 { 6597 return directoryServer.baseDnRegistry.getPublicNamingContextsMap(); 6598 } 6599 6600 6601 6602 /** 6603 * Retrieves the set of private naming contexts defined in the Directory 6604 * Server, mapped from the naming context DN to the corresponding backend. 6605 * 6606 * @return The set of private naming contexts defined in the Directory 6607 * Server. 6608 */ 6609 public static Map<DN,Backend> getPrivateNamingContexts() 6610 { 6611 return directoryServer.baseDnRegistry.getPrivateNamingContextsMap(); 6612 } 6613 6614 6615 6616 /** 6617 * Indicates whether the specified DN is one of the Directory Server naming 6618 * contexts. 6619 * 6620 * @param dn The DN for which to make the determination. 6621 * 6622 * @return {@code true} if the specified DN is a naming context for the 6623 * Directory Server, or {@code false} if it is not. 6624 */ 6625 public static boolean isNamingContext(DN dn) 6626 { 6627 return directoryServer.baseDnRegistry.containsNamingContext(dn); 6628 } 6629 6630 6631 6632 /** 6633 * Retrieves the root DSE entry for the Directory Server. 6634 * 6635 * @return The root DSE entry for the Directory Server. 6636 */ 6637 public static Entry getRootDSE() 6638 { 6639 return directoryServer.rootDSEBackend.getRootDSE(); 6640 } 6641 6642 6643 6644 /** 6645 * Retrieves the root DSE backend for the Directory Server. 6646 * 6647 * @return The root DSE backend for the Directory Server. 6648 */ 6649 public static RootDSEBackend getRootDSEBackend() 6650 { 6651 return directoryServer.rootDSEBackend; 6652 } 6653 6654 6655 6656 /** 6657 * Retrieves the DN of the entry containing the server schema definitions. 6658 * 6659 * @return The DN of the entry containing the server schema definitions, or 6660 * <CODE>null</CODE> if none has been defined (e.g., if no schema 6661 * backend has been configured). 6662 */ 6663 public static DN getSchemaDN() 6664 { 6665 return directoryServer.schemaDN; 6666 } 6667 6668 6669 6670 /** 6671 * Specifies the DN of the entry containing the server schema definitions. 6672 * 6673 * @param schemaDN The DN of the entry containing the server schema 6674 * definitions. 6675 */ 6676 public static void setSchemaDN(DN schemaDN) 6677 { 6678 directoryServer.schemaDN = schemaDN; 6679 } 6680 6681 6682 6683 /** 6684 * Retrieves the entry with the requested DN. It will first determine which 6685 * backend should be used for this DN and will then use that backend to 6686 * retrieve the entry. The caller must already hold the appropriate lock on 6687 * the specified entry. 6688 * 6689 * @param entryDN The DN of the entry to retrieve. 6690 * 6691 * @return The requested entry, or <CODE>null</CODE> if it does not exist. 6692 * 6693 * @throws DirectoryException If a problem occurs while attempting to 6694 * retrieve the entry. 6695 */ 6696 public static Entry getEntry(DN entryDN) 6697 throws DirectoryException 6698 { 6699 // If the entry is the root DSE, then get and return that. 6700 if (entryDN.isNullDN()) 6701 { 6702 return directoryServer.rootDSEBackend.getRootDSE(); 6703 } 6704 6705 // Figure out which backend should be used for the entry. If it isn't 6706 // appropriate for any backend, then return null. 6707 Backend backend = getBackend(entryDN); 6708 if (backend == null) 6709 { 6710 return null; 6711 } 6712 6713 // Retrieve the requested entry from the backend. 6714 return backend.getEntry(entryDN); 6715 } 6716 6717 6718 6719 /** 6720 * Indicates whether the specified entry exists in the Directory Server. The 6721 * caller is not required to hold any locks when invoking this method. 6722 * 6723 * @param entryDN The DN of the entry for which to make the determination. 6724 * 6725 * @return <CODE>true</CODE> if the specified entry exists in one of the 6726 * backends, or <CODE>false</CODE> if it does not. 6727 * 6728 * @throws DirectoryException If a problem occurs while attempting to 6729 * make the determination. 6730 */ 6731 public static boolean entryExists(DN entryDN) 6732 throws DirectoryException 6733 { 6734 // If the entry is the root DSE, then it will always exist. 6735 if (entryDN.isNullDN()) 6736 { 6737 return true; 6738 } 6739 6740 // Figure out which backend should be used for the entry. If it isn't 6741 // appropriate for any backend, then return false. 6742 Backend backend = getBackend(entryDN); 6743 if (backend == null) 6744 { 6745 return false; 6746 } 6747 6748 // Ask the appropriate backend if the entry exists. 6749 return backend.entryExists(entryDN); 6750 } 6751 6752 6753 6754 /** 6755 * Retrieves the set of supported controls registered with the Directory 6756 * Server. 6757 * 6758 * @return The set of supported controls registered with the Directory 6759 * Server. 6760 */ 6761 public static TreeSet<String> getSupportedControls() 6762 { 6763 return directoryServer.supportedControls; 6764 } 6765 6766 6767 6768 /** 6769 * Indicates whether the specified OID is registered with the Directory Server 6770 * as a supported control. 6771 * 6772 * @param controlOID The OID of the control for which to make the 6773 * determination. 6774 * 6775 * @return <CODE>true</CODE> if the specified OID is registered with the 6776 * server as a supported control, or <CODE>false</CODE> if not. 6777 */ 6778 public static boolean isSupportedControl(String controlOID) 6779 { 6780 return directoryServer.supportedControls.contains(controlOID); 6781 } 6782 6783 6784 6785 /** 6786 * Registers the provided OID as a supported control for the Directory Server. 6787 * This will have no effect if the specified control OID is already present in 6788 * the list of supported controls. 6789 * 6790 * @param controlOID The OID of the control to register as a supported 6791 * control. 6792 */ 6793 public static void registerSupportedControl(String controlOID) 6794 { 6795 synchronized (directoryServer.supportedControls) 6796 { 6797 directoryServer.supportedControls.add(controlOID); 6798 } 6799 } 6800 6801 6802 6803 /** 6804 * Deregisters the provided OID as a supported control for the Directory 6805 * Server. This will have no effect if the specified control OID is not 6806 * present in the list of supported controls. 6807 * 6808 * @param controlOID The OID of the control to deregister as a supported 6809 * control. 6810 */ 6811 public static void deregisterSupportedControl(String controlOID) 6812 { 6813 synchronized (directoryServer.supportedControls) 6814 { 6815 directoryServer.supportedControls.remove(controlOID); 6816 } 6817 } 6818 6819 6820 6821 /** 6822 * Retrieves the set of supported features registered with the Directory 6823 * Server. 6824 * 6825 * @return The set of supported features registered with the Directory 6826 * Server. 6827 */ 6828 public static TreeSet<String> getSupportedFeatures() 6829 { 6830 return directoryServer.supportedFeatures; 6831 } 6832 6833 6834 6835 /** 6836 * Indicates whether the specified OID is registered with the Directory Server 6837 * as a supported feature. 6838 * 6839 * @param featureOID The OID of the feature for which to make the 6840 * determination. 6841 * 6842 * @return <CODE>true</CODE> if the specified OID is registered with the 6843 * server as a supported feature, or <CODE>false</CODE> if not. 6844 */ 6845 public static boolean isSupportedFeature(String featureOID) 6846 { 6847 return directoryServer.supportedFeatures.contains(featureOID); 6848 } 6849 6850 6851 6852 /** 6853 * Registers the provided OID as a supported feature for the Directory Server. 6854 * This will have no effect if the specified feature OID is already present in 6855 * the list of supported features. 6856 * 6857 * @param featureOID The OID of the feature to register as a supported 6858 * feature. 6859 */ 6860 public static void registerSupportedFeature(String featureOID) 6861 { 6862 synchronized (directoryServer.supportedFeatures) 6863 { 6864 directoryServer.supportedFeatures.add(featureOID); 6865 } 6866 } 6867 6868 6869 6870 /** 6871 * Deregisters the provided OID as a supported feature for the Directory 6872 * Server. This will have no effect if the specified feature OID is not 6873 * present in the list of supported features. 6874 * 6875 * @param featureOID The OID of the feature to deregister as a supported 6876 * feature. 6877 */ 6878 public static void deregisterSupportedFeature(String featureOID) 6879 { 6880 synchronized (directoryServer.supportedFeatures) 6881 { 6882 directoryServer.supportedFeatures.remove(featureOID); 6883 } 6884 } 6885 6886 6887 6888 /** 6889 * Retrieves the set of extended operations that may be processed by the 6890 * Directory Server. 6891 * 6892 * @return The set of extended operations that may be processed by the 6893 * Directory Server. 6894 */ 6895 public static ConcurrentHashMap<String,ExtendedOperationHandler> 6896 getSupportedExtensions() 6897 { 6898 return directoryServer.extendedOperationHandlers; 6899 } 6900 6901 6902 6903 /** 6904 * Retrieves the handler for the extended operation for the provided OID. 6905 * 6906 * @param oid The OID of the extended operation to retrieve. 6907 * 6908 * @return The handler for the specified extended operation, or 6909 * <CODE>null</CODE> if there is none. 6910 */ 6911 public static ExtendedOperationHandler getExtendedOperationHandler(String oid) 6912 { 6913 return directoryServer.extendedOperationHandlers.get(oid); 6914 } 6915 6916 6917 6918 /** 6919 * Registers the provided extended operation handler with the Directory 6920 * Server. 6921 * 6922 * @param oid The OID for the extended operation to register. 6923 * @param handler The extended operation handler to register with the 6924 * Directory Server. 6925 */ 6926 public static void registerSupportedExtension(String oid, 6927 ExtendedOperationHandler handler) 6928 { 6929 directoryServer.extendedOperationHandlers.put(toLowerCase(oid), handler); 6930 } 6931 6932 6933 6934 /** 6935 * Deregisters the provided extended operation handler with the Directory 6936 * Server. 6937 * 6938 * @param oid The OID for the extended operation to deregister. 6939 */ 6940 public static void deregisterSupportedExtension(String oid) 6941 { 6942 directoryServer.extendedOperationHandlers.remove(toLowerCase(oid)); 6943 } 6944 6945 6946 6947 /** 6948 * Retrieves the set of SASL mechanisms that are supported by the Directory 6949 * Server. 6950 * 6951 * @return The set of SASL mechanisms that are supported by the Directory 6952 * Server. 6953 */ 6954 public static ConcurrentHashMap<String,SASLMechanismHandler> 6955 getSupportedSASLMechanisms() 6956 { 6957 return directoryServer.saslMechanismHandlers; 6958 } 6959 6960 6961 6962 /** 6963 * Retrieves the handler for the specified SASL mechanism. 6964 * 6965 * @param name The name of the SASL mechanism to retrieve. 6966 * 6967 * @return The handler for the specified SASL mechanism, or <CODE>null</CODE> 6968 * if there is none. 6969 */ 6970 public static SASLMechanismHandler getSASLMechanismHandler(String name) 6971 { 6972 return directoryServer.saslMechanismHandlers.get(name); 6973 } 6974 6975 6976 6977 /** 6978 * Registers the provided SASL mechanism handler with the Directory Server. 6979 * 6980 * @param name The name of the SASL mechanism to be registered. 6981 * @param handler The SASL mechanism handler to register with the Directory 6982 * Server. 6983 */ 6984 public static void registerSASLMechanismHandler(String name, 6985 SASLMechanismHandler handler) 6986 { 6987 // FIXME -- Should we force this name to be lowercase? If so, then will 6988 // that cause the lower name to be used in the root DSE? 6989 directoryServer.saslMechanismHandlers.put(name, handler); 6990 } 6991 6992 6993 6994 /** 6995 * Deregisters the provided SASL mechanism handler with the Directory Server. 6996 * 6997 * @param name The name of the SASL mechanism to be deregistered. 6998 */ 6999 public static void deregisterSASLMechanismHandler(String name) 7000 { 7001 // FIXME -- Should we force this name to be lowercase? 7002 directoryServer.saslMechanismHandlers.remove(name); 7003 } 7004 7005 7006 7007 /** 7008 * Retrieves the supported LDAP versions for the Directory Server. 7009 * 7010 * @return The supported LDAP versions for the Directory Server. 7011 */ 7012 public static Set<Integer> getSupportedLDAPVersions() 7013 { 7014 return directoryServer.supportedLDAPVersions.keySet(); 7015 } 7016 7017 7018 7019 /** 7020 * Registers the provided LDAP protocol version as supported within the 7021 * Directory Server. 7022 * 7023 * @param supportedLDAPVersion The LDAP protocol version to register as 7024 * supported. 7025 * @param connectionHandler The connection handler that supports the 7026 * provided LDAP version. Note that multiple 7027 * connection handlers can provide support for 7028 * the same LDAP versions. 7029 */ 7030 public static synchronized void registerSupportedLDAPVersion( 7031 int supportedLDAPVersion, 7032 ConnectionHandler connectionHandler) 7033 { 7034 List<ConnectionHandler> handlers = 7035 directoryServer.supportedLDAPVersions.get(supportedLDAPVersion); 7036 if (handlers == null) 7037 { 7038 handlers = new LinkedList<ConnectionHandler>(); 7039 handlers.add(connectionHandler); 7040 directoryServer.supportedLDAPVersions.put(supportedLDAPVersion, handlers); 7041 } 7042 else 7043 { 7044 if (! handlers.contains(connectionHandler)) 7045 { 7046 handlers.add(connectionHandler); 7047 } 7048 } 7049 } 7050 7051 7052 7053 /** 7054 * Deregisters the provided LDAP protocol version as supported within the 7055 * Directory Server. 7056 * 7057 * @param supportedLDAPVersion The LDAP protocol version to deregister. 7058 * @param connectionHandler The connection handler that no longer 7059 * supports the provided LDAP version. 7060 */ 7061 public static synchronized void deregisterSupportedLDAPVersion( 7062 int supportedLDAPVersion, 7063 ConnectionHandler connectionHandler) 7064 { 7065 List<ConnectionHandler> handlers = 7066 directoryServer.supportedLDAPVersions.get(supportedLDAPVersion); 7067 if (handlers != null) 7068 { 7069 handlers.remove(connectionHandler); 7070 if (handlers.isEmpty()) 7071 { 7072 directoryServer.supportedLDAPVersions.remove(supportedLDAPVersion); 7073 } 7074 } 7075 } 7076 7077 7078 7079 7080 /** 7081 * Retrieves the set of identity mappers defined in the Directory Server 7082 * configuration, as a mapping between the DN of the configuration entry and 7083 * the identity mapper. 7084 * 7085 * @return The set of identity mappers defined in the Directory Server 7086 * configuration. 7087 */ 7088 public static ConcurrentHashMap<DN,IdentityMapper> getIdentityMappers() 7089 { 7090 return directoryServer.identityMappers; 7091 } 7092 7093 7094 7095 /** 7096 * Retrieves the Directory Server identity mapper whose configuration resides 7097 * in the specified configuration entry. 7098 * 7099 * @param configEntryDN The DN of the configuration entry for the identity 7100 * mapper to retrieve. 7101 * 7102 * @return The requested identity mapper, or <CODE>null</CODE> if the 7103 * provided entry DN is not associated with an active identity 7104 * mapper. 7105 */ 7106 public static IdentityMapper getIdentityMapper(DN configEntryDN) 7107 { 7108 return directoryServer.identityMappers.get(configEntryDN); 7109 } 7110 7111 7112 7113 /** 7114 * Registers the provided identity mapper for use with the Directory Server. 7115 * 7116 * @param configEntryDN The DN of the configuration entry in which the 7117 * identity mapper definition resides. 7118 * @param identityMapper The identity mapper to be registered. 7119 */ 7120 public static void registerIdentityMapper(DN configEntryDN, 7121 IdentityMapper identityMapper) 7122 { 7123 directoryServer.identityMappers.put(configEntryDN, identityMapper); 7124 } 7125 7126 7127 7128 /** 7129 * Deregisters the provided identity mapper for use with the Directory Server. 7130 * 7131 * @param configEntryDN The DN of the configuration entry in which the 7132 * identity mapper definition resides. 7133 */ 7134 public static void deregisterIdentityMapper(DN configEntryDN) 7135 { 7136 directoryServer.identityMappers.remove(configEntryDN); 7137 } 7138 7139 7140 7141 /** 7142 * Retrieves the DN of the configuration entry for the identity mapper that 7143 * should be used in conjunction with proxied authorization V2 controls. 7144 * 7145 * @return The DN of the configuration entry for the identity mapper that 7146 * should be used in conjunction with proxied authorization V2 7147 * controls, or <CODE>null</CODE> if none is defined. 7148 */ 7149 public static DN getProxiedAuthorizationIdentityMapperDN() 7150 { 7151 return directoryServer.proxiedAuthorizationIdentityMapperDN; 7152 } 7153 7154 7155 7156 /** 7157 * Specifies the DN of the configuration entry for the identity mapper that 7158 * should be used in conjunction with proxied authorization V2 controls. 7159 * 7160 * @param proxiedAuthorizationIdentityMapperDN The DN of the configuration 7161 * entry for the identity mapper 7162 * that should be used in 7163 * conjunction with proxied 7164 * authorization V2 controls. 7165 */ 7166 public static void setProxiedAuthorizationIdentityMapperDN( 7167 DN proxiedAuthorizationIdentityMapperDN) 7168 { 7169 directoryServer.proxiedAuthorizationIdentityMapperDN = 7170 proxiedAuthorizationIdentityMapperDN; 7171 } 7172 7173 7174 7175 /** 7176 * Retrieves the identity mapper that should be used to resolve authorization 7177 * IDs contained in proxied authorization V2 controls. 7178 * 7179 * @return The identity mapper that should be used to resolve authorization 7180 * IDs contained in proxied authorization V2 controls, or 7181 * <CODE>null</CODE> if none is defined. 7182 */ 7183 public static IdentityMapper getProxiedAuthorizationIdentityMapper() 7184 { 7185 if (directoryServer.proxiedAuthorizationIdentityMapperDN == null) 7186 { 7187 return null; 7188 } 7189 7190 return directoryServer.identityMappers.get( 7191 directoryServer.proxiedAuthorizationIdentityMapperDN); 7192 } 7193 7194 7195 7196 /** 7197 * Retrieves the set of connection handlers configured in the Directory 7198 * Server. The returned list must not be altered. 7199 * 7200 * @return The set of connection handlers configured in the Directory Server. 7201 */ 7202 public static CopyOnWriteArrayList<ConnectionHandler> getConnectionHandlers() 7203 { 7204 return directoryServer.connectionHandlers; 7205 } 7206 7207 7208 7209 /** 7210 * Registers the provided connection handler with the Directory Server. 7211 * 7212 * @param handler The connection handler to register with the Directory 7213 * Server. 7214 */ 7215 public static void registerConnectionHandler( 7216 ConnectionHandler<? extends ConnectionHandlerCfg> 7217 handler) 7218 { 7219 synchronized (directoryServer.connectionHandlers) 7220 { 7221 directoryServer.connectionHandlers.add(handler); 7222 7223 ConnectionHandlerMonitor monitor = new ConnectionHandlerMonitor(handler); 7224 monitor.initializeMonitorProvider(null); 7225 handler.setConnectionHandlerMonitor(monitor); 7226 registerMonitorProvider(monitor); 7227 } 7228 } 7229 7230 7231 7232 /** 7233 * Deregisters the provided connection handler with the Directory Server. 7234 * 7235 * @param handler The connection handler to deregister with the Directory 7236 * Server. 7237 */ 7238 public static void deregisterConnectionHandler(ConnectionHandler handler) 7239 { 7240 synchronized (directoryServer.connectionHandlers) 7241 { 7242 directoryServer.connectionHandlers.remove(handler); 7243 7244 ConnectionHandlerMonitor monitor = handler.getConnectionHandlerMonitor(); 7245 if (monitor != null) 7246 { 7247 String instanceName = toLowerCase(monitor.getMonitorInstanceName()); 7248 deregisterMonitorProvider(instanceName); 7249 monitor.finalizeMonitorProvider(); 7250 handler.setConnectionHandlerMonitor(null); 7251 } 7252 } 7253 } 7254 7255 7256 7257 /** 7258 * Starts the connection handlers defined in the Directory Server 7259 * Configuration. 7260 * 7261 * @throws ConfigException If there are more than one connection handlers 7262 * using the same host port or no connection handler 7263 * are enabled or we could not bind to any of the 7264 * listeners. 7265 */ 7266 private void startConnectionHandlers() throws ConfigException 7267 { 7268 LinkedHashSet<HostPort> usedListeners = new LinkedHashSet<HostPort>(); 7269 LinkedHashSet<Message> errorMessages = new LinkedHashSet<Message>(); 7270 // Check that the port specified in the connection handlers is 7271 // available. 7272 for (ConnectionHandler<?> c : connectionHandlers) 7273 { 7274 for (HostPort listener : c.getListeners()) 7275 { 7276 if (usedListeners.contains(listener)) 7277 { 7278 // The port was already specified: this is a configuration error, 7279 // log a message. 7280 Message message = ERR_HOST_PORT_ALREADY_SPECIFIED.get( 7281 c.getConnectionHandlerName(), listener.toString()); 7282 logError(message); 7283 errorMessages.add(message); 7284 7285 } 7286 else 7287 { 7288 usedListeners.add(listener); 7289 } 7290 } 7291 } 7292 7293 if (errorMessages.size() > 0) 7294 { 7295 throw new ConfigException(ERR_ERROR_STARTING_CONNECTION_HANDLERS.get()); 7296 } 7297 7298 7299 // If there are no connection handlers log a message. 7300 if (connectionHandlers.isEmpty()) 7301 { 7302 Message message = ERR_NOT_AVAILABLE_CONNECTION_HANDLERS.get(); 7303 logError(message); 7304 throw new ConfigException(ERR_ERROR_STARTING_CONNECTION_HANDLERS.get()); 7305 } 7306 7307 // At this point, we should be ready to go. Start all the connection 7308 // handlers. 7309 for (ConnectionHandler c : connectionHandlers) 7310 { 7311 c.start(); 7312 } 7313 } 7314 7315 /** 7316 * Retrieves a reference to the Directory Server work queue. 7317 * 7318 * @return A reference to the Directory Server work queue. 7319 */ 7320 public static WorkQueue getWorkQueue() 7321 { 7322 return directoryServer.workQueue; 7323 } 7324 7325 7326 7327 /** 7328 * Adds the provided operation to the work queue so that it will be processed 7329 * by one of the worker threads. 7330 * 7331 * @param operation The operation to be added to the work queue. 7332 * 7333 * @throws DirectoryException If a problem prevents the operation from being 7334 * added to the queue (e.g., the queue is full). 7335 */ 7336 public static void enqueueRequest(AbstractOperation operation) 7337 throws DirectoryException 7338 { 7339 // See if a bind is already in progress on the associated connection. If so 7340 // then reject the operation. 7341 ClientConnection clientConnection = operation.getClientConnection(); 7342 if (clientConnection.bindInProgress() && 7343 (operation.getOperationType() != OperationType.BIND)) 7344 { 7345 Message message = ERR_ENQUEUE_BIND_IN_PROGRESS.get(); 7346 throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message); 7347 } 7348 7349 7350 //Reject or accept the unauthenticated requests based on the configuration 7351 // settings. 7352 if ((directoryServer.rejectUnauthenticatedRequests || 7353 directoryServer.lockdownMode) && 7354 !clientConnection.getAuthenticationInfo().isAuthenticated()) 7355 { 7356 switch(operation.getOperationType()) 7357 { 7358 case ADD: 7359 case COMPARE: 7360 case DELETE: 7361 case SEARCH: 7362 case MODIFY: 7363 case MODIFY_DN: 7364 if (directoryServer.lockdownMode) 7365 { 7366 Message message = NOTE_REJECT_OPERATION_IN_LOCKDOWN_MODE.get(); 7367 throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, 7368 message); 7369 } 7370 else 7371 { 7372 Message message = ERR_REJECT_UNAUTHENTICATED_OPERATION.get(); 7373 throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, 7374 message); 7375 } 7376 7377 case EXTENDED: 7378 ExtendedOperationBasis extOp = (ExtendedOperationBasis) operation; 7379 String requestOID = extOp.getRequestOID(); 7380 if (!((requestOID != null) && 7381 requestOID.equals(OID_START_TLS_REQUEST))) 7382 { 7383 if (directoryServer.lockdownMode) 7384 { 7385 Message message = NOTE_REJECT_OPERATION_IN_LOCKDOWN_MODE.get(); 7386 throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, 7387 message); 7388 } 7389 else 7390 { 7391 Message message = ERR_REJECT_UNAUTHENTICATED_OPERATION.get(); 7392 throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, 7393 message); 7394 } 7395 } 7396 break; 7397 7398 } 7399 7400 } 7401 7402 7403 // If the associated user is required to change their password before 7404 // continuing, then make sure the associated operation is one that could 7405 // result in the password being changed. If not, then reject it. 7406 if (clientConnection.mustChangePassword()) 7407 { 7408 switch (operation.getOperationType()) 7409 { 7410 case ADD: 7411 case COMPARE: 7412 case DELETE: 7413 case MODIFY_DN: 7414 case SEARCH: 7415 // See if the request included the password policy request control. 7416 // If it did, then add a corresponding response control. 7417 for (Control c : operation.getRequestControls()) 7418 { 7419 if (c.getOID().equals(OID_PASSWORD_POLICY_CONTROL)) 7420 { 7421 operation.addResponseControl(new PasswordPolicyResponseControl( 7422 null, 0, PasswordPolicyErrorType.CHANGE_AFTER_RESET)); 7423 break; 7424 } 7425 } 7426 7427 Message message = ERR_ENQUEUE_MUST_CHANGE_PASSWORD.get(); 7428 throw new DirectoryException( 7429 ResultCode.CONSTRAINT_VIOLATION, message); 7430 7431 case EXTENDED: 7432 // We will only allow the password modify and StartTLS extended 7433 // operations. 7434 ExtendedOperationBasis extOp = (ExtendedOperationBasis) operation; 7435 String requestOID = extOp.getRequestOID(); 7436 if ((requestOID == null) || 7437 ((! requestOID.equals(OID_PASSWORD_MODIFY_REQUEST)) && 7438 (! requestOID.equals(OID_START_TLS_REQUEST)))) 7439 { 7440 // See if the request included the password policy request control. 7441 // If it did, then add a corresponding response control. 7442 for (Control c : operation.getRequestControls()) 7443 { 7444 if (c.getOID().equals(OID_PASSWORD_POLICY_CONTROL)) 7445 { 7446 operation.addResponseControl(new PasswordPolicyResponseControl( 7447 null, 0, PasswordPolicyErrorType.CHANGE_AFTER_RESET)); 7448 break; 7449 } 7450 } 7451 7452 message = ERR_ENQUEUE_MUST_CHANGE_PASSWORD.get(); 7453 throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, 7454 message); 7455 } 7456 7457 break; 7458 7459 // Bind, unbind, and abandon will always be allowed. 7460 7461 // Modify may or may not be allowed, but we'll leave that 7462 // determination up to the modify operation itself. 7463 } 7464 } 7465 7466 7467 7468 directoryServer.workQueue.submitOperation(operation); 7469 } 7470 7471 7472 7473 /** 7474 * Retrieves the set of change notification listeners registered with the 7475 * Directory Server. 7476 * 7477 * @return The set of change notification listeners registered with the 7478 * Directory Server. 7479 */ 7480 public static CopyOnWriteArrayList<ChangeNotificationListener> 7481 getChangeNotificationListeners() 7482 { 7483 return directoryServer.changeNotificationListeners; 7484 } 7485 7486 7487 7488 /** 7489 * Registers the provided change notification listener with the Directory 7490 * Server so that it will be notified of any add, delete, modify, or modify DN 7491 * operations that are performed. 7492 * 7493 * @param changeListener The change notification listener to register with 7494 * the Directory Server. 7495 */ 7496 public static void registerChangeNotificationListener( 7497 ChangeNotificationListener changeListener) 7498 { 7499 directoryServer.changeNotificationListeners.add(changeListener); 7500 } 7501 7502 7503 7504 /** 7505 * Deregisters the provided change notification listener with the Directory 7506 * Server so that it will no longer be notified of any add, delete, modify, or 7507 * modify DN operations that are performed. 7508 * 7509 * @param changeListener The change notification listener to deregister with 7510 * the Directory Server. 7511 */ 7512 public static void deregisterChangeNotificationListener( 7513 ChangeNotificationListener changeListener) 7514 { 7515 directoryServer.changeNotificationListeners.remove(changeListener); 7516 } 7517 7518 7519 7520 /** 7521 * Retrieves the set of persistent searches registered with the Directory 7522 * Server. 7523 * 7524 * @return The set of persistent searches registered with the Directory 7525 * Server. 7526 */ 7527 public static CopyOnWriteArrayList<PersistentSearch> getPersistentSearches() 7528 { 7529 return directoryServer.persistentSearches; 7530 } 7531 7532 7533 7534 /** 7535 * Registers the provided persistent search operation with the Directory 7536 * Server so that it will be notified of any add, delete, modify, or modify DN 7537 * operations that are performed. 7538 * 7539 * @param persistentSearch The persistent search operation to register with 7540 * the Directory Server. 7541 */ 7542 public static void registerPersistentSearch(PersistentSearch persistentSearch) 7543 { 7544 directoryServer.persistentSearches.add(persistentSearch); 7545 persistentSearch.getSearchOperation().getClientConnection(). 7546 registerPersistentSearch(persistentSearch); 7547 } 7548 7549 7550 7551 /** 7552 * Deregisters the provided persistent search operation with the Directory 7553 * Server so that it will no longer be notified of any add, delete, modify, or 7554 * modify DN operations that are performed. 7555 * 7556 * @param persistentSearch The persistent search operation to deregister 7557 * with the Directory Server. 7558 */ 7559 public static void deregisterPersistentSearch(PersistentSearch 7560 persistentSearch) 7561 { 7562 directoryServer.persistentSearches.remove(persistentSearch); 7563 persistentSearch.getSearchOperation().getClientConnection(). 7564 deregisterPersistentSearch(persistentSearch); 7565 } 7566 7567 7568 7569 7570 /** 7571 * Retrieves the set of synchronization providers that have been registered 7572 * with the Directory Server. 7573 * 7574 * @return The set of synchronization providers that have been registered 7575 * with the Directory Server. 7576 */ 7577 public static 7578 CopyOnWriteArrayList<SynchronizationProvider<SynchronizationProviderCfg>> 7579 getSynchronizationProviders() 7580 { 7581 return directoryServer.synchronizationProviders; 7582 } 7583 7584 7585 7586 /** 7587 * Registers the provided synchronization provider with the Directory Server. 7588 * 7589 * @param provider The synchronization provider to register. 7590 */ 7591 public static void registerSynchronizationProvider( 7592 SynchronizationProvider<SynchronizationProviderCfg> provider) 7593 { 7594 directoryServer.synchronizationProviders.add(provider); 7595 7596 provider.completeSynchronizationProvider(); 7597 } 7598 7599 7600 7601 /** 7602 * Deregisters the provided synchronization provider with the Directory 7603 * Server. 7604 * 7605 * @param provider The synchronization provider to deregister. 7606 */ 7607 public static void deregisterSynchronizationProvider(SynchronizationProvider 7608 provider) 7609 { 7610 directoryServer.synchronizationProviders.remove(provider); 7611 } 7612 7613 7614 7615 /** 7616 * Retrieves a set containing the names of the allowed tasks that may be 7617 * invoked in the server. 7618 * 7619 * @return A set containing the names of the allowed tasks that may be 7620 * invoked in the server. 7621 */ 7622 public static Set<String> getAllowedTasks() 7623 { 7624 return directoryServer.allowedTasks; 7625 } 7626 7627 7628 7629 /** 7630 * Specifies the set of allowed tasks that may be invoked in the server. 7631 * 7632 * @param allowedTasks A set containing the names of the allowed tasks that 7633 * may be invoked in the server. 7634 */ 7635 public static void setAllowedTasks(Set<String> allowedTasks) 7636 { 7637 directoryServer.allowedTasks = allowedTasks; 7638 } 7639 7640 7641 7642 /** 7643 * Retrieves the set of privileges that have been disabled. 7644 * 7645 * @return The set of privileges that have been disabled. 7646 */ 7647 public static Set<Privilege> getDisabledPrivileges() 7648 { 7649 return directoryServer.disabledPrivileges; 7650 } 7651 7652 7653 7654 /** 7655 * Indicates whether the specified privilege is disabled. 7656 * 7657 * @param privilege The privilege for which to make the determination. 7658 * 7659 * @return {@code true} if the specified privilege is disabled, or 7660 * {@code false} if not. 7661 */ 7662 public static boolean isDisabled(Privilege privilege) 7663 { 7664 return directoryServer.disabledPrivileges.contains(privilege); 7665 } 7666 7667 7668 7669 /** 7670 * Specifies the set of privileges that should be disabled in the server. 7671 * 7672 * @param disabledPrivileges The set of privileges that should be disabled 7673 * in the server. 7674 */ 7675 public static void setDisabledPrivileges(Set<Privilege> disabledPrivileges) 7676 { 7677 directoryServer.disabledPrivileges = disabledPrivileges; 7678 } 7679 7680 7681 7682 /** 7683 * Indicates whether responses to failed bind operations should include a 7684 * message explaining the reason for the failure. 7685 * 7686 * @return {@code true} if bind responses should include error messages, or 7687 * {@code false} if not. 7688 */ 7689 public static boolean returnBindErrorMessages() 7690 { 7691 return directoryServer.returnBindErrorMessages; 7692 } 7693 7694 7695 7696 /** 7697 * Specifies whether responses to failed bind operations should include a 7698 * message explaining the reason for the failure. 7699 * 7700 * @param returnBindErrorMessages Specifies whether responses to failed bind 7701 * operations should include a message 7702 * explaining the reason for the failure. 7703 */ 7704 public static void setReturnBindErrorMessages(boolean returnBindErrorMessages) 7705 { 7706 directoryServer.returnBindErrorMessages = returnBindErrorMessages; 7707 } 7708 7709 7710 7711 /** 7712 * Retrieves the maximum length of time in milliseconds that client 7713 * connections should be allowed to remain idle without being disconnected. 7714 * 7715 * @return The maximum length of time in milliseconds that client connections 7716 * should be allowed to remain idle without being disconnected. 7717 */ 7718 public static long getIdleTimeLimit() 7719 { 7720 return directoryServer.idleTimeLimit; 7721 } 7722 7723 7724 7725 /** 7726 * Specifies the maximum length of time in milliseconds that client 7727 * connections should be allowed to remain idle without being disconnected. 7728 * 7729 * @param idleTimeLimit The maximum length of time in milliseconds that 7730 * client connections should be allowed to remain idle 7731 * without being disconnected. 7732 */ 7733 public static void setIdleTimeLimit(long idleTimeLimit) 7734 { 7735 directoryServer.idleTimeLimit = idleTimeLimit; 7736 } 7737 7738 7739 7740 /** 7741 * Indicates whether the Directory Server should save a copy of its 7742 * configuration whenever it is started successfully. 7743 * 7744 * @return {@code true} if the server should save a copy of its configuration 7745 * whenever it is started successfully, or {@code false} if not. 7746 */ 7747 public static boolean saveConfigOnSuccessfulStartup() 7748 { 7749 return directoryServer.saveConfigOnSuccessfulStartup; 7750 } 7751 7752 7753 7754 /** 7755 * Specifies whether the Directory Server should save a copy of its 7756 * configuration whenever it is started successfully. 7757 * 7758 * @param saveConfigOnSuccessfulStartup Specifies whether the server should 7759 * save a copy of its configuration 7760 * whenever it is started successfully. 7761 */ 7762 public static void setSaveConfigOnSuccessfulStartup( 7763 boolean saveConfigOnSuccessfulStartup) 7764 { 7765 directoryServer.saveConfigOnSuccessfulStartup = 7766 saveConfigOnSuccessfulStartup; 7767 } 7768 7769 7770 7771 /** 7772 * Registers the provided backup task listener with the Directory Server. 7773 * 7774 * @param listener The backup task listener to register with the Directory 7775 * Server. 7776 */ 7777 public static void registerBackupTaskListener(BackupTaskListener listener) 7778 { 7779 directoryServer.backupTaskListeners.addIfAbsent(listener); 7780 } 7781 7782 7783 7784 /** 7785 * Deregisters the provided backup task listener with the Directory Server. 7786 * 7787 * @param listener The backup task listener to deregister with the Directory 7788 * Server. 7789 */ 7790 public static void deregisterBackupTaskListener(BackupTaskListener listener) 7791 { 7792 directoryServer.backupTaskListeners.remove(listener); 7793 } 7794 7795 7796 7797 /** 7798 * Notifies the registered backup task listeners that the server will be 7799 * beginning a backup task with the provided information. 7800 * 7801 * @param backend The backend in which the backup is to be performed. 7802 * @param config The configuration for the backup to be performed. 7803 */ 7804 public static void notifyBackupBeginning(Backend backend, BackupConfig config) 7805 { 7806 for (BackupTaskListener listener : directoryServer.backupTaskListeners) 7807 { 7808 try 7809 { 7810 listener.processBackupBegin(backend, config); 7811 } 7812 catch (Exception e) 7813 { 7814 if (debugEnabled()) 7815 { 7816 TRACER.debugCaught(DebugLogLevel.ERROR, e); 7817 } 7818 } 7819 } 7820 } 7821 7822 7823 7824 /** 7825 * Notifies the registered backup task listeners that the server has completed 7826 * processing on a backup task with the provided information. 7827 * 7828 * @param backend The backend in which the backup was performed. 7829 * @param config The configuration for the backup that was performed. 7830 * @param successful Indicates whether the backup completed successfully. 7831 */ 7832 public static void notifyBackupEnded(Backend backend, BackupConfig config, 7833 boolean successful) 7834 { 7835 for (BackupTaskListener listener : directoryServer.backupTaskListeners) 7836 { 7837 try 7838 { 7839 listener.processBackupEnd(backend, config, successful); 7840 } 7841 catch (Exception e) 7842 { 7843 if (debugEnabled()) 7844 { 7845 TRACER.debugCaught(DebugLogLevel.ERROR, e); 7846 } 7847 } 7848 } 7849 } 7850 7851 7852 7853 /** 7854 * Registers the provided restore task listener with the Directory Server. 7855 * 7856 * @param listener The restore task listener to register with the Directory 7857 * Server. 7858 */ 7859 public static void registerRestoreTaskListener(RestoreTaskListener listener) 7860 { 7861 directoryServer.restoreTaskListeners.addIfAbsent(listener); 7862 } 7863 7864 7865 7866 /** 7867 * Deregisters the provided restore task listener with the Directory Server. 7868 * 7869 * @param listener The restore task listener to deregister with the 7870 * Directory Server. 7871 */ 7872 public static void deregisterRestoreTaskListener(RestoreTaskListener listener) 7873 { 7874 directoryServer.restoreTaskListeners.remove(listener); 7875 } 7876 7877 7878 7879 /** 7880 * Notifies the registered restore task listeners that the server will be 7881 * beginning a restore task with the provided information. 7882 * 7883 * @param backend The backend in which the restore is to be performed. 7884 * @param config The configuration for the restore to be performed. 7885 */ 7886 public static void notifyRestoreBeginning(Backend backend, 7887 RestoreConfig config) 7888 { 7889 for (RestoreTaskListener listener : directoryServer.restoreTaskListeners) 7890 { 7891 try 7892 { 7893 listener.processRestoreBegin(backend, config); 7894 } 7895 catch (Exception e) 7896 { 7897 if (debugEnabled()) 7898 { 7899 TRACER.debugCaught(DebugLogLevel.ERROR, e); 7900 } 7901 } 7902 } 7903 } 7904 7905 7906 7907 /** 7908 * Notifies the registered restore task listeners that the server has 7909 * completed processing on a restore task with the provided information. 7910 * 7911 * @param backend The backend in which the restore was performed. 7912 * @param config The configuration for the restore that was performed. 7913 * @param successful Indicates whether the restore completed successfully. 7914 */ 7915 public static void notifyRestoreEnded(Backend backend, RestoreConfig config, 7916 boolean successful) 7917 { 7918 for (RestoreTaskListener listener : directoryServer.restoreTaskListeners) 7919 { 7920 try 7921 { 7922 listener.processRestoreEnd(backend, config, successful); 7923 } 7924 catch (Exception e) 7925 { 7926 if (debugEnabled()) 7927 { 7928 TRACER.debugCaught(DebugLogLevel.ERROR, e); 7929 } 7930 } 7931 } 7932 } 7933 7934 7935 7936 /** 7937 * Registers the provided LDIF export task listener with the Directory Server. 7938 * 7939 * @param listener The export task listener to register with the Directory 7940 * Server. 7941 */ 7942 public static void registerExportTaskListener(ExportTaskListener listener) 7943 { 7944 directoryServer.exportTaskListeners.addIfAbsent(listener); 7945 } 7946 7947 7948 7949 /** 7950 * Deregisters the provided LDIF export task listener with the Directory 7951 * Server. 7952 * 7953 * @param listener The export task listener to deregister with the Directory 7954 * Server. 7955 */ 7956 public static void deregisterExportTaskListener(ExportTaskListener listener) 7957 { 7958 directoryServer.exportTaskListeners.remove(listener); 7959 } 7960 7961 7962 7963 /** 7964 * Notifies the registered LDIF export task listeners that the server will be 7965 * beginning an export task with the provided information. 7966 * 7967 * @param backend The backend in which the export is to be performed. 7968 * @param config The configuration for the export to be performed. 7969 */ 7970 public static void notifyExportBeginning(Backend backend, 7971 LDIFExportConfig config) 7972 { 7973 for (ExportTaskListener listener : directoryServer.exportTaskListeners) 7974 { 7975 try 7976 { 7977 listener.processExportBegin(backend, config); 7978 } 7979 catch (Exception e) 7980 { 7981 if (debugEnabled()) 7982 { 7983 TRACER.debugCaught(DebugLogLevel.ERROR, e); 7984 } 7985 } 7986 } 7987 } 7988 7989 7990 7991 /** 7992 * Notifies the registered LDIF export task listeners that the server has 7993 * completed processing on an export task with the provided information. 7994 * 7995 * @param backend The backend in which the export was performed. 7996 * @param config The configuration for the export that was performed. 7997 * @param successful Indicates whether the export completed successfully. 7998 */ 7999 public static void notifyExportEnded(Backend backend, LDIFExportConfig config, 8000 boolean successful) 8001 { 8002 for (ExportTaskListener listener : directoryServer.exportTaskListeners) 8003 { 8004 try 8005 { 8006 listener.processExportEnd(backend, config, successful); 8007 } 8008 catch (Exception e) 8009 { 8010 if (debugEnabled()) 8011 { 8012 TRACER.debugCaught(DebugLogLevel.ERROR, e); 8013 } 8014 } 8015 } 8016 } 8017 8018 8019 8020 /** 8021 * Registers the provided LDIF import task listener with the Directory Server. 8022 * 8023 * @param listener The import task listener to register with the Directory 8024 * Server. 8025 */ 8026 public static void registerImportTaskListener(ImportTaskListener listener) 8027 { 8028 directoryServer.importTaskListeners.addIfAbsent(listener); 8029 } 8030 8031 8032 8033 /** 8034 * Deregisters the provided LDIF import task listener with the Directory 8035 * Server. 8036 * 8037 * @param listener The import task listener to deregister with the Directory 8038 * Server. 8039 */ 8040 public static void deregisterImportTaskListener(ImportTaskListener listener) 8041 { 8042 directoryServer.importTaskListeners.remove(listener); 8043 } 8044 8045 8046 8047 /** 8048 * Notifies the registered LDIF import task listeners that the server will be 8049 * beginning an import task with the provided information. 8050 * 8051 * @param backend The backend in which the import is to be performed. 8052 * @param config The configuration for the import to be performed. 8053 */ 8054 public static void notifyImportBeginning(Backend backend, 8055 LDIFImportConfig config) 8056 { 8057 for (ImportTaskListener listener : directoryServer.importTaskListeners) 8058 { 8059 try 8060 { 8061 listener.processImportBegin(backend, config); 8062 } 8063 catch (Exception e) 8064 { 8065 if (debugEnabled()) 8066 { 8067 TRACER.debugCaught(DebugLogLevel.ERROR, e); 8068 } 8069 } 8070 } 8071 } 8072 8073 8074 8075 /** 8076 * Notifies the registered LDIF import task listeners that the server has 8077 * completed processing on an import task with the provided information. 8078 * 8079 * @param backend The backend in which the import was performed. 8080 * @param config The configuration for the import that was performed. 8081 * @param successful Indicates whether the import completed successfully. 8082 */ 8083 public static void notifyImportEnded(Backend backend, LDIFImportConfig config, 8084 boolean successful) 8085 { 8086 for (ImportTaskListener listener : directoryServer.importTaskListeners) 8087 { 8088 try 8089 { 8090 listener.processImportEnd(backend, config, successful); 8091 } 8092 catch (Exception e) 8093 { 8094 if (debugEnabled()) 8095 { 8096 TRACER.debugCaught(DebugLogLevel.ERROR, e); 8097 } 8098 } 8099 } 8100 } 8101 8102 8103 8104 /** 8105 * Registers the provided shutdown listener with the Directory Server so that 8106 * it will be notified when the server shuts down. 8107 * 8108 * @param listener The shutdown listener to register with the Directory 8109 * Server. 8110 */ 8111 public static void registerShutdownListener(ServerShutdownListener listener) 8112 { 8113 directoryServer.shutdownListeners.add(listener); 8114 } 8115 8116 8117 8118 /** 8119 * Deregisters the provided shutdown listener with the Directory Server. 8120 * 8121 * @param listener The shutdown listener to deregister with the Directory 8122 * Server. 8123 */ 8124 public static void deregisterShutdownListener(ServerShutdownListener listener) 8125 { 8126 directoryServer.shutdownListeners.remove(listener); 8127 } 8128 8129 8130 /** 8131 * Initiates the Directory Server shutdown process. Note that once this has 8132 * started, it should not be interrupted. 8133 * 8134 * @param className The fully-qualified name of the Java class that 8135 * initiated the shutdown. 8136 * @param reason The human-readable reason that the directory server is 8137 * shutting down. 8138 */ 8139 public static void shutDown(String className, Message reason) 8140 { 8141 synchronized (directoryServer) 8142 { 8143 if (directoryServer.shuttingDown) 8144 { 8145 // We already know that the server is shutting down, so we don't need to 8146 // do anything. 8147 return; 8148 } 8149 8150 directoryServer.shuttingDown = true; 8151 } 8152 8153 ConfigEntry rootConfigEntry = null; 8154 try { 8155 rootConfigEntry = directoryServer.configHandler.getConfigRootEntry(); 8156 } catch (Exception e) { 8157 8158 } 8159 8160 // Send an alert notification that the server is shutting down. 8161 Message message = NOTE_SERVER_SHUTDOWN.get(className, reason); 8162 sendAlertNotification(directoryServer, ALERT_TYPE_SERVER_SHUTDOWN, 8163 message); 8164 8165 8166 // Create a shutdown monitor that will watch the rest of the shutdown 8167 // process to ensure that everything goes smoothly. 8168 ServerShutdownMonitor shutdownMonitor = new ServerShutdownMonitor(); 8169 shutdownMonitor.start(); 8170 8171 8172 // Shut down the connection handlers. 8173 for (ConnectionHandler handler : directoryServer.connectionHandlers) 8174 { 8175 try 8176 { 8177 8178 handler.finalizeConnectionHandler( 8179 INFO_CONNHANDLER_CLOSED_BY_SHUTDOWN.get(), true); 8180 } 8181 catch (Exception e) 8182 { 8183 if (debugEnabled()) 8184 { 8185 TRACER.debugCaught(DebugLogLevel.ERROR, e); 8186 } 8187 } 8188 } 8189 directoryServer.connectionHandlers.clear(); 8190 8191 8192 8193 // Call the shutdown plugins, and then finalize all the plugins defined in 8194 // the server. 8195 if (directoryServer.pluginConfigManager != null) 8196 { 8197 directoryServer.pluginConfigManager.invokeShutdownPlugins(reason); 8198 directoryServer.pluginConfigManager.finalizePlugins(); 8199 } 8200 8201 8202 // shutdown the Synchronization Providers 8203 for (SynchronizationProvider provider : 8204 directoryServer.synchronizationProviders) 8205 { 8206 provider.finalizeSynchronizationProvider(); 8207 } 8208 8209 // Deregister the shutdown hook. 8210 if (directoryServer.shutdownHook != null) 8211 { 8212 try 8213 { 8214 Runtime.getRuntime().removeShutdownHook(directoryServer.shutdownHook); 8215 } 8216 catch (Exception e) {} 8217 } 8218 8219 8220 // Stop the work queue. 8221 if (directoryServer.workQueue != null) 8222 { 8223 directoryServer.workQueue.finalizeWorkQueue(reason); 8224 } 8225 8226 8227 // Notify all the shutdown listeners. 8228 for (ServerShutdownListener shutdownListener : 8229 directoryServer.shutdownListeners) 8230 { 8231 try 8232 { 8233 shutdownListener.processServerShutdown(reason); 8234 } 8235 catch (Exception e) 8236 { 8237 if (debugEnabled()) 8238 { 8239 TRACER.debugCaught(DebugLogLevel.ERROR, e); 8240 } 8241 } 8242 } 8243 8244 8245 // Shut down all of the alert handlers. 8246 for (AlertHandler alertHandler : directoryServer.alertHandlers) 8247 { 8248 alertHandler.finalizeAlertHandler(); 8249 } 8250 8251 8252 // Deregister all of the JMX MBeans. 8253 if (directoryServer.mBeanServer != null) 8254 { 8255 Set mBeanSet = directoryServer.mBeanServer.queryMBeans(null, null); 8256 for (Object o : mBeanSet) 8257 { 8258 if (o instanceof DirectoryServerMBean) 8259 { 8260 try 8261 { 8262 DirectoryServerMBean mBean = (DirectoryServerMBean) o; 8263 directoryServer.mBeanServer.unregisterMBean(mBean.getObjectName()); 8264 } 8265 catch (Exception e) 8266 { 8267 if (debugEnabled()) 8268 { 8269 TRACER.debugCaught(DebugLogLevel.ERROR, e); 8270 } 8271 } 8272 } 8273 } 8274 } 8275 8276 8277 // Finalize all of the SASL mechanism handlers. 8278 for (SASLMechanismHandler handler : 8279 directoryServer.saslMechanismHandlers.values()) 8280 { 8281 try 8282 { 8283 handler.finalizeSASLMechanismHandler(); 8284 } 8285 catch (Exception e) 8286 { 8287 if (debugEnabled()) 8288 { 8289 TRACER.debugCaught(DebugLogLevel.ERROR, e); 8290 } 8291 } 8292 } 8293 8294 8295 // Finalize all of the extended operation handlers. 8296 for (ExtendedOperationHandler handler : 8297 directoryServer.extendedOperationHandlers.values()) 8298 { 8299 try 8300 { 8301 handler.finalizeExtendedOperationHandler(); 8302 } 8303 catch (Exception e) 8304 { 8305 if (debugEnabled()) 8306 { 8307 TRACER.debugCaught(DebugLogLevel.ERROR, e); 8308 } 8309 } 8310 } 8311 8312 8313 // Finalize the password policy map. 8314 for (DN configEntryDN : directoryServer.passwordPolicies.keySet()) 8315 { 8316 DirectoryServer.deregisterPasswordPolicy(configEntryDN); 8317 } 8318 8319 // Finalize the access control handler 8320 AccessControlHandler accessControlHandler = 8321 AccessControlConfigManager.getInstance().getAccessControlHandler(); 8322 if (accessControlHandler != null) 8323 { 8324 accessControlHandler.finalizeAccessControlHandler(); 8325 } 8326 8327 // Perform any necessary cleanup work for the group manager. 8328 if (directoryServer.groupManager != null) 8329 { 8330 directoryServer.groupManager.finalizeGroupManager(); 8331 } 8332 8333 8334 // Shut down all the other components that may need special handling. 8335 // NYI 8336 8337 8338 // Shut down the monitor providers. 8339 for (MonitorProvider monitor : directoryServer.monitorProviders.values()) 8340 { 8341 try 8342 { 8343 monitor.finalizeMonitorProvider(); 8344 } 8345 catch (Exception e) 8346 { 8347 if (debugEnabled()) 8348 { 8349 TRACER.debugCaught(DebugLogLevel.ERROR, e); 8350 } 8351 } 8352 } 8353 8354 8355 // Shut down the backends. 8356 for (Backend backend : directoryServer.backends.values()) 8357 { 8358 try 8359 { 8360 // Deregister all the local backend workflow elements that have been 8361 // registered with the server. 8362 LocalBackendWorkflowElement.removeAll(); 8363 8364 for (BackendInitializationListener listener : 8365 directoryServer.backendInitializationListeners) 8366 { 8367 listener.performBackendFinalizationProcessing(backend); 8368 } 8369 8370 backend.finalizeBackend(); 8371 8372 // Remove the shared lock for this backend. 8373 try 8374 { 8375 String lockFile = LockFileManager.getBackendLockFileName(backend); 8376 StringBuilder failureReason = new StringBuilder(); 8377 if (! LockFileManager.releaseLock(lockFile, failureReason)) 8378 { 8379 message = WARN_SHUTDOWN_CANNOT_RELEASE_SHARED_BACKEND_LOCK. 8380 get(backend.getBackendID(), String.valueOf(failureReason)); 8381 logError(message); 8382 // FIXME -- Do we need to send an admin alert? 8383 } 8384 8385 serverLocked = false; 8386 } 8387 catch (Exception e2) 8388 { 8389 if (debugEnabled()) 8390 { 8391 TRACER.debugCaught(DebugLogLevel.ERROR, e2); 8392 } 8393 8394 message = WARN_SHUTDOWN_CANNOT_RELEASE_SHARED_BACKEND_LOCK. 8395 get(backend.getBackendID(), stackTraceToSingleLineString(e2)); 8396 logError(message); 8397 // FIXME -- Do we need to send an admin alert? 8398 } 8399 } 8400 catch (Exception e) 8401 { 8402 if (debugEnabled()) 8403 { 8404 TRACER.debugCaught(DebugLogLevel.ERROR, e); 8405 } 8406 } 8407 } 8408 8409 // Finalize the entry cache. 8410 EntryCache ec = DirectoryServer.getEntryCache(); 8411 if (ec != null) 8412 { 8413 ec.finalizeEntryCache(); 8414 } 8415 8416 // Release the exclusive lock for the Directory Server process. 8417 String lockFile = LockFileManager.getServerLockFileName(); 8418 try 8419 { 8420 StringBuilder failureReason = new StringBuilder(); 8421 if (! LockFileManager.releaseLock(lockFile, failureReason)) 8422 { 8423 message = WARN_CANNOT_RELEASE_EXCLUSIVE_SERVER_LOCK.get( 8424 lockFile, String.valueOf(failureReason)); 8425 logError(message); 8426 } 8427 } 8428 catch (Exception e) 8429 { 8430 if (debugEnabled()) 8431 { 8432 TRACER.debugCaught(DebugLogLevel.ERROR, e); 8433 } 8434 8435 message = WARN_CANNOT_RELEASE_EXCLUSIVE_SERVER_LOCK.get( 8436 lockFile, stackTraceToSingleLineString(e)); 8437 logError(message); 8438 } 8439 8440 // Deregister all workflows. 8441 WorkflowImpl.deregisterAllOnShutdown(); 8442 8443 // Deregister all network group configuration. 8444 NetworkGroup.deregisterAllOnShutdown(); 8445 8446 // Force a new InternalClientConnection to be created on restart. 8447 InternalConnectionHandler.clearRootClientConnectionAtShutdown(); 8448 8449 // Log a final message indicating that the server is stopped (which should 8450 // be true for all practical purposes), and then shut down all the error 8451 // loggers. 8452 logError(NOTE_SERVER_STOPPED.get()); 8453 8454 removeAllAccessLogPublishers(); 8455 removeAllErrorLogPublishers(); 8456 removeAllDebugLogPublishers(); 8457 8458 // Just in case there's something that isn't shut down properly, wait for 8459 // the monitor to give the OK to stop. 8460 shutdownMonitor.waitForMonitor(); 8461 8462 8463 // At this point, the server is no longer running. We should destroy the 8464 // handle to the previous instance, but we will want to get a new instance 8465 // in case the server is to be started again later in the same JVM. Before 8466 // doing that, destroy the previous instance. 8467 DirectoryEnvironmentConfig envConfig = directoryServer.environmentConfig; 8468 directoryServer.destroy(); 8469 directoryServer = getNewInstance(envConfig); 8470 } 8471 8472 8473 8474 /** 8475 * Destroy key structures in the current Directory Server instance in a manner 8476 * that can help detect any inappropriate cached references to server 8477 * components. 8478 */ 8479 private void destroy() 8480 { 8481 checkSchema = true; 8482 isBootstrapped = false; 8483 isClientBootstrapped = false; 8484 isRunning = false; 8485 lockdownMode = true; 8486 rejectUnauthenticatedRequests = true; 8487 shuttingDown = true; 8488 8489 configClass = null; 8490 configFile = null; 8491 configHandler = null; 8492 coreConfigManager = null; 8493 compressedSchema = null; 8494 cryptoManager = null; 8495 defaultBinarySyntax = null; 8496 defaultBooleanSyntax = null; 8497 defaultDNSyntax = null; 8498 defaultIntegerSyntax = null; 8499 defaultStringSyntax = null; 8500 defaultSyntax = null; 8501 entryCache = null; 8502 environmentConfig = null; 8503 objectClassAttributeType = null; 8504 schemaDN = null; 8505 shutdownHook = null; 8506 workQueue = null; 8507 8508 if (baseDnRegistry != null) 8509 { 8510 baseDnRegistry.clear(); 8511 baseDnRegistry = null; 8512 } 8513 8514 if (backends != null) 8515 { 8516 backends.clear(); 8517 backends = null; 8518 } 8519 8520 if (schema != null) 8521 { 8522 schema.destroy(); 8523 schema = null; 8524 } 8525 } 8526 8527 8528 8529 /** 8530 * Causes the Directory Server to perform an in-core restart. This will 8531 * cause virtually all components of the Directory Server to shut down, and 8532 * once that has completed it will be restarted. 8533 * 8534 * @param className The fully-qualified name of the Java class that 8535 * initiated the shutdown. 8536 * @param reason The human-readable reason that the directory server is 8537 * shutting down. 8538 */ 8539 public static void restart(String className, Message reason) 8540 { 8541 restart(className, reason, directoryServer.environmentConfig); 8542 } 8543 8544 8545 8546 /** 8547 * Causes the Directory Server to perform an in-core restart. This will 8548 * cause virtually all components of the Directory Server to shut down, and 8549 * once that has completed it will be restarted. 8550 * 8551 * @param className The fully-qualified name of the Java class that 8552 * initiated the shutdown. 8553 * @param reason The human-readable reason that the directory server is 8554 * shutting down. 8555 * @param config The environment configuration to use for the server. 8556 */ 8557 public static void restart(String className, Message reason, 8558 DirectoryEnvironmentConfig config) 8559 { 8560 try 8561 { 8562 shutDown(className, reason); 8563 reinitialize(config); 8564 directoryServer.startServer(); 8565 } 8566 catch (Exception e) 8567 { 8568 System.err.println("ERROR: Unable to perform an in-core restart:"); 8569 e.printStackTrace(); 8570 System.err.println("Halting the JVM so that it must be manually " + 8571 "restarted."); 8572 8573 Runtime.getRuntime().halt(1); 8574 } 8575 } 8576 8577 8578 8579 /** 8580 * Reinitializes the server following a shutdown, preparing it for a call to 8581 * {@code startServer}. 8582 * 8583 * @return The new Directory Server instance created during the 8584 * reinitialization process. 8585 * 8586 * @throws InitializationException If a problem occurs while trying to 8587 * initialize the config handler or 8588 * bootstrap that server. 8589 */ 8590 public static DirectoryServer reinitialize() 8591 throws InitializationException 8592 { 8593 return reinitialize(directoryServer.environmentConfig); 8594 } 8595 8596 8597 8598 /** 8599 * Reinitializes the server following a shutdown, preparing it for a call to 8600 * {@code startServer}. 8601 * 8602 * @param config The environment configuration for the Directory Server. 8603 * 8604 * @return The new Directory Server instance created during the 8605 * reinitialization process. 8606 * 8607 * @throws InitializationException If a problem occurs while trying to 8608 * initialize the config handler or 8609 * bootstrap that server. 8610 */ 8611 public static DirectoryServer reinitialize(DirectoryEnvironmentConfig config) 8612 throws InitializationException 8613 { 8614 getNewInstance(config); 8615 LockManager.reinitializeLockTable(); 8616 directoryServer.bootstrapServer(); 8617 directoryServer.initializeConfiguration(); 8618 return directoryServer; 8619 } 8620 8621 8622 8623 /** 8624 * Retrieves the maximum number of concurrent client connections that may be 8625 * established. 8626 * 8627 * @return The maximum number of concurrent client connections that may be 8628 * established, or -1 if there is no limit. 8629 */ 8630 public static long getMaxAllowedConnections() 8631 { 8632 return directoryServer.maxAllowedConnections; 8633 } 8634 8635 8636 8637 /** 8638 * Specifies the maximum number of concurrent client connections that may be 8639 * established. A value that is less than or equal to zero will indicate that 8640 * no limit should be enforced. 8641 * 8642 * @param maxAllowedConnections The maximum number of concurrent client 8643 * connections that may be established. 8644 */ 8645 public static void setMaxAllowedConnections(long maxAllowedConnections) 8646 { 8647 if (maxAllowedConnections > 0) 8648 { 8649 directoryServer.maxAllowedConnections = maxAllowedConnections; 8650 } 8651 else 8652 { 8653 directoryServer.maxAllowedConnections = -1; 8654 } 8655 } 8656 8657 8658 8659 /** 8660 * Indicates that a new connection has been accepted and increments the 8661 * associated counters. 8662 * 8663 * @param clientConnection The client connection that has been established. 8664 * 8665 * @return The connection ID that should be used for this connection, or -1 8666 * if the connection has been rejected for some reason (e.g., the 8667 * maximum numberof concurrent connections have already been 8668 * established). 8669 */ 8670 public static long newConnectionAccepted(ClientConnection clientConnection) 8671 { 8672 synchronized (directoryServer.establishedConnections) 8673 { 8674 if (directoryServer.lockdownMode) 8675 { 8676 InetAddress remoteAddress = clientConnection.getRemoteAddress(); 8677 if ((remoteAddress != null) && (! remoteAddress.isLoopbackAddress())) 8678 { 8679 return -1; 8680 } 8681 } 8682 8683 if ((directoryServer.maxAllowedConnections > 0) && 8684 (directoryServer.currentConnections >= 8685 directoryServer.maxAllowedConnections)) 8686 { 8687 return -1; 8688 } 8689 8690 directoryServer.establishedConnections.add(clientConnection); 8691 directoryServer.currentConnections++; 8692 8693 if (directoryServer.currentConnections > directoryServer.maxConnections) 8694 { 8695 directoryServer.maxConnections = directoryServer.currentConnections; 8696 } 8697 8698 return directoryServer.totalConnections++; 8699 } 8700 } 8701 8702 8703 8704 /** 8705 * Indicates that the specified client connection has been closed. 8706 * 8707 * @param clientConnection The client connection that has been closed. 8708 */ 8709 public static void connectionClosed(ClientConnection clientConnection) 8710 { 8711 synchronized (directoryServer.establishedConnections) 8712 { 8713 directoryServer.establishedConnections.remove(clientConnection); 8714 directoryServer.currentConnections--; 8715 } 8716 } 8717 8718 8719 8720 /** 8721 * Retrieves the number of client connections that are currently established. 8722 * 8723 * @return The number of client connections that are currently established. 8724 */ 8725 public static long getCurrentConnections() 8726 { 8727 return directoryServer.currentConnections; 8728 } 8729 8730 8731 8732 /** 8733 * Retrieves the maximum number of client connections that have been 8734 * established concurrently. 8735 * 8736 * @return The maximum number of client connections that have been 8737 * established concurrently. 8738 */ 8739 public static long getMaxConnections() 8740 { 8741 return directoryServer.maxConnections; 8742 } 8743 8744 8745 8746 /** 8747 * Retrieves the total number of client connections that have been established 8748 * since the Directory Server started. 8749 * 8750 * @return The total number of client connections that have been established 8751 * since the Directory Server started. 8752 */ 8753 public static long getTotalConnections() 8754 { 8755 return directoryServer.totalConnections; 8756 } 8757 8758 8759 8760 /** 8761 * Retrieves the full version string for the Directory Server. 8762 * 8763 * @return The full version string for the Directory Server. 8764 */ 8765 public static String getVersionString() 8766 { 8767 return FULL_VERSION_STRING; 8768 } 8769 8770 /** 8771 * Prints out the version string for the Directory Server. 8772 * 8773 * 8774 * @param outputStream The output stream to which the version information 8775 * should be written. 8776 * 8777 * @throws IOException If a problem occurs while attempting to write the 8778 * version information to the provided output stream. 8779 */ 8780 public static void printVersion(OutputStream outputStream) 8781 throws IOException 8782 { 8783 outputStream.write(getBytes(PRINTABLE_VERSION_STRING)); 8784 return; 8785 } 8786 8787 8788 /** 8789 * Retrieves the default maximum number of entries that should be returned for 8790 * a search. 8791 * 8792 * @return The default maximum number of entries that should be returned for 8793 * a search. 8794 */ 8795 public static int getSizeLimit() 8796 { 8797 return directoryServer.sizeLimit; 8798 } 8799 8800 8801 8802 /** 8803 * Specifies the default maximum number of entries that should be returned for 8804 * a search. 8805 * 8806 * @param sizeLimit The default maximum number of entries that should be 8807 * returned for a search. 8808 */ 8809 public static void setSizeLimit(int sizeLimit) 8810 { 8811 directoryServer.sizeLimit = sizeLimit; 8812 } 8813 8814 8815 8816 /** 8817 * Retrieves the default maximum number of entries that should checked for 8818 * matches during a search. 8819 * 8820 * @return The default maximum number of entries that should checked for 8821 * matches during a search. 8822 */ 8823 public static int getLookthroughLimit() 8824 { 8825 return directoryServer.lookthroughLimit; 8826 } 8827 8828 8829 8830 /** 8831 * Specifies the default maximum number of entries that should be checked for 8832 * matches during a search. 8833 * 8834 * @param lookthroughLimit The default maximum number of entries that should 8835 * be check for matches during a search. 8836 */ 8837 public static void setLookthroughLimit(int lookthroughLimit) 8838 { 8839 directoryServer.lookthroughLimit = lookthroughLimit; 8840 } 8841 8842 8843 8844 /** 8845 * Retrieves the default maximum length of time in seconds that should be 8846 * allowed when processing a search. 8847 * 8848 * @return The default maximum length of time in seconds that should be 8849 * allowed when processing a search. 8850 */ 8851 public static int getTimeLimit() 8852 { 8853 return directoryServer.timeLimit; 8854 } 8855 8856 8857 8858 /** 8859 * Specifies the default maximum length of time in seconds that should be 8860 * allowed when processing a search. 8861 * 8862 * @param timeLimit The default maximum length of time in seconds that 8863 * should be allowed when processing a search. 8864 */ 8865 public static void setTimeLimit(int timeLimit) 8866 { 8867 directoryServer.timeLimit = timeLimit; 8868 } 8869 8870 8871 8872 /** 8873 * Specifies whether to collect nanosecond resolution processing times for 8874 * operations. 8875 * 8876 * @param useNanoTime <code>true</code> if nanosecond resolution times 8877 * should be collected or <code>false</code> to 8878 * only collect in millisecond resolution. 8879 */ 8880 public static void setUseNanoTime(boolean useNanoTime) 8881 { 8882 directoryServer.useNanoTime = useNanoTime; 8883 } 8884 8885 8886 8887 /** 8888 * Retrieves whether operation processing times should be collected with 8889 * nanosecond resolution. 8890 * 8891 * @return <code>true</code> if nanosecond resolution times are collected 8892 * or <code>false</code> if only millisecond resolution times are 8893 * being collected. 8894 */ 8895 public static boolean getUseNanoTime() 8896 { 8897 return directoryServer.useNanoTime; 8898 } 8899 8900 8901 8902 /** 8903 * Retrieves the writability mode for the Directory Server. This will only 8904 * be applicable for user suffixes. 8905 * 8906 * @return The writability mode for the Directory Server. 8907 */ 8908 public static WritabilityMode getWritabilityMode() 8909 { 8910 return directoryServer.writabilityMode; 8911 } 8912 8913 8914 8915 /** 8916 * Specifies the writability mode for the Directory Server. This will only 8917 * be applicable for user suffixes. 8918 * 8919 * @param writabilityMode Specifies the writability mode for the Directory 8920 * Server. 8921 */ 8922 public static void setWritabilityMode(WritabilityMode writabilityMode) 8923 { 8924 directoryServer.writabilityMode = writabilityMode; 8925 } 8926 8927 8928 8929 8930 /** 8931 * Indicates whether simple bind requests that contain a bind DN will also be 8932 * required to have a password. 8933 * 8934 * @return <CODE>true</CODE> if simple bind requests containing a bind DN 8935 * will be required to have a password, or <CODE>false</CODE> if not 8936 * (and therefore will be treated as anonymous binds). 8937 */ 8938 public static boolean bindWithDNRequiresPassword() 8939 { 8940 return directoryServer.bindWithDNRequiresPassword; 8941 } 8942 8943 8944 8945 /** 8946 * Specifies whether simple bind requests that contain a bind DN will also be 8947 * required to have a password. 8948 * 8949 * @param bindWithDNRequiresPassword Indicates whether simple bind requests 8950 * that contain a bind DN will also be 8951 * required to have a password. 8952 */ 8953 public static void setBindWithDNRequiresPassword(boolean 8954 bindWithDNRequiresPassword) 8955 { 8956 directoryServer.bindWithDNRequiresPassword = bindWithDNRequiresPassword; 8957 } 8958 8959 8960 8961 /** 8962 * Indicates whether an unauthenticated request should be rejected. 8963 * 8964 * @return <CODE>true</CODE>if an unauthenticated request should be 8965 * rejected, or <CODE>false</CODE>f if not. 8966 */ 8967 public static boolean rejectUnauthenticatedRequests() 8968 { 8969 return directoryServer.rejectUnauthenticatedRequests; 8970 } 8971 8972 /** 8973 * Specifies whether an unauthenticated request should be rejected. 8974 * 8975 * @param rejectUnauthenticatedRequests Indicates whether an 8976 * unauthenticated request should 8977 * be rejected. 8978 */ 8979 public static void setRejectUnauthenticatedRequests(boolean 8980 rejectUnauthenticatedRequests) 8981 { 8982 directoryServer.rejectUnauthenticatedRequests = 8983 rejectUnauthenticatedRequests; 8984 } 8985 8986 8987 8988 /** 8989 * Indicates whether the Directory Server is currently configured to operate 8990 * in the lockdown mode, in which all non-root requests will be rejected and 8991 * all connection attempts from non-loopback clients will be rejected. 8992 * 8993 * @return {@code true} if the Directory Server is currently configured to 8994 * operate in the lockdown mode, or {@code false} if not. 8995 */ 8996 public static boolean lockdownMode() 8997 { 8998 return directoryServer.lockdownMode; 8999 } 9000 9001 9002 9003 /** 9004 * Specifies whether the server should operate in lockdown mode. 9005 * 9006 * @param lockdownMode Indicates whether the Directory Server should operate 9007 * in lockdown mode. 9008 */ 9009 public static void setLockdownMode(boolean lockdownMode) 9010 { 9011 directoryServer.lockdownMode = lockdownMode; 9012 9013 if (lockdownMode) 9014 { 9015 Message message = WARN_DIRECTORY_SERVER_ENTERING_LOCKDOWN_MODE.get(); 9016 logError(message); 9017 9018 sendAlertNotification(directoryServer, ALERT_TYPE_ENTERING_LOCKDOWN_MODE, 9019 message); 9020 } 9021 else 9022 { 9023 Message message = NOTE_DIRECTORY_SERVER_LEAVING_LOCKDOWN_MODE.get(); 9024 logError(message); 9025 9026 sendAlertNotification(directoryServer, ALERT_TYPE_LEAVING_LOCKDOWN_MODE, 9027 message); 9028 } 9029 } 9030 9031 9032 9033 /** 9034 * Retrieves the DN of the configuration entry with which this alert generator 9035 * is associated. 9036 * 9037 * @return The DN of the configuration entry with which this alert generator 9038 * is associated. 9039 */ 9040 public DN getComponentEntryDN() 9041 { 9042 try 9043 { 9044 if (configHandler == null) 9045 { 9046 // The config handler hasn't been initialized yet. Just return the DN 9047 // of the root DSE. 9048 return DN.nullDN(); 9049 } 9050 9051 return configHandler.getConfigRootEntry().getDN(); 9052 } 9053 catch (Exception e) 9054 { 9055 if (debugEnabled()) 9056 { 9057 TRACER.debugCaught(DebugLogLevel.ERROR, e); 9058 } 9059 9060 // This could theoretically happen if an alert needs to be sent before the 9061 // configuration is initialized. In that case, just return an empty DN. 9062 return DN.nullDN(); 9063 } 9064 } 9065 9066 9067 9068 /** 9069 * Retrieves the fully-qualified name of the Java class for this alert 9070 * generator implementation. 9071 * 9072 * @return The fully-qualified name of the Java class for this alert 9073 * generator implementation. 9074 */ 9075 public String getClassName() 9076 { 9077 return CLASS_NAME; 9078 } 9079 9080 9081 9082 /** 9083 * Retrieves information about the set of alerts that this generator may 9084 * produce. The map returned should be between the notification type for a 9085 * particular notification and the human-readable description for that 9086 * notification. This alert generator must not generate any alerts with types 9087 * that are not contained in this list. 9088 * 9089 * @return Information about the set of alerts that this generator may 9090 * produce. 9091 */ 9092 public LinkedHashMap<String,String> getAlerts() 9093 { 9094 LinkedHashMap<String,String> alerts = new LinkedHashMap<String,String>(); 9095 9096 alerts.put(ALERT_TYPE_SERVER_STARTED, ALERT_DESCRIPTION_SERVER_STARTED); 9097 alerts.put(ALERT_TYPE_SERVER_SHUTDOWN, ALERT_DESCRIPTION_SERVER_SHUTDOWN); 9098 alerts.put(ALERT_TYPE_UNCAUGHT_EXCEPTION, 9099 ALERT_DESCRIPTION_UNCAUGHT_EXCEPTION); 9100 alerts.put(ALERT_TYPE_ENTERING_LOCKDOWN_MODE, 9101 ALERT_DESCRIPTION_ENTERING_LOCKDOWN_MODE); 9102 alerts.put(ALERT_TYPE_LEAVING_LOCKDOWN_MODE, 9103 ALERT_DESCRIPTION_LEAVING_LOCKDOWN_MODE); 9104 9105 return alerts; 9106 } 9107 9108 9109 9110 /** 9111 * Provides a means of handling a case in which a thread is about to die 9112 * because of an unhandled exception. This method does nothing to try to 9113 * prevent the death of that thread, but will at least log it so that it can 9114 * be available for debugging purposes. 9115 * 9116 * @param thread The thread that threw the exception. 9117 * @param exception The exception that was thrown but not properly handled. 9118 */ 9119 public void uncaughtException(Thread thread, Throwable exception) 9120 { 9121 if (debugEnabled()) 9122 { 9123 TRACER.debugCaught(DebugLogLevel.ERROR, exception); 9124 } 9125 9126 Message message = ERR_UNCAUGHT_THREAD_EXCEPTION.get( 9127 thread.getName(), stackTraceToString(exception)); 9128 logError(message); 9129 sendAlertNotification(this, ALERT_TYPE_UNCAUGHT_EXCEPTION, message); 9130 } 9131 9132 9133 9134 /** 9135 * Indicates whether the server is currently in the process of shutting down. 9136 * @return <CODE>true</CODE> if this server is currently in the process of 9137 * shutting down and <CODE>false</CODE> otherwise. 9138 */ 9139 public boolean isShuttingDown() 9140 { 9141 return shuttingDown; 9142 } 9143 9144 9145 9146 /** 9147 * Parses the provided command-line arguments and uses that information to 9148 * bootstrap and start the Directory Server. 9149 * 9150 * @param args The command-line arguments provided to this program. 9151 */ 9152 public static void main(String[] args) 9153 { 9154 // Define the arguments that may be provided to the server. 9155 BooleanArgument checkStartability = null; 9156 BooleanArgument quietMode = null; 9157 BooleanArgument windowsNetStart = null; 9158 BooleanArgument displayUsage = null; 9159 BooleanArgument fullVersion = null; 9160 BooleanArgument noDetach = null; 9161 BooleanArgument systemInfo = null; 9162 BooleanArgument useLastKnownGoodConfig = null; 9163 StringArgument configClass = null; 9164 StringArgument configFile = null; 9165 9166 9167 // Create the command-line argument parser for use with this program. 9168 Message toolDescription = INFO_DSCORE_TOOL_DESCRIPTION.get(); 9169 ArgumentParser argParser = 9170 new ArgumentParser("org.opends.server.core.DirectoryServer", 9171 toolDescription, false); 9172 9173 9174 // Initialize all the command-line argument types and register them with the 9175 // parser. 9176 try 9177 { 9178 configClass = new StringArgument("configclass", 'C', "configClass", 9179 true, false, true, 9180 INFO_CONFIGCLASS_PLACEHOLDER.get(), 9181 ConfigFileHandler.class.getName(), null, 9182 INFO_DSCORE_DESCRIPTION_CONFIG_CLASS 9183 .get()); 9184 configClass.setHidden(true); 9185 argParser.addArgument(configClass); 9186 9187 9188 configFile = new StringArgument("configfile", 'f', "configFile", 9189 true, false, true, 9190 INFO_CONFIGFILE_PLACEHOLDER.get(), null, 9191 null, 9192 INFO_DSCORE_DESCRIPTION_CONFIG_FILE 9193 .get()); 9194 configFile.setHidden(true); 9195 argParser.addArgument(configFile); 9196 9197 9198 checkStartability = new BooleanArgument("checkstartability", null, 9199 "checkStartability", 9200 INFO_DSCORE_DESCRIPTION_CHECK_STARTABILITY.get()); 9201 checkStartability.setHidden(true); 9202 argParser.addArgument(checkStartability); 9203 9204 windowsNetStart = new BooleanArgument("windowsnetstart", null, 9205 "windowsNetStart", 9206 INFO_DSCORE_DESCRIPTION_WINDOWS_NET_START.get()); 9207 windowsNetStart.setHidden(true); 9208 argParser.addArgument(windowsNetStart); 9209 9210 9211 fullVersion = new BooleanArgument("fullversion", 'F', "fullVersion", 9212 INFO_DSCORE_DESCRIPTION_FULLVERSION 9213 .get()); 9214 fullVersion.setHidden(true); 9215 argParser.addArgument(fullVersion); 9216 9217 9218 systemInfo = new BooleanArgument("systeminfo", 's', "systemInfo", 9219 INFO_DSCORE_DESCRIPTION_SYSINFO.get()); 9220 argParser.addArgument(systemInfo); 9221 9222 9223 useLastKnownGoodConfig = 9224 new BooleanArgument("lastknowngoodconfig", 'L', 9225 "useLastKnownGoodConfig", 9226 INFO_DSCORE_DESCRIPTION_LASTKNOWNGOODCFG.get()); 9227 argParser.addArgument(useLastKnownGoodConfig); 9228 9229 9230 noDetach = new BooleanArgument("nodetach", 'N', "nodetach", 9231 INFO_DSCORE_DESCRIPTION_NODETACH.get()); 9232 argParser.addArgument(noDetach); 9233 9234 9235 quietMode = new BooleanArgument("quiet", 'Q', "quiet", 9236 INFO_DESCRIPTION_QUIET.get()); 9237 argParser.addArgument(quietMode); 9238 9239 9240 displayUsage = new BooleanArgument("help", 'H', "help", 9241 INFO_DSCORE_DESCRIPTION_USAGE.get()); 9242 argParser.addArgument(displayUsage); 9243 argParser.setUsageArgument(displayUsage); 9244 } 9245 catch (ArgumentException ae) 9246 { 9247 Message message = ERR_DSCORE_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()); 9248 System.err.println(message); 9249 System.exit(1); 9250 } 9251 9252 9253 // Parse the command-line arguments provided to this program. 9254 try 9255 { 9256 argParser.parseArguments(args); 9257 } 9258 catch (ArgumentException ae) 9259 { 9260 Message message = ERR_DSCORE_ERROR_PARSING_ARGS.get(ae.getMessage()); 9261 System.err.println(message); 9262 System.err.println(argParser.getUsage()); 9263 System.exit(1); 9264 } 9265 9266 9267 // If we should just display usage information, then print it and exit. 9268 if (checkStartability.isPresent()) 9269 { 9270 // This option should only be used if a PID file already exists in the 9271 // server logs directory, and we need to check which of the following 9272 // conditions best describes the current usage: 9273 // - We're trying to start the server, but it's already running. The 9274 // attempt to start the server should fail, and the server process will 9275 // exit with a result code of 98. 9276 // - We're trying to start the server and it's not already running. We 9277 // won't start it in this invocation, but the script used to get to this 9278 // point should go ahead and overwrite the PID file and retry the 9279 // startup process. The server process will exit with a result code of 9280 // 99. 9281 // - We're not trying to start the server, but instead are trying to do 9282 // something else like display the version number. In that case, we 9283 // don't need to write the PID file at all and can just execute the 9284 // intended command. If that command was successful, then we'll have an 9285 // exit code of NOTHING_TO_DO (0). Otherwise, it will have an exit code 9286 // that is something other than NOTHING_TO_DO, SERVER_ALREADY_STARTED, 9287 // START_AS_DETACH, START_AS_NON_DETACH, START_AS_WINDOWS_SERVICE to 9288 // indicate that a problem occurred. 9289 if (argParser.usageOrVersionDisplayed()) 9290 { 9291 // We're just trying to display usage, and that's already been done so 9292 // exit with a code of zero. 9293 System.exit(NOTHING_TO_DO); 9294 } 9295 else if (fullVersion.isPresent() || systemInfo.isPresent()) 9296 { 9297 // We're not really trying to start, so rebuild the argument list 9298 // without the "--checkStartability" argument and try again. Exit with 9299 // whatever that exits with. 9300 LinkedList<String> newArgList = new LinkedList<String>(); 9301 for (String arg : args) 9302 { 9303 if (! arg.equalsIgnoreCase("--checkstartability")) 9304 { 9305 newArgList.add(arg); 9306 } 9307 } 9308 String[] newArgs = new String[newArgList.size()]; 9309 newArgList.toArray(newArgs); 9310 main(newArgs); 9311 System.exit(NOTHING_TO_DO); 9312 } 9313 else 9314 { 9315 System.exit(checkStartability(argParser)); 9316 } 9317 } 9318 else if (argParser.usageOrVersionDisplayed()) 9319 { 9320 System.exit(0); 9321 } 9322 else if (fullVersion.isPresent()) 9323 { 9324 printFullVersionInformation(); 9325 return; 9326 } 9327 else if (systemInfo.isPresent()) 9328 { 9329 RuntimeInformation.printInfo(); 9330 return; 9331 } 9332 9333 9334 // At this point, we know that we're going to try to start the server. 9335 // Attempt to grab an exclusive lock for the Directory Server process. 9336 String lockFile = LockFileManager.getServerLockFileName(); 9337 try 9338 { 9339 StringBuilder failureReason = new StringBuilder(); 9340 if (! LockFileManager.acquireExclusiveLock(lockFile, failureReason)) 9341 { 9342 Message message = ERR_CANNOT_ACQUIRE_EXCLUSIVE_SERVER_LOCK.get(lockFile, 9343 String.valueOf(failureReason)); 9344 System.err.println(message); 9345 System.exit(1); 9346 } 9347 } 9348 catch (Exception e) 9349 { 9350 if (debugEnabled()) 9351 { 9352 TRACER.debugCaught(DebugLogLevel.ERROR, e); 9353 } 9354 9355 Message message = ERR_CANNOT_ACQUIRE_EXCLUSIVE_SERVER_LOCK.get(lockFile, 9356 stackTraceToSingleLineString(e)); 9357 System.err.println(message); 9358 System.exit(1); 9359 } 9360 serverLocked = true; 9361 9362 9363 // Configure the JVM to delete the PID file on exit, if it exists. 9364 boolean pidFileMarkedForDeletion = false; 9365 boolean startingFileMarkedForDeletion = false; 9366 try 9367 { 9368 String pidFilePath; 9369 String startingFilePath; 9370 String serverRoot = System.getenv(ENV_VAR_INSTANCE_ROOT); 9371 if (serverRoot == null) 9372 { 9373 pidFilePath = "logs/server.pid"; 9374 startingFilePath = "logs/server.starting"; 9375 } 9376 else 9377 { 9378 pidFilePath = serverRoot + File.separator + "logs" + 9379 File.separator + "server.pid"; 9380 startingFilePath = serverRoot + File.separator + "logs" + 9381 File.separator + "server.starting"; 9382 } 9383 9384 File pidFile = new File(pidFilePath); 9385 if (pidFile.exists()) 9386 { 9387 pidFile.deleteOnExit(); 9388 pidFileMarkedForDeletion = true; 9389 } 9390 9391 File startingFile = new File(startingFilePath); 9392 if (startingFile.exists()) 9393 { 9394 startingFile.deleteOnExit(); 9395 startingFileMarkedForDeletion = true; 9396 } 9397 } catch (Exception e) {} 9398 9399 9400 // Redirect standard output and standard error to the server.out file. If 9401 // the server hasn't detached from the terminal, then also continue writing 9402 // to the original standard output and standard error. Also, configure the 9403 // JVM to delete the PID and server.starting files on exit, if they exist. 9404 PrintStream serverOutStream; 9405 try 9406 { 9407 // We need to figure out where to put the file. See if the server root 9408 // is available as an environment variable and if so then use it. 9409 // Otherwise, try to figure it out from the location of the config file. 9410 String serverRoot = System.getenv(ENV_VAR_INSTANCE_ROOT); 9411 if (serverRoot == null) 9412 { 9413 serverRoot = new File(configFile.getValue()).getParentFile(). 9414 getParentFile().getAbsolutePath(); 9415 } 9416 9417 if (serverRoot == null) 9418 { 9419 System.err.println("WARNING: Unable to determine server root in " + 9420 "order to redirect standard output and standard " + 9421 "error."); 9422 } 9423 else 9424 { 9425 File logDir = new File(serverRoot + File.separator + "logs"); 9426 if (logDir.exists()) 9427 { 9428 FileOutputStream fos = 9429 new FileOutputStream(new File(logDir, "server.out"), true); 9430 serverOutStream = new PrintStream(fos); 9431 9432 if (noDetach.isPresent()) 9433 { 9434 if (! quietMode.isPresent()) 9435 { 9436 MultiOutputStream multiStream = 9437 new MultiOutputStream(System.out, serverOutStream); 9438 serverOutStream = new PrintStream(multiStream); 9439 } 9440 } 9441 9442 System.setOut(serverOutStream); 9443 System.setErr(serverOutStream); 9444 9445 if (! pidFileMarkedForDeletion) 9446 { 9447 File f = new File(logDir, "server.pid"); 9448 if (f.exists()) 9449 { 9450 f.deleteOnExit(); 9451 } 9452 } 9453 9454 if (! startingFileMarkedForDeletion) 9455 { 9456 File f = new File(logDir, "server.starting"); 9457 if (f.exists()) 9458 { 9459 f.deleteOnExit(); 9460 } 9461 } 9462 } 9463 else 9464 { 9465 System.err.println("WARNING: Unable to redirect standard output " + 9466 "and standard error because the logs directory " + 9467 logDir.getAbsolutePath() + " does not exist."); 9468 } 9469 } 9470 } 9471 catch (Exception e) 9472 { 9473 System.err.println("WARNING: Unable to redirect standard output and " + 9474 "standard error: " + stackTraceToSingleLineString(e)); 9475 } 9476 9477 9478 // Install the default loggers so the startup messages 9479 // will be printed. 9480 TextErrorLogPublisher startupErrorLogPublisher = null; 9481 TextDebugLogPublisher startupDebugLogPublisher = null; 9482 9483 startupErrorLogPublisher = 9484 TextErrorLogPublisher.getStartupTextErrorPublisher( 9485 new TextWriter.STDOUT()); 9486 ErrorLogger.addErrorLogPublisher(startupErrorLogPublisher); 9487 9488 startupDebugLogPublisher = 9489 TextDebugLogPublisher.getStartupTextDebugPublisher( 9490 new TextWriter.STDOUT()); 9491 DebugLogger.addDebugLogPublisher(startupDebugLogPublisher); 9492 9493 9494 // Create an environment configuration for the server and populate a number 9495 // of appropriate properties. 9496 DirectoryEnvironmentConfig environmentConfig = 9497 new DirectoryEnvironmentConfig(); 9498 try 9499 { 9500 environmentConfig.setProperty(PROPERTY_CONFIG_CLASS, 9501 configClass.getValue()); 9502 environmentConfig.setProperty(PROPERTY_CONFIG_FILE, 9503 configFile.getValue()); 9504 environmentConfig.setProperty(PROPERTY_USE_LAST_KNOWN_GOOD_CONFIG, 9505 String.valueOf(useLastKnownGoodConfig.isPresent())); 9506 } 9507 catch (Exception e) 9508 { 9509 // This shouldn't happen. For the methods we are using, the exception is 9510 // just a guard against making changes with the server running. 9511 } 9512 9513 9514 // Bootstrap and start the Directory Server. 9515 DirectoryServer directoryServer = DirectoryServer.getInstance(); 9516 try 9517 { 9518 directoryServer.setEnvironmentConfig(environmentConfig); 9519 directoryServer.bootstrapServer(); 9520 directoryServer.initializeConfiguration(configClass.getValue(), 9521 configFile.getValue()); 9522 } 9523 catch (InitializationException ie) 9524 { 9525 if (debugEnabled()) 9526 { 9527 TRACER.debugCaught(DebugLogLevel.ERROR, ie); 9528 } 9529 9530 Message message = ERR_DSCORE_CANNOT_BOOTSTRAP.get(ie.getMessage()); 9531 System.err.println(message); 9532 System.exit(1); 9533 } 9534 catch (Exception e) 9535 { 9536 Message message = ERR_DSCORE_CANNOT_BOOTSTRAP.get( 9537 stackTraceToSingleLineString(e)); 9538 System.err.println(message); 9539 System.exit(1); 9540 } 9541 9542 try 9543 { 9544 directoryServer.startServer(); 9545 } 9546 catch (InitializationException ie) 9547 { 9548 if (debugEnabled()) 9549 { 9550 TRACER.debugCaught(DebugLogLevel.ERROR, ie); 9551 } 9552 9553 Message message = ERR_DSCORE_CANNOT_START.get(ie.getMessage()); 9554 shutDown(directoryServer.getClass().getName(), message); 9555 } 9556 catch (Exception e) 9557 { 9558 Message message = ERR_DSCORE_CANNOT_START.get( 9559 stackTraceToSingleLineString(e)); 9560 shutDown(directoryServer.getClass().getName(), message); 9561 } 9562 9563 ErrorLogger.removeErrorLogPublisher(startupErrorLogPublisher); 9564 DebugLogger.removeDebugLogPublisher(startupDebugLogPublisher); 9565 } 9566 9567 /** 9568 * Construct the DN of a monitor provider entry. 9569 * @param provider The monitor provider for which a DN is desired. 9570 * @return The DN of the monitor provider entry. 9571 */ 9572 public static DN getMonitorProviderDN(MonitorProvider provider) 9573 { 9574 String monitorName = provider.getMonitorInstanceName(); 9575 AttributeType cnType = getAttributeType(ATTR_COMMON_NAME); 9576 DN monitorRootDN; 9577 try 9578 { 9579 monitorRootDN = DN.decode(DN_MONITOR_ROOT); 9580 } 9581 catch (DirectoryException e) 9582 { 9583 // Cannot reach this point. 9584 throw new RuntimeException(); 9585 } 9586 9587 RDN rdn = RDN.create(cnType, new AttributeValue(cnType, monitorName)); 9588 return monitorRootDN.concat(rdn); 9589 } 9590 9591 9592 9593 /** 9594 * Gets the class loader to be used with this directory server 9595 * application. 9596 * <p> 9597 * The class loader will automatically load classes from plugins 9598 * where required. 9599 * 9600 * @return Returns the class loader to be used with this directory 9601 * server application. 9602 */ 9603 public static ClassLoader getClassLoader() 9604 { 9605 return ClassLoaderProvider.getInstance().getClassLoader(); 9606 } 9607 9608 9609 9610 /** 9611 * Loads the named class using this directory server application's 9612 * class loader. 9613 * <p> 9614 * This method provided as a convenience and is equivalent to 9615 * calling: 9616 * 9617 * <pre> 9618 * Class.forName(name, true, DirectoryServer.getClassLoader()); 9619 * </pre> 9620 * 9621 * @param name 9622 * The fully qualified name of the desired class. 9623 * @return Returns the class object representing the desired class. 9624 * @throws LinkageError 9625 * If the linkage fails. 9626 * @throws ExceptionInInitializerError 9627 * If the initialization provoked by this method fails. 9628 * @throws ClassNotFoundException 9629 * If the class cannot be located by the specified class 9630 * loader. 9631 * @see Class#forName(String, boolean, ClassLoader) 9632 */ 9633 public static Class<?> loadClass(String name) throws LinkageError, 9634 ExceptionInInitializerError, ClassNotFoundException 9635 { 9636 return Class.forName(name, true, DirectoryServer.getClassLoader()); 9637 } 9638 9639 9640 9641 /** 9642 * Returns the error code that we return when we are checking the startability 9643 * of the server. 9644 * If there are conflicting arguments (like asking to run the server in non 9645 * detach mode when the server is configured to run as a window service) it 9646 * returns CHECK_ERROR (1). 9647 * @param argParser the ArgumentParser with the arguments already parsed. 9648 * @return the error code that we return when we are checking the startability 9649 * of the server. 9650 */ 9651 private static int checkStartability(ArgumentParser argParser) 9652 { 9653 int returnValue; 9654 boolean isServerRunning; 9655 9656 BooleanArgument noDetach = 9657 (BooleanArgument)argParser.getArgumentForLongID("nodetach"); 9658 BooleanArgument quietMode = 9659 (BooleanArgument)argParser.getArgumentForLongID("quiet"); 9660 BooleanArgument windowsNetStart = 9661 (BooleanArgument)argParser.getArgumentForLongID("windowsnetstart"); 9662 9663 boolean noDetachPresent = noDetach.isPresent(); 9664 boolean windowsNetStartPresent = windowsNetStart.isPresent(); 9665 9666 // We're trying to start the server, so see if it's already running by 9667 // trying to grab an exclusive lock on the server lock file. If it 9668 // succeeds, then the server isn't running and we can try to start. 9669 // Otherwise, the server is running and this attempt should fail. 9670 String lockFile = LockFileManager.getServerLockFileName(); 9671 try 9672 { 9673 StringBuilder failureReason = new StringBuilder(); 9674 if (LockFileManager.acquireExclusiveLock(lockFile, failureReason)) 9675 { 9676 // The server isn't running, so it can be started. 9677 LockFileManager.releaseLock(lockFile, failureReason); 9678 isServerRunning = false; 9679 } 9680 else 9681 { 9682 // The server's already running. 9683 Message message = ERR_CANNOT_ACQUIRE_EXCLUSIVE_SERVER_LOCK.get(lockFile, 9684 String.valueOf(failureReason)); 9685 System.err.println(message); 9686 isServerRunning = true; 9687 } 9688 } 9689 catch (Exception e) 9690 { 9691 // We'll treat this as if the server is running because we won't 9692 // be able to start it anyway. 9693 Message message = ERR_CANNOT_ACQUIRE_EXCLUSIVE_SERVER_LOCK.get(lockFile, 9694 getExceptionMessage(e)); 9695 System.err.println(message); 9696 isServerRunning = true; 9697 } 9698 9699 boolean configuredAsService = isRunningAsWindowsService(); 9700 9701 if (isServerRunning) 9702 { 9703 if (configuredAsService && !windowsNetStartPresent) 9704 { 9705 returnValue = START_AS_WINDOWS_SERVICE; 9706 } 9707 else 9708 { 9709 returnValue = SERVER_ALREADY_STARTED; 9710 } 9711 } 9712 else 9713 { 9714 if (configuredAsService) 9715 { 9716 if (noDetachPresent) 9717 { 9718 // Conflicting arguments 9719 returnValue = CHECK_ERROR; 9720 Message message = ERR_DSCORE_ERROR_NODETACH_AND_WINDOW_SERVICE.get(); 9721 System.err.println(message); 9722 9723 } 9724 else 9725 { 9726 if (windowsNetStartPresent) 9727 { 9728 // start-ds.bat is being called through net start, so return 9729 // START_AS_DETACH_CALLED_FROM_WINDOWS_SERVICE so that the batch 9730 // file actually starts the server. 9731 returnValue = START_AS_DETACH_CALLED_FROM_WINDOWS_SERVICE; 9732 } 9733 else 9734 { 9735 returnValue = START_AS_WINDOWS_SERVICE; 9736 } 9737 } 9738 } 9739 else 9740 { 9741 if (noDetachPresent) 9742 { 9743 returnValue = START_AS_NON_DETACH; 9744 } 9745 else if (quietMode.isPresent()) 9746 { 9747 returnValue = START_AS_DETACH_QUIET; 9748 } 9749 else 9750 { 9751 returnValue = START_AS_DETACH; 9752 } 9753 } 9754 } 9755 return returnValue; 9756 } 9757 9758 /** 9759 * Returns true if this server is configured to run as a windows service. 9760 * @return <CODE>true</CODE> if this server is configured to run as a windows 9761 * service and <CODE>false</CODE> otherwise. 9762 */ 9763 public static boolean isRunningAsWindowsService() 9764 { 9765 boolean isRunningAsWindowsService; 9766 if (SetupUtils.isWindows()) 9767 { 9768 isRunningAsWindowsService = ConfigureWindowsService.serviceState(null, 9769 null) == ConfigureWindowsService.SERVICE_STATE_ENABLED; 9770 } 9771 else 9772 { 9773 isRunningAsWindowsService = false; 9774 } 9775 return isRunningAsWindowsService; 9776 } 9777 9778 9779 /** 9780 * Specifies whether the workflows are configured automatically or manually. 9781 * In auto configuration mode one workflow is created for each and every 9782 * base DN in the local backends. In the auto configuration mode the 9783 * workflows are created according to their description in the configuration 9784 * file. 9785 * 9786 * @param workflowConfigurationMode Indicates whether the workflows are 9787 * configured automatically or manually 9788 */ 9789 public static void setWorkflowConfigurationMode( 9790 WorkflowConfigurationMode workflowConfigurationMode) 9791 { 9792 directoryServer.workflowConfigurationMode = workflowConfigurationMode; 9793 } 9794 9795 9796 /** 9797 * Indicates whether the workflow configuration mode is 'auto' or not. 9798 * 9799 * @return the workflow configuration mode 9800 */ 9801 public static boolean workflowConfigurationModeIsAuto() 9802 { 9803 boolean isAuto = 9804 (directoryServer.workflowConfigurationMode 9805 == WorkflowConfigurationMode.AUTO); 9806 return isAuto; 9807 } 9808 9809 9810 9811 /** 9812 * Retrieves the workflow configuration mode. 9813 * 9814 * @return the workflow configuration mode 9815 */ 9816 public static WorkflowConfigurationMode getWorkflowConfigurationMode() 9817 { 9818 return directoryServer.workflowConfigurationMode; 9819 } 9820 9821 9822 9823 /** 9824 * Print messages for start-ds "-F" option (full version information). 9825 */ 9826 9827 private static 9828 void printFullVersionInformation() { 9829 /** 9830 * This option is used by the upgrade to identify the server build and it 9831 * can eventually also be used to be sent to the support in case of an 9832 * issue. Since this is not a public interface and since it is better 9833 * to always have it in English for the support team, the message is 9834 * not localized. 9835 */ 9836 String separator = ": "; 9837 System.out.println(getVersionString()); 9838 System.out.println(SetupUtils.BUILD_ID+separator+BUILD_ID); 9839 System.out.println(SetupUtils.MAJOR_VERSION+separator+MAJOR_VERSION); 9840 System.out.println(SetupUtils.MINOR_VERSION+separator+MINOR_VERSION); 9841 System.out.println(SetupUtils.POINT_VERSION+separator+POINT_VERSION); 9842 System.out.println(SetupUtils.VERSION_QUALIFIER+separator+ 9843 VERSION_QUALIFIER); 9844 if (BUILD_NUMBER > 0) 9845 { 9846 System.out.println(SetupUtils.BUILD_NUMBER+separator+ 9847 new DecimalFormat("000").format(BUILD_NUMBER)); 9848 } 9849 System.out.println(SetupUtils.REVISION_NUMBER+separator+REVISION_NUMBER); 9850 System.out.println(SetupUtils.FIX_IDS+separator+FIX_IDS); 9851 System.out.println(SetupUtils.DEBUG_BUILD+separator+DEBUG_BUILD); 9852 System.out.println(SetupUtils.BUILD_OS+separator+BUILD_OS); 9853 System.out.println(SetupUtils.BUILD_USER+separator+BUILD_USER); 9854 System.out.println(SetupUtils.BUILD_JAVA_VERSION+separator+ 9855 BUILD_JAVA_VERSION); 9856 System.out.println(SetupUtils.BUILD_JAVA_VENDOR+separator+ 9857 BUILD_JAVA_VENDOR); 9858 System.out.println(SetupUtils.BUILD_JVM_VERSION+separator+ 9859 BUILD_JVM_VERSION); 9860 System.out.println(SetupUtils.BUILD_JVM_VENDOR+separator+BUILD_JVM_VENDOR); 9861 System.out.println(SetupUtils.INCOMPATIBILITY_EVENTS+separator+ 9862 StaticUtils.listToString( 9863 VersionCompatibilityIssue.getAllEvents(), ",")); 9864 } 9865 9866 } 9867