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 legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2006-2010 Sun Microsystems, Inc. 025 * Portions Copyright 2010-2017 ForgeRock AS. 026 */ 027package org.opends.server.core; 028 029import static org.forgerock.util.Reject.*; 030import static org.opends.messages.CoreMessages.*; 031import static org.opends.messages.ToolMessages.*; 032import static org.opends.server.config.ConfigConstants.*; 033import static org.opends.server.schema.SchemaConstants.*; 034import static org.opends.server.tools.ConfigureWindowsService.*; 035import static org.opends.server.util.CollectionUtils.*; 036import static org.opends.server.util.DynamicConstants.*; 037import static org.opends.server.util.ServerConstants.*; 038import static org.opends.server.util.StaticUtils.*; 039 040import java.io.File; 041import java.io.FileOutputStream; 042import java.io.IOException; 043import java.io.OutputStream; 044import java.io.PrintStream; 045import java.lang.management.ManagementFactory; 046import java.net.InetAddress; 047import java.text.DecimalFormat; 048import java.util.Collection; 049import java.util.Collections; 050import java.util.LinkedHashMap; 051import java.util.LinkedHashSet; 052import java.util.LinkedList; 053import java.util.List; 054import java.util.Map; 055import java.util.Properties; 056import java.util.Set; 057import java.util.TreeMap; 058import java.util.TreeSet; 059import java.util.concurrent.ConcurrentHashMap; 060import java.util.concurrent.ConcurrentMap; 061import java.util.concurrent.CopyOnWriteArrayList; 062import java.util.concurrent.CopyOnWriteArraySet; 063import java.util.concurrent.atomic.AtomicInteger; 064 065import javax.management.MBeanServer; 066import javax.management.MBeanServerFactory; 067 068import org.forgerock.i18n.LocalizableMessage; 069import org.forgerock.i18n.slf4j.LocalizedLogger; 070import org.forgerock.opendj.config.server.ConfigException; 071import org.forgerock.opendj.ldap.ResultCode; 072import org.forgerock.opendj.ldap.schema.AttributeUsage; 073import org.forgerock.opendj.ldap.schema.CoreSchema; 074import org.forgerock.opendj.ldap.schema.MatchingRule; 075import org.forgerock.opendj.ldap.schema.ObjectClassType; 076import org.forgerock.opendj.ldap.schema.SchemaBuilder; 077import org.forgerock.opendj.ldap.schema.Syntax; 078import org.forgerock.util.Reject; 079import org.opends.server.admin.AdministrationConnector; 080import org.opends.server.admin.AdministrationDataSync; 081import org.opends.server.admin.ClassLoaderProvider; 082import org.opends.server.admin.server.ServerManagementContext; 083import org.opends.server.admin.std.server.AlertHandlerCfg; 084import org.opends.server.admin.std.server.ConnectionHandlerCfg; 085import org.opends.server.admin.std.server.CryptoManagerCfg; 086import org.opends.server.admin.std.server.MonitorProviderCfg; 087import org.opends.server.admin.std.server.PasswordValidatorCfg; 088import org.opends.server.admin.std.server.RootCfg; 089import org.opends.server.admin.std.server.RootDSEBackendCfg; 090import org.opends.server.admin.std.server.SynchronizationProviderCfg; 091import org.opends.server.api.AccessControlHandler; 092import org.opends.server.api.AccountStatusNotificationHandler; 093import org.opends.server.api.AlertGenerator; 094import org.opends.server.api.AlertHandler; 095import org.opends.server.api.AuthenticationPolicy; 096import org.opends.server.api.Backend; 097import org.opends.server.api.BackendInitializationListener; 098import org.opends.server.api.BackupTaskListener; 099import org.opends.server.api.CertificateMapper; 100import org.opends.server.api.ClientConnection; 101import org.opends.server.api.CompressedSchema; 102import org.opends.server.api.ConfigAddListener; 103import org.opends.server.api.ConfigChangeListener; 104import org.opends.server.api.ConfigDeleteListener; 105import org.opends.server.api.ConfigHandler; 106import org.opends.server.api.ConnectionHandler; 107import org.opends.server.api.DirectoryServerMBean; 108import org.opends.server.api.EntryCache; 109import org.opends.server.api.ExportTaskListener; 110import org.opends.server.api.ExtendedOperationHandler; 111import org.opends.server.api.IdentityMapper; 112import org.opends.server.api.ImportTaskListener; 113import org.opends.server.api.InitializationCompletedListener; 114import org.opends.server.api.InvokableComponent; 115import org.opends.server.api.KeyManagerProvider; 116import org.opends.server.api.MatchingRuleFactory; 117import org.opends.server.api.MonitorProvider; 118import org.opends.server.api.PasswordGenerator; 119import org.opends.server.api.PasswordStorageScheme; 120import org.opends.server.api.PasswordValidator; 121import org.opends.server.api.RestoreTaskListener; 122import org.opends.server.api.SASLMechanismHandler; 123import org.opends.server.api.ServerShutdownListener; 124import org.opends.server.api.SynchronizationProvider; 125import org.opends.server.api.TrustManagerProvider; 126import org.opends.server.api.WorkQueue; 127import org.opends.server.api.plugin.InternalDirectoryServerPlugin; 128import org.opends.server.api.plugin.PluginResult; 129import org.opends.server.api.plugin.PluginType; 130import org.opends.server.backends.RootDSEBackend; 131import org.opends.server.config.ConfigEntry; 132import org.opends.server.config.JMXMBean; 133import org.opends.server.controls.PasswordPolicyErrorType; 134import org.opends.server.controls.PasswordPolicyResponseControl; 135import org.opends.server.crypto.CryptoManagerImpl; 136import org.opends.server.crypto.CryptoManagerSync; 137import org.opends.server.extensions.ConfigFileHandler; 138import org.opends.server.extensions.DiskSpaceMonitor; 139import org.opends.server.extensions.JMXAlertHandler; 140import org.opends.server.loggers.AccessLogger; 141import org.opends.server.loggers.CommonAudit; 142import org.opends.server.loggers.DebugLogPublisher; 143import org.opends.server.loggers.DebugLogger; 144import org.opends.server.loggers.ErrorLogPublisher; 145import org.opends.server.loggers.ErrorLogger; 146import org.opends.server.loggers.RetentionPolicy; 147import org.opends.server.loggers.RotationPolicy; 148import org.opends.server.loggers.TextErrorLogPublisher; 149import org.opends.server.loggers.TextWriter; 150import org.opends.server.monitors.BackendMonitor; 151import org.opends.server.monitors.ConnectionHandlerMonitor; 152import org.opends.server.protocols.internal.InternalClientConnection; 153import org.opends.server.protocols.internal.InternalConnectionHandler; 154import org.opends.server.schema.BooleanEqualityMatchingRuleFactory; 155import org.opends.server.schema.CaseExactEqualityMatchingRuleFactory; 156import org.opends.server.schema.CaseExactIA5EqualityMatchingRuleFactory; 157import org.opends.server.schema.CaseExactIA5SubstringMatchingRuleFactory; 158import org.opends.server.schema.CaseExactOrderingMatchingRuleFactory; 159import org.opends.server.schema.CaseExactSubstringMatchingRuleFactory; 160import org.opends.server.schema.CaseIgnoreEqualityMatchingRuleFactory; 161import org.opends.server.schema.CaseIgnoreIA5EqualityMatchingRuleFactory; 162import org.opends.server.schema.CaseIgnoreIA5SubstringMatchingRuleFactory; 163import org.opends.server.schema.CaseIgnoreOrderingMatchingRuleFactory; 164import org.opends.server.schema.CaseIgnoreSubstringMatchingRuleFactory; 165import org.opends.server.schema.DistinguishedNameEqualityMatchingRuleFactory; 166import org.opends.server.schema.DoubleMetaphoneApproximateMatchingRuleFactory; 167import org.opends.server.schema.GeneralizedTimeEqualityMatchingRuleFactory; 168import org.opends.server.schema.GeneralizedTimeOrderingMatchingRuleFactory; 169import org.opends.server.schema.IntegerEqualityMatchingRuleFactory; 170import org.opends.server.schema.IntegerOrderingMatchingRuleFactory; 171import org.opends.server.schema.ObjectIdentifierEqualityMatchingRuleFactory; 172import org.opends.server.schema.OctetStringEqualityMatchingRuleFactory; 173import org.opends.server.schema.OctetStringOrderingMatchingRuleFactory; 174import org.opends.server.schema.OctetStringSubstringMatchingRuleFactory; 175import org.opends.server.schema.SchemaUpdater; 176import org.opends.server.schema.TelephoneNumberEqualityMatchingRuleFactory; 177import org.opends.server.schema.TelephoneNumberSubstringMatchingRuleFactory; 178import org.opends.server.types.AcceptRejectWarn; 179import org.opends.server.types.AttributeType; 180import org.opends.server.types.BackupConfig; 181import org.opends.server.types.Control; 182import org.opends.server.types.DITContentRule; 183import org.opends.server.types.DITStructureRule; 184import org.opends.server.types.DN; 185import org.opends.server.types.DirectoryEnvironmentConfig; 186import org.opends.server.types.DirectoryException; 187import org.opends.server.types.Entry; 188import org.opends.server.types.HostPort; 189import org.opends.server.types.InitializationException; 190import org.opends.server.types.LDIFExportConfig; 191import org.opends.server.types.LDIFImportConfig; 192import org.opends.server.types.LockManager; 193import org.opends.server.types.MatchingRuleUse; 194import org.opends.server.types.Modification; 195import org.opends.server.types.NameForm; 196import org.opends.server.types.ObjectClass; 197import org.opends.server.types.Operation; 198import org.opends.server.types.Privilege; 199import org.opends.server.types.RestoreConfig; 200import org.opends.server.types.Schema; 201import org.opends.server.types.VirtualAttributeRule; 202import org.opends.server.types.WritabilityMode; 203import org.opends.server.util.ActivateOnceNewConfigFrameworkIsUsed; 204import org.opends.server.util.ActivateOnceSDKSchemaIsUsed; 205import org.opends.server.util.BuildVersion; 206import org.opends.server.util.MultiOutputStream; 207import org.opends.server.util.RemoveOnceSDKSchemaIsUsed; 208import org.opends.server.util.RuntimeInformation; 209import org.opends.server.util.SetupUtils; 210import org.opends.server.util.TimeThread; 211import org.opends.server.workflowelement.localbackend.LocalBackendWorkflowElement; 212 213import com.forgerock.opendj.cli.ArgumentConstants; 214import com.forgerock.opendj.cli.ArgumentException; 215import com.forgerock.opendj.cli.ArgumentParser; 216import com.forgerock.opendj.cli.BooleanArgument; 217import com.forgerock.opendj.cli.CommonArguments; 218import com.forgerock.opendj.cli.IntegerArgument; 219import com.forgerock.opendj.cli.StringArgument; 220import com.forgerock.opendj.cli.VersionHandler; 221import com.forgerock.opendj.util.OperatingSystem; 222 223/** 224 * This class defines the core of the Directory Server. It manages the startup 225 * and shutdown processes and coordinates activities between all other 226 * components. 227 */ 228public final class DirectoryServer 229 implements AlertGenerator 230{ 231 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 232 233 /** The singleton Directory Server instance. */ 234 private static DirectoryServer directoryServer = new DirectoryServer(); 235 236 /** Indicates whether the server currently holds an exclusive lock on the server lock file. */ 237 private static boolean serverLocked; 238 239 /** The message to be displayed on the command-line when the user asks for the usage. */ 240 private static LocalizableMessage toolDescription = INFO_DSCORE_TOOL_DESCRIPTION.get(); 241 242 /** 243 * Return codes used when the hidden option --checkStartability is used. 244 * NOTE: when checkstartability is specified is recommended not to allocate 245 * a lot of memory for the JVM (Using -Xms and -Xmx options) as there might 246 * be calls to Runtime.exec. 247 */ 248 /** 249 * Returned when the user specified the --checkStartability option with other 250 * options like printing the usage, dumping messages, displaying version, etc. 251 */ 252 private static final int NOTHING_TO_DO = 0; 253 /** 254 * Returned when the user specified the --checkStartability option with 255 * some incompatible arguments. 256 */ 257 private static final int CHECK_ERROR = 1; 258 /** The server is already started. */ 259 private static final int SERVER_ALREADY_STARTED = 98; 260 /** The server must be started as detached process. */ 261 private static final int START_AS_DETACH = 99; 262 /** The server must be started as a non-detached process. */ 263 private static final int START_AS_NON_DETACH = 100; 264 /** The server must be started as a window service. */ 265 private static final int START_AS_WINDOWS_SERVICE = 101; 266 /** The server must be started as detached and it is being called from the Windows Service. */ 267 private static final int START_AS_DETACH_CALLED_FROM_WINDOWS_SERVICE = 102; 268 /** The server must be started as detached process and should not produce any output. */ 269 private static final int START_AS_DETACH_QUIET = 103; 270 /** The server must be started as non-detached process and should not produce any output. */ 271 private static final int START_AS_NON_DETACH_QUIET = 104; 272 273 /** Temporary context object, to provide instance methods instead of static methods. */ 274 private final DirectoryServerContext serverContext; 275 276 /** The policy to use regarding single structural objectclass enforcement. */ 277 private AcceptRejectWarn singleStructuralClassPolicy; 278 /** The policy to use regarding syntax enforcement. */ 279 private AcceptRejectWarn syntaxEnforcementPolicy; 280 281 /** The account status notification handler config manager for the server. */ 282 private AccountStatusNotificationHandlerConfigManager accountStatusNotificationHandlerConfigManager; 283 284 /** The attribute type used to reference the "objectclass" attribute. */ 285 private AttributeType objectClassAttributeType; 286 /** The authenticated users manager for the server. */ 287 private AuthenticatedUsers authenticatedUsers; 288 /** The configuration manager that will handle the server backends. */ 289 private BackendConfigManager backendConfigManager; 290 291 /** 292 * Indicates whether to automatically add missing RDN attributes to entries 293 * during an add request. 294 */ 295 private boolean addMissingRDNAttributes; 296 297 /** 298 * Indicates whether to allow attribute name exceptions (i.e., attribute names 299 * can contain underscores and may start with a digit). 300 */ 301 private boolean allowAttributeNameExceptions; 302 303 /** Indicates whether a simple bind request containing a DN must also provide a password. */ 304 private boolean bindWithDNRequiresPassword; 305 306 /** Indicates whether the Directory Server should perform schema checking for update operations. */ 307 private boolean checkSchema; 308 309 /** Indicates whether the server has been bootstrapped. */ 310 private boolean isBootstrapped; 311 /** Indicates whether the server is currently online. */ 312 private boolean isRunning; 313 /** Indicates whether the server is currently in "lockdown mode". */ 314 private boolean lockdownMode; 315 316 /** Indicates whether the server should send a response to operations that have been abandoned. */ 317 private boolean notifyAbandonedOperations; 318 319 /** Indicates whether to save a copy of the configuration on successful startup. */ 320 private boolean saveConfigOnSuccessfulStartup; 321 322 /** Indicates whether the server is currently in the process of shutting down. */ 323 private boolean shuttingDown; 324 325 /** Indicates whether the server should reject unauthenticated requests. */ 326 private boolean rejectUnauthenticatedRequests; 327 328 /** Indicates whether bind responses should include failure reason messages. */ 329 private boolean returnBindErrorMessages; 330 331 /** The configuration manager that will handle the certificate mapper. */ 332 private CertificateMapperConfigManager certificateMapperConfigManager; 333 334 /** The class used to provide the config handler implementation. */ 335 private Class<ConfigHandler> configClass; 336 337 /** The configuration handler for the Directory Server. */ 338 private ConfigHandler configHandler; 339 340 /** The set of account status notification handlers defined in the server. */ 341 private ConcurrentMap<DN, AccountStatusNotificationHandler> 342 accountStatusNotificationHandlers; 343 344 /** The set of certificate mappers registered with the server. */ 345 private ConcurrentMap<DN, CertificateMapper> certificateMappers; 346 347 /** The set of alternate bind DNs for the root users. */ 348 private ConcurrentMap<DN, DN> alternateRootBindDNs; 349 350 /** 351 * The set of identity mappers registered with the server (mapped between the 352 * configuration entry Dn and the mapper). 353 */ 354 private ConcurrentMap<DN, IdentityMapper> identityMappers; 355 356 /** 357 * The set of JMX MBeans that have been registered with the server (mapped 358 * between the associated configuration entry DN and the MBean). 359 */ 360 private ConcurrentHashMap<DN,JMXMBean> mBeans; 361 362 /** The set of key manager providers registered with the server. */ 363 private ConcurrentMap<DN, KeyManagerProvider> keyManagerProviders; 364 365 /** 366 * The set of password generators registered with the Directory Server, as a 367 * mapping between the DN of the associated configuration entry and the 368 * generator implementation. 369 */ 370 private ConcurrentMap<DN, PasswordGenerator> passwordGenerators; 371 372 /** 373 * The set of authentication policies registered with the Directory Server, as 374 * a mapping between the DN of the associated configuration entry and the 375 * policy implementation. 376 */ 377 private ConcurrentMap<DN, AuthenticationPolicy> authenticationPolicies; 378 379 /** 380 * The set of password validators registered with the Directory Server, as a 381 * mapping between the DN of the associated configuration entry and the 382 * validator implementation. 383 */ 384 private ConcurrentMap<DN, PasswordValidator<? extends PasswordValidatorCfg>> 385 passwordValidators; 386 387 /** The set of trust manager providers registered with the server. */ 388 private ConcurrentMap<DN, TrustManagerProvider> trustManagerProviders; 389 390 /** 391 * The set of log rotation policies registered with the Directory Server, as a 392 * mapping between the DN of the associated configuration entry and the policy 393 * implementation. 394 */ 395 private ConcurrentMap<DN, RotationPolicy> rotationPolicies; 396 397 /** 398 * The set of log retention policies registered with the Directory Server, as 399 * a mapping between the DN of the associated configuration entry and the 400 * policy implementation. 401 */ 402 private ConcurrentMap<DN, RetentionPolicy> retentionPolicies; 403 404 /** The set supported LDAP protocol versions. */ 405 private ConcurrentMap<Integer, List<ConnectionHandler>> 406 supportedLDAPVersions; 407 408 /** 409 * The set of extended operation handlers registered with the server (mapped 410 * between the OID of the extended operation and the handler). 411 */ 412 private ConcurrentMap<String, ExtendedOperationHandler> 413 extendedOperationHandlers; 414 415 /** 416 * The set of monitor providers registered with the Directory Server, as a 417 * mapping between the monitor name and the corresponding implementation. 418 */ 419 private ConcurrentMap<String, MonitorProvider<? extends MonitorProviderCfg>> 420 monitorProviders; 421 422 /** 423 * The set of password storage schemes defined in the server (mapped between 424 * the lowercase scheme name and the storage scheme) that support the 425 * authentication password syntax. 426 */ 427 private ConcurrentHashMap<String,PasswordStorageScheme> 428 authPasswordStorageSchemes; 429 430 /** 431 * The set of password storage schemes defined in the server (mapped between 432 * the lowercase scheme name and the storage scheme). 433 */ 434 private ConcurrentHashMap<String,PasswordStorageScheme> 435 passwordStorageSchemes; 436 437 /** 438 * The set of password storage schemes defined in the server (mapped between 439 * the DN of the configuration entry and the storage scheme). 440 */ 441 private ConcurrentMap<DN, PasswordStorageScheme> 442 passwordStorageSchemesByDN; 443 444 /** 445 * The set of SASL mechanism handlers registered with the server (mapped 446 * between the mechanism name and the handler). 447 */ 448 private ConcurrentMap<String, SASLMechanismHandler> saslMechanismHandlers; 449 450 /** The connection handler configuration manager for the Directory Server. */ 451 private ConnectionHandlerConfigManager connectionHandlerConfigManager; 452 453 /** The set of alert handlers registered with the Directory Server. */ 454 private List<AlertHandler> alertHandlers; 455 456 /** The set of backup task listeners registered with the Directory Server. */ 457 private CopyOnWriteArrayList<BackupTaskListener> backupTaskListeners; 458 459 /** The set of connection handlers registered with the Directory Server. */ 460 private List<ConnectionHandler> connectionHandlers; 461 462 /** The set of export task listeners registered with the Directory Server. */ 463 private CopyOnWriteArrayList<ExportTaskListener> exportTaskListeners; 464 465 /** The set of import task listeners registered with the Directory Server. */ 466 private CopyOnWriteArrayList<ImportTaskListener> importTaskListeners; 467 468 /** The set of restore task listeners registered with the Directory Server. */ 469 private CopyOnWriteArrayList<RestoreTaskListener> restoreTaskListeners; 470 471 /** 472 * The set of initialization completed listeners that have been registered 473 * with the Directory Server. 474 */ 475 private List<InitializationCompletedListener> 476 initializationCompletedListeners; 477 478 /** The set of shutdown listeners that have been registered with the Directory Server. */ 479 private List<ServerShutdownListener> shutdownListeners; 480 /** The set of synchronization providers that have been registered with the Directory Server. */ 481 private List<SynchronizationProvider<SynchronizationProviderCfg>> synchronizationProviders; 482 /** The set of backend initialization listeners registered with the Directory Server. */ 483 private Set<BackendInitializationListener> backendInitializationListeners; 484 485 /** The set of root DNs registered with the Directory Server. */ 486 private Set<DN> rootDNs; 487 488 /** The core configuration manager for the Directory Server. */ 489 private CoreConfigManager coreConfigManager; 490 491 /** The crypto manager for the Directory Server. */ 492 private CryptoManagerImpl cryptoManager; 493 494 /** The default compressed schema manager. */ 495 private DefaultCompressedSchema compressedSchema; 496 497 /** The environment configuration for the Directory Server. */ 498 private DirectoryEnvironmentConfig environmentConfig; 499 500 /** The shutdown hook that has been registered with the server. */ 501 private DirectoryServerShutdownHook shutdownHook; 502 503 /** The DN of the default password policy configuration entry. */ 504 private DN defaultPasswordPolicyDN; 505 506 /** 507 * The DN of the identity mapper that will be used to resolve authorization 508 * IDs contained in the proxied authorization V2 control. 509 */ 510 private DN proxiedAuthorizationIdentityMapperDN; 511 512 /** The DN of the entry containing the server schema definitions. */ 513 private DN schemaDN; 514 515 /** The Directory Server entry cache. */ 516 private EntryCache entryCache; 517 518 /** The configuration manager for the entry cache. */ 519 private EntryCacheConfigManager entryCacheConfigManager; 520 521 /** The configuration manager for extended operation handlers. */ 522 private ExtendedOperationConfigManager extendedOperationConfigManager; 523 524 /** 525 * The path to the file containing the Directory Server configuration, or the 526 * information needed to bootstrap the configuration handler. 527 */ 528 private File configFile; 529 530 /** The group manager for the Directory Server. */ 531 private GroupManager groupManager; 532 533 /** The subentry manager for the Directory Server. */ 534 private SubentryManager subentryManager; 535 536 /** The configuration manager for identity mappers. */ 537 private IdentityMapperConfigManager identityMapperConfigManager; 538 539 /** 540 * The maximum number of entries that should be returned for a search unless 541 * overridden on a per-user basis. 542 */ 543 private int sizeLimit; 544 545 /** 546 * The maximum length of time in seconds that should be allowed for a search 547 * unless overridden on a per-user basis. 548 */ 549 private int timeLimit; 550 /** The maximum number of candidates that should be check for matches during a search. */ 551 private int lookthroughLimit; 552 553 /** The current active persistent searches. */ 554 private final AtomicInteger activePSearches = new AtomicInteger(0); 555 556 /** The maximum number of concurrent persistent searches. */ 557 private int maxPSearches; 558 559 /** Whether to use collect operation processing times in nanosecond resolution. */ 560 private boolean useNanoTime; 561 562 /** The key manager provider configuration manager for the Directory Server. */ 563 private KeyManagerProviderConfigManager keyManagerProviderConfigManager; 564 565 /** The set of connections that are currently established. */ 566 private Set<ClientConnection> establishedConnections; 567 568 /** The sets of mail server properties. */ 569 private List<Properties> mailServerPropertySets; 570 571 /** 572 * The set of schema changes made by editing the schema configuration files 573 * with the server offline. 574 */ 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 /** The idle time limit for the server. */ 589 private long idleTimeLimit; 590 591 /** The maximum number of connections that will be allowed at any given time. */ 592 private long maxAllowedConnections; 593 /** The maximum number of connections established at one time. */ 594 private long maxConnections; 595 596 /** The time that this Directory Server instance was started. */ 597 private long startUpTime; 598 599 /** The total number of connections established since startup. */ 600 private long totalConnections; 601 602 /** The MBean server used to handle JMX interaction. */ 603 private MBeanServer mBeanServer; 604 605 /** The monitor config manager for the Directory Server. */ 606 private MonitorConfigManager monitorConfigManager; 607 608 /** The operating system on which the server is running. */ 609 private final OperatingSystem operatingSystem; 610 611 /** The configuration handler used to manage the password generators. */ 612 private PasswordGeneratorConfigManager passwordGeneratorConfigManager; 613 /** The default password policy for the Directory Server. */ 614 private PasswordPolicy defaultPasswordPolicy; 615 /** The configuration handler used to manage the authentication policies. */ 616 private PasswordPolicyConfigManager authenticationPolicyConfigManager; 617 /** The configuration handler used to manage the password storage schemes. */ 618 private PasswordStorageSchemeConfigManager storageSchemeConfigManager; 619 /** The configuration handler used to manage the password validators. */ 620 private PasswordValidatorConfigManager passwordValidatorConfigManager; 621 622 /** The plugin config manager for the Directory Server. */ 623 private PluginConfigManager pluginConfigManager; 624 625 /** The result code that should be used for internal "server" errors. */ 626 private ResultCode serverErrorResultCode; 627 628 /** The special backend used for the Directory Server root DSE. */ 629 private RootDSEBackend rootDSEBackend; 630 /** The root DN config manager for the server. */ 631 private RootDNConfigManager rootDNConfigManager; 632 633 /** The SASL mechanism config manager for the Directory Server. */ 634 private SASLConfigManager saslConfigManager; 635 636 /** The schema for the Directory Server. */ 637 private Schema schema; 638 639 /** 640 * The schema for the Directory Server. 641 * <p> 642 * This schema is synchronized indirectly to the existing schema, because 643 * syntaxes are defined in schemaNG (i.e, migrated to SDK classes) and there 644 * is currently no way to handle the SchemaOptions in the configuration (e.g. 645 * SchemaOptions.ALLOW_ZERO_LENGTH_DIRECTORY_STRINGS). 646 * Thus, configuration of the legacy syntaxes are kept, and any change related 647 * to them is synchronized with this schema. 648 */ 649 @RemoveOnceSDKSchemaIsUsed("'schema' field will then be a reference to a SDK schema") 650 private org.forgerock.opendj.ldap.schema.Schema schemaNG; 651 652 /** The schema configuration manager for the Directory Server. */ 653 private SchemaConfigManager schemaConfigManager; 654 655 /** The set of disabled privileges. */ 656 private Set<Privilege> disabledPrivileges; 657 658 /** The set of allowed task classes. */ 659 private Set<String> allowedTasks; 660 661 /** The time that the server was started, formatted in UTC time. */ 662 private String startTimeUTC; 663 664 /** The synchronization provider configuration manager for the Directory Server. */ 665 private SynchronizationProviderConfigManager synchronizationProviderConfigManager; 666 667 /** Registry for base DN and naming context information. */ 668 private BaseDnRegistry baseDnRegistry; 669 670 /** The set of backends registered with the server. */ 671 private TreeMap<String, Backend<?>> backends; 672 673 /** The set of supported controls registered with the Directory Server. */ 674 private final TreeSet<String> supportedControls = newTreeSet( 675 OID_LDAP_ASSERTION, 676 OID_LDAP_READENTRY_PREREAD, 677 OID_LDAP_READENTRY_POSTREAD, 678 OID_LDAP_NOOP_OPENLDAP_ASSIGNED, 679 OID_PERSISTENT_SEARCH, 680 OID_PROXIED_AUTH_V1, 681 OID_PROXIED_AUTH_V2, 682 OID_AUTHZID_REQUEST, 683 OID_MATCHED_VALUES, 684 OID_LDAP_SUBENTRIES, 685 OID_LDUP_SUBENTRIES, 686 OID_PASSWORD_POLICY_CONTROL, 687 OID_PERMISSIVE_MODIFY_CONTROL, 688 OID_REAL_ATTRS_ONLY, 689 OID_VIRTUAL_ATTRS_ONLY, 690 OID_ACCOUNT_USABLE_CONTROL, 691 OID_NS_PASSWORD_EXPIRED, 692 OID_NS_PASSWORD_EXPIRING); 693 694 /** The set of supported feature OIDs registered with the Directory Server. */ 695 private final TreeSet<String> supportedFeatures = newTreeSet( 696 OID_ALL_OPERATIONAL_ATTRS_FEATURE, 697 OID_MODIFY_INCREMENT_FEATURE, 698 OID_TRUE_FALSE_FILTERS_FEATURE); 699 700 /** The trust manager provider configuration manager for the Directory Server. */ 701 private TrustManagerProviderConfigManager trustManagerProviderConfigManager; 702 703 /** The virtual attribute provider configuration manager for the Directory Server. */ 704 private final VirtualAttributeConfigManager virtualAttributeConfigManager; 705 706 /** The work queue that will be used to service client requests. */ 707 private WorkQueue workQueue; 708 709 /** The writability mode for the Directory Server. */ 710 private WritabilityMode writabilityMode; 711 712 /** The memory reservation system. */ 713 private MemoryQuota memoryQuota; 714 715 /** The Disk Space Monitor. */ 716 private DiskSpaceMonitor diskSpaceMonitor; 717 718 /** The lock manager which will be used for coordinating access to LDAP entries. */ 719 private final LockManager lockManager = new LockManager(); 720 721 /** The maximum size that internal buffers will be allowed to grow to until they are trimmed. */ 722 private int maxInternalBufferSize = DEFAULT_MAX_INTERNAL_BUFFER_SIZE; 723 724 /** The default timeout used to start the server in detach mode. */ 725 public static final int DEFAULT_TIMEOUT = 200; 726 727 /** Entry point for server configuration. */ 728 private org.forgerock.opendj.config.server.ServerManagementContext serverManagementContext; 729 730 /** Entry point to common audit service, where all audit events must be published. */ 731 private CommonAudit commonAudit; 732 733 /** Class that prints the version of OpenDJ server to System.out. */ 734 public static final class DirectoryServerVersionHandler implements VersionHandler 735 { 736 /** {@inheritDoc} */ 737 @Override 738 public void printVersion() 739 { 740 try 741 { 742 DirectoryServer.printVersion(System.out); 743 } 744 catch (Exception e){} 745 } 746 } 747 748 /** 749 * Temporary class to provide instance methods instead of static methods for 750 * server. Once all static methods related to context are removed from the 751 * server then DirectoryServer class can be used directly as implementation of 752 * ServerContext. 753 */ 754 private class DirectoryServerContext implements ServerContext 755 { 756 757 /** {@inheritDoc} */ 758 @Override 759 public String getInstanceRoot() 760 { 761 return DirectoryServer.getInstanceRoot(); 762 } 763 764 /** {@inheritDoc} */ 765 @Override 766 public String getServerRoot() 767 { 768 return DirectoryServer.getServerRoot(); 769 } 770 771 /** {@inheritDoc} */ 772 @Override 773 public Schema getSchema() 774 { 775 return directoryServer.schema; 776 } 777 778 /** {@inheritDoc} */ 779 @Override 780 public org.forgerock.opendj.ldap.schema.Schema getSchemaNG() 781 { 782 return directoryServer.schemaNG; 783 } 784 785 /** {@inheritDoc} */ 786 @Override 787 public DirectoryEnvironmentConfig getEnvironment() 788 { 789 return directoryServer.environmentConfig; 790 } 791 792 /** {@inheritDoc} */ 793 @Override 794 public SchemaUpdater getSchemaUpdater() 795 { 796 return new SchemaUpdater() 797 { 798 @Override 799 public boolean updateSchema(org.forgerock.opendj.ldap.schema.Schema schema) 800 { 801 schemaNG = schema; 802 return true; 803 } 804 805 @Override 806 public SchemaBuilder getSchemaBuilder() 807 { 808 return new SchemaBuilder(schemaNG); 809 } 810 }; 811 } 812 813 /** {@inheritDoc} */ 814 @Override 815 public org.forgerock.opendj.config.server.ServerManagementContext getServerManagementContext() 816 { 817 return serverManagementContext; 818 } 819 820 @Override 821 public MemoryQuota getMemoryQuota() 822 { 823 return directoryServer.memoryQuota; 824 } 825 826 @Override 827 public DiskSpaceMonitor getDiskSpaceMonitor() 828 { 829 return directoryServer.diskSpaceMonitor; 830 } 831 832 @Override 833 public CommonAudit getCommonAudit() 834 { 835 return directoryServer.commonAudit; 836 } 837 } 838 839 /** 840 * Creates a new instance of the Directory Server. This will allow only a 841 * single instance of the server per JVM. 842 */ 843 private DirectoryServer() 844 { 845 this(new DirectoryEnvironmentConfig()); 846 } 847 848 /** 849 * Creates a new instance of the Directory Server. This will allow only a 850 * single instance of the server per JVM. 851 * 852 * @param config The environment configuration to use for the Directory 853 * Server instance. 854 */ 855 private DirectoryServer(DirectoryEnvironmentConfig config) 856 { 857 environmentConfig = config; 858 isBootstrapped = false; 859 isRunning = false; 860 shuttingDown = false; 861 lockdownMode = false; 862 serverErrorResultCode = ResultCode.OTHER; 863 864 operatingSystem = OperatingSystem.forName(System.getProperty("os.name")); 865 serverContext = new DirectoryServerContext(); 866 virtualAttributeConfigManager = new VirtualAttributeConfigManager(serverContext); 867 memoryQuota = new MemoryQuota(); 868 diskSpaceMonitor = new DiskSpaceMonitor(); 869 } 870 871 /** 872 * Retrieves the instance of the Directory Server that is associated with this 873 * JVM. 874 * 875 * @return The instance of the Directory Server that is associated with this 876 * JVM. 877 */ 878 public static DirectoryServer getInstance() 879 { 880 return directoryServer; 881 } 882 883 /** 884 * Creates a new instance of the Directory Server and replaces the static 885 * reference to it. This should only be used in the context of an in-core 886 * restart after the existing server has been shut down. 887 * 888 * @param config The environment configuration for the Directory Server. 889 * 890 * @return The new instance of the Directory Server that is associated with 891 * this JVM. 892 */ 893 private static DirectoryServer 894 getNewInstance(DirectoryEnvironmentConfig config) 895 { 896 synchronized (directoryServer) 897 { 898 return directoryServer = new DirectoryServer(config); 899 } 900 } 901 902 /** 903 * Retrieves the environment configuration for the Directory Server. 904 * 905 * @return The environment configuration for the Directory Server. 906 */ 907 public static DirectoryEnvironmentConfig getEnvironmentConfig() 908 { 909 return directoryServer.environmentConfig; 910 } 911 912 /** 913 * Sets the environment configuration for the Directory Server. This method 914 * may only be invoked when the server is not running. 915 * 916 * @param config The environment configuration for the Directory Server. 917 * 918 * @throws InitializationException If the Directory Server is currently 919 * running. 920 */ 921 public void setEnvironmentConfig(DirectoryEnvironmentConfig config) 922 throws InitializationException 923 { 924 if (isRunning) 925 { 926 throw new InitializationException( 927 ERR_CANNOT_SET_ENVIRONMENT_CONFIG_WHILE_RUNNING.get()); 928 } 929 930 environmentConfig = config; 931 } 932 933 /** 934 * Returns the server context. 935 * 936 * @return the server context 937 */ 938 public ServerContext getServerContext() { 939 return serverContext; 940 } 941 942 /** 943 * Indicates whether the Directory Server is currently running. 944 * 945 * @return {@code true} if the server is currently running, or {@code false} 946 * if not. 947 */ 948 public static boolean isRunning() 949 { 950 return directoryServer.isRunning; 951 } 952 953 /** 954 * Bootstraps the appropriate Directory Server structures that may be needed 955 * by both server and client-side tools. 956 */ 957 public static void bootstrapClient() 958 { 959 synchronized (directoryServer) 960 { 961 // Set default values for variables that may be needed during schema 962 // processing. 963 directoryServer.syntaxEnforcementPolicy = AcceptRejectWarn.REJECT; 964 965 // Create the server schema and initialize and register a minimal set of 966 // matching rules and attribute syntaxes. 967 directoryServer.schema = new Schema(); 968 directoryServer.schemaNG = new SchemaBuilder("mainSchema").addSchema(CoreSchema.getInstance(), true).toSchema(); 969 directoryServer.bootstrapMatchingRules(); 970 directoryServer.bootstrapAttributeSyntaxes(); 971 972 // Perform any additional initialization that might be necessary before 973 // loading the configuration. 974 directoryServer.alertHandlers = new CopyOnWriteArrayList<>(); 975 directoryServer.passwordStorageSchemes = new ConcurrentHashMap<>(); 976 directoryServer.passwordStorageSchemesByDN = new ConcurrentHashMap<>(); 977 directoryServer.passwordGenerators = new ConcurrentHashMap<>(); 978 directoryServer.authPasswordStorageSchemes = new ConcurrentHashMap<>(); 979 directoryServer.passwordValidators = new ConcurrentHashMap<>(); 980 directoryServer.accountStatusNotificationHandlers = new ConcurrentHashMap<>(); 981 directoryServer.rootDNs = new CopyOnWriteArraySet<>(); 982 directoryServer.alternateRootBindDNs = new ConcurrentHashMap<>(); 983 directoryServer.keyManagerProviders = new ConcurrentHashMap<>(); 984 directoryServer.trustManagerProviders = new ConcurrentHashMap<>(); 985 directoryServer.rotationPolicies = new ConcurrentHashMap<>(); 986 directoryServer.retentionPolicies = new ConcurrentHashMap<>(); 987 directoryServer.certificateMappers = new ConcurrentHashMap<>(); 988 directoryServer.authenticationPolicies = new ConcurrentHashMap<>(); 989 directoryServer.defaultPasswordPolicyDN = null; 990 directoryServer.defaultPasswordPolicy = null; 991 directoryServer.monitorProviders = new ConcurrentHashMap<>(); 992 directoryServer.backends = new TreeMap<>(); 993 directoryServer.backendInitializationListeners = new CopyOnWriteArraySet<>(); 994 directoryServer.baseDnRegistry = new BaseDnRegistry(); 995 directoryServer.initializationCompletedListeners = new CopyOnWriteArrayList<>(); 996 directoryServer.shutdownListeners = new CopyOnWriteArrayList<>(); 997 directoryServer.synchronizationProviders = new CopyOnWriteArrayList<>(); 998 directoryServer.supportedLDAPVersions = new ConcurrentHashMap<>(); 999 directoryServer.connectionHandlers = new CopyOnWriteArrayList<>(); 1000 directoryServer.identityMappers = new ConcurrentHashMap<>(); 1001 directoryServer.extendedOperationHandlers = new ConcurrentHashMap<>(); 1002 directoryServer.saslMechanismHandlers = new ConcurrentHashMap<>(); 1003 directoryServer.offlineSchemaChanges = new LinkedList<>(); 1004 directoryServer.backupTaskListeners = new CopyOnWriteArrayList<>(); 1005 directoryServer.restoreTaskListeners = new CopyOnWriteArrayList<>(); 1006 directoryServer.exportTaskListeners = new CopyOnWriteArrayList<>(); 1007 directoryServer.importTaskListeners = new CopyOnWriteArrayList<>(); 1008 directoryServer.allowedTasks = new LinkedHashSet<>(0); 1009 directoryServer.disabledPrivileges = new LinkedHashSet<>(0); 1010 directoryServer.returnBindErrorMessages = false; 1011 directoryServer.idleTimeLimit = 0L; 1012 } 1013 } 1014 1015 /** 1016 * Bootstraps the Directory Server by initializing all the necessary 1017 * structures that should be in place before the configuration may be read. 1018 * This step must be completed before the server may be started or the 1019 * configuration is loaded, but it will not be allowed while the server is 1020 * running. 1021 * 1022 * @throws InitializationException If a problem occurs while attempting to 1023 * bootstrap the server. 1024 */ 1025 private void bootstrapServer() throws InitializationException 1026 { 1027 // First, make sure that the server isn't currently running. If it isn't, 1028 // then make sure that no other thread will try to start or bootstrap the 1029 // server before this thread is done. 1030 synchronized (directoryServer) 1031 { 1032 if (isRunning) 1033 { 1034 LocalizableMessage message = ERR_CANNOT_BOOTSTRAP_WHILE_RUNNING.get(); 1035 throw new InitializationException(message); 1036 } 1037 1038 isBootstrapped = false; 1039 shuttingDown = false; 1040 } 1041 1042 // Add a shutdown hook so that the server can be notified when the JVM 1043 // starts shutting down. 1044 shutdownHook = new DirectoryServerShutdownHook(); 1045 Runtime.getRuntime().addShutdownHook(shutdownHook); 1046 1047 // Create the MBean server that we will use for JMX interaction. 1048 initializeJMX(); 1049 1050 logger.debug(INFO_DIRECTORY_BOOTSTRAPPING); 1051 1052 // Perform all the bootstrapping that is shared with the client-side processing. 1053 bootstrapClient(); 1054 1055 // Initialize the variables that will be used for connection tracking. 1056 establishedConnections = new LinkedHashSet<>(1000); 1057 currentConnections = 0; 1058 maxConnections = 0; 1059 totalConnections = 0; 1060 1061 // Create the plugin config manager, but don't initialize it yet. This will 1062 // make it possible to process internal operations before the plugins have 1063 // been loaded. 1064 pluginConfigManager = new PluginConfigManager(serverContext); 1065 1066 // If we have gotten here, then the configuration should be properly bootstrapped. 1067 synchronized (directoryServer) 1068 { 1069 isBootstrapped = true; 1070 } 1071 } 1072 1073 /** 1074 * Performs a minimal set of JMX initialization. This may be used by the core 1075 * Directory Server or by command-line tools. 1076 * 1077 * @throws InitializationException If a problem occurs while attempting to 1078 * initialize the JMX subsystem. 1079 */ 1080 public static void initializeJMX() 1081 throws InitializationException 1082 { 1083 try 1084 { 1085 // It is recommended by ManagementFactory javadoc that the platform 1086 // MBeanServer also be used to register other application managed 1087 // beans besides the platform MXBeans. Try platform MBeanServer 1088 // first. If it fails create a new, private, MBeanServer instance. 1089 try 1090 { 1091 directoryServer.mBeanServer = 1092 ManagementFactory.getPlatformMBeanServer(); 1093 } 1094 catch (Exception e) 1095 { 1096 logger.traceException(e); 1097 1098 directoryServer.mBeanServer = MBeanServerFactory.newMBeanServer(); 1099 } 1100 directoryServer.mBeans = new ConcurrentHashMap<>(); 1101 registerAlertGenerator(directoryServer); 1102 } 1103 catch (Exception e) 1104 { 1105 logger.traceException(e); 1106 1107 throw new InitializationException(ERR_CANNOT_CREATE_MBEAN_SERVER.get(e), e); 1108 } 1109 } 1110 1111 /** 1112 * Instantiates the configuration handler and loads the Directory Server 1113 * configuration. 1114 * 1115 * @param configClass The fully-qualified name of the Java class that will 1116 * serve as the configuration handler for the Directory 1117 * Server. 1118 * @param configFile The path to the file that will hold either the entire 1119 * server configuration or enough information to allow 1120 * the server to access the configuration in some other 1121 * repository. 1122 * 1123 * @throws InitializationException If a problem occurs while trying to 1124 * initialize the config handler. 1125 */ 1126 public void initializeConfiguration(String configClass, String configFile) 1127 throws InitializationException 1128 { 1129 Class<?> cfgClass; 1130 try 1131 { 1132 cfgClass = Class.forName(configClass); 1133 } 1134 catch (Exception e) 1135 { 1136 logger.traceException(e); 1137 1138 LocalizableMessage message = 1139 ERR_CANNOT_LOAD_CONFIG_HANDLER_CLASS.get( 1140 configClass, stackTraceToSingleLineString(e)); 1141 throw new InitializationException(message, e); 1142 } 1143 1144 File cfgFile = new File(configFile); 1145 1146 environmentConfig.setConfigClass(cfgClass); 1147 environmentConfig.setConfigFile(cfgFile); 1148 initializeConfiguration(); 1149 } 1150 1151 /** 1152 * Initializes this server. 1153 * <p> 1154 * Initialization involves the following steps: 1155 * <ul> 1156 * <li>Configuration</li> 1157 * <li>Schema</li> 1158 * </ul> 1159 * @throws InitializationException 1160 */ 1161 @ActivateOnceNewConfigFrameworkIsUsed("it will need adaptation to be activated before sdk schema is ready") 1162 @ActivateOnceSDKSchemaIsUsed 1163 private void initializeNG() throws InitializationException 1164 { 1165 serverManagementContext = ConfigurationBootstrapper.bootstrap(serverContext); 1166 initializeSchemaNG(); 1167 1168 // TODO : config backend should be initialized later, with the other backends 1169 //ConfigBackend configBackend = new ConfigBackend(); 1170 //configBackend.initializeConfigBackend(serverContext, configurationHandler); 1171 } 1172 1173 /** Initialize the schema of this server. */ 1174 @ActivateOnceSDKSchemaIsUsed 1175 private void initializeSchemaNG() throws InitializationException 1176 { 1177 SchemaHandler schemaHandler = new SchemaHandler(); 1178 try 1179 { 1180 schemaHandler.initialize(serverContext); 1181 } 1182 catch (org.forgerock.opendj.config.server.ConfigException e) 1183 { 1184 // TODO : fix message 1185 throw new InitializationException(LocalizableMessage.raw("Cannot initialize schema handler"), e); 1186 } 1187 } 1188 1189 /** 1190 * Instantiates the configuration handler and loads the Directory Server 1191 * configuration. 1192 * 1193 * @throws InitializationException If a problem occurs while trying to 1194 * initialize the config handler. 1195 */ 1196 public void initializeConfiguration() 1197 throws InitializationException 1198 { 1199 this.configClass = environmentConfig.getConfigClass(); 1200 this.configFile = environmentConfig.getConfigFile(); 1201 1202 // Make sure that administration framework definition classes are loaded. 1203 ClassLoaderProvider provider = ClassLoaderProvider.getInstance(); 1204 if (! provider.isEnabled()) 1205 { 1206 provider.enable(); 1207 } 1208 1209 // Load and instantiate the configuration handler class. 1210 Class<ConfigHandler> handlerClass = configClass; 1211 try 1212 { 1213 configHandler = handlerClass.newInstance(); 1214 } 1215 catch (Exception e) 1216 { 1217 logger.traceException(e); 1218 1219 LocalizableMessage message = 1220 ERR_CANNOT_INSTANTIATE_CONFIG_HANDLER.get(configClass, e.getLocalizedMessage()); 1221 throw new InitializationException(message, e); 1222 } 1223 1224 // Perform the handler-specific initialization. 1225 try 1226 { 1227 String path; 1228 try 1229 { 1230 path = configFile.getCanonicalPath(); 1231 } 1232 catch (Exception ex) 1233 { 1234 path = configFile.getAbsolutePath(); 1235 } 1236 configHandler.initializeConfigHandler(path, false); 1237 } 1238 catch (InitializationException ie) 1239 { 1240 logger.traceException(ie); 1241 1242 throw ie; 1243 } 1244 catch (Exception e) 1245 { 1246 logger.traceException(e); 1247 1248 LocalizableMessage message = 1249 ERR_CANNOT_INITIALIZE_CONFIG_HANDLER.get( 1250 configClass, configFile, e.getLocalizedMessage()); 1251 throw new InitializationException(message, e); 1252 } 1253 } 1254 1255 /** 1256 * Retrieves the path to the configuration file used to initialize the 1257 * Directory Server. 1258 * 1259 * @return The path to the configuration file used to initialize the 1260 * Directory Server. 1261 */ 1262 public static String getConfigFile() 1263 { 1264 return directoryServer.configFile.getAbsolutePath(); 1265 } 1266 1267 /** 1268 * Starts up the Directory Server. It must have already been bootstrapped 1269 * and cannot be running. 1270 * 1271 * @throws ConfigException If there is a problem with the Directory Server 1272 * configuration that prevents a critical component 1273 * from being instantiated. 1274 * 1275 * @throws InitializationException If some other problem occurs while 1276 * attempting to initialize and start the 1277 * Directory Server. 1278 */ 1279 public void startServer() 1280 throws ConfigException, InitializationException 1281 { 1282 // Checks the version - if upgrade required, cannot launch the server. 1283 try 1284 { 1285 BuildVersion.checkVersionMismatch(); 1286 } 1287 catch (InitializationException e) 1288 { 1289 logger.traceException(e); 1290 throw new InitializationException(e.getMessageObject()); 1291 } 1292 1293 synchronized (directoryServer) 1294 { 1295 if (! isBootstrapped) 1296 { 1297 LocalizableMessage message = ERR_CANNOT_START_BEFORE_BOOTSTRAP.get(); 1298 throw new InitializationException(message); 1299 } 1300 1301 if (isRunning) 1302 { 1303 LocalizableMessage message = ERR_CANNOT_START_WHILE_RUNNING.get(); 1304 throw new InitializationException(message); 1305 } 1306 1307 logger.info(NOTE_DIRECTORY_SERVER_STARTING, getVersionString(), BUILD_ID, REVISION); 1308 1309 // Acquire an exclusive lock for the Directory Server process. 1310 if (! serverLocked) 1311 { 1312 String lockFile = LockFileManager.getServerLockFileName(); 1313 try 1314 { 1315 StringBuilder failureReason = new StringBuilder(); 1316 if (! LockFileManager.acquireExclusiveLock(lockFile, failureReason)) 1317 { 1318 LocalizableMessage message = ERR_CANNOT_ACQUIRE_EXCLUSIVE_SERVER_LOCK.get( 1319 lockFile, failureReason); 1320 throw new InitializationException(message); 1321 } 1322 1323 serverLocked = true; 1324 } 1325 catch (InitializationException ie) 1326 { 1327 throw ie; 1328 } 1329 catch (Exception e) 1330 { 1331 logger.traceException(e); 1332 1333 LocalizableMessage message = ERR_CANNOT_ACQUIRE_EXCLUSIVE_SERVER_LOCK.get( 1334 lockFile, stackTraceToSingleLineString(e)); 1335 throw new InitializationException(message, e); 1336 } 1337 } 1338 1339 // Mark the current time as the start time. 1340 startUpTime = System.currentTimeMillis(); 1341 startTimeUTC = TimeThread.getGMTTime(); 1342 1343 // Determine whether or not we should start the connection handlers. 1344 boolean startConnectionHandlers = !environmentConfig.disableConnectionHandlers(); 1345 1346 diskSpaceMonitor.startDiskSpaceMonitor(); 1347 1348 initializeSchema(); 1349 1350 commonAudit = new CommonAudit(); 1351 1352 // Allow internal plugins to be registered. 1353 pluginConfigManager.initializePluginConfigManager(); 1354 1355 virtualAttributeConfigManager.initializeVirtualAttributes(); 1356 1357 // The core Directory Server configuration. 1358 coreConfigManager = new CoreConfigManager(serverContext); 1359 coreConfigManager.initializeCoreConfig(); 1360 1361 initializeCryptoManager(); 1362 1363 rotationPolicyConfigManager = new LogRotationPolicyConfigManager(serverContext); 1364 rotationPolicyConfigManager.initializeLogRotationPolicyConfig(); 1365 1366 retentionPolicyConfigManager = new LogRetentionPolicyConfigManager(serverContext); 1367 retentionPolicyConfigManager.initializeLogRetentionPolicyConfig(); 1368 1369 loggerConfigManager = new LoggerConfigManager(serverContext); 1370 loggerConfigManager.initializeLoggerConfig(); 1371 1372 RuntimeInformation.logInfo(); 1373 1374 new AlertHandlerConfigManager(serverContext).initializeAlertHandlers(); 1375 1376 // Initialize the default entry cache. We have to have one before 1377 // <CODE>initializeBackends()</CODE> method kicks in further down. 1378 entryCacheConfigManager = new EntryCacheConfigManager(serverContext); 1379 entryCacheConfigManager.initializeDefaultEntryCache(); 1380 1381 // Initialize the administration connector self signed certificate if 1382 // needed and do this before initializing the key managers so that it is 1383 // picked up. 1384 if (startConnectionHandlers) 1385 { 1386 AdministrationConnector.createSelfSignedCertificateIfNeeded(serverContext); 1387 } 1388 1389 keyManagerProviderConfigManager = new KeyManagerProviderConfigManager(serverContext); 1390 keyManagerProviderConfigManager.initializeKeyManagerProviders(); 1391 1392 trustManagerProviderConfigManager = new TrustManagerProviderConfigManager(serverContext); 1393 trustManagerProviderConfigManager.initializeTrustManagerProviders(); 1394 1395 certificateMapperConfigManager = new CertificateMapperConfigManager(serverContext); 1396 certificateMapperConfigManager.initializeCertificateMappers(); 1397 1398 identityMapperConfigManager = new IdentityMapperConfigManager(serverContext); 1399 identityMapperConfigManager.initializeIdentityMappers(); 1400 1401 initializeRootDNConfigManager(); 1402 1403 initializeAuthenticatedUsers(); 1404 // initialize both subentry manager and group manager for this backend. 1405 initializeSubentryManager(); 1406 initializeGroupManager(); 1407 1408 // Initialize both subentry manager and group manager 1409 // for the configuration backend. 1410 // TODO : why do we initialize these now ? Can't we do them after backend initialization ? 1411 subentryManager.performBackendPreInitializationProcessing(configHandler); 1412 groupManager.performBackendPreInitializationProcessing(configHandler); 1413 1414 AccessControlConfigManager.getInstance().initializeAccessControl(serverContext); 1415 1416 // Initialize all the backends and their associated suffixes 1417 // and initialize the workflows when workflow configuration mode is auto. 1418 initializeBackends(); 1419 1420 // configure the remaining workflows (rootDSE and config backend). 1421 createAndRegisterRemainingWorkflows(); 1422 1423 // Check for and initialize user configured entry cache if any. 1424 // If not then stick with default entry cache initialized earlier. 1425 entryCacheConfigManager.initializeEntryCache(); 1426 1427 initializeExtendedOperations(); 1428 initializeSASLMechanisms(); 1429 1430 if (startConnectionHandlers) 1431 { 1432 // Includes the administration connector. 1433 initializeConnectionHandlers(); 1434 } 1435 1436 monitorConfigManager = new MonitorConfigManager(serverContext); 1437 monitorConfigManager.initializeMonitorProviders(); 1438 1439 initializeAuthenticationPolicyComponents(); 1440 1441 pluginConfigManager.initializeUserPlugins(null); 1442 1443 if (!environmentConfig.disableSynchronization()) 1444 { 1445 synchronizationProviderConfigManager = new SynchronizationProviderConfigManager(serverContext); 1446 synchronizationProviderConfigManager.initializeSynchronizationProviders(); 1447 } 1448 1449 workQueue = new WorkQueueConfigManager(serverContext).initializeWorkQueue(); 1450 1451 PluginResult.Startup startupPluginResult = pluginConfigManager.invokeStartupPlugins(); 1452 if (! startupPluginResult.continueProcessing()) 1453 { 1454 throw new InitializationException(ERR_STARTUP_PLUGIN_ERROR.get(startupPluginResult.getErrorMessage(), 1455 startupPluginResult.getErrorMessage().ordinal())); 1456 } 1457 1458 for (InitializationCompletedListener listener : initializationCompletedListeners) 1459 { 1460 try 1461 { 1462 listener.initializationCompleted(); 1463 } 1464 catch (Exception e) 1465 { 1466 logger.traceException(e); 1467 } 1468 } 1469 1470 if (startConnectionHandlers) 1471 { 1472 startConnectionHandlers(); 1473 new IdleTimeLimitThread().start(); 1474 } 1475 1476 // Synchronization of ADS with the crypto manager. 1477 new CryptoManagerSync(); 1478 1479 // Write a copy of the config if needed. 1480 if (saveConfigOnSuccessfulStartup) 1481 { 1482 configHandler.writeSuccessfulStartupConfig(); 1483 } 1484 1485 isRunning = true; 1486 1487 LocalizableMessage message = NOTE_DIRECTORY_SERVER_STARTED.get(); 1488 logger.info(message); 1489 sendAlertNotification(this, ALERT_TYPE_SERVER_STARTED, message); 1490 1491 // Force the root connection to be initialized. 1492 InternalClientConnection rootConnection = InternalClientConnection.getRootConnection(); 1493 1494 if (! environmentConfig.disableAdminDataSynchronization()) 1495 { 1496 AdministrationDataSync admDataSync = new AdministrationDataSync(rootConnection); 1497 admDataSync.synchronize(); 1498 } 1499 1500 deleteUnnecessaryFiles(); 1501 } 1502 } 1503 1504 /** Delete "server.starting" and "hostname" files if they are present. */ 1505 private void deleteUnnecessaryFiles() 1506 { 1507 File serverStartingFile = new File(configHandler.getInstanceRoot() + File.separator + "logs" 1508 + File.separator + "server.starting"); 1509 if (serverStartingFile.exists()) 1510 { 1511 serverStartingFile.delete(); 1512 } 1513 1514 File hostNameFile = new File(configHandler.getInstanceRoot() + File.separator + SetupUtils.HOST_NAME_FILE); 1515 if (hostNameFile.exists()) 1516 { 1517 hostNameFile.delete(); 1518 } 1519 } 1520 1521 /** Initializes authenticated users. */ 1522 public void initializeAuthenticatedUsers() 1523 { 1524 directoryServer.authenticatedUsers = new AuthenticatedUsers(); 1525 } 1526 1527 /** 1528 * Registers a basic set of matching rules with the server that should always 1529 * be available regardless of the server configuration and may be needed for 1530 * configuration processing. 1531 */ 1532 private void bootstrapMatchingRules() 1533 { 1534 MatchingRuleFactory<?>[] factories = 1535 new MatchingRuleFactory<?>[] { 1536 new DoubleMetaphoneApproximateMatchingRuleFactory(), 1537 new BooleanEqualityMatchingRuleFactory(), 1538 new CaseExactEqualityMatchingRuleFactory(), 1539 new CaseExactIA5EqualityMatchingRuleFactory(), 1540 new CaseIgnoreEqualityMatchingRuleFactory(), 1541 new CaseIgnoreIA5EqualityMatchingRuleFactory(), 1542 new DistinguishedNameEqualityMatchingRuleFactory(), 1543 new GeneralizedTimeEqualityMatchingRuleFactory(), 1544 new IntegerEqualityMatchingRuleFactory(), 1545 new OctetStringEqualityMatchingRuleFactory(), 1546 new ObjectIdentifierEqualityMatchingRuleFactory(), 1547 new TelephoneNumberEqualityMatchingRuleFactory(), 1548 new CaseExactOrderingMatchingRuleFactory(), 1549 new CaseIgnoreOrderingMatchingRuleFactory(), 1550 new GeneralizedTimeOrderingMatchingRuleFactory(), 1551 new IntegerOrderingMatchingRuleFactory(), 1552 new OctetStringOrderingMatchingRuleFactory(), 1553 new CaseExactSubstringMatchingRuleFactory(), 1554 new CaseExactIA5SubstringMatchingRuleFactory(), 1555 new CaseIgnoreSubstringMatchingRuleFactory(), 1556 new CaseIgnoreIA5SubstringMatchingRuleFactory(), 1557 new OctetStringSubstringMatchingRuleFactory(), 1558 new TelephoneNumberSubstringMatchingRuleFactory()}; 1559 1560 MatchingRuleFactory<?> currentFactory = null; 1561 try 1562 { 1563 for(MatchingRuleFactory<?> factory: factories) 1564 { 1565 currentFactory = factory; 1566 currentFactory.initializeMatchingRule(null); 1567 for(MatchingRule matchingRule: currentFactory.getMatchingRules()) 1568 { 1569 registerMatchingRule(matchingRule, true); 1570 } 1571 } 1572 } 1573 catch (Exception e) 1574 { 1575 logger.traceException(e); 1576 1577 logger.error(ERR_CANNOT_BOOTSTRAP_MATCHING_RULE, currentFactory.getClass().getName(), 1578 stackTraceToSingleLineString(e)); 1579 } 1580 } 1581 1582 /** 1583 * Registers a basic set of attribute syntaxes with the server that should 1584 * always be available regardless of the server configuration and may be 1585 * needed for configuration processing. 1586 */ 1587 private void bootstrapAttributeSyntaxes() 1588 { 1589 schema.registerDefaultSyntax(getDefaultSyntax()); 1590 1591 Syntax[] syntaxes = { 1592 getDefaultBinarySyntax(), 1593 getDefaultBooleanSyntax(), 1594 getDefaultStringSyntax(), 1595 getDefaultDNSyntax(), 1596 getDefaultIntegerSyntax(), 1597 CoreSchema.getAttributeTypeDescriptionSyntax(), 1598 CoreSchema.getIA5StringSyntax(), 1599 CoreSchema.getGeneralizedTimeSyntax(), 1600 CoreSchema.getObjectClassDescriptionSyntax(), 1601 CoreSchema.getOIDSyntax(), 1602 CoreSchema.getTelephoneNumberSyntax() 1603 }; 1604 for (Syntax syntax : syntaxes) 1605 { 1606 registerSyntax(syntax); 1607 } 1608 } 1609 1610 private Syntax registerSyntax(Syntax syntax) 1611 { 1612 try 1613 { 1614 schema.registerSyntax(syntax, true); 1615 } 1616 catch (Exception e) 1617 { 1618 logger.error(ERR_CANNOT_BOOTSTRAP_SYNTAX, syntax.getClass().getName(), stackTraceToSingleLineString(e)); 1619 } 1620 return syntax; 1621 } 1622 1623 /** 1624 * Retrieves the authenticated users manager for the Directory Server. 1625 * 1626 * @return The authenticated users manager for the Directory Server. 1627 */ 1628 public static AuthenticatedUsers getAuthenticatedUsers() 1629 { 1630 return directoryServer.authenticatedUsers; 1631 } 1632 1633 /** 1634 * Initializes the crypto manager for the Directory Server. 1635 * 1636 * @throws ConfigException 1637 * If a configuration problem is identified while initializing the 1638 * crypto manager. 1639 * @throws InitializationException 1640 * If a problem occurs while initializing the crypto manager that is 1641 * not related to the server configuration. 1642 */ 1643 public void initializeCryptoManager() 1644 throws ConfigException, InitializationException 1645 { 1646 RootCfg root = 1647 ServerManagementContext.getInstance().getRootConfiguration(); 1648 CryptoManagerCfg cryptoManagerCfg = root.getCryptoManager(); 1649 cryptoManager = new CryptoManagerImpl(serverContext, cryptoManagerCfg); 1650 } 1651 1652 /** 1653 * Retrieves a reference to the Directory Server crypto manager. 1654 * 1655 * @return A reference to the Directory Server crypto manager. 1656 */ 1657 public static CryptoManagerImpl getCryptoManager() 1658 { 1659 return directoryServer.cryptoManager; 1660 } 1661 1662 /** 1663 * Indicates whether the Directory Server is configured with information about 1664 * one or more mail servers and may therefore be used to send e-mail messages. 1665 * 1666 * @return {@code true} if the Directory Server is configured to be able to 1667 * send e-mail messages, or {@code false} if not. 1668 */ 1669 public static boolean mailServerConfigured() 1670 { 1671 return directoryServer.mailServerPropertySets != null 1672 && !directoryServer.mailServerPropertySets.isEmpty(); 1673 } 1674 1675 /** 1676 * Specifies the set of mail server properties that should be used for SMTP 1677 * communication. 1678 * 1679 * @param mailServerPropertySets A list of {@code Properties} objects that 1680 * provide information that can be used to 1681 * communicate with SMTP servers. 1682 */ 1683 public static void setMailServerPropertySets(List<Properties> 1684 mailServerPropertySets) 1685 { 1686 directoryServer.mailServerPropertySets = mailServerPropertySets; 1687 } 1688 1689 /** 1690 * Retrieves the sets of information about the mail servers configured for use 1691 * by the Directory Server. 1692 * 1693 * @return The sets of information about the mail servers configured for use 1694 * by the Directory Server. 1695 */ 1696 public static List<Properties> getMailServerPropertySets() 1697 { 1698 return directoryServer.mailServerPropertySets; 1699 } 1700 1701 /** 1702 * Initializes the schema elements for the Directory Server, including the 1703 * matching rules, attribute syntaxes, attribute types, and object classes. 1704 * 1705 * @throws ConfigException If there is a configuration problem with any of 1706 * the schema elements. 1707 * 1708 * @throws InitializationException If a problem occurs while initializing 1709 * the schema elements that is not related 1710 * to the server configuration. 1711 */ 1712 public void initializeSchema() 1713 throws ConfigException, InitializationException 1714 { 1715 // Create the schema configuration manager, and initialize the schema from 1716 // the configuration. 1717 schemaConfigManager = new SchemaConfigManager(serverContext); 1718 schema = schemaConfigManager.getSchema(); 1719 1720 schemaConfigManager.initializeMatchingRules(); 1721 schemaConfigManager.initializeAttributeSyntaxes(); 1722 schemaConfigManager.initializeSchemaFromFiles(); 1723 1724 // With server schema in place set compressed schema. 1725 compressedSchema = new DefaultCompressedSchema(); 1726 1727 // At this point we have a problem, because none of the configuration is 1728 // usable because it was all read before we had a schema (and therefore all 1729 // of the attribute types and objectclasses are bogus and won't let us find 1730 // anything). So we have to re-read the configuration so that we can 1731 // continue the necessary startup process. In the process, we want to 1732 // preserve any configuration add/delete/change listeners that might have 1733 // been registered with the old configuration (which will primarily be 1734 // schema elements) so they can be re-registered with the new configuration. 1735 Map<String, List<ConfigAddListener>> addListeners = new LinkedHashMap<>(); 1736 Map<String, List<ConfigDeleteListener>> deleteListeners = new LinkedHashMap<>(); 1737 Map<String, List<ConfigChangeListener>> changeListeners = new LinkedHashMap<>(); 1738 getChangeListeners(configHandler.getConfigRootEntry(), addListeners, 1739 deleteListeners, changeListeners); 1740 1741 try 1742 { 1743 configHandler.finalizeConfigHandler(); 1744 } 1745 catch (Exception e) 1746 { 1747 logger.traceException(e); 1748 } 1749 1750 try 1751 { 1752 configHandler.initializeConfigHandler(configFile.getAbsolutePath(), true); 1753 } 1754 catch (InitializationException ie) 1755 { 1756 logger.traceException(ie); 1757 1758 throw ie; 1759 } 1760 catch (Exception e) 1761 { 1762 logger.traceException(e); 1763 1764 throw new InitializationException(ERR_CANNOT_INITIALIZE_CONFIG_HANDLER.get( 1765 configClass, configFile, e.getLocalizedMessage())); 1766 } 1767 1768 // Re-register all of the change listeners with the configuration. 1769 for (String dnStr : addListeners.keySet()) 1770 { 1771 try 1772 { 1773 DN dn = DN.valueOf(dnStr); 1774 for (ConfigAddListener listener : addListeners.get(dnStr)) 1775 { 1776 configHandler.getConfigEntry(dn).registerAddListener(listener); 1777 } 1778 } 1779 catch (DirectoryException de) 1780 { 1781 // This should never happen, so we'll just re-throw it. 1782 throw new InitializationException(de.getMessageObject()); 1783 } 1784 } 1785 1786 for (String dnStr : deleteListeners.keySet()) 1787 { 1788 try 1789 { 1790 DN dn = DN.valueOf(dnStr); 1791 for (ConfigDeleteListener listener : deleteListeners.get(dnStr)) 1792 { 1793 configHandler.getConfigEntry(dn).registerDeleteListener(listener); 1794 } 1795 } 1796 catch (DirectoryException de) 1797 { 1798 // This should never happen, so we'll just re-throw it. 1799 throw new InitializationException(de.getMessageObject()); 1800 } 1801 } 1802 1803 for (String dnStr : changeListeners.keySet()) 1804 { 1805 try 1806 { 1807 DN dn = DN.valueOf(dnStr); 1808 for (ConfigChangeListener listener : changeListeners.get(dnStr)) 1809 { 1810 configHandler.getConfigEntry(dn).registerChangeListener(listener); 1811 } 1812 } 1813 catch (DirectoryException de) 1814 { 1815 // This should never happen, so we'll just re-throw it. 1816 throw new InitializationException(de.getMessageObject()); 1817 } 1818 } 1819 } 1820 1821 /** 1822 * Retrieves the default compressed schema manager for the Directory Server. 1823 * 1824 * @return The default compressed schema manager for the Directory Server. 1825 */ 1826 public static CompressedSchema getDefaultCompressedSchema() 1827 { 1828 return directoryServer.compressedSchema; 1829 } 1830 1831 /** 1832 * Gets all of the add, delete, and change listeners from the provided 1833 * configuration entry and all of its descendants and puts them in the 1834 * appropriate lists. 1835 * 1836 * @param configEntry The configuration entry to be processed, along 1837 * with all of its descendants. 1838 * @param addListeners The set of add listeners mapped to the DN of the 1839 * corresponding configuration entry. 1840 * @param deleteListeners The set of delete listeners mapped to the DN of 1841 * the corresponding configuration entry. 1842 * @param changeListeners The set of change listeners mapped to the DN of 1843 * the corresponding configuration entry. 1844 */ 1845 private void getChangeListeners(ConfigEntry configEntry, 1846 Map<String, List<ConfigAddListener>> addListeners, 1847 Map<String, List<ConfigDeleteListener>> deleteListeners, 1848 Map<String, List<ConfigChangeListener>> changeListeners) 1849 { 1850 put(addListeners, configEntry, configEntry.getAddListeners()); 1851 put(deleteListeners, configEntry, configEntry.getDeleteListeners()); 1852 put(changeListeners, configEntry, configEntry.getChangeListeners()); 1853 1854 for (ConfigEntry child : configEntry.getChildren().values()) 1855 { 1856 getChangeListeners(child, addListeners, deleteListeners, changeListeners); 1857 } 1858 } 1859 1860 private <T> void put(Map<String, List<T>> listeners, ConfigEntry configEntry, List<T> cfgListeners) 1861 { 1862 if (cfgListeners != null && !cfgListeners.isEmpty()) 1863 { 1864 listeners.put(configEntry.getDN().toString(), cfgListeners); 1865 } 1866 } 1867 1868 /** 1869 * Retrieves the set of backend initialization listeners that have been 1870 * registered with the Directory Server. The contents of the returned set 1871 * must not be altered. 1872 * 1873 * @return The set of backend initialization listeners that have been 1874 * registered with the Directory Server. 1875 */ 1876 public static Set<BackendInitializationListener> 1877 getBackendInitializationListeners() 1878 { 1879 return directoryServer.backendInitializationListeners; 1880 } 1881 1882 /** 1883 * Registers the provided backend initialization listener with the Directory 1884 * Server. 1885 * 1886 * @param listener The backend initialization listener to register with the 1887 * Directory Server. 1888 */ 1889 public static void registerBackendInitializationListener( 1890 BackendInitializationListener listener) 1891 { 1892 directoryServer.backendInitializationListeners.add(listener); 1893 } 1894 1895 /** 1896 * Deregisters the provided backend initialization listener with the Directory 1897 * Server. 1898 * 1899 * @param listener The backend initialization listener to deregister with 1900 * the Directory Server. 1901 */ 1902 public static void deregisterBackendInitializationListener( 1903 BackendInitializationListener listener) 1904 { 1905 directoryServer.backendInitializationListeners.remove(listener); 1906 } 1907 1908 /** 1909 * Initializes the set of backends defined in the Directory Server. 1910 * 1911 * @throws ConfigException If there is a configuration problem with any of 1912 * the backends. 1913 * 1914 * @throws InitializationException If a problem occurs while initializing 1915 * the backends that is not related to the 1916 * server configuration. 1917 */ 1918 private void initializeBackends() throws ConfigException, InitializationException 1919 { 1920 backendConfigManager = new BackendConfigManager(serverContext); 1921 backendConfigManager.initializeBackendConfig(); 1922 1923 // Make sure to initialize the root DSE backend separately after all other 1924 // backends. 1925 RootDSEBackendCfg rootDSECfg; 1926 try 1927 { 1928 RootCfg root = ServerManagementContext.getInstance().getRootConfiguration(); 1929 rootDSECfg = root.getRootDSEBackend(); 1930 } 1931 catch (Exception e) 1932 { 1933 logger.traceException(e); 1934 throw new InitializationException(ERR_CANNOT_GET_ROOT_DSE_CONFIG_ENTRY.get( 1935 stackTraceToSingleLineString(e)), e); 1936 } 1937 1938 rootDSEBackend = new RootDSEBackend(); 1939 rootDSEBackend.configureBackend(rootDSECfg, serverContext); 1940 rootDSEBackend.openBackend(); 1941 } 1942 1943 /** 1944 * Creates a set of workflows for a given backend and registers the 1945 * workflows with the default network group, the internal network group 1946 * and he admin network group. There are as many workflows 1947 * as base DNs defined in the backend. 1948 * 1949 * @param backend the backend handled by the workflow 1950 * 1951 * @throws DirectoryException If the workflow ID for the provided 1952 * workflow conflicts with the workflow 1953 * ID of an existing workflow. 1954 */ 1955 private static void createAndRegisterWorkflows(Backend<?> backend) throws DirectoryException 1956 { 1957 // Create a workflow for each backend base DN and register the workflow 1958 // with the default/internal/admin network group. 1959 for (DN curBaseDN: backend.getBaseDNs()) 1960 { 1961 createWorkflow(curBaseDN, backend); 1962 } 1963 } 1964 1965 /** 1966 * Creates one workflow for a given base DN in a backend. 1967 * 1968 * @param baseDN the base DN of the workflow to create 1969 * @param backend the backend handled by the workflow 1970 * @throws DirectoryException If the workflow ID for the provided 1971 * workflow conflicts with the workflow 1972 * ID of an existing workflow. 1973 */ 1974 private static void createWorkflow(DN baseDN, Backend<?> backend) throws DirectoryException 1975 { 1976 LocalBackendWorkflowElement.createAndRegister(baseDN, backend); 1977 } 1978 1979 /** 1980 * Creates the missing workflows, one for the config backend and one for 1981 * the rootDSE backend. 1982 * 1983 * This method should be invoked whatever may be the workflow 1984 * configuration mode because config backend and rootDSE backend 1985 * will not have any configuration section, ever. 1986 * 1987 * @throws ConfigException If there is a configuration problem with any of 1988 * the workflows. 1989 */ 1990 private void createAndRegisterRemainingWorkflows() 1991 throws ConfigException 1992 { 1993 try 1994 { 1995 createAndRegisterWorkflows(configHandler); 1996 createAndRegisterWorkflows(rootDSEBackend); 1997 } 1998 catch (DirectoryException de) 1999 { 2000 throw new ConfigException(de.getMessageObject()); 2001 } 2002 } 2003 2004 /** 2005 * Initializes the Directory Server group manager. 2006 * 2007 * @throws ConfigException If there is a configuration problem with any of 2008 * the group implementations. 2009 * 2010 * @throws InitializationException If a problem occurs while initializing 2011 * the group manager that is not related to 2012 * the server configuration. 2013 */ 2014 private void initializeGroupManager() 2015 throws ConfigException, InitializationException 2016 { 2017 try 2018 { 2019 groupManager = new GroupManager(serverContext); 2020 } 2021 catch (DirectoryException de) 2022 { 2023 logger.traceException(de); 2024 2025 throw new InitializationException(de.getMessageObject()); 2026 } 2027 2028 groupManager.initializeGroupImplementations(); 2029 2030 // The configuration backend has already been registered by this point 2031 // so we need to handle it explicitly. 2032 // Because subentryManager may depend on the groupManager, let's 2033 // delay this. 2034 // groupManager.performBackendPreInitializationProcessing(configHandler); 2035 } 2036 2037 /** 2038 * Retrieves the Directory Server group manager. 2039 * 2040 * @return The Directory Server group manager. 2041 */ 2042 public static GroupManager getGroupManager() 2043 { 2044 return directoryServer.groupManager; 2045 } 2046 2047 /** 2048 * Retrieves the Directory Server subentry manager. 2049 * 2050 * @return The Directory Server subentry manager. 2051 */ 2052 public static SubentryManager getSubentryManager() 2053 { 2054 return directoryServer.subentryManager; 2055 } 2056 2057 /** 2058 * Initializes the set of extended operation handlers for the Directory 2059 * Server. 2060 * 2061 * @throws ConfigException If there is a configuration problem with any of 2062 * the extended operation handlers. 2063 * 2064 * @throws InitializationException If a problem occurs while initializing 2065 * the extended operation handlers that is 2066 * not related to the server configuration. 2067 */ 2068 private void initializeExtendedOperations() 2069 throws ConfigException, InitializationException 2070 { 2071 extendedOperationConfigManager = new ExtendedOperationConfigManager(serverContext); 2072 extendedOperationConfigManager.initializeExtendedOperationHandlers(); 2073 } 2074 2075 /** 2076 * Initializes the set of SASL mechanism handlers for the Directory Server. 2077 * 2078 * @throws ConfigException If there is a configuration problem with any of 2079 * the SASL mechanism handlers. 2080 * 2081 * @throws InitializationException If a problem occurs while initializing 2082 * the SASL mechanism handlers that is not 2083 * related to the server configuration. 2084 */ 2085 private void initializeSASLMechanisms() 2086 throws ConfigException, InitializationException 2087 { 2088 saslConfigManager = new SASLConfigManager(serverContext); 2089 saslConfigManager.initializeSASLMechanismHandlers(); 2090 } 2091 2092 /** 2093 * Initializes the set of connection handlers that should be defined in the 2094 * Directory Server. 2095 * 2096 * @throws ConfigException If there is a configuration problem with any of 2097 * the connection handlers. 2098 * 2099 * @throws InitializationException If a problem occurs while initializing 2100 * the connection handlers that is not 2101 * related to the server configuration. 2102 */ 2103 private void initializeConnectionHandlers() 2104 throws ConfigException, InitializationException 2105 { 2106 if (connectionHandlerConfigManager == null) { 2107 connectionHandlerConfigManager = new ConnectionHandlerConfigManager(serverContext); 2108 } 2109 connectionHandlerConfigManager.initializeConnectionHandlerConfig(); 2110 } 2111 2112 /** 2113 * Initializes the subentry manager for the Directory Server. 2114 * Note that the subentry manager initialization should be 2115 * done before any dependent components initialization and 2116 * before bringing any backends online. Configuration backend 2117 * is a special case and therefore is exception to this rule. 2118 * 2119 * @throws InitializationException If a problem occurs while 2120 * initializing the subentry 2121 * manager. 2122 */ 2123 public void initializeSubentryManager() 2124 throws InitializationException 2125 { 2126 try 2127 { 2128 subentryManager = new SubentryManager(); 2129 2130 // The configuration backend should already be registered 2131 // at this point so we need to handle it explicitly here. 2132 // However, subentryManager may have dependencies on the 2133 // groupManager. So lets delay the backend initialization until then. 2134 // subentryManager.performBackendPreInitializationProcessing( 2135 // configHandler); 2136 } 2137 catch (DirectoryException de) 2138 { 2139 throw new InitializationException(de.getMessageObject()); 2140 } 2141 } 2142 2143 /** 2144 * Initializes the set of authentication policy components for use by the 2145 * Directory Server. 2146 * 2147 * @throws ConfigException 2148 * If there is a configuration problem with any of the 2149 * authentication policy components. 2150 * @throws InitializationException 2151 * If a problem occurs while initializing the authentication policy 2152 * components that is not related to the server configuration. 2153 */ 2154 public void initializeAuthenticationPolicyComponents() throws ConfigException, InitializationException 2155 { 2156 storageSchemeConfigManager = new PasswordStorageSchemeConfigManager(serverContext); 2157 storageSchemeConfigManager.initializePasswordStorageSchemes(); 2158 2159 passwordValidatorConfigManager = new PasswordValidatorConfigManager(serverContext); 2160 passwordValidatorConfigManager.initializePasswordValidators(); 2161 2162 passwordGeneratorConfigManager = new PasswordGeneratorConfigManager(serverContext); 2163 passwordGeneratorConfigManager.initializePasswordGenerators(); 2164 2165 accountStatusNotificationHandlerConfigManager = new AccountStatusNotificationHandlerConfigManager(serverContext); 2166 accountStatusNotificationHandlerConfigManager.initializeNotificationHandlers(); 2167 2168 authenticationPolicyConfigManager = new PasswordPolicyConfigManager(serverContext); 2169 authenticationPolicyConfigManager.initializeAuthenticationPolicies(); 2170 } 2171 2172 /** 2173 * Retrieves the operating system on which the Directory Server is running. 2174 * 2175 * @return The operating system on which the Directory Server is running. 2176 */ 2177 public static OperatingSystem getOperatingSystem() 2178 { 2179 return directoryServer.operatingSystem; 2180 } 2181 2182 /** 2183 * Retrieves a reference to the Directory Server configuration handler. 2184 * 2185 * @return A reference to the Directory Server configuration handler. 2186 */ 2187 public static ConfigHandler getConfigHandler() 2188 { 2189 return directoryServer.configHandler; 2190 } 2191 2192 /** 2193 * Initializes the set of plugins defined in the Directory Server. Only the 2194 * specified types of plugins will be initialized. 2195 * 2196 * @param pluginTypes The set of plugin types for the plugins to 2197 * initialize. 2198 * 2199 * @throws ConfigException If there is a configuration problem with any of 2200 * the Directory Server plugins. 2201 * 2202 * @throws InitializationException If a problem occurs while initializing 2203 * the plugins that is not related to the 2204 * server configuration. 2205 */ 2206 public void initializePlugins(Set<PluginType> pluginTypes) 2207 throws ConfigException, InitializationException 2208 { 2209 pluginConfigManager = new PluginConfigManager(serverContext); 2210 pluginConfigManager.initializePluginConfigManager(); 2211 pluginConfigManager.initializeUserPlugins(pluginTypes); 2212 } 2213 2214 /** 2215 * Initializes the root DN Config Manager in the Directory Server. 2216 * 2217 * @throws ConfigException If a problem occurs registering a DN. 2218 * @throws InitializationException If a problem occurs initializing the root 2219 * DN manager. 2220 */ 2221 public void initializeRootDNConfigManager() 2222 throws ConfigException, InitializationException{ 2223 rootDNConfigManager = new RootDNConfigManager(serverContext); 2224 rootDNConfigManager.initializeRootDNs(); 2225 } 2226 2227 /** 2228 * Initialize the root DSE in the Directory Server. 2229 * 2230 * @throws ConfigException If a problem occurs retrieving the root DSE backend 2231 * configuration. 2232 * @throws InitializationException If a problem occurs initializing the root 2233 * root DSE backend. 2234 */ 2235 public void initializeRootDSE() 2236 throws ConfigException, InitializationException { 2237 RootDSEBackendCfg rootDSECfg; 2238 try { 2239 RootCfg root = 2240 ServerManagementContext.getInstance().getRootConfiguration(); 2241 rootDSECfg = root.getRootDSEBackend(); 2242 } catch (Exception e) { 2243 logger.traceException(e); 2244 LocalizableMessage message = ERR_CANNOT_GET_ROOT_DSE_CONFIG_ENTRY.get( 2245 stackTraceToSingleLineString(e)); 2246 throw new InitializationException(message, e); 2247 } 2248 rootDSEBackend = new RootDSEBackend(); 2249 rootDSEBackend.configureBackend(rootDSECfg, serverContext); 2250 rootDSEBackend.openBackend(); 2251} 2252 2253 /** 2254 * Retrieves a reference to the Directory Server plugin configuration manager. 2255 * 2256 * @return A reference to the Directory Server plugin configuration manager. 2257 */ 2258 public static PluginConfigManager getPluginConfigManager() 2259 { 2260 return directoryServer.pluginConfigManager; 2261 } 2262 2263 /** 2264 * Registers the provided internal plugin with the Directory Server 2265 * and ensures that it will be invoked in the specified ways. 2266 * 2267 * @param plugin 2268 * The internal plugin to register with the Directory Server. 2269 * The plugin must specify a configuration entry which is 2270 * guaranteed to be unique. 2271 */ 2272 public static void registerInternalPlugin( 2273 InternalDirectoryServerPlugin plugin) 2274 { 2275 directoryServer.pluginConfigManager.registerInternalPlugin(plugin); 2276 } 2277 2278 /** 2279 * Deregisters the provided internal plugin with the Directory Server. 2280 * 2281 * @param plugin 2282 * The internal plugin to deregister from the Directory Server. 2283 */ 2284 public static void deregisterInternalPlugin( 2285 InternalDirectoryServerPlugin plugin) 2286 { 2287 directoryServer.pluginConfigManager.deregisterInternalPlugin(plugin); 2288 } 2289 2290 /** 2291 * Retrieves the requested entry from the Directory Server configuration. 2292 * 2293 * @param entryDN The DN of the configuration entry to retrieve. 2294 * 2295 * @return The requested entry from the Directory Server configuration. 2296 * 2297 * @throws ConfigException If a problem occurs while trying to retrieve the 2298 * requested entry. 2299 */ 2300 public static ConfigEntry getConfigEntry(DN entryDN) 2301 throws ConfigException 2302 { 2303 return directoryServer.configHandler.getConfigEntry(entryDN); 2304 } 2305 2306 /** 2307 * Retrieves the path to the root directory for this instance of the Directory 2308 * Server. 2309 * 2310 * @return The path to the root directory for this instance of the Directory 2311 * Server. 2312 */ 2313 public static String getServerRoot() 2314 { 2315 return directoryServer.environmentConfig.getServerRootAsString(); 2316 } 2317 2318 /** 2319 * Retrieves the path to the instance directory for this instance of the 2320 * Directory Server. 2321 * 2322 * @return The path to the instance directory for this instance of 2323 * the Directory Server. 2324 */ 2325 public static String getInstanceRoot() 2326 { 2327 return directoryServer.environmentConfig.getInstanceRootAsString(); 2328 } 2329 2330 /** 2331 * Retrieves the time that the Directory Server was started, in milliseconds 2332 * since the epoch. 2333 * 2334 * @return The time that the Directory Server was started, in milliseconds 2335 * since the epoch. 2336 */ 2337 public static long getStartTime() 2338 { 2339 return directoryServer.startUpTime; 2340 } 2341 2342 /** 2343 * Retrieves the time that the Directory Server was started, formatted in UTC. 2344 * 2345 * @return The time that the Directory Server was started, formatted in UTC. 2346 */ 2347 public static String getStartTimeUTC() 2348 { 2349 return directoryServer.startTimeUTC; 2350 } 2351 2352 /** 2353 * Retrieves a reference to the Directory Server schema. 2354 * 2355 * @return A reference to the Directory Server schema. 2356 */ 2357 public static Schema getSchema() 2358 { 2359 return directoryServer.schema; 2360 } 2361 2362 /** 2363 * Replaces the Directory Server schema with the provided schema. 2364 * 2365 * @param schema The new schema to use for the Directory Server. 2366 */ 2367 public static void setSchema(Schema schema) 2368 { 2369 directoryServer.schema = schema; 2370 } 2371 2372 /** 2373 * Retrieves a list of modifications detailing any schema changes that may 2374 * have been made with the server offline (e.g., by directly editing the 2375 * schema configuration files). Note that this information will not be 2376 * available until the server backends (and in particular, the schema backend) 2377 * have been initialized. 2378 * 2379 * @return A list of modifications detailing any schema changes that may have 2380 * been made with the server offline, or an empty list if no offline 2381 * schema changes have been detected. 2382 */ 2383 public static List<Modification> getOfflineSchemaChanges() 2384 { 2385 return directoryServer.offlineSchemaChanges; 2386 } 2387 2388 /** 2389 * Specifies a list of modifications detailing any schema changes that may 2390 * have been made with the server offline. 2391 * 2392 * @param offlineSchemaChanges A list of modifications detailing any schema 2393 * changes that may have been made with the 2394 * server offline. It must not be {@code null}. 2395 */ 2396 public static void setOfflineSchemaChanges(List<Modification> 2397 offlineSchemaChanges) 2398 { 2399 ifNull(offlineSchemaChanges); 2400 2401 directoryServer.offlineSchemaChanges = offlineSchemaChanges; 2402 } 2403 2404 /** 2405 * Retrieves the set of matching rules registered with the Directory Server. 2406 * The mapping will be between the lowercase name or OID for each matching 2407 * rule and the matching rule implementation. The same matching rule instance 2408 * may be included multiple times with different keys. 2409 * 2410 * @return The set of matching rules registered with the Directory Server. 2411 */ 2412 public static ConcurrentMap<String, MatchingRule> getMatchingRules() 2413 { 2414 return directoryServer.schema.getMatchingRules(); 2415 } 2416 2417 /** 2418 * Retrieves the matching rule with the specified name or OID. 2419 * 2420 * @param lowerName The lowercase name or OID for the matching rule to 2421 * retrieve. 2422 * 2423 * @return The requested matching rule, or <CODE>null</CODE> if no such 2424 * matching rule has been defined in the server. 2425 */ 2426 public static MatchingRule getMatchingRule(String lowerName) 2427 { 2428 return directoryServer.schema.getMatchingRule(lowerName); 2429 } 2430 2431 /** 2432 * Registers the provided matching rule with the Directory Server. 2433 * 2434 * @param matchingRule The matching rule to register with the server. 2435 * @param overwriteExisting Indicates whether to overwrite an existing 2436 * mapping if there are any conflicts (i.e., 2437 * another matching rule with the same OID or 2438 * name). 2439 * 2440 * @throws DirectoryException If a conflict is encountered and the 2441 * <CODE>overwriteExisting</CODE> flag is set to 2442 * <CODE>false</CODE> 2443 */ 2444 public static void registerMatchingRule(MatchingRule matchingRule, 2445 boolean overwriteExisting) 2446 throws DirectoryException 2447 { 2448 directoryServer.schema.registerMatchingRule(matchingRule, 2449 overwriteExisting); 2450 } 2451 2452 /** 2453 * Deregisters the provided matching rule with the Directory Server. 2454 * 2455 * @param matchingRule The matching rule to deregister with the server. 2456 */ 2457 public static void deregisterMatchingRule(MatchingRule matchingRule) 2458 { 2459 directoryServer.schema.deregisterMatchingRule(matchingRule); 2460 } 2461 2462 /** 2463 * Retrieves the set of objectclasses defined in the Directory Server. 2464 * 2465 * @return The set of objectclasses defined in the Directory Server. 2466 */ 2467 public static ConcurrentMap<String, ObjectClass> getObjectClasses() 2468 { 2469 return directoryServer.schema.getObjectClasses(); 2470 } 2471 2472 /** 2473 * Retrieves the objectclass for the provided lowercase name or OID. 2474 * 2475 * @param lowerName The lowercase name or OID for the objectclass to 2476 * retrieve. 2477 * 2478 * @return The requested objectclass, or <CODE>null</CODE> if there is no 2479 * such objectclass defined in the server schema. 2480 */ 2481 public static ObjectClass getObjectClass(String lowerName) 2482 { 2483 return directoryServer.schema.getObjectClass(lowerName); 2484 } 2485 2486 /** 2487 * Retrieves the objectclass for the provided lowercase name or OID. It can 2488 * optionally return a generated "default" version if the requested 2489 * objectclass is not defined in the schema. 2490 * 2491 * @param lowerName The lowercase name or OID for the objectclass to 2492 * retrieve. 2493 * @param returnDefault Indicates whether to generate a default version if 2494 * the requested objectclass is not defined in the 2495 * server schema. 2496 * 2497 * @return The objectclass type, or <CODE>null</CODE> if there is no 2498 * objectclass with the specified name or OID defined in the server 2499 * schema and a default class should not be returned. 2500 */ 2501 public static ObjectClass getObjectClass(String lowerName, 2502 boolean returnDefault) 2503 { 2504 ObjectClass oc = directoryServer.schema.getObjectClass(lowerName); 2505 if (returnDefault && oc == null) 2506 { 2507 oc = getDefaultObjectClass(lowerName); 2508 } 2509 2510 return oc; 2511 } 2512 2513 /** 2514 * Registers the provided objectclass with the Directory Server. 2515 * 2516 * @param objectClass The objectclass instance to register with the 2517 * server. 2518 * @param overwriteExisting Indicates whether to overwrite an existing 2519 * mapping if there are any conflicts (i.e., 2520 * another objectclass with the same OID or 2521 * name). 2522 * 2523 * @throws DirectoryException If a conflict is encountered and the 2524 * <CODE>overwriteExisting</CODE> flag is set to 2525 * <CODE>false</CODE> 2526 */ 2527 public static void registerObjectClass(ObjectClass objectClass, 2528 boolean overwriteExisting) 2529 throws DirectoryException 2530 { 2531 directoryServer.schema.registerObjectClass(objectClass, overwriteExisting); 2532 } 2533 2534 /** 2535 * Deregisters the provided objectclass with the Directory Server. 2536 * 2537 * @param objectClass The objectclass instance to deregister with the 2538 * server. 2539 */ 2540 public static void deregisterObjectClass(ObjectClass objectClass) 2541 { 2542 directoryServer.schema.deregisterObjectClass(objectClass); 2543 } 2544 2545 /** 2546 * Retrieves the "top" objectClass, which should be the topmost objectclass in 2547 * the inheritance chain for most other objectclasses. If no such objectclass 2548 * could be found, then one will be constructed. 2549 * 2550 * @return The "top" objectClass. 2551 */ 2552 public static ObjectClass getTopObjectClass() 2553 { 2554 ObjectClass objectClass = 2555 directoryServer.schema.getObjectClass(TOP_OBJECTCLASS_NAME); 2556 if (objectClass == null) 2557 { 2558 String definition = 2559 "( 2.5.6.0 NAME 'top' ABSTRACT MUST objectClass " + 2560 "X-ORIGIN 'RFC 2256' )"; 2561 2562 objectClass = new ObjectClass(definition, TOP_OBJECTCLASS_NAME, 2563 Collections.singleton(TOP_OBJECTCLASS_NAME), 2564 TOP_OBJECTCLASS_OID, 2565 TOP_OBJECTCLASS_DESCRIPTION, null, null, 2566 null, ObjectClassType.ABSTRACT, false, 2567 null); 2568 } 2569 2570 return objectClass; 2571 } 2572 2573 /** 2574 * Causes the Directory Server to construct a new objectclass 2575 * definition with the provided name and with no required or allowed 2576 * attributes. This should only be used if there is no objectclass 2577 * for the specified name. It will not register the created 2578 * objectclass with the Directory Server. 2579 * 2580 * @param name 2581 * The name to use for the objectclass, as provided by the 2582 * user. 2583 * @return The constructed objectclass definition. 2584 */ 2585 public static ObjectClass getDefaultObjectClass(String name) 2586 { 2587 String lowerName = toLowerCase(name); 2588 ObjectClass objectClass = directoryServer.schema.getObjectClass(lowerName); 2589 if (objectClass == null) 2590 { 2591 String oid = lowerName + "-oid"; 2592 String definition = "( " + oid + " NAME '" + name + "' ABSTRACT )"; 2593 2594 // Temporary object classes are immediately dirty. 2595 objectClass = new ObjectClass(definition, name, 2596 Collections.singleton(name), oid, null, 2597 Collections.singleton(getTopObjectClass()), null, null, 2598 ObjectClassType.ABSTRACT, false, null).setDirty(); 2599 } 2600 2601 return objectClass; 2602 } 2603 2604 /** 2605 * Causes the Directory Server to construct a new auxiliary objectclass 2606 * definition with the provided name and with no required or allowed 2607 * attributes. This should only be used if there is no objectclass for the 2608 * specified name. It will not register the created objectclass with the 2609 * Directory Server. 2610 * 2611 * @param name The name to use for the objectclass, as provided by the user. 2612 * 2613 * @return The constructed objectclass definition. 2614 */ 2615 public static ObjectClass getDefaultAuxiliaryObjectClass(String name) 2616 { 2617 String lowerName = toLowerCase(name); 2618 ObjectClass objectClass = directoryServer.schema.getObjectClass(lowerName); 2619 if (objectClass == null) 2620 { 2621 String oid = lowerName + "-oid"; 2622 String definition = "( " + oid + " NAME '" + name + "' ABSTRACT )"; 2623 2624 objectClass = new ObjectClass(definition, name, 2625 Collections.singleton(name), oid, null, 2626 Collections.singleton(getTopObjectClass()), 2627 null, null, 2628 ObjectClassType.AUXILIARY, false, null); 2629 } 2630 2631 return objectClass; 2632 } 2633 2634 /** 2635 * Retrieves the set of attribute type definitions that have been 2636 * defined in the Directory Server. 2637 * 2638 * @return The set of attribute type definitions that have been 2639 * defined in the Directory Server. 2640 */ 2641 public static ConcurrentMap<String, AttributeType> getAttributeTypes() 2642 { 2643 return directoryServer.schema.getAttributeTypes(); 2644 } 2645 2646 /** 2647 * Retrieves the attribute type for the provided lowercase name or OID. 2648 * 2649 * @param lowerName The lowercase attribute name or OID for the attribute 2650 * type to retrieve. 2651 * 2652 * @return The requested attribute type, or <CODE>null</CODE> if there is no 2653 * attribute with the specified type defined in the server schema. 2654 */ 2655 public static AttributeType getAttributeTypeOrNull(String lowerName) 2656 { 2657 return directoryServer.schema.getAttributeType(lowerName); 2658 } 2659 2660 /** 2661 * Retrieves the attribute type for the provided lowercase name or OID. It 2662 * can optionally return a generated "default" version if the requested 2663 * attribute type is not defined in the schema. 2664 * 2665 * @param lowerName The lowercase name or OID for the attribute type to 2666 * retrieve. 2667 * @return The requested attribute type, or <CODE>null</CODE> if there is no 2668 * attribute with the specified type defined in the server schema and 2669 * a default type should not be returned. 2670 */ 2671 public static AttributeType getAttributeTypeOrDefault(String lowerName) 2672 { 2673 return getAttributeTypeOrDefault(lowerName, lowerName, getDefaultAttributeSyntax()); 2674 } 2675 2676 /** 2677 * Retrieves the attribute type for the provided lowercase name or OID. It will return a generated 2678 * "default" version with the uppercase name or OID if the requested attribute type is not defined 2679 * in the schema. 2680 * 2681 * @param lowerName 2682 * The lowercase name or OID for the attribute type to retrieve. 2683 * @param upperName 2684 * The uppercase name or OID for the attribute type to generate. 2685 * @return The requested attribute type, or a generated "default" version if there is no attribute 2686 * with the specified type defined in the server schema 2687 */ 2688 public static AttributeType getAttributeTypeOrDefault(String lowerName, String upperName) 2689 { 2690 return getAttributeTypeOrDefault(lowerName, upperName, getDefaultAttributeSyntax()); 2691 } 2692 2693 /** 2694 * Retrieves the attribute type for the provided lowercase name or OID. It will return a generated 2695 * "default" version with the uppercase name or OID if the requested attribute type is not defined 2696 * in the schema. 2697 * 2698 * @param lowerName 2699 * The lowercase name or OID for the attribute type to retrieve. 2700 * @param upperName 2701 * The uppercase name or OID for the attribute type to generate. 2702 * @param syntax 2703 * The syntax for the attribute type to generate. 2704 * @return The requested attribute type, or a generated "default" version if there is no attribute 2705 * with the specified type defined in the server schema 2706 */ 2707 public static AttributeType getAttributeTypeOrDefault(String lowerName, String upperName, Syntax syntax) 2708 { 2709 AttributeType attrType = getAttributeTypeOrNull(lowerName); 2710 if (attrType == null) 2711 { 2712 attrType = getDefaultAttributeType(upperName, syntax); 2713 } 2714 return attrType; 2715 } 2716 2717 /** 2718 * Registers the provided attribute type with the Directory Server. 2719 * 2720 * @param attributeType The attribute type to register with the 2721 * Directory Server. 2722 * @param overwriteExisting Indicates whether to overwrite an existing 2723 * mapping if there are any conflicts (i.e., 2724 * another attribute type with the same OID or 2725 * name). 2726 * 2727 * @throws DirectoryException If a conflict is encountered and the 2728 * <CODE>overwriteExisting</CODE> flag is set to 2729 * <CODE>false</CODE> 2730 */ 2731 public static void registerAttributeType(AttributeType attributeType, 2732 boolean overwriteExisting) 2733 throws DirectoryException 2734 { 2735 directoryServer.schema.registerAttributeType(attributeType, 2736 overwriteExisting); 2737 } 2738 2739 /** 2740 * Deregisters the provided attribute type with the Directory Server. 2741 * 2742 * @param attributeType The attribute type to deregister with the Directory 2743 * Server. 2744 */ 2745 public static void deregisterAttributeType(AttributeType attributeType) 2746 { 2747 directoryServer.schema.deregisterAttributeType(attributeType); 2748 } 2749 2750 /** 2751 * Retrieves the attribute type for the "objectClass" attribute. 2752 * 2753 * @return The attribute type for the "objectClass" attribute. 2754 */ 2755 public static AttributeType getObjectClassAttributeType() 2756 { 2757 if (directoryServer.objectClassAttributeType == null) 2758 { 2759 directoryServer.objectClassAttributeType = 2760 directoryServer.schema.getAttributeType( 2761 OBJECTCLASS_ATTRIBUTE_TYPE_NAME); 2762 2763 if (directoryServer.objectClassAttributeType == null) 2764 { 2765 Syntax oidSyntax = directoryServer.schema.getSyntax(SYNTAX_OID_NAME); 2766 if (oidSyntax == null) 2767 { 2768 try 2769 { 2770 oidSyntax = CoreSchema.getOIDSyntax(); 2771 directoryServer.schema.registerSyntax(oidSyntax, true); 2772 } 2773 catch (Exception e) 2774 { 2775 logger.traceException(e); 2776 } 2777 } 2778 2779 String definition = 2780 "( 2.5.4.0 NAME 'objectClass' EQUALITY objectIdentifierMatch " + 2781 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 X-ORIGIN 'RFC 2256' )"; 2782 2783 directoryServer.objectClassAttributeType = 2784 newAttributeType(definition, "objectClass", OBJECTCLASS_ATTRIBUTE_TYPE_OID, oidSyntax); 2785 try 2786 { 2787 directoryServer.schema.registerAttributeType( 2788 directoryServer.objectClassAttributeType, true); 2789 } 2790 catch (Exception e) 2791 { 2792 // This should never happen. 2793 logger.traceException(e); 2794 } 2795 } 2796 } 2797 2798 return directoryServer.objectClassAttributeType; 2799 } 2800 2801 /** 2802 * Causes the Directory Server to construct a new attribute type definition 2803 * with the provided name and syntax. This should only be used if there is no 2804 * real attribute type for the specified name. 2805 * <p> 2806 * TODO remove once we switch to the SDK Schema 2807 * <p> 2808 * FIXME move to {@link org.opends.server.types.Schema}? 2809 * 2810 * @param name The name to use for the attribute type, as provided by the user. 2811 * @param syntax The syntax to use for the attribute type. 2812 * 2813 * @return The constructed attribute type definition. 2814 */ 2815 public static AttributeType getDefaultAttributeType(String name, Syntax syntax) 2816 { 2817 String oid = toLowerCase(name) + "-oid"; 2818 String definition = "( " + oid + " NAME '" + name + "' SYNTAX " + 2819 syntax.getOID() + " )"; 2820 2821 // Temporary attribute types are immediately dirty. 2822 return newAttributeType(definition, name, oid, syntax).setDirty(); 2823 } 2824 2825 private static AttributeType newAttributeType(String definition, String name, String oid, Syntax syntax) 2826 { 2827 return new AttributeType(definition, name, Collections.singleton(name), oid, null, null, syntax, 2828 AttributeUsage.USER_APPLICATIONS, false, false, false, false); 2829 } 2830 2831 /** 2832 * Retrieves the set of attribute syntaxes defined in the Directory Server. 2833 * 2834 * @return The set of attribute syntaxes defined in the Directory Server. 2835 */ 2836 public static ConcurrentMap<String, Syntax> getAttributeSyntaxes() 2837 { 2838 return directoryServer.schema.getSyntaxes(); 2839 } 2840 2841 /** 2842 * Retrieves the default attribute syntax that should be used for attributes 2843 * that are not defined in the server schema. 2844 * 2845 * @return The default attribute syntax that should be used for attributes 2846 * that are not defined in the server schema. 2847 */ 2848 public static Syntax getDefaultAttributeSyntax() 2849 { 2850 return directoryServer.getDefaultSyntax(); 2851 } 2852 2853 /** 2854 * Retrieves the default attribute syntax that should be used for attributes 2855 * that are not defined in the server schema and are meant to store binary 2856 * values. 2857 * 2858 * @return The default attribute syntax that should be used for attributes 2859 * that are not defined in the server schema and are meant to store 2860 * binary values. 2861 */ 2862 public static Syntax getDefaultBinarySyntax() 2863 { 2864 return CoreSchema.getBinarySyntax(); 2865 } 2866 2867 /** 2868 * Retrieves the default attribute syntax that should be used for attributes 2869 * that are not defined in the server schema and are meant to store Boolean 2870 * values. 2871 * 2872 * @return The default attribute syntax that should be used for attributes 2873 * that are not defined in the server schema and are meant to store 2874 * Boolean values. 2875 */ 2876 public static Syntax getDefaultBooleanSyntax() 2877 { 2878 return CoreSchema.getBooleanSyntax(); 2879 } 2880 2881 /** 2882 * Retrieves the default attribute syntax that should be used for attributes 2883 * that are not defined in the server schema and are meant to store DN values. 2884 * 2885 * @return The default attribute syntax that should be used for attributes 2886 * that are not defined in the server schema and are meant to store 2887 * DN values. 2888 */ 2889 public static Syntax getDefaultDNSyntax() 2890 { 2891 return CoreSchema.getDNSyntax(); 2892 } 2893 2894 /** 2895 * Retrieves the default attribute syntax that should be used for attributes 2896 * that are not defined in the server schema and are meant to store integer 2897 * values. 2898 * 2899 * @return The default attribute syntax that should be used for attributes 2900 * that are not defined in the server schema and are meant to store 2901 * integer values. 2902 */ 2903 public static Syntax getDefaultIntegerSyntax() 2904 { 2905 return CoreSchema.getIntegerSyntax(); 2906 } 2907 2908 /** 2909 * Retrieves the default attribute syntax that should be used for attributes 2910 * that are not defined in the server schema and are meant to store string 2911 * values. 2912 * 2913 * @return The default attribute syntax that should be used for attributes 2914 * that are not defined in the server schema and are meant to store 2915 * string values. 2916 */ 2917 public static Syntax getDefaultStringSyntax() 2918 { 2919 return CoreSchema.getDirectoryStringSyntax(); 2920 } 2921 2922 private Syntax getDefaultSyntax() 2923 { 2924 return CoreSchema.getDirectoryStringSyntax(); 2925 } 2926 2927 /** 2928 * Retrieves the set of matching rule uses defined in the Directory Server. 2929 * 2930 * @return The set of matching rule uses defined in the Directory Server. 2931 */ 2932 public static ConcurrentMap<MatchingRule, MatchingRuleUse> 2933 getMatchingRuleUses() 2934 { 2935 return directoryServer.schema.getMatchingRuleUses(); 2936 } 2937 2938 /** 2939 * Retrieves the matching rule use associated with the provided matching rule. 2940 * 2941 * @param matchingRule The matching rule for which to retrieve the matching 2942 * rule use. 2943 * 2944 * @return The matching rule use for the provided matching rule, or 2945 * <CODE>null</CODE> if none is defined. 2946 */ 2947 public static MatchingRuleUse getMatchingRuleUse(MatchingRule matchingRule) 2948 { 2949 return directoryServer.schema.getMatchingRuleUse(matchingRule); 2950 } 2951 2952 /** 2953 * Registers the provided matching rule use with the Directory Server. 2954 * 2955 * @param matchingRuleUse The matching rule use to register with the 2956 * server. 2957 * @param overwriteExisting Indicates whether to overwrite an existing 2958 * mapping if there are any conflicts (i.e., 2959 * another matching rule use with the same matching 2960 * rule). 2961 * 2962 * @throws DirectoryException If a conflict is encountered and the 2963 * <CODE>overwriteExisting</CODE> flag is set to 2964 * <CODE>false</CODE> 2965 */ 2966 public static void registerMatchingRuleUse(MatchingRuleUse matchingRuleUse, 2967 boolean overwriteExisting) 2968 throws DirectoryException 2969 { 2970 directoryServer.schema.registerMatchingRuleUse(matchingRuleUse, 2971 overwriteExisting); 2972 } 2973 2974 /** 2975 * Deregisters the provided matching rule use with the Directory Server. 2976 * 2977 * @param matchingRuleUse The matching rule use to deregister with the 2978 * server. 2979 */ 2980 public static void deregisterMatchingRuleUse(MatchingRuleUse matchingRuleUse) 2981 { 2982 directoryServer.schema.deregisterMatchingRuleUse(matchingRuleUse); 2983 } 2984 2985 /** 2986 * Retrieves the set of DIT content rules defined in the Directory Server. 2987 * 2988 * @return The set of DIT content rules defined in the Directory Server. 2989 */ 2990 public static ConcurrentMap<ObjectClass, DITContentRule> 2991 getDITContentRules() 2992 { 2993 return directoryServer.schema.getDITContentRules(); 2994 } 2995 2996 /** 2997 * Retrieves the DIT content rule associated with the specified objectclass. 2998 * 2999 * @param objectClass The objectclass for which to retrieve the associated 3000 * DIT content rule. 3001 * 3002 * @return The requested DIT content rule, or <CODE>null</CODE> if no such 3003 * rule is defined in the schema. 3004 */ 3005 public static DITContentRule getDITContentRule(ObjectClass objectClass) 3006 { 3007 return directoryServer.schema.getDITContentRule(objectClass); 3008 } 3009 3010 /** 3011 * Registers the provided DIT content rule with the Directory Server. 3012 * 3013 * @param ditContentRule The DIT content rule to register with the 3014 * server. 3015 * @param overwriteExisting Indicates whether to overwrite an existing 3016 * mapping if there are any conflicts (i.e., 3017 * another DIT content rule with the same 3018 * structural objectclass). 3019 * 3020 * @throws DirectoryException If a conflict is encountered and the 3021 * <CODE>overwriteExisting</CODE> flag is set to 3022 * <CODE>false</CODE> 3023 */ 3024 public static void registerDITContentRule(DITContentRule ditContentRule, 3025 boolean overwriteExisting) 3026 throws DirectoryException 3027 { 3028 directoryServer.schema.registerDITContentRule(ditContentRule, 3029 overwriteExisting); 3030 } 3031 3032 /** 3033 * Deregisters the provided DIT content rule with the Directory Server. 3034 * 3035 * @param ditContentRule The DIT content rule to deregister with the server. 3036 */ 3037 public static void deregisterDITContentRule(DITContentRule ditContentRule) 3038 { 3039 directoryServer.schema.deregisterDITContentRule(ditContentRule); 3040 } 3041 3042 /** 3043 * Retrieves the set of DIT structure rules defined in the Directory Server. 3044 * 3045 * @return The set of DIT structure rules defined in the Directory Server. 3046 */ 3047 public static ConcurrentMap<NameForm, DITStructureRule> 3048 getDITStructureRules() 3049 { 3050 return directoryServer.schema.getDITStructureRulesByNameForm(); 3051 } 3052 3053 /** 3054 * Retrieves the DIT structure rule associated with the provided rule ID. 3055 * 3056 * @param ruleID The rule ID for which to retrieve the associated DIT 3057 * structure rule. 3058 * 3059 * @return The requested DIT structure rule, or <CODE>null</CODE> if no such 3060 * rule is defined. 3061 */ 3062 public static DITStructureRule getDITStructureRule(int ruleID) 3063 { 3064 return directoryServer.schema.getDITStructureRule(ruleID); 3065 } 3066 3067 /** 3068 * Retrieves the DIT structure rule associated with the provided name form. 3069 * 3070 * @param nameForm The name form for which to retrieve the associated DIT 3071 * structure rule. 3072 * 3073 * @return The requested DIT structure rule, or <CODE>null</CODE> if no such 3074 * rule is defined. 3075 */ 3076 public static DITStructureRule getDITStructureRule(NameForm nameForm) 3077 { 3078 return directoryServer.schema.getDITStructureRule(nameForm); 3079 } 3080 3081 /** 3082 * Registers the provided DIT structure rule with the Directory Server. 3083 * 3084 * @param ditStructureRule The DIT structure rule to register with the 3085 * server. 3086 * @param overwriteExisting Indicates whether to overwrite an existing 3087 * mapping if there are any conflicts (i.e., 3088 * another DIT structure rule with the same name 3089 * form). 3090 * 3091 * @throws DirectoryException If a conflict is encountered and the 3092 * <CODE>overwriteExisting</CODE> flag is set to 3093 * <CODE>false</CODE> 3094 */ 3095 public static void registerDITStructureRule(DITStructureRule ditStructureRule, 3096 boolean overwriteExisting) 3097 throws DirectoryException 3098 { 3099 directoryServer.schema.registerDITStructureRule(ditStructureRule, 3100 overwriteExisting); 3101 } 3102 3103 /** 3104 * Deregisters the provided DIT structure rule with the Directory Server. 3105 * 3106 * @param ditStructureRule The DIT structure rule to deregister with the 3107 * server. 3108 */ 3109 public static void deregisterDITStructureRule(DITStructureRule 3110 ditStructureRule) 3111 { 3112 directoryServer.schema.deregisterDITStructureRule(ditStructureRule); 3113 } 3114 3115 /** 3116 * Retrieves the set of name forms defined in the Directory Server. 3117 * 3118 * @return The set of name forms defined in the Directory Server. 3119 */ 3120 public static ConcurrentMap<ObjectClass, List<NameForm>> getNameForms() 3121 { 3122 return directoryServer.schema.getNameFormsByObjectClass(); 3123 } 3124 3125 /** 3126 * Retrieves the name forms associated with the specified objectclass. 3127 * 3128 * @param objectClass The objectclass for which to retrieve the associated 3129 * name form. 3130 * 3131 * @return The requested name forms, or <CODE>null</CODE> if no such name 3132 * form is defined in the schema. 3133 */ 3134 public static List<NameForm> getNameForm(ObjectClass objectClass) 3135 { 3136 return directoryServer.schema.getNameForm(objectClass); 3137 } 3138 3139 /** 3140 * Retrieves the name form associated with the specified name or OID. 3141 * 3142 * @param lowerName The name or OID of the name form to retrieve, formatted 3143 * in all lowercase characters. 3144 * 3145 * @return The requested name form, or <CODE>null</CODE> if no such name form 3146 * is defined in the schema. 3147 */ 3148 public static NameForm getNameForm(String lowerName) 3149 { 3150 return directoryServer.schema.getNameForm(lowerName); 3151 } 3152 3153 /** 3154 * Registers the provided name form with the Directory Server. 3155 * 3156 * @param nameForm The name form to register with the server. 3157 * @param overwriteExisting Indicates whether to overwrite an existing 3158 * mapping if there are any conflicts (i.e., 3159 * another name form with the same structural 3160 * objectclass). 3161 * 3162 * @throws DirectoryException If a conflict is encountered and the 3163 * <CODE>overwriteExisting</CODE> flag is set to 3164 * <CODE>false</CODE> 3165 */ 3166 public static void registerNameForm(NameForm nameForm, 3167 boolean overwriteExisting) 3168 throws DirectoryException 3169 { 3170 directoryServer.schema.registerNameForm(nameForm, overwriteExisting); 3171 } 3172 3173 /** 3174 * Deregisters the provided name form with the Directory Server. 3175 * 3176 * @param nameForm The name form to deregister with the server. 3177 */ 3178 public static void deregisterNameForm(NameForm nameForm) 3179 { 3180 directoryServer.schema.deregisterNameForm(nameForm); 3181 } 3182 3183 /** 3184 * Retrieves the set of virtual attribute rules registered with the Directory 3185 * Server. 3186 * 3187 * @return The set of virtual attribute rules registered with the Directory 3188 * Server. 3189 */ 3190 public static Collection<VirtualAttributeRule> getVirtualAttributes() 3191 { 3192 return directoryServer.virtualAttributeConfigManager.getVirtualAttributes(); 3193 } 3194 3195 /** 3196 * Retrieves the set of virtual attribute rules registered with the Directory 3197 * Server that are applicable to the provided entry. 3198 * 3199 * @param entry The entry for which to retrieve the applicable virtual 3200 * attribute rules. 3201 * 3202 * @return The set of virtual attribute rules registered with the Directory 3203 * Server that apply to the given entry. It may be an empty list if 3204 * there are no applicable virtual attribute rules. 3205 */ 3206 public static List<VirtualAttributeRule> getVirtualAttributes(Entry entry) 3207 { 3208 List<VirtualAttributeRule> ruleList = new LinkedList<>(); 3209 for (VirtualAttributeRule rule : getVirtualAttributes()) 3210 { 3211 if (rule.appliesToEntry(entry)) 3212 { 3213 ruleList.add(rule); 3214 } 3215 } 3216 return ruleList; 3217 } 3218 3219 /** 3220 * Registers the provided virtual attribute rule with the Directory Server. 3221 * 3222 * @param rule The virtual attribute rule to be registered. 3223 */ 3224 public static void registerVirtualAttribute(final VirtualAttributeRule rule) 3225 { 3226 getInstance().virtualAttributeConfigManager.register(rule); 3227 } 3228 3229 /** 3230 * Deregisters the provided virtual attribute rule with the Directory Server. 3231 * 3232 * @param rule The virtual attribute rule to be deregistered. 3233 */ 3234 public static void deregisterVirtualAttribute(VirtualAttributeRule rule) 3235 { 3236 getInstance().virtualAttributeConfigManager.deregister(rule); 3237 } 3238 3239 /** 3240 * Retrieves a reference to the JMX MBean server that is associated with the 3241 * Directory Server. 3242 * 3243 * @return The JMX MBean server that is associated with the Directory Server. 3244 */ 3245 public static MBeanServer getJMXMBeanServer() 3246 { 3247 return directoryServer.mBeanServer; 3248 } 3249 3250 /** 3251 * Retrieves the set of JMX MBeans that are associated with the server. 3252 * 3253 * @return The set of JMX MBeans that are associated with the server. 3254 */ 3255 public static ConcurrentHashMap<DN,JMXMBean> getJMXMBeans() 3256 { 3257 return directoryServer.mBeans; 3258 } 3259 3260 /** 3261 * Retrieves the JMX MBean associated with the specified entry in the 3262 * Directory Server configuration. 3263 * 3264 * @param configEntryDN The DN of the configuration entry for which to 3265 * retrieve the associated JMX MBean. 3266 * 3267 * @return The JMX MBean associated with the specified entry in the Directory 3268 * Server configuration, or <CODE>null</CODE> if there is no MBean 3269 * for the specified entry. 3270 */ 3271 public static JMXMBean getJMXMBean(DN configEntryDN) 3272 { 3273 return directoryServer.mBeans.get(configEntryDN); 3274 } 3275 3276 /** 3277 * Registers the provided invokable component with the Directory Server. 3278 * 3279 * @param component The invokable component to register. 3280 */ 3281 public static void registerInvokableComponent(InvokableComponent component) 3282 { 3283 DN componentDN = component.getInvokableComponentEntryDN(); 3284 JMXMBean mBean = directoryServer.mBeans.get(componentDN); 3285 if (mBean == null) 3286 { 3287 mBean = new JMXMBean(componentDN); 3288 mBean.addInvokableComponent(component); 3289 directoryServer.mBeans.put(componentDN, mBean); 3290 } 3291 else 3292 { 3293 mBean.addInvokableComponent(component); 3294 } 3295 } 3296 3297 /** 3298 * Deregisters the provided invokable component with the Directory Server. 3299 * 3300 * @param component The invokable component to deregister. 3301 */ 3302 public static void deregisterInvokableComponent(InvokableComponent component) 3303 { 3304 DN componentDN = component.getInvokableComponentEntryDN(); 3305 JMXMBean mBean = directoryServer.mBeans.get(componentDN); 3306 if (mBean != null) 3307 { 3308 mBean.removeInvokableComponent(component); 3309 } 3310 } 3311 3312 /** 3313 * Registers the provided alert generator with the Directory Server. 3314 * 3315 * @param alertGenerator The alert generator to register. 3316 */ 3317 public static void registerAlertGenerator(AlertGenerator alertGenerator) 3318 { 3319 DN componentDN = alertGenerator.getComponentEntryDN(); 3320 JMXMBean mBean = directoryServer.mBeans.get(componentDN); 3321 if (mBean == null) 3322 { 3323 mBean = new JMXMBean(componentDN); 3324 mBean.addAlertGenerator(alertGenerator); 3325 directoryServer.mBeans.put(componentDN, mBean); 3326 } 3327 else 3328 { 3329 mBean.addAlertGenerator(alertGenerator); 3330 } 3331 } 3332 3333 /** 3334 * Deregisters the provided alert generator with the Directory Server. 3335 * 3336 * @param alertGenerator The alert generator to deregister. 3337 */ 3338 public static void deregisterAlertGenerator(AlertGenerator alertGenerator) 3339 { 3340 DN componentDN = alertGenerator.getComponentEntryDN(); 3341 JMXMBean mBean = directoryServer.mBeans.get(componentDN); 3342 if (mBean != null) 3343 { 3344 mBean.removeAlertGenerator(alertGenerator); 3345 } 3346 } 3347 3348 /** 3349 * Retrieves the set of alert handlers that have been registered with the 3350 * Directory Server. 3351 * 3352 * @return The set of alert handlers that have been registered with the 3353 * Directory Server. 3354 */ 3355 public static List<AlertHandler> getAlertHandlers() 3356 { 3357 return directoryServer.alertHandlers; 3358 } 3359 3360 /** 3361 * Registers the provided alert handler with the Directory Server. 3362 * 3363 * @param alertHandler The alert handler to register. 3364 */ 3365 public static void registerAlertHandler(AlertHandler alertHandler) 3366 { 3367 directoryServer.alertHandlers.add(alertHandler); 3368 } 3369 3370 /** 3371 * Deregisters the provided alert handler with the Directory Server. 3372 * 3373 * @param alertHandler The alert handler to deregister. 3374 */ 3375 public static void deregisterAlertHandler(AlertHandler alertHandler) 3376 { 3377 directoryServer.alertHandlers.remove(alertHandler); 3378 } 3379 3380 /** 3381 * Sends an alert notification with the provided information. 3382 * 3383 * @param generator The alert generator that created the alert. 3384 * @param alertType The alert type name for this alert. 3385 * @param alertMessage A message (possibly <CODE>null</CODE>) that can 3386 */ 3387 public static void sendAlertNotification(AlertGenerator generator, 3388 String alertType, 3389 LocalizableMessage alertMessage) 3390 { 3391 if (directoryServer.alertHandlers == null 3392 || directoryServer.alertHandlers.isEmpty()) 3393 { 3394 // If the Directory Server is still in the process of starting up, then 3395 // create a JMX alert handler to use for this notification. 3396 if (! directoryServer.isRunning) 3397 { 3398 try 3399 { 3400 JMXAlertHandler alertHandler = new JMXAlertHandler(); 3401 alertHandler.initializeAlertHandler(null); 3402 alertHandler.sendAlertNotification(generator, alertType, 3403 alertMessage); 3404 } 3405 catch (Exception e) 3406 { 3407 logger.traceException(e); 3408 } 3409 } 3410 } 3411 else 3412 { 3413 for (AlertHandler alertHandler : directoryServer.alertHandlers) 3414 { 3415 AlertHandlerCfg config = alertHandler.getAlertHandlerConfiguration(); 3416 Set<String> enabledAlerts = config.getEnabledAlertType(); 3417 Set<String> disabledAlerts = config.getDisabledAlertType(); 3418 if (enabledAlerts == null || enabledAlerts.isEmpty()) 3419 { 3420 if (disabledAlerts != null && disabledAlerts.contains(alertType)) 3421 { 3422 continue; 3423 } 3424 } 3425 else 3426 { 3427 if (enabledAlerts.contains(alertType)) 3428 { 3429 if (disabledAlerts != null && disabledAlerts.contains(alertType)) 3430 { 3431 continue; 3432 } 3433 } 3434 else 3435 { 3436 continue; 3437 } 3438 } 3439 3440 alertHandler.sendAlertNotification(generator, alertType, alertMessage); 3441 } 3442 } 3443 3444 String alertID = alertMessage != null ? alertMessage.resourceName() + "-" + alertMessage.ordinal() : "-1"; 3445 logger.info(NOTE_SENT_ALERT_NOTIFICATION, generator.getClassName(), alertType, alertID, alertMessage); 3446 } 3447 3448 /** 3449 * Retrieves the password storage scheme defined in the specified 3450 * configuration entry. 3451 * 3452 * @param configEntryDN The DN of the configuration entry that defines the 3453 * password storage scheme to retrieve. 3454 * 3455 * @return The requested password storage scheme, or {@code null} if no such 3456 * scheme is defined. 3457 */ 3458 public static PasswordStorageScheme getPasswordStorageScheme(DN configEntryDN) 3459 { 3460 return directoryServer.passwordStorageSchemesByDN.get(configEntryDN); 3461 } 3462 3463 /** 3464 * Retrieves the set of password storage schemes defined in the Directory 3465 * Server, as a mapping between the all-lowercase scheme name and the 3466 * corresponding implementation. 3467 * 3468 * @return The set of password storage schemes defined in the Directory 3469 * Server. 3470 */ 3471 public static ConcurrentHashMap<String,PasswordStorageScheme> 3472 getPasswordStorageSchemes() 3473 { 3474 return directoryServer.passwordStorageSchemes; 3475 } 3476 3477 /** 3478 * Retrieves the specified password storage scheme. 3479 * 3480 * @param lowerName The name of the password storage scheme to retrieve, 3481 * formatted in all lowercase characters. 3482 * 3483 * @return The requested password storage scheme, or <CODE>null</CODE> if no 3484 * such scheme is defined. 3485 */ 3486 public static PasswordStorageScheme getPasswordStorageScheme(String lowerName) 3487 { 3488 return directoryServer.passwordStorageSchemes.get(lowerName); 3489 } 3490 3491 /** 3492 * Retrieves the set of authentication password storage schemes defined in the 3493 * Directory Server, as a mapping between the scheme name and the 3494 * corresponding implementation. 3495 * 3496 * @return The set of authentication password storage schemes defined in the 3497 * Directory Server. 3498 */ 3499 public static ConcurrentHashMap<String,PasswordStorageScheme> 3500 getAuthPasswordStorageSchemes() 3501 { 3502 return directoryServer.authPasswordStorageSchemes; 3503 } 3504 3505 /** 3506 * Retrieves the specified authentication password storage scheme. 3507 * 3508 * @param name The case-sensitive name of the authentication password 3509 * storage scheme to retrieve. 3510 * 3511 * @return The requested authentication password storage scheme, or 3512 * <CODE>null</CODE> if no such scheme is defined. 3513 */ 3514 public static PasswordStorageScheme getAuthPasswordStorageScheme(String name) 3515 { 3516 return directoryServer.authPasswordStorageSchemes.get(name); 3517 } 3518 3519 /** 3520 * Registers the provided password storage scheme with the Directory Server. 3521 * If an existing password storage scheme is registered with the same name, 3522 * then it will be replaced with the provided scheme. 3523 * 3524 * @param configEntryDN The DN of the configuration entry that defines the 3525 * password storage scheme. 3526 * @param scheme The password storage scheme to register with the 3527 * Directory Server. 3528 */ 3529 public static void registerPasswordStorageScheme(DN configEntryDN, 3530 PasswordStorageScheme scheme) 3531 { 3532 directoryServer.passwordStorageSchemesByDN.put(configEntryDN, scheme); 3533 3534 String name = toLowerCase(scheme.getStorageSchemeName()); 3535 directoryServer.passwordStorageSchemes.put(name, scheme); 3536 3537 if (scheme.supportsAuthPasswordSyntax()) 3538 { 3539 directoryServer.authPasswordStorageSchemes.put( 3540 scheme.getAuthPasswordSchemeName(), scheme); 3541 } 3542 } 3543 3544 /** 3545 * Deregisters the specified password storage scheme with the Directory 3546 * Server. If no scheme is registered with the specified name, then no action 3547 * will be taken. 3548 * 3549 * @param configEntryDN The DN of the configuration entry that defines the 3550 * password storage scheme. 3551 */ 3552 public static void deregisterPasswordStorageScheme(DN configEntryDN) 3553 { 3554 PasswordStorageScheme scheme = 3555 directoryServer.passwordStorageSchemesByDN.remove(configEntryDN); 3556 3557 if (scheme != null) 3558 { 3559 directoryServer.passwordStorageSchemes.remove( 3560 toLowerCase(scheme.getStorageSchemeName())); 3561 3562 if (scheme.supportsAuthPasswordSyntax()) 3563 { 3564 directoryServer.authPasswordStorageSchemes.remove( 3565 scheme.getAuthPasswordSchemeName()); 3566 } 3567 } 3568 } 3569 3570 /** 3571 * Retrieves the set of password validators that have been registered for use 3572 * with the Directory Server as a mapping between the DN of the associated 3573 * validator configuration entry and the validator implementation. 3574 * 3575 * @return The set of password validators that have been registered for use 3576 * with the Directory Server. 3577 */ 3578 public static ConcurrentMap<DN, 3579 PasswordValidator<? extends PasswordValidatorCfg>> 3580 getPasswordValidators() 3581 { 3582 return directoryServer.passwordValidators; 3583 } 3584 3585 /** 3586 * Retrieves the password validator registered with the provided configuration 3587 * entry DN. 3588 * 3589 * @param configEntryDN The DN of the configuration entry for which to 3590 * retrieve the associated password validator. 3591 * 3592 * @return The requested password validator, or <CODE>null</CODE> if no such 3593 * validator is defined. 3594 */ 3595 public static PasswordValidator<? extends PasswordValidatorCfg> 3596 getPasswordValidator(DN configEntryDN) 3597 { 3598 return directoryServer.passwordValidators.get(configEntryDN); 3599 } 3600 3601 /** 3602 * Registers the provided password validator for use with the Directory 3603 * Server. 3604 * 3605 * @param configEntryDN The DN of the configuration entry that defines the 3606 * specified password validator. 3607 * @param validator The password validator to register with the 3608 * Directory Server. 3609 */ 3610 public static void 3611 registerPasswordValidator(DN configEntryDN, 3612 PasswordValidator<? extends PasswordValidatorCfg> 3613 validator) 3614 { 3615 directoryServer.passwordValidators.put(configEntryDN, validator); 3616 } 3617 3618 /** 3619 * Deregisters the provided password validator for use with the Directory 3620 * Server. 3621 * 3622 * @param configEntryDN The DN of the configuration entry that defines the 3623 * password validator to deregister. 3624 */ 3625 public static void deregisterPasswordValidator(DN configEntryDN) 3626 { 3627 directoryServer.passwordValidators.remove(configEntryDN); 3628 } 3629 3630 /** 3631 * Retrieves the set of account status notification handlers defined in the 3632 * Directory Server, as a mapping between the DN of the configuration entry 3633 * and the notification handler implementation. 3634 * 3635 * @return The set of account status notification handlers defined in the 3636 * Directory Server. 3637 */ 3638 public static ConcurrentMap<DN, AccountStatusNotificationHandler> 3639 getAccountStatusNotificationHandlers() 3640 { 3641 return directoryServer.accountStatusNotificationHandlers; 3642 } 3643 3644 /** 3645 * Retrieves the account status notification handler with the specified 3646 * configuration entry DN. 3647 * 3648 * @param handlerDN The DN of the configuration entry associated with the 3649 * account status notification handler to retrieve. 3650 * 3651 * @return The requested account status notification handler, or 3652 * <CODE>null</CODE> if no such handler is defined in the server. 3653 */ 3654 public static AccountStatusNotificationHandler 3655 getAccountStatusNotificationHandler(DN handlerDN) 3656 { 3657 return directoryServer.accountStatusNotificationHandlers.get(handlerDN); 3658 } 3659 3660 /** 3661 * Registers the provided account status notification handler with the 3662 * Directory Server. 3663 * 3664 * @param handlerDN The DN of the configuration entry that defines the 3665 * provided account status notification handler. 3666 * @param handler The account status notification handler to register with 3667 * the Directory Server. 3668 */ 3669 public static void registerAccountStatusNotificationHandler(DN handlerDN, 3670 AccountStatusNotificationHandler handler) 3671 { 3672 directoryServer.accountStatusNotificationHandlers.put(handlerDN, handler); 3673 } 3674 3675 /** 3676 * Deregisters the specified account status notification handler with the 3677 * Directory Server. 3678 * 3679 * @param handlerDN The DN of the configuration entry for the account status 3680 * notification handler to deregister. 3681 */ 3682 public static void deregisterAccountStatusNotificationHandler(DN handlerDN) 3683 { 3684 directoryServer.accountStatusNotificationHandlers.remove(handlerDN); 3685 } 3686 3687 /** 3688 * Retrieves the set of password generators that have been registered for use 3689 * with the Directory Server as a mapping between the DN of the associated 3690 * generator configuration entry and the generator implementation. 3691 * 3692 * @return The set of password generators that have been registered for use 3693 * with the Directory Server. 3694 */ 3695 public static ConcurrentMap<DN, PasswordGenerator> getPasswordGenerators() 3696 { 3697 return directoryServer.passwordGenerators; 3698 } 3699 3700 /** 3701 * Retrieves the password generator registered with the provided configuration 3702 * entry DN. 3703 * 3704 * @param configEntryDN The DN of the configuration entry for which to 3705 * retrieve the associated password generator. 3706 * 3707 * @return The requested password generator, or <CODE>null</CODE> if no such 3708 * generator is defined. 3709 */ 3710 public static PasswordGenerator getPasswordGenerator(DN configEntryDN) 3711 { 3712 return directoryServer.passwordGenerators.get(configEntryDN); 3713 } 3714 3715 /** 3716 * Registers the provided password generator for use with the Directory 3717 * Server. 3718 * 3719 * @param configEntryDN The DN of the configuration entry that defines the 3720 * specified password generator. 3721 * @param generator The password generator to register with the 3722 * Directory Server. 3723 */ 3724 public static void registerPasswordGenerator(DN configEntryDN, 3725 PasswordGenerator generator) 3726 { 3727 directoryServer.passwordGenerators.put(configEntryDN, generator); 3728 } 3729 3730 /** 3731 * Deregisters the provided password generator for use with the Directory 3732 * Server. 3733 * 3734 * @param configEntryDN The DN of the configuration entry that defines the 3735 * password generator to deregister. 3736 */ 3737 public static void deregisterPasswordGenerator(DN configEntryDN) 3738 { 3739 directoryServer.passwordGenerators.remove(configEntryDN); 3740 } 3741 3742 /** 3743 * Returns an unmodifiable collection containing all of the authentication 3744 * policies registered with the Directory Server. The references returned are 3745 * to the actual authentication policy objects currently in use by the 3746 * directory server and the referenced objects must not be modified. 3747 * 3748 * @return The unmodifiable collection containing all of the authentication 3749 * policies registered with the Directory Server. 3750 */ 3751 public static Collection<AuthenticationPolicy> getAuthenticationPolicies() 3752 { 3753 return Collections 3754 .unmodifiableCollection(directoryServer.authenticationPolicies.values()); 3755 } 3756 3757 /** 3758 * Retrieves the authentication policy registered for the provided 3759 * configuration entry. 3760 * 3761 * @param configEntryDN 3762 * The DN of the configuration entry for which to retrieve the 3763 * associated authentication policy. 3764 * @return The authentication policy registered for the provided configuration 3765 * entry, or <CODE>null</CODE> if there is no such policy. 3766 */ 3767 public static AuthenticationPolicy getAuthenticationPolicy(DN configEntryDN) 3768 { 3769 Reject.ifNull(configEntryDN); 3770 return directoryServer.authenticationPolicies.get(configEntryDN); 3771 } 3772 3773 /** 3774 * Registers the provided authentication policy with the Directory Server. If 3775 * a policy is already registered for the provided configuration entry DN, 3776 * then it will be replaced. 3777 * 3778 * @param configEntryDN 3779 * The DN of the configuration entry that defines the authentication 3780 * policy. 3781 * @param policy 3782 * The authentication policy to register with the server. 3783 */ 3784 public static void registerAuthenticationPolicy(DN configEntryDN, 3785 AuthenticationPolicy policy) 3786 { 3787 Reject.ifNull(configEntryDN, policy); 3788 3789 // Ensure default policy is synchronized. 3790 synchronized (directoryServer.authenticationPolicies) 3791 { 3792 if (directoryServer.defaultPasswordPolicyDN.equals(configEntryDN)) 3793 { 3794 // The correct policy type is enforced by the core config manager. 3795 directoryServer.defaultPasswordPolicy = (PasswordPolicy) policy; 3796 } 3797 3798 AuthenticationPolicy oldPolicy = directoryServer.authenticationPolicies 3799 .put(configEntryDN, policy); 3800 3801 if (oldPolicy != null) 3802 { 3803 oldPolicy.finalizeAuthenticationPolicy(); 3804 } 3805 } 3806 } 3807 3808 /** 3809 * Deregisters the provided authentication policy with the Directory Server. 3810 * If no such policy is registered, then no action will be taken. 3811 * 3812 * @param configEntryDN 3813 * The DN of the configuration entry that defines the authentication 3814 * policy to deregister. 3815 */ 3816 public static void deregisterAuthenticationPolicy(DN configEntryDN) 3817 { 3818 Reject.ifNull(configEntryDN); 3819 3820 // Ensure default policy is synchronized. 3821 synchronized (directoryServer.authenticationPolicies) 3822 { 3823 if (directoryServer.defaultPasswordPolicyDN.equals(configEntryDN)) 3824 { 3825 directoryServer.defaultPasswordPolicy = null; 3826 } 3827 3828 AuthenticationPolicy oldPolicy = directoryServer.authenticationPolicies 3829 .remove(configEntryDN); 3830 if (oldPolicy != null) 3831 { 3832 oldPolicy.finalizeAuthenticationPolicy(); 3833 } 3834 } 3835 } 3836 3837 /** 3838 * Retrieves the DN of the configuration entry for the default password policy 3839 * for the Directory Server. 3840 * 3841 * @return The DN of the configuration entry for the default password policy 3842 * for the Directory Server. 3843 */ 3844 public static DN getDefaultPasswordPolicyDN() 3845 { 3846 synchronized (directoryServer.authenticationPolicies) 3847 { 3848 return directoryServer.defaultPasswordPolicyDN; 3849 } 3850 } 3851 3852 /** 3853 * Specifies the DN of the configuration entry for the default authentication 3854 * policy for the Directory Server. This routine does not check the registered 3855 * authentication policies for the specified DN, since in the case of server 3856 * initialization, the authentication policy entries will not yet have been 3857 * loaded from the configuration backend. 3858 * 3859 * @param defaultPasswordPolicyDN 3860 * The DN of the configuration entry for the default authentication 3861 * policy for the Directory Server. 3862 */ 3863 public static void setDefaultPasswordPolicyDN(DN defaultPasswordPolicyDN) 3864 { 3865 // Ensure default policy is synchronized. 3866 synchronized (directoryServer.authenticationPolicies) 3867 { 3868 directoryServer.defaultPasswordPolicyDN = defaultPasswordPolicyDN; 3869 directoryServer.defaultPasswordPolicy = null; 3870 } 3871 } 3872 3873 /** 3874 * Retrieves the default password policy for the Directory Server. This 3875 * method is equivalent to invoking <CODE>getAuthenticationPolicy</CODE> on 3876 * the DN returned from 3877 * <CODE>DirectoryServer.getDefaultPasswordPolicyDN()</CODE>. 3878 * 3879 * @return The default password policy for the Directory Server. 3880 */ 3881 public static PasswordPolicy getDefaultPasswordPolicy() 3882 { 3883 // Ensure default policy is synchronized. 3884 synchronized (directoryServer.authenticationPolicies) 3885 { 3886 assert null != directoryServer.authenticationPolicies 3887 .get(directoryServer.defaultPasswordPolicyDN) : 3888 "Internal Error: no default password policy defined."; 3889 3890 if (directoryServer.defaultPasswordPolicy == null 3891 && directoryServer.defaultPasswordPolicyDN != null) 3892 { 3893 // The correct policy type is enforced by the core config manager. 3894 directoryServer.defaultPasswordPolicy = (PasswordPolicy) 3895 directoryServer.authenticationPolicies 3896 .get(directoryServer.defaultPasswordPolicyDN); 3897 } 3898 assert directoryServer.authenticationPolicies 3899 .get(directoryServer.defaultPasswordPolicyDN) == 3900 directoryServer.defaultPasswordPolicy : 3901 "Internal Error: inconsistency between defaultPasswordPolicy" 3902 + " cache and value in authenticationPolicies map."; 3903 return directoryServer.defaultPasswordPolicy; 3904 } 3905 } 3906 3907 /** 3908 * Retrieves the log rotation policy registered for the provided configuration 3909 * entry. 3910 * 3911 * @param configEntryDN The DN of the configuration entry for which to 3912 * retrieve the associated rotation policy. 3913 * 3914 * @return The rotation policy registered for the provided configuration 3915 * entry, or <CODE>null</CODE> if there is no such policy. 3916 */ 3917 public static RotationPolicy getRotationPolicy(DN configEntryDN) 3918 { 3919 Reject.ifNull(configEntryDN); 3920 3921 return directoryServer.rotationPolicies.get(configEntryDN); 3922 } 3923 3924 /** 3925 * Registers the provided log rotation policy with the Directory Server. If a 3926 * policy is already registered for the provided configuration entry DN, then 3927 * it will be replaced. 3928 * 3929 * @param configEntryDN The DN of the configuration entry that defines the 3930 * password policy. 3931 * @param policy The rotation policy to register with the server. 3932 */ 3933 public static void registerRotationPolicy(DN configEntryDN, 3934 RotationPolicy policy) 3935 { 3936 Reject.ifNull(configEntryDN, policy); 3937 3938 directoryServer.rotationPolicies.put(configEntryDN, policy); 3939 } 3940 3941 /** 3942 * Deregisters the provided log rotation policy with the Directory Server. 3943 * If no such policy is registered, then no action will be taken. 3944 * 3945 * @param configEntryDN The DN of the configuration entry that defines the 3946 * rotation policy to deregister. 3947 */ 3948 public static void deregisterRotationPolicy(DN configEntryDN) 3949 { 3950 Reject.ifNull(configEntryDN); 3951 3952 directoryServer.rotationPolicies.remove(configEntryDN); 3953 } 3954 3955 /** 3956 * Retrieves the log retention policy registered for the provided 3957 * configuration entry. 3958 * 3959 * @param configEntryDN The DN of the configuration entry for which to 3960 * retrieve the associated retention policy. 3961 * 3962 * @return The retention policy registered for the provided configuration 3963 * entry, or <CODE>null</CODE> if there is no such policy. 3964 */ 3965 public static RetentionPolicy getRetentionPolicy(DN configEntryDN) 3966 { 3967 Reject.ifNull(configEntryDN); 3968 3969 return directoryServer.retentionPolicies.get(configEntryDN); 3970 } 3971 3972 /** 3973 * Registers the provided log retention policy with the Directory Server. 3974 * If a policy is already registered for the provided configuration entry DN, 3975 * then it will be replaced. 3976 * 3977 * @param configEntryDN The DN of the configuration entry that defines the 3978 * password policy. 3979 * @param policy The retention policy to register with the server. 3980 */ 3981 public static void registerRetentionPolicy(DN configEntryDN, 3982 RetentionPolicy policy) 3983 { 3984 Reject.ifNull(configEntryDN, policy); 3985 3986 directoryServer.retentionPolicies.put(configEntryDN, policy); 3987 } 3988 3989 /** 3990 * Deregisters the provided log retention policy with the Directory Server. 3991 * If no such policy is registered, then no action will be taken. 3992 * 3993 * @param configEntryDN The DN of the configuration entry that defines the 3994 * retention policy to deregister. 3995 */ 3996 public static void deregisterRetentionPolicy(DN configEntryDN) 3997 { 3998 Reject.ifNull(configEntryDN); 3999 4000 directoryServer.retentionPolicies.remove(configEntryDN); 4001 } 4002 4003 /** 4004 * Retrieves the set of monitor providers that have been registered with the 4005 * Directory Server, as a mapping between the monitor name (in all lowercase 4006 * characters) and the monitor implementation. 4007 * 4008 * @return The set of monitor providers that have been registered with the 4009 * Directory Server. 4010 */ 4011 public static ConcurrentMap<String, 4012 MonitorProvider<? extends MonitorProviderCfg>> 4013 getMonitorProviders() 4014 { 4015 return directoryServer.monitorProviders; 4016 } 4017 4018 /** 4019 * Retrieves the monitor provider with the specified name. 4020 * 4021 * @param lowerName The name of the monitor provider to retrieve, in all 4022 * lowercase characters. 4023 * 4024 * @return The requested resource monitor, or <CODE>null</CODE> if none 4025 * exists with the specified name. 4026 */ 4027 public static MonitorProvider<? extends MonitorProviderCfg> 4028 getMonitorProvider(String lowerName) 4029 { 4030 return directoryServer.monitorProviders.get(lowerName); 4031 } 4032 4033 /** 4034 * Registers the provided monitor provider with the Directory Server. Note 4035 * that if a monitor provider is already registered with the specified name, 4036 * then it will be replaced with the provided implementation. 4037 * 4038 * @param monitorProvider The monitor provider to register with the 4039 * Directory Server. 4040 */ 4041 public static void registerMonitorProvider( 4042 MonitorProvider<? extends MonitorProviderCfg> 4043 monitorProvider) 4044 { 4045 String lowerName = toLowerCase(monitorProvider.getMonitorInstanceName()); 4046 directoryServer.monitorProviders.put(lowerName, monitorProvider); 4047 4048 // Try to register this monitor provider with an appropriate JMX MBean. 4049 try 4050 { 4051 DN monitorDN = getMonitorProviderDN(monitorProvider); 4052 JMXMBean mBean = directoryServer.mBeans.get(monitorDN); 4053 if (mBean == null) 4054 { 4055 mBean = new JMXMBean(monitorDN); 4056 mBean.addMonitorProvider(monitorProvider); 4057 directoryServer.mBeans.put(monitorDN, mBean); 4058 } 4059 else 4060 { 4061 mBean.addMonitorProvider(monitorProvider); 4062 } 4063 } 4064 catch (Exception e) 4065 { 4066 logger.traceException(e); 4067 } 4068 } 4069 4070 /** 4071 * Deregisters the specified monitor provider from the Directory Server. If no 4072 * such monitor provider is registered, no action will be taken. 4073 * 4074 * @param monitorProvider 4075 * The monitor provider to deregister from the Directory Server. 4076 */ 4077 public static void deregisterMonitorProvider( 4078 MonitorProvider<? extends MonitorProviderCfg> monitorProvider) 4079 { 4080 String monitorName = toLowerCase(monitorProvider.getMonitorInstanceName()); 4081 MonitorProvider<?> provider = directoryServer.monitorProviders 4082 .remove(monitorName); 4083 4084 // Try to deregister the monitor provider as an MBean. 4085 if (provider != null) 4086 { 4087 try 4088 { 4089 DN monitorDN = getMonitorProviderDN(provider); 4090 JMXMBean mBean = directoryServer.mBeans.get(monitorDN); 4091 if (mBean != null) 4092 { 4093 mBean.removeMonitorProvider(provider); 4094 } 4095 } 4096 catch (Exception e) 4097 { 4098 logger.traceException(e); 4099 } 4100 } 4101 } 4102 4103 /** 4104 * Retrieves the entry cache for the Directory Server. 4105 * 4106 * @return The entry cache for the Directory Server. 4107 */ 4108 public static EntryCache getEntryCache() 4109 { 4110 return directoryServer.entryCache; 4111 } 4112 4113 /** 4114 * Specifies the entry cache that should be used by the Directory Server. 4115 * This should only be called by the entry cache configuration manager. 4116 * 4117 * @param entryCache The entry cache for the Directory Server. 4118 */ 4119 public static void setEntryCache(EntryCache entryCache) 4120 { 4121 synchronized (directoryServer) 4122 { 4123 directoryServer.entryCache = entryCache; 4124 } 4125 } 4126 4127 /** 4128 * Retrieves the set of key manager providers registered with the Directory 4129 * Server. 4130 * 4131 * @return The set of key manager providers registered with the Directory 4132 * Server. 4133 */ 4134 public static Map<DN,KeyManagerProvider> getKeyManagerProviders() 4135 { 4136 return directoryServer.keyManagerProviders; 4137 } 4138 4139 /** 4140 * Retrieves the key manager provider registered with the provided entry DN. 4141 * 4142 * @param providerDN The DN with which the key manager provider is 4143 * registered. 4144 * 4145 * @return The key manager provider registered with the provided entry DN, or 4146 * {@code null} if there is no such key manager provider registered 4147 * with the server. 4148 */ 4149 public static KeyManagerProvider getKeyManagerProvider(DN providerDN) 4150 { 4151 return directoryServer.keyManagerProviders.get(providerDN); 4152 } 4153 4154 /** 4155 * Registers the provided key manager provider with the Directory Server. 4156 * 4157 * @param providerDN The DN with which to register the key manager provider. 4158 * @param provider The key manager provider to register with the server. 4159 */ 4160 public static void registerKeyManagerProvider(DN providerDN, 4161 KeyManagerProvider provider) 4162 { 4163 directoryServer.keyManagerProviders.put(providerDN, provider); 4164 } 4165 4166 /** 4167 * Deregisters the specified key manager provider with the Directory Server. 4168 * 4169 * @param providerDN The DN with which the key manager provider is 4170 * registered. 4171 */ 4172 public static void deregisterKeyManagerProvider(DN providerDN) 4173 { 4174 directoryServer.keyManagerProviders.remove(providerDN); 4175 } 4176 4177 /** 4178 * Retrieves the set of trust manager providers registered with the Directory 4179 * Server. 4180 * 4181 * @return The set of trust manager providers registered with the Directory 4182 * Server. 4183 */ 4184 public static Map<DN,TrustManagerProvider> getTrustManagerProviders() 4185 { 4186 return directoryServer.trustManagerProviders; 4187 } 4188 4189 /** 4190 * Retrieves the trust manager provider registered with the provided entry DN. 4191 * 4192 * @param providerDN The DN with which the trust manager provider is 4193 * registered. 4194 * 4195 * @return The trust manager provider registered with the provided entry DN, 4196 * or {@code null} if there is no such trust manager provider 4197 * registered with the server. 4198 */ 4199 public static TrustManagerProvider getTrustManagerProvider(DN providerDN) 4200 { 4201 return directoryServer.trustManagerProviders.get(providerDN); 4202 } 4203 4204 /** 4205 * Registers the provided trust manager provider with the Directory Server. 4206 * 4207 * @param providerDN The DN with which to register the trust manager 4208 * provider. 4209 * @param provider The trust manager provider to register with the server. 4210 */ 4211 public static void registerTrustManagerProvider(DN providerDN, 4212 TrustManagerProvider provider) 4213 { 4214 directoryServer.trustManagerProviders.put(providerDN, provider); 4215 } 4216 4217 /** 4218 * Deregisters the specified trust manager provider with the Directory Server. 4219 * 4220 * @param providerDN The DN with which the trust manager provider is 4221 * registered. 4222 */ 4223 public static void deregisterTrustManagerProvider(DN providerDN) 4224 { 4225 directoryServer.trustManagerProviders.remove(providerDN); 4226 } 4227 4228 /** 4229 * Retrieves the set of certificate mappers registered with the Directory 4230 * Server. 4231 * 4232 * @return The set of certificate mappers registered with the Directory 4233 * Server. 4234 */ 4235 public static Map<DN,CertificateMapper> getCertificateMappers() 4236 { 4237 return directoryServer.certificateMappers; 4238 } 4239 4240 /** 4241 * Retrieves the certificate mapper registered with the provided entry DN. 4242 * 4243 * @param mapperDN The DN with which the certificate mapper is registered. 4244 * 4245 * @return The certificate mapper registered with the provided entry DN, or 4246 * {@code null} if there is no such certificate mapper registered 4247 * with the server. 4248 */ 4249 public static CertificateMapper getCertificateMapper(DN mapperDN) 4250 { 4251 return directoryServer.certificateMappers.get(mapperDN); 4252 } 4253 4254 /** 4255 * Registers the provided certificate mapper with the Directory Server. 4256 * 4257 * @param mapperDN The DN with which to register the certificate mapper. 4258 * @param mapper The certificate mapper to register with the server. 4259 */ 4260 public static void registerCertificateMapper(DN mapperDN, 4261 CertificateMapper mapper) 4262 { 4263 directoryServer.certificateMappers.put(mapperDN, mapper); 4264 } 4265 4266 /** 4267 * Deregisters the specified certificate mapper with the Directory Server. 4268 * 4269 * @param mapperDN The DN with which the certificate mapper is registered. 4270 */ 4271 public static void deregisterCertificateMapper(DN mapperDN) 4272 { 4273 directoryServer.certificateMappers.remove(mapperDN); 4274 } 4275 4276 /** 4277 * Retrieves the set of privileges that should automatically be granted to 4278 * root users when they authenticate. 4279 * 4280 * @return The set of privileges that should automatically be granted to root 4281 * users when they authenticate. 4282 */ 4283 public static Set<Privilege> getRootPrivileges() 4284 { 4285 return directoryServer.rootDNConfigManager.getRootPrivileges(); 4286 } 4287 4288 /** 4289 * Retrieves the DNs for the root users configured in the Directory Server. 4290 * Note that this set should only contain the actual DNs for the root users 4291 * and not any alternate DNs. Also, the contents of the returned set must not 4292 * be altered by the caller. 4293 * 4294 * @return The DNs for the root users configured in the Directory Server. 4295 */ 4296 public static Set<DN> getRootDNs() 4297 { 4298 return directoryServer.rootDNs; 4299 } 4300 4301 /** 4302 * Indicates whether the provided DN is the DN for one of the root users 4303 * configured in the Directory Server. 4304 * 4305 * @param userDN The user DN for which to make the determination. 4306 * 4307 * @return <CODE>true</CODE> if the provided user DN is a Directory Server 4308 * root DN, or <CODE>false</CODE> if not. 4309 */ 4310 public static boolean isRootDN(DN userDN) 4311 { 4312 return directoryServer.rootDNs.contains(userDN); 4313 } 4314 4315 /** 4316 * Registers the provided root DN with the Directory Server. 4317 * 4318 * @param rootDN The root DN to register with the Directory Server. 4319 */ 4320 public static void registerRootDN(DN rootDN) 4321 { 4322 directoryServer.rootDNs.add(rootDN); 4323 } 4324 4325 /** 4326 * Deregisters the provided root DN with the Directory Server. This will have 4327 * no effect if the provided DN is not registered as a root DN. 4328 * 4329 * @param rootDN The root DN to deregister. 4330 */ 4331 public static void deregisterRootDN(DN rootDN) 4332 { 4333 directoryServer.rootDNs.remove(rootDN); 4334 } 4335 4336 /** 4337 * Retrieves the set of alternate bind DNs for root users, mapped between the 4338 * alternate DN and the real DN. The contents of the returned map must not be 4339 * altered by the caller. 4340 * 4341 * @return The set of alternate bind DNs for root users, mapped between the 4342 * alternate DN and the real DN. 4343 */ 4344 public static ConcurrentMap<DN, DN> getAlternateRootBindDNs() 4345 { 4346 return directoryServer.alternateRootBindDNs; 4347 } 4348 4349 /** 4350 * Retrieves the real entry DN for the root user with the provided alternate 4351 * bind DN. 4352 * 4353 * @param alternateRootBindDN The alternate root bind DN for which to 4354 * retrieve the real entry DN. 4355 * 4356 * @return The real entry DN for the root user with the provided alternate 4357 * bind DN, or <CODE>null</CODE> if no such mapping has been defined. 4358 */ 4359 public static DN getActualRootBindDN(DN alternateRootBindDN) 4360 { 4361 return directoryServer.alternateRootBindDNs.get(alternateRootBindDN); 4362 } 4363 4364 /** 4365 * Registers an alternate root bind DN using the provided information. 4366 * 4367 * @param actualRootEntryDN The actual DN for the root user's entry. 4368 * @param alternateRootBindDN The alternate DN that should be interpreted as 4369 * if it were the provided actual root entry DN. 4370 * 4371 * @throws DirectoryException If the provided alternate bind DN is already 4372 * in use for another root user. 4373 */ 4374 public static void registerAlternateRootDN(DN actualRootEntryDN, 4375 DN alternateRootBindDN) 4376 throws DirectoryException 4377 { 4378 DN existingRootEntryDN = 4379 directoryServer.alternateRootBindDNs.putIfAbsent(alternateRootBindDN, 4380 actualRootEntryDN); 4381 if (existingRootEntryDN != null 4382 && !existingRootEntryDN.equals(actualRootEntryDN)) 4383 { 4384 LocalizableMessage message = ERR_CANNOT_REGISTER_DUPLICATE_ALTERNATE_ROOT_BIND_DN. 4385 get(alternateRootBindDN, existingRootEntryDN); 4386 throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message); 4387 } 4388 } 4389 4390 /** 4391 * Deregisters the provided alternate root bind DN from the server. This will 4392 * have no effect if there was no mapping defined for the provided alternate 4393 * root bind DN. 4394 * 4395 * @param alternateRootBindDN The alternate root bind DN to be deregistered. 4396 * 4397 * @return The actual root entry DN to which the provided alternate bind DN 4398 * was mapped, or <CODE>null</CODE> if there was no mapping for the 4399 * provided DN. 4400 */ 4401 public static DN deregisterAlternateRootBindDN(DN alternateRootBindDN) 4402 { 4403 return directoryServer.alternateRootBindDNs.remove(alternateRootBindDN); 4404 } 4405 4406 /** 4407 * Retrieves the result code that should be used when the Directory Server 4408 * encounters an internal server error. 4409 * 4410 * @return The result code that should be used when the Directory Server 4411 * encounters an internal server error. 4412 */ 4413 public static ResultCode getServerErrorResultCode() 4414 { 4415 return directoryServer.serverErrorResultCode; 4416 } 4417 4418 /** 4419 * Specifies the result code that should be used when the Directory Server 4420 * encounters an internal server error. 4421 * 4422 * @param serverErrorResultCode The result code that should be used when the 4423 * Directory Server encounters an internal 4424 * server error. 4425 */ 4426 public static void setServerErrorResultCode(ResultCode serverErrorResultCode) 4427 { 4428 directoryServer.serverErrorResultCode = serverErrorResultCode; 4429 } 4430 4431 /** 4432 * Indicates whether the Directory Server should automatically add missing RDN 4433 * attributes to an entry whenever it is added. 4434 * 4435 * @return <CODE>true</CODE> if the Directory Server should automatically add 4436 * missing RDN attributes to an entry, or <CODE>false</CODE> if it 4437 * should return an error to the client. 4438 */ 4439 public static boolean addMissingRDNAttributes() 4440 { 4441 return directoryServer.addMissingRDNAttributes; 4442 } 4443 4444 /** 4445 * Specifies whether the Directory Server should automatically add missing RDN 4446 * attributes to an entry whenever it is added. 4447 * 4448 * @param addMissingRDNAttributes Specifies whether the Directory Server 4449 * should automatically add missing RDN 4450 * attributes to an entry whenever it is 4451 * added. 4452 */ 4453 public static void setAddMissingRDNAttributes(boolean addMissingRDNAttributes) 4454 { 4455 directoryServer.addMissingRDNAttributes = addMissingRDNAttributes; 4456 } 4457 4458 /** 4459 * Indicates whether to be more flexible in the set of characters allowed for 4460 * attribute names. The standard requires that only ASCII alphabetic letters, 4461 * numeric digits, and hyphens be allowed, and that the name start with a 4462 * letter. If attribute name exceptions are enabled, then underscores will 4463 * also be allowed, and the name will be allowed to start with a digit. 4464 * 4465 * @return <CODE>true</CODE> if the server should use a more flexible 4466 * syntax for attribute names, or <CODE>false</CODE> if not. 4467 */ 4468 public static boolean allowAttributeNameExceptions() 4469 { 4470 return directoryServer.allowAttributeNameExceptions; 4471 } 4472 4473 /** 4474 * Specifies whether to be more flexible in the set of characters allowed for 4475 * attribute names. 4476 * 4477 * @param allowAttributeNameExceptions Specifies whether to be more flexible 4478 * in the set of characters allowed for 4479 * attribute names. 4480 */ 4481 public static void setAllowAttributeNameExceptions( 4482 boolean allowAttributeNameExceptions) 4483 { 4484 directoryServer.allowAttributeNameExceptions = allowAttributeNameExceptions; 4485 } 4486 4487 /** 4488 * Indicates whether the Directory Server should perform schema checking. 4489 * 4490 * @return <CODE>true</CODE> if the Directory Server should perform schema 4491 * checking, or <CODE>false</CODE> if not. 4492 */ 4493 public static boolean checkSchema() 4494 { 4495 return directoryServer.checkSchema; 4496 } 4497 4498 /** 4499 * Specifies whether the Directory Server should perform schema checking. 4500 * 4501 * @param checkSchema Specifies whether the Directory Server should perform 4502 * schema checking. 4503 */ 4504 public static void setCheckSchema(boolean checkSchema) 4505 { 4506 directoryServer.checkSchema = checkSchema; 4507 } 4508 4509 /** 4510 * Retrieves the policy that should be used regarding enforcement of a single 4511 * structural objectclass per entry. 4512 * 4513 * @return The policy that should be used regarding enforcement of a single 4514 * structural objectclass per entry. 4515 */ 4516 public static AcceptRejectWarn getSingleStructuralObjectClassPolicy() 4517 { 4518 return directoryServer.singleStructuralClassPolicy; 4519 } 4520 4521 /** 4522 * Specifies the policy that should be used regarding enforcement of a single 4523 * structural objectclass per entry. 4524 * 4525 * @param singleStructuralClassPolicy The policy that should be used 4526 * regarding enforcement of a single 4527 * structural objectclass per entry. 4528 */ 4529 public static void setSingleStructuralObjectClassPolicy( 4530 AcceptRejectWarn singleStructuralClassPolicy) 4531 { 4532 directoryServer.singleStructuralClassPolicy = singleStructuralClassPolicy; 4533 } 4534 4535 /** 4536 * Retrieves the policy that should be used when an attribute value is found 4537 * that is not valid according to the associated attribute syntax. 4538 * 4539 * @return The policy that should be used when an attribute value is found 4540 * that is not valid according to the associated attribute syntax. 4541 */ 4542 public static AcceptRejectWarn getSyntaxEnforcementPolicy() 4543 { 4544 return directoryServer.syntaxEnforcementPolicy; 4545 } 4546 4547 /** 4548 * Retrieves the policy that should be used when an attribute value is found 4549 * that is not valid according to the associated attribute syntax. 4550 * 4551 * @param syntaxEnforcementPolicy The policy that should be used when an 4552 * attribute value is found that is not valid 4553 * according to the associated attribute 4554 * syntax. 4555 */ 4556 public static void setSyntaxEnforcementPolicy( 4557 AcceptRejectWarn syntaxEnforcementPolicy) 4558 { 4559 directoryServer.syntaxEnforcementPolicy = syntaxEnforcementPolicy; 4560 } 4561 4562 /** 4563 * Indicates whether the Directory Server should send a response to an 4564 * operation that has been abandoned. Sending such a response is technically 4565 * a violation of the LDAP protocol specification, but not doing so in that 4566 * case can cause problems with clients that are expecting a response and may 4567 * hang until they get one. 4568 * 4569 * @return <CODE>true</CODE> if the Directory Server should send a response 4570 * to an operation that has been abandoned, or <CODE>false</CODE> if 4571 * not. 4572 */ 4573 public static boolean notifyAbandonedOperations() 4574 { 4575 return directoryServer.notifyAbandonedOperations; 4576 } 4577 4578 /** 4579 * Specifies whether the Directory Server should send a response to an 4580 * operation that has been abandoned. Sending such a response is technically 4581 * a violation of the LDAP protocol specification, but not doing so in that 4582 * case can cause problems with clients that are expecting a response and may 4583 * hang until they get one. 4584 * 4585 * @param notifyAbandonedOperations Indicates whether the Directory Server 4586 * should send a response to an operation 4587 * that has been abandoned. 4588 */ 4589 public static void setNotifyAbandonedOperations( 4590 boolean notifyAbandonedOperations) 4591 { 4592 directoryServer.notifyAbandonedOperations = notifyAbandonedOperations; 4593 } 4594 4595 /** 4596 * Retrieves the set of backends that have been registered with the Directory 4597 * Server, as a mapping between the backend ID and the corresponding backend. 4598 * 4599 * @return The set of backends that have been registered with the Directory 4600 * Server. 4601 */ 4602 public static Map<String, Backend> getBackends() 4603 { 4604 return new TreeMap<String, Backend>(directoryServer.backends); 4605 } 4606 4607 /** 4608 * Retrieves the backend with the specified backend ID. 4609 * 4610 * @param backendID The backend ID of the backend to retrieve. 4611 * 4612 * @return The backend with the specified backend ID, or {@code null} if 4613 * there is none. 4614 */ 4615 public static Backend<?> getBackend(String backendID) 4616 { 4617 return directoryServer.backends.get(backendID); 4618 } 4619 4620 /** 4621 * Indicates whether the Directory Server has a backend with the specified 4622 * backend ID. 4623 * 4624 * @param backendID The backend ID for which to make the determination. 4625 * 4626 * @return {@code true} if the Directory Server has a backend with the 4627 * specified backend ID, or {@code false} if not. 4628 */ 4629 public static boolean hasBackend(String backendID) 4630 { 4631 return directoryServer.backends.containsKey(backendID); 4632 } 4633 4634 /** 4635 * Registers the provided backend with the Directory Server. Note that this 4636 * will not register the set of configured suffixes with the server, as that 4637 * must be done by the backend itself. 4638 * 4639 * @param backend The backend to register with the server. Neither the 4640 * backend nor its backend ID may be null. 4641 * 4642 * @throws DirectoryException If the backend ID for the provided backend 4643 * conflicts with the backend ID of an existing 4644 * backend. 4645 */ 4646 public static void registerBackend(Backend<?> backend) throws DirectoryException 4647 { 4648 ifNull(backend); 4649 4650 String backendID = backend.getBackendID(); 4651 ifNull(backendID); 4652 4653 synchronized (directoryServer) 4654 { 4655 TreeMap<String, Backend<?>> newBackends = new TreeMap<>(directoryServer.backends); 4656 if (newBackends.containsKey(backendID)) 4657 { 4658 LocalizableMessage message = ERR_REGISTER_BACKEND_ALREADY_EXISTS.get(backendID); 4659 throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); 4660 } 4661 else 4662 { 4663 newBackends.put(backendID, backend); 4664 directoryServer.backends = newBackends; 4665 4666 for (String oid : backend.getSupportedControls()) 4667 { 4668 registerSupportedControl(oid); 4669 } 4670 4671 for (String oid : backend.getSupportedFeatures()) 4672 { 4673 registerSupportedFeature(oid); 4674 } 4675 4676 BackendMonitor monitor = new BackendMonitor(backend); 4677 monitor.initializeMonitorProvider(null); 4678 backend.setBackendMonitor(monitor); 4679 registerMonitorProvider(monitor); 4680 } 4681 } 4682 } 4683 4684 /** 4685 * Deregisters the provided backend with the Directory Server. Note that this 4686 * will not deregister the set of configured suffixes with the server, as that 4687 * must be done by the backend itself. 4688 * 4689 * @param backend The backend to deregister with the server. It must not be 4690 * {@code null}. 4691 */ 4692 public static void deregisterBackend(Backend<?> backend) 4693 { 4694 ifNull(backend); 4695 4696 synchronized (directoryServer) 4697 { 4698 TreeMap<String, Backend<?>> newBackends = new TreeMap<>(directoryServer.backends); 4699 newBackends.remove(backend.getBackendID()); 4700 4701 directoryServer.backends = newBackends; 4702 4703 // Don't need anymore the local backend workflow element so we can remove it 4704 for (DN baseDN : backend.getBaseDNs()) 4705 { 4706 LocalBackendWorkflowElement.remove(baseDN); 4707 } 4708 4709 BackendMonitor monitor = backend.getBackendMonitor(); 4710 if (monitor != null) 4711 { 4712 deregisterMonitorProvider(monitor); 4713 monitor.finalizeMonitorProvider(); 4714 backend.setBackendMonitor(null); 4715 } 4716 } 4717 } 4718 4719 /** 4720 * Retrieves the entire set of base DNs registered with the Directory Server, 4721 * mapped from the base DN to the backend responsible for that base DN. The 4722 * same backend may be present multiple times, mapped from different base DNs. 4723 * 4724 * @return The entire set of base DNs registered with the Directory Server. 4725 */ 4726 public static Map<DN,Backend> getBaseDNs() 4727 { 4728 return directoryServer.baseDnRegistry.getBaseDnMap(); 4729 } 4730 4731 /** 4732 * Retrieves the backend with the specified base DN. 4733 * 4734 * @param baseDN The DN that is registered as one of the base DNs for the 4735 * backend to retrieve. 4736 * 4737 * @return The backend with the specified base DN, or {@code null} if there 4738 * is no backend registered with the specified base DN. 4739 */ 4740 public static Backend<?> getBackendWithBaseDN(DN baseDN) 4741 { 4742 return directoryServer.baseDnRegistry.getBaseDnMap().get(baseDN); 4743 } 4744 4745 /** 4746 * Retrieves the backend that should be used to handle operations on the 4747 * specified entry. 4748 * 4749 * @param entryDN The DN of the entry for which to retrieve the 4750 * corresponding backend. 4751 * 4752 * @return The backend that should be used to handle operations on the 4753 * specified entry, or {@code null} if no appropriate backend is 4754 * registered with the server. 4755 */ 4756 public static Backend<?> getBackend(DN entryDN) 4757 { 4758 if (entryDN.isRootDN()) 4759 { 4760 return directoryServer.rootDSEBackend; 4761 } 4762 4763 Map<DN,Backend> baseDNs = directoryServer.baseDnRegistry.getBaseDnMap(); 4764 Backend<?> b = baseDNs.get(entryDN); 4765 while (b == null) 4766 { 4767 entryDN = entryDN.parent(); 4768 if (entryDN == null) 4769 { 4770 return null; 4771 } 4772 4773 b = baseDNs.get(entryDN); 4774 } 4775 4776 return b; 4777 } 4778 4779 /** 4780 * Obtains a copy of the server's base DN registry. The copy can be used 4781 * to test registration/deregistration of base DNs but cannot be used to 4782 * modify the backends. To modify the server's live base DN to backend 4783 * mappings use {@link #registerBaseDN(DN, Backend, boolean)} and 4784 * {@link #deregisterBaseDN(DN)}. 4785 * 4786 * @return copy of the base DN registry 4787 */ 4788 public static BaseDnRegistry copyBaseDnRegistry() 4789 { 4790 return directoryServer.baseDnRegistry.copy(); 4791 } 4792 4793 /** 4794 * Registers the provided base DN with the server. 4795 * 4796 * @param baseDN The base DN to register with the server. It must not be 4797 * {@code null}. 4798 * @param backend The backend responsible for the provided base DN. It 4799 * must not be {@code null}. 4800 * @param isPrivate Indicates whether the base DN should be considered a 4801 * private base DN. If the provided base DN is a naming 4802 * context, then this controls whether it is public or 4803 * private. 4804 * 4805 * @throws DirectoryException If a problem occurs while attempting to 4806 * register the provided base DN. 4807 */ 4808 public static void registerBaseDN(DN baseDN, Backend<?> backend, boolean isPrivate) 4809 throws DirectoryException 4810 { 4811 ifNull(baseDN, backend); 4812 4813 synchronized (directoryServer) 4814 { 4815 List<LocalizableMessage> warnings = 4816 directoryServer.baseDnRegistry.registerBaseDN( 4817 baseDN, backend, isPrivate); 4818 4819 // Since we've committed the changes we need to log any issues 4820 // that this registration has caused 4821 for (LocalizableMessage warning : warnings) { 4822 logger.error(warning); 4823 } 4824 4825 // When a new baseDN is registered with the server we have to create 4826 // a new workflow to handle the base DN. 4827 if (!baseDN.equals(DN.valueOf("cn=config"))) 4828 { 4829 // Now create a workflow for the registered baseDN and register 4830 // the workflow with the default network group, but don't register 4831 // the workflow if the backend happens to be the configuration 4832 // backend because it's too soon for the config backend. 4833 createWorkflow(baseDN, backend); 4834 } 4835 } 4836 } 4837 4838 /** 4839 * Deregisters the provided base DN with the server. 4840 * 4841 * @param baseDN The base DN to deregister with the server. It must not 4842 * be {@code null}. 4843 * 4844 * @throws DirectoryException If a problem occurs while attempting to 4845 * deregister the provided base DN. 4846 */ 4847 public static void deregisterBaseDN(DN baseDN) 4848 throws DirectoryException 4849 { 4850 ifNull(baseDN); 4851 4852 synchronized(directoryServer) { 4853 4854 List<LocalizableMessage> warnings = 4855 directoryServer.baseDnRegistry.deregisterBaseDN(baseDN); 4856 4857 // Since we've committed the changes we need to log any issues 4858 // that this registration has caused 4859 for (LocalizableMessage error : warnings) { 4860 logger.error(error); 4861 } 4862 4863 // Now we need to deregister the workflow that was associated with the base DN 4864 if (!baseDN.equals(DN.valueOf("cn=config"))) 4865 { 4866 LocalBackendWorkflowElement.remove(baseDN); 4867 } 4868 } 4869 } 4870 4871 /** 4872 * Retrieves the set of public naming contexts defined in the Directory 4873 * Server, mapped from the naming context DN to the corresponding backend. 4874 * 4875 * @return The set of public naming contexts defined in the Directory Server. 4876 */ 4877 public static Map<DN,Backend> getPublicNamingContexts() 4878 { 4879 return directoryServer.baseDnRegistry.getPublicNamingContextsMap(); 4880 } 4881 4882 /** 4883 * Retrieves the set of private naming contexts defined in the Directory 4884 * Server, mapped from the naming context DN to the corresponding backend. 4885 * 4886 * @return The set of private naming contexts defined in the Directory 4887 * Server. 4888 */ 4889 public static Map<DN,Backend> getPrivateNamingContexts() 4890 { 4891 return directoryServer.baseDnRegistry.getPrivateNamingContextsMap(); 4892 } 4893 4894 /** 4895 * Indicates whether the specified DN is one of the Directory Server naming 4896 * contexts. 4897 * 4898 * @param dn The DN for which to make the determination. 4899 * 4900 * @return {@code true} if the specified DN is a naming context for the 4901 * Directory Server, or {@code false} if it is not. 4902 */ 4903 public static boolean isNamingContext(DN dn) 4904 { 4905 return directoryServer.baseDnRegistry.containsNamingContext(dn); 4906 } 4907 4908 /** 4909 * Retrieves the root DSE entry for the Directory Server. 4910 * 4911 * @return The root DSE entry for the Directory Server. 4912 */ 4913 public static Entry getRootDSE() 4914 { 4915 return directoryServer.rootDSEBackend.getRootDSE(); 4916 } 4917 4918 /** 4919 * Retrieves the root DSE backend for the Directory Server. 4920 * 4921 * @return The root DSE backend for the Directory Server. 4922 */ 4923 public static RootDSEBackend getRootDSEBackend() 4924 { 4925 return directoryServer.rootDSEBackend; 4926 } 4927 4928 /** 4929 * Retrieves the DN of the entry containing the server schema definitions. 4930 * 4931 * @return The DN of the entry containing the server schema definitions, or 4932 * <CODE>null</CODE> if none has been defined (e.g., if no schema 4933 * backend has been configured). 4934 */ 4935 public static DN getSchemaDN() 4936 { 4937 return directoryServer.schemaDN; 4938 } 4939 4940 /** 4941 * Specifies the DN of the entry containing the server schema definitions. 4942 * 4943 * @param schemaDN The DN of the entry containing the server schema 4944 * definitions. 4945 */ 4946 public static void setSchemaDN(DN schemaDN) 4947 { 4948 directoryServer.schemaDN = schemaDN; 4949 } 4950 4951 /** 4952 * Retrieves the entry with the requested DN. It will first determine which backend should be used 4953 * for this DN and will then use that backend to retrieve the entry. The caller is not required to 4954 * hold any locks on the specified DN. 4955 * 4956 * @param entryDN 4957 * The DN of the entry to retrieve. 4958 * @return The requested entry, or <CODE>null</CODE> if it does not exist. 4959 * @throws DirectoryException 4960 * If a problem occurs while attempting to retrieve the entry. 4961 */ 4962 public static Entry getEntry(DN entryDN) throws DirectoryException 4963 { 4964 if (entryDN.isRootDN()) 4965 { 4966 return directoryServer.rootDSEBackend.getRootDSE(); 4967 } 4968 final Backend<?> backend = getBackend(entryDN); 4969 return backend != null ? backend.getEntry(entryDN) : null; 4970 } 4971 4972 /** 4973 * Indicates whether the specified entry exists in the Directory Server. The 4974 * caller is not required to hold any locks when invoking this method. 4975 * 4976 * @param entryDN The DN of the entry for which to make the determination. 4977 * 4978 * @return <CODE>true</CODE> if the specified entry exists in one of the 4979 * backends, or <CODE>false</CODE> if it does not. 4980 * 4981 * @throws DirectoryException If a problem occurs while attempting to 4982 * make the determination. 4983 */ 4984 public static boolean entryExists(DN entryDN) 4985 throws DirectoryException 4986 { 4987 // If the entry is the root DSE, then it will always exist. 4988 if (entryDN.isRootDN()) 4989 { 4990 return true; 4991 } 4992 4993 // Ask the appropriate backend if the entry exists. 4994 // If it is not appropriate for any backend, then return false. 4995 Backend<?> backend = getBackend(entryDN); 4996 return backend != null && backend.entryExists(entryDN); 4997 } 4998 4999 /** 5000 * Retrieves the set of supported controls registered with the Directory 5001 * Server. 5002 * 5003 * @return The set of supported controls registered with the Directory 5004 * Server. 5005 */ 5006 public static TreeSet<String> getSupportedControls() 5007 { 5008 return directoryServer.supportedControls; 5009 } 5010 5011 /** 5012 * Indicates whether the specified OID is registered with the Directory Server 5013 * as a supported control. 5014 * 5015 * @param controlOID The OID of the control for which to make the 5016 * determination. 5017 * 5018 * @return <CODE>true</CODE> if the specified OID is registered with the 5019 * server as a supported control, or <CODE>false</CODE> if not. 5020 */ 5021 public static boolean isSupportedControl(String controlOID) 5022 { 5023 return directoryServer.supportedControls.contains(controlOID); 5024 } 5025 5026 /** 5027 * Registers the provided OID as a supported control for the Directory Server. 5028 * This will have no effect if the specified control OID is already present in 5029 * the list of supported controls. 5030 * 5031 * @param controlOID The OID of the control to register as a supported 5032 * control. 5033 */ 5034 public static void registerSupportedControl(String controlOID) 5035 { 5036 synchronized (directoryServer.supportedControls) 5037 { 5038 directoryServer.supportedControls.add(controlOID); 5039 } 5040 } 5041 5042 /** 5043 * Deregisters the provided OID as a supported control for the Directory 5044 * Server. This will have no effect if the specified control OID is not 5045 * present in the list of supported controls. 5046 * 5047 * @param controlOID The OID of the control to deregister as a supported 5048 * control. 5049 */ 5050 public static void deregisterSupportedControl(String controlOID) 5051 { 5052 synchronized (directoryServer.supportedControls) 5053 { 5054 directoryServer.supportedControls.remove(controlOID); 5055 } 5056 } 5057 5058 /** 5059 * Retrieves the set of supported features registered with the Directory 5060 * Server. 5061 * 5062 * @return The set of supported features registered with the Directory 5063 * Server. 5064 */ 5065 public static TreeSet<String> getSupportedFeatures() 5066 { 5067 return directoryServer.supportedFeatures; 5068 } 5069 5070 /** 5071 * Indicates whether the specified OID is registered with the Directory Server 5072 * as a supported feature. 5073 * 5074 * @param featureOID The OID of the feature for which to make the 5075 * determination. 5076 * 5077 * @return <CODE>true</CODE> if the specified OID is registered with the 5078 * server as a supported feature, or <CODE>false</CODE> if not. 5079 */ 5080 public static boolean isSupportedFeature(String featureOID) 5081 { 5082 return directoryServer.supportedFeatures.contains(featureOID); 5083 } 5084 5085 /** 5086 * Registers the provided OID as a supported feature for the Directory Server. 5087 * This will have no effect if the specified feature OID is already present in 5088 * the list of supported features. 5089 * 5090 * @param featureOID The OID of the feature to register as a supported 5091 * feature. 5092 */ 5093 public static void registerSupportedFeature(String featureOID) 5094 { 5095 synchronized (directoryServer.supportedFeatures) 5096 { 5097 directoryServer.supportedFeatures.add(featureOID); 5098 } 5099 } 5100 5101 /** 5102 * Deregisters the provided OID as a supported feature for the Directory 5103 * Server. This will have no effect if the specified feature OID is not 5104 * present in the list of supported features. 5105 * 5106 * @param featureOID The OID of the feature to deregister as a supported 5107 * feature. 5108 */ 5109 public static void deregisterSupportedFeature(String featureOID) 5110 { 5111 synchronized (directoryServer.supportedFeatures) 5112 { 5113 directoryServer.supportedFeatures.remove(featureOID); 5114 } 5115 } 5116 5117 /** 5118 * Retrieves the set of extended operations that may be processed by the 5119 * Directory Server. 5120 * 5121 * @return The set of extended operations that may be processed by the 5122 * Directory Server. 5123 */ 5124 public static ConcurrentMap<String, ExtendedOperationHandler> 5125 getSupportedExtensions() 5126 { 5127 return directoryServer.extendedOperationHandlers; 5128 } 5129 5130 /** 5131 * Retrieves the handler for the extended operation for the provided OID. 5132 * 5133 * @param oid The OID of the extended operation to retrieve. 5134 * 5135 * @return The handler for the specified extended operation, or 5136 * <CODE>null</CODE> if there is none. 5137 */ 5138 public static ExtendedOperationHandler getExtendedOperationHandler(String oid) 5139 { 5140 return directoryServer.extendedOperationHandlers.get(oid); 5141 } 5142 5143 /** 5144 * Registers the provided extended operation handler with the Directory 5145 * Server. 5146 * 5147 * @param oid The OID for the extended operation to register. 5148 * @param handler The extended operation handler to register with the 5149 * Directory Server. 5150 */ 5151 public static void registerSupportedExtension(String oid, 5152 ExtendedOperationHandler handler) 5153 { 5154 directoryServer.extendedOperationHandlers.put(toLowerCase(oid), handler); 5155 } 5156 5157 /** 5158 * Deregisters the provided extended operation handler with the Directory 5159 * Server. 5160 * 5161 * @param oid The OID for the extended operation to deregister. 5162 */ 5163 public static void deregisterSupportedExtension(String oid) 5164 { 5165 directoryServer.extendedOperationHandlers.remove(toLowerCase(oid)); 5166 } 5167 5168 /** 5169 * Retrieves the set of SASL mechanisms that are supported by the Directory 5170 * Server. 5171 * 5172 * @return The set of SASL mechanisms that are supported by the Directory 5173 * Server. 5174 */ 5175 public static ConcurrentMap<String, SASLMechanismHandler> 5176 getSupportedSASLMechanisms() 5177 { 5178 return directoryServer.saslMechanismHandlers; 5179 } 5180 5181 /** 5182 * Retrieves the handler for the specified SASL mechanism. 5183 * 5184 * @param name The name of the SASL mechanism to retrieve. 5185 * 5186 * @return The handler for the specified SASL mechanism, or <CODE>null</CODE> 5187 * if there is none. 5188 */ 5189 public static SASLMechanismHandler getSASLMechanismHandler(String name) 5190 { 5191 return directoryServer.saslMechanismHandlers.get(name); 5192 } 5193 5194 /** 5195 * Registers the provided SASL mechanism handler with the Directory Server. 5196 * 5197 * @param name The name of the SASL mechanism to be registered. 5198 * @param handler The SASL mechanism handler to register with the Directory 5199 * Server. 5200 */ 5201 public static void registerSASLMechanismHandler(String name, 5202 SASLMechanismHandler handler) 5203 { 5204 // FIXME -- Should we force this name to be lowercase? If so, then will 5205 // that cause the lower name to be used in the root DSE? 5206 directoryServer.saslMechanismHandlers.put(name, handler); 5207 } 5208 5209 /** 5210 * Deregisters the provided SASL mechanism handler with the Directory Server. 5211 * 5212 * @param name The name of the SASL mechanism to be deregistered. 5213 */ 5214 public static void deregisterSASLMechanismHandler(String name) 5215 { 5216 // FIXME -- Should we force this name to be lowercase? 5217 directoryServer.saslMechanismHandlers.remove(name); 5218 } 5219 5220 /** 5221 * Retrieves the supported LDAP versions for the Directory Server. 5222 * 5223 * @return The supported LDAP versions for the Directory Server. 5224 */ 5225 public static Set<Integer> getSupportedLDAPVersions() 5226 { 5227 return directoryServer.supportedLDAPVersions.keySet(); 5228 } 5229 5230 /** 5231 * Registers the provided LDAP protocol version as supported within the 5232 * Directory Server. 5233 * 5234 * @param supportedLDAPVersion The LDAP protocol version to register as 5235 * supported. 5236 * @param connectionHandler The connection handler that supports the 5237 * provided LDAP version. Note that multiple 5238 * connection handlers can provide support for 5239 * the same LDAP versions. 5240 */ 5241 public static synchronized void registerSupportedLDAPVersion( 5242 int supportedLDAPVersion, 5243 ConnectionHandler connectionHandler) 5244 { 5245 List<ConnectionHandler> handlers = directoryServer.supportedLDAPVersions.get(supportedLDAPVersion); 5246 if (handlers == null) 5247 { 5248 directoryServer.supportedLDAPVersions.put(supportedLDAPVersion, newLinkedList(connectionHandler)); 5249 } 5250 else if (!handlers.contains(connectionHandler)) 5251 { 5252 handlers.add(connectionHandler); 5253 } 5254 } 5255 5256 /** 5257 * Deregisters the provided LDAP protocol version as supported within the 5258 * Directory Server. 5259 * 5260 * @param supportedLDAPVersion The LDAP protocol version to deregister. 5261 * @param connectionHandler The connection handler that no longer 5262 * supports the provided LDAP version. 5263 */ 5264 public static synchronized void deregisterSupportedLDAPVersion( 5265 int supportedLDAPVersion, 5266 ConnectionHandler connectionHandler) 5267 { 5268 List<ConnectionHandler> handlers = 5269 directoryServer.supportedLDAPVersions.get(supportedLDAPVersion); 5270 if (handlers != null) 5271 { 5272 handlers.remove(connectionHandler); 5273 if (handlers.isEmpty()) 5274 { 5275 directoryServer.supportedLDAPVersions.remove(supportedLDAPVersion); 5276 } 5277 } 5278 } 5279 5280 /** 5281 * Retrieves the set of identity mappers defined in the Directory Server 5282 * configuration, as a mapping between the DN of the configuration entry and 5283 * the identity mapper. 5284 * 5285 * @return The set of identity mappers defined in the Directory Server 5286 * configuration. 5287 */ 5288 public static ConcurrentMap<DN, IdentityMapper> getIdentityMappers() 5289 { 5290 return directoryServer.identityMappers; 5291 } 5292 5293 /** 5294 * Retrieves the Directory Server identity mapper whose configuration resides 5295 * in the specified configuration entry. 5296 * 5297 * @param configEntryDN The DN of the configuration entry for the identity 5298 * mapper to retrieve. 5299 * 5300 * @return The requested identity mapper, or <CODE>null</CODE> if the 5301 * provided entry DN is not associated with an active identity 5302 * mapper. 5303 */ 5304 public static IdentityMapper getIdentityMapper(DN configEntryDN) 5305 { 5306 return directoryServer.identityMappers.get(configEntryDN); 5307 } 5308 5309 /** 5310 * Registers the provided identity mapper for use with the Directory Server. 5311 * 5312 * @param configEntryDN The DN of the configuration entry in which the 5313 * identity mapper definition resides. 5314 * @param identityMapper The identity mapper to be registered. 5315 */ 5316 public static void registerIdentityMapper(DN configEntryDN, 5317 IdentityMapper identityMapper) 5318 { 5319 directoryServer.identityMappers.put(configEntryDN, identityMapper); 5320 } 5321 5322 /** 5323 * Deregisters the provided identity mapper for use with the Directory Server. 5324 * 5325 * @param configEntryDN The DN of the configuration entry in which the 5326 * identity mapper definition resides. 5327 */ 5328 public static void deregisterIdentityMapper(DN configEntryDN) 5329 { 5330 directoryServer.identityMappers.remove(configEntryDN); 5331 } 5332 5333 /** 5334 * Retrieves the DN of the configuration entry for the identity mapper that 5335 * should be used in conjunction with proxied authorization V2 controls. 5336 * 5337 * @return The DN of the configuration entry for the identity mapper that 5338 * should be used in conjunction with proxied authorization V2 5339 * controls, or <CODE>null</CODE> if none is defined. 5340 */ 5341 public static DN getProxiedAuthorizationIdentityMapperDN() 5342 { 5343 return directoryServer.proxiedAuthorizationIdentityMapperDN; 5344 } 5345 5346 /** 5347 * Specifies the DN of the configuration entry for the identity mapper that 5348 * should be used in conjunction with proxied authorization V2 controls. 5349 * 5350 * @param proxiedAuthorizationIdentityMapperDN The DN of the configuration 5351 * entry for the identity mapper 5352 * that should be used in 5353 * conjunction with proxied 5354 * authorization V2 controls. 5355 */ 5356 public static void setProxiedAuthorizationIdentityMapperDN( 5357 DN proxiedAuthorizationIdentityMapperDN) 5358 { 5359 directoryServer.proxiedAuthorizationIdentityMapperDN = 5360 proxiedAuthorizationIdentityMapperDN; 5361 } 5362 5363 /** 5364 * Retrieves the identity mapper that should be used to resolve authorization 5365 * IDs contained in proxied authorization V2 controls. 5366 * 5367 * @return The identity mapper that should be used to resolve authorization 5368 * IDs contained in proxied authorization V2 controls, or 5369 * <CODE>null</CODE> if none is defined. 5370 */ 5371 public static IdentityMapper getProxiedAuthorizationIdentityMapper() 5372 { 5373 if (directoryServer.proxiedAuthorizationIdentityMapperDN == null) 5374 { 5375 return null; 5376 } 5377 5378 return directoryServer.identityMappers.get( 5379 directoryServer.proxiedAuthorizationIdentityMapperDN); 5380 } 5381 5382 /** 5383 * Retrieves the set of connection handlers configured in the Directory 5384 * Server. The returned list must not be altered. 5385 * 5386 * @return The set of connection handlers configured in the Directory Server. 5387 */ 5388 public static List<ConnectionHandler> getConnectionHandlers() 5389 { 5390 return directoryServer.connectionHandlers; 5391 } 5392 5393 /** 5394 * Registers the provided connection handler with the Directory Server. 5395 * 5396 * @param handler The connection handler to register with the Directory 5397 * Server. 5398 */ 5399 public static void registerConnectionHandler( 5400 ConnectionHandler<? extends ConnectionHandlerCfg> 5401 handler) 5402 { 5403 synchronized (directoryServer.connectionHandlers) 5404 { 5405 directoryServer.connectionHandlers.add(handler); 5406 5407 ConnectionHandlerMonitor monitor = new ConnectionHandlerMonitor(handler); 5408 monitor.initializeMonitorProvider(null); 5409 handler.setConnectionHandlerMonitor(monitor); 5410 registerMonitorProvider(monitor); 5411 } 5412 } 5413 5414 /** 5415 * Deregisters the provided connection handler with the Directory Server. 5416 * 5417 * @param handler The connection handler to deregister with the Directory 5418 * Server. 5419 */ 5420 public static void deregisterConnectionHandler(ConnectionHandler handler) 5421 { 5422 synchronized (directoryServer.connectionHandlers) 5423 { 5424 directoryServer.connectionHandlers.remove(handler); 5425 5426 ConnectionHandlerMonitor monitor = handler.getConnectionHandlerMonitor(); 5427 if (monitor != null) 5428 { 5429 deregisterMonitorProvider(monitor); 5430 monitor.finalizeMonitorProvider(); 5431 handler.setConnectionHandlerMonitor(null); 5432 } 5433 } 5434 } 5435 5436 /** 5437 * Starts the connection handlers defined in the Directory Server 5438 * Configuration. 5439 * 5440 * @throws ConfigException If there are more than one connection handlers 5441 * using the same host port or no connection handler 5442 * are enabled or we could not bind to any of the 5443 * listeners. 5444 */ 5445 private void startConnectionHandlers() throws ConfigException 5446 { 5447 Set<HostPort> usedListeners = new LinkedHashSet<>(); 5448 Set<LocalizableMessage> errorMessages = new LinkedHashSet<>(); 5449 // Check that the port specified in the connection handlers is available. 5450 for (ConnectionHandler<?> c : connectionHandlers) 5451 { 5452 for (HostPort listener : c.getListeners()) 5453 { 5454 if (!usedListeners.add(listener)) 5455 { 5456 // The port was already specified: this is a configuration error, 5457 // log a message. 5458 LocalizableMessage message = ERR_HOST_PORT_ALREADY_SPECIFIED.get(c.getConnectionHandlerName(), listener); 5459 logger.error(message); 5460 errorMessages.add(message); 5461 } 5462 } 5463 } 5464 5465 if (!errorMessages.isEmpty()) 5466 { 5467 throw new ConfigException(ERR_ERROR_STARTING_CONNECTION_HANDLERS.get()); 5468 } 5469 5470 // If there are no connection handlers log a message. 5471 if (connectionHandlers.isEmpty()) 5472 { 5473 logger.error(ERR_NOT_AVAILABLE_CONNECTION_HANDLERS); 5474 throw new ConfigException(ERR_ERROR_STARTING_CONNECTION_HANDLERS.get()); 5475 } 5476 5477 // At this point, we should be ready to go. 5478 for (ConnectionHandler handler : connectionHandlers) 5479 { 5480 handler.start(); 5481 } 5482 } 5483 5484 /** 5485 * Retrieves a reference to the Directory Server work queue. 5486 * 5487 * @return A reference to the Directory Server work queue. 5488 */ 5489 public static WorkQueue getWorkQueue() 5490 { 5491 return directoryServer.workQueue; 5492 } 5493 5494 /** 5495 * Runs all the necessary checks prior to adding an operation to the work 5496 * queue. It throws a DirectoryException if one of the check fails. 5497 * 5498 * @param operation 5499 * The operation to be added to the work queue. 5500 * @param isAllowedInLockDownMode 5501 * Flag to indicate if the request can be added to the work queue regardless 5502 * of the server's lock down mode. 5503 * @throws DirectoryException 5504 * If a check failed preventing the operation from being added to 5505 * the queue 5506 */ 5507 public static void checkCanEnqueueRequest(Operation operation, boolean isAllowedInLockDownMode) 5508 throws DirectoryException 5509 { 5510 ClientConnection clientConnection = operation.getClientConnection(); 5511 //Reject or accept the unauthenticated requests based on the configuration settings. 5512 if (!clientConnection.getAuthenticationInfo().isAuthenticated() && 5513 (directoryServer.rejectUnauthenticatedRequests || 5514 (directoryServer.lockdownMode && !isAllowedInLockDownMode))) 5515 { 5516 switch(operation.getOperationType()) 5517 { 5518 case ADD: 5519 case COMPARE: 5520 case DELETE: 5521 case SEARCH: 5522 case MODIFY: 5523 case MODIFY_DN: 5524 LocalizableMessage message = directoryServer.lockdownMode 5525 ? NOTE_REJECT_OPERATION_IN_LOCKDOWN_MODE.get() 5526 : ERR_REJECT_UNAUTHENTICATED_OPERATION.get(); 5527 throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); 5528 5529 case EXTENDED: 5530 ExtendedOperationBasis extOp = (ExtendedOperationBasis) operation; 5531 switch (extOp.getRequestOID()) 5532 { 5533 case OID_START_TLS_REQUEST: 5534 // Clients must be allowed to enable TLS before authenticating. 5535 break; 5536 case OID_GET_SYMMETRIC_KEY_EXTENDED_OP: 5537 // Authentication is not required for the get symmetric key request as it depends on out of band trust 5538 // negotiation. See OPENDJ-3445. 5539 break; 5540 default: 5541 message = directoryServer.lockdownMode 5542 ? NOTE_REJECT_OPERATION_IN_LOCKDOWN_MODE.get() 5543 : ERR_REJECT_UNAUTHENTICATED_OPERATION.get(); 5544 throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); 5545 } 5546 break; 5547 } 5548 } 5549 5550 // If the associated user is required to change their password before 5551 // continuing, then make sure the associated operation is one that could 5552 // result in the password being changed. If not, then reject it. 5553 if (clientConnection.mustChangePassword()) 5554 { 5555 switch (operation.getOperationType()) 5556 { 5557 case ADD: 5558 case COMPARE: 5559 case DELETE: 5560 case MODIFY_DN: 5561 case SEARCH: 5562 // See if the request included the password policy request control. 5563 // If it did, then add a corresponding response control. 5564 for (Control c : operation.getRequestControls()) 5565 { 5566 if (OID_PASSWORD_POLICY_CONTROL.equals(c.getOID())) 5567 { 5568 operation.addResponseControl(new PasswordPolicyResponseControl( 5569 null, 0, PasswordPolicyErrorType.CHANGE_AFTER_RESET)); 5570 break; 5571 } 5572 } 5573 5574 DN user = clientConnection.getAuthenticationInfo() 5575 .getAuthorizationDN(); 5576 LocalizableMessage message = ERR_ENQUEUE_MUST_CHANGE_PASSWORD 5577 .get(user != null ? user : "anonymous"); 5578 throw new DirectoryException( 5579 ResultCode.CONSTRAINT_VIOLATION, message); 5580 5581 case EXTENDED: 5582 // We will only allow the password modify and StartTLS extended 5583 // operations. 5584 ExtendedOperationBasis extOp = (ExtendedOperationBasis) operation; 5585 String requestOID = extOp.getRequestOID(); 5586 if (!OID_PASSWORD_MODIFY_REQUEST.equals(requestOID) 5587 && !OID_START_TLS_REQUEST.equals(requestOID)) 5588 { 5589 // See if the request included the password policy request control. 5590 // If it did, then add a corresponding response control. 5591 for (Control c : operation.getRequestControls()) 5592 { 5593 if (OID_PASSWORD_POLICY_CONTROL.equals(c.getOID())) 5594 { 5595 operation.addResponseControl(new PasswordPolicyResponseControl( 5596 null, 0, PasswordPolicyErrorType.CHANGE_AFTER_RESET)); 5597 break; 5598 } 5599 } 5600 5601 user = clientConnection.getAuthenticationInfo() 5602 .getAuthorizationDN(); 5603 message = ERR_ENQUEUE_MUST_CHANGE_PASSWORD 5604 .get(user != null ? user : "anonymous"); 5605 throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, 5606 message); 5607 } 5608 5609 break; 5610 5611 // Bind, unbind, and abandon will always be allowed. 5612 5613 // Modify may or may not be allowed, but we'll leave that 5614 // determination up to the modify operation itself. 5615 } 5616 } 5617 } 5618 5619 /** 5620 * Adds the provided operation to the work queue so that it will be processed 5621 * by one of the worker threads. 5622 * 5623 * @param operation The operation to be added to the work queue. 5624 * 5625 * @throws DirectoryException If a problem prevents the operation from being 5626 * added to the queue (e.g., the queue is full). 5627 */ 5628 public static void enqueueRequest(Operation operation) 5629 throws DirectoryException 5630 { 5631 checkCanEnqueueRequest(operation, false); 5632 directoryServer.workQueue.submitOperation(operation); 5633 } 5634 5635 /** 5636 * Tries to add the provided operation to the work queue if not full so that 5637 * it will be processed by one of the worker threads. 5638 * 5639 * @param operation 5640 * The operation to be added to the work queue. 5641 * @return true if the operation could be enqueued, false otherwise 5642 * @throws DirectoryException 5643 * If a problem prevents the operation from being added to the queue 5644 * (e.g., the queue is full). 5645 */ 5646 public static boolean tryEnqueueRequest(Operation operation) 5647 throws DirectoryException 5648 { 5649 checkCanEnqueueRequest(operation, false); 5650 return directoryServer.workQueue.trySubmitOperation(operation); 5651 } 5652 5653 /** 5654 * Retrieves the set of synchronization providers that have been registered 5655 * with the Directory Server. 5656 * 5657 * @return The set of synchronization providers that have been registered 5658 * with the Directory Server. 5659 */ 5660 public static List<SynchronizationProvider<SynchronizationProviderCfg>> 5661 getSynchronizationProviders() 5662 { 5663 return directoryServer.synchronizationProviders; 5664 } 5665 5666 /** 5667 * Registers the provided synchronization provider with the Directory Server. 5668 * 5669 * @param provider The synchronization provider to register. 5670 */ 5671 public static void registerSynchronizationProvider( 5672 SynchronizationProvider<SynchronizationProviderCfg> provider) 5673 { 5674 directoryServer.synchronizationProviders.add(provider); 5675 5676 provider.completeSynchronizationProvider(); 5677 } 5678 5679 /** 5680 * Deregisters the provided synchronization provider with the Directory 5681 * Server. 5682 * 5683 * @param provider The synchronization provider to deregister. 5684 */ 5685 public static void deregisterSynchronizationProvider(SynchronizationProvider 5686 provider) 5687 { 5688 directoryServer.synchronizationProviders.remove(provider); 5689 } 5690 5691 /** 5692 * Retrieves a set containing the names of the allowed tasks that may be 5693 * invoked in the server. 5694 * 5695 * @return A set containing the names of the allowed tasks that may be 5696 * invoked in the server. 5697 */ 5698 public static Set<String> getAllowedTasks() 5699 { 5700 return directoryServer.allowedTasks; 5701 } 5702 5703 /** 5704 * Specifies the set of allowed tasks that may be invoked in the server. 5705 * 5706 * @param allowedTasks A set containing the names of the allowed tasks that 5707 * may be invoked in the server. 5708 */ 5709 public static void setAllowedTasks(Set<String> allowedTasks) 5710 { 5711 directoryServer.allowedTasks = allowedTasks; 5712 } 5713 5714 /** 5715 * Retrieves the set of privileges that have been disabled. 5716 * 5717 * @return The set of privileges that have been disabled. 5718 */ 5719 public static Set<Privilege> getDisabledPrivileges() 5720 { 5721 return directoryServer.disabledPrivileges; 5722 } 5723 5724 /** 5725 * Indicates whether the specified privilege is disabled. 5726 * 5727 * @param privilege The privilege for which to make the determination. 5728 * 5729 * @return {@code true} if the specified privilege is disabled, or 5730 * {@code false} if not. 5731 */ 5732 public static boolean isDisabled(Privilege privilege) 5733 { 5734 return directoryServer.disabledPrivileges.contains(privilege); 5735 } 5736 5737 /** 5738 * Specifies the set of privileges that should be disabled in the server. 5739 * 5740 * @param disabledPrivileges The set of privileges that should be disabled 5741 * in the server. 5742 */ 5743 public static void setDisabledPrivileges(Set<Privilege> disabledPrivileges) 5744 { 5745 directoryServer.disabledPrivileges = disabledPrivileges; 5746 } 5747 5748 /** 5749 * Indicates whether responses to failed bind operations should include a 5750 * message explaining the reason for the failure. 5751 * 5752 * @return {@code true} if bind responses should include error messages, or 5753 * {@code false} if not. 5754 */ 5755 public static boolean returnBindErrorMessages() 5756 { 5757 return directoryServer.returnBindErrorMessages; 5758 } 5759 5760 /** 5761 * Specifies whether responses to failed bind operations should include a 5762 * message explaining the reason for the failure. 5763 * 5764 * @param returnBindErrorMessages Specifies whether responses to failed bind 5765 * operations should include a message 5766 * explaining the reason for the failure. 5767 */ 5768 public static void setReturnBindErrorMessages(boolean returnBindErrorMessages) 5769 { 5770 directoryServer.returnBindErrorMessages = returnBindErrorMessages; 5771 } 5772 5773 /** 5774 * Retrieves the maximum length of time in milliseconds that client 5775 * connections should be allowed to remain idle without being disconnected. 5776 * 5777 * @return The maximum length of time in milliseconds that client connections 5778 * should be allowed to remain idle without being disconnected. 5779 */ 5780 public static long getIdleTimeLimit() 5781 { 5782 return directoryServer.idleTimeLimit; 5783 } 5784 5785 /** 5786 * Specifies the maximum length of time in milliseconds that client 5787 * connections should be allowed to remain idle without being disconnected. 5788 * 5789 * @param idleTimeLimit The maximum length of time in milliseconds that 5790 * client connections should be allowed to remain idle 5791 * without being disconnected. 5792 */ 5793 public static void setIdleTimeLimit(long idleTimeLimit) 5794 { 5795 directoryServer.idleTimeLimit = idleTimeLimit; 5796 } 5797 5798 /** 5799 * Indicates whether the Directory Server should save a copy of its 5800 * configuration whenever it is started successfully. 5801 * 5802 * @return {@code true} if the server should save a copy of its configuration 5803 * whenever it is started successfully, or {@code false} if not. 5804 */ 5805 public static boolean saveConfigOnSuccessfulStartup() 5806 { 5807 return directoryServer.saveConfigOnSuccessfulStartup; 5808 } 5809 5810 /** 5811 * Specifies whether the Directory Server should save a copy of its 5812 * configuration whenever it is started successfully. 5813 * 5814 * @param saveConfigOnSuccessfulStartup Specifies whether the server should 5815 * save a copy of its configuration 5816 * whenever it is started successfully. 5817 */ 5818 public static void setSaveConfigOnSuccessfulStartup( 5819 boolean saveConfigOnSuccessfulStartup) 5820 { 5821 directoryServer.saveConfigOnSuccessfulStartup = 5822 saveConfigOnSuccessfulStartup; 5823 } 5824 5825 /** 5826 * Registers the provided backup task listener with the Directory Server. 5827 * 5828 * @param listener The backup task listener to register with the Directory 5829 * Server. 5830 */ 5831 public static void registerBackupTaskListener(BackupTaskListener listener) 5832 { 5833 directoryServer.backupTaskListeners.addIfAbsent(listener); 5834 } 5835 5836 /** 5837 * Deregisters the provided backup task listener with the Directory Server. 5838 * 5839 * @param listener The backup task listener to deregister with the Directory 5840 * Server. 5841 */ 5842 public static void deregisterBackupTaskListener(BackupTaskListener listener) 5843 { 5844 directoryServer.backupTaskListeners.remove(listener); 5845 } 5846 5847 /** 5848 * Notifies the registered backup task listeners that the server will be 5849 * beginning a backup task with the provided information. 5850 * 5851 * @param backend The backend in which the backup is to be performed. 5852 * @param config The configuration for the backup to be performed. 5853 */ 5854 public static void notifyBackupBeginning(Backend<?> backend, BackupConfig config) 5855 { 5856 for (BackupTaskListener listener : directoryServer.backupTaskListeners) 5857 { 5858 try 5859 { 5860 listener.processBackupBegin(backend, config); 5861 } 5862 catch (Exception e) 5863 { 5864 logger.traceException(e); 5865 } 5866 } 5867 } 5868 5869 /** 5870 * Notifies the registered backup task listeners that the server has completed 5871 * processing on a backup task with the provided information. 5872 * 5873 * @param backend The backend in which the backup was performed. 5874 * @param config The configuration for the backup that was performed. 5875 * @param successful Indicates whether the backup completed successfully. 5876 */ 5877 public static void notifyBackupEnded(Backend<?> backend, BackupConfig config, boolean successful) 5878 { 5879 for (BackupTaskListener listener : directoryServer.backupTaskListeners) 5880 { 5881 try 5882 { 5883 listener.processBackupEnd(backend, config, successful); 5884 } 5885 catch (Exception e) 5886 { 5887 logger.traceException(e); 5888 } 5889 } 5890 } 5891 5892 /** 5893 * Registers the provided restore task listener with the Directory Server. 5894 * 5895 * @param listener The restore task listener to register with the Directory 5896 * Server. 5897 */ 5898 public static void registerRestoreTaskListener(RestoreTaskListener listener) 5899 { 5900 directoryServer.restoreTaskListeners.addIfAbsent(listener); 5901 } 5902 5903 /** 5904 * Deregisters the provided restore task listener with the Directory Server. 5905 * 5906 * @param listener The restore task listener to deregister with the 5907 * Directory Server. 5908 */ 5909 public static void deregisterRestoreTaskListener(RestoreTaskListener listener) 5910 { 5911 directoryServer.restoreTaskListeners.remove(listener); 5912 } 5913 5914 /** 5915 * Notifies the registered restore task listeners that the server will be 5916 * beginning a restore task with the provided information. 5917 * 5918 * @param backend The backend in which the restore is to be performed. 5919 * @param config The configuration for the restore to be performed. 5920 */ 5921 public static void notifyRestoreBeginning(Backend<?> backend, RestoreConfig config) 5922 { 5923 for (RestoreTaskListener listener : directoryServer.restoreTaskListeners) 5924 { 5925 try 5926 { 5927 listener.processRestoreBegin(backend, config); 5928 } 5929 catch (Exception e) 5930 { 5931 logger.traceException(e); 5932 } 5933 } 5934 } 5935 5936 /** 5937 * Notifies the registered restore task listeners that the server has 5938 * completed processing on a restore task with the provided information. 5939 * 5940 * @param backend The backend in which the restore was performed. 5941 * @param config The configuration for the restore that was performed. 5942 * @param successful Indicates whether the restore completed successfully. 5943 */ 5944 public static void notifyRestoreEnded(Backend<?> backend, RestoreConfig config, boolean successful) 5945 { 5946 for (RestoreTaskListener listener : directoryServer.restoreTaskListeners) 5947 { 5948 try 5949 { 5950 listener.processRestoreEnd(backend, config, successful); 5951 } 5952 catch (Exception e) 5953 { 5954 logger.traceException(e); 5955 } 5956 } 5957 } 5958 5959 /** 5960 * Registers the provided LDIF export task listener with the Directory Server. 5961 * 5962 * @param listener The export task listener to register with the Directory 5963 * Server. 5964 */ 5965 public static void registerExportTaskListener(ExportTaskListener listener) 5966 { 5967 directoryServer.exportTaskListeners.addIfAbsent(listener); 5968 } 5969 5970 /** 5971 * Deregisters the provided LDIF export task listener with the Directory 5972 * Server. 5973 * 5974 * @param listener The export task listener to deregister with the Directory 5975 * Server. 5976 */ 5977 public static void deregisterExportTaskListener(ExportTaskListener listener) 5978 { 5979 directoryServer.exportTaskListeners.remove(listener); 5980 } 5981 5982 /** 5983 * Notifies the registered LDIF export task listeners that the server will be 5984 * beginning an export task with the provided information. 5985 * 5986 * @param backend The backend in which the export is to be performed. 5987 * @param config The configuration for the export to be performed. 5988 */ 5989 public static void notifyExportBeginning(Backend<?> backend, LDIFExportConfig config) 5990 { 5991 for (ExportTaskListener listener : directoryServer.exportTaskListeners) 5992 { 5993 try 5994 { 5995 listener.processExportBegin(backend, config); 5996 } 5997 catch (Exception e) 5998 { 5999 logger.traceException(e); 6000 } 6001 } 6002 } 6003 6004 /** 6005 * Notifies the registered LDIF export task listeners that the server has 6006 * completed processing on an export task with the provided information. 6007 * 6008 * @param backend The backend in which the export was performed. 6009 * @param config The configuration for the export that was performed. 6010 * @param successful Indicates whether the export completed successfully. 6011 */ 6012 public static void notifyExportEnded(Backend<?> backend, LDIFExportConfig config, boolean successful) 6013 { 6014 for (ExportTaskListener listener : directoryServer.exportTaskListeners) 6015 { 6016 try 6017 { 6018 listener.processExportEnd(backend, config, successful); 6019 } 6020 catch (Exception e) 6021 { 6022 logger.traceException(e); 6023 } 6024 } 6025 } 6026 6027 /** 6028 * Registers the provided LDIF import task listener with the Directory Server. 6029 * 6030 * @param listener The import task listener to register with the Directory 6031 * Server. 6032 */ 6033 public static void registerImportTaskListener(ImportTaskListener listener) 6034 { 6035 directoryServer.importTaskListeners.addIfAbsent(listener); 6036 } 6037 6038 /** 6039 * Deregisters the provided LDIF import task listener with the Directory 6040 * Server. 6041 * 6042 * @param listener The import task listener to deregister with the Directory 6043 * Server. 6044 */ 6045 public static void deregisterImportTaskListener(ImportTaskListener listener) 6046 { 6047 directoryServer.importTaskListeners.remove(listener); 6048 } 6049 6050 /** 6051 * Notifies the registered LDIF import task listeners that the server will be 6052 * beginning an import task with the provided information. 6053 * 6054 * @param backend The backend in which the import is to be performed. 6055 * @param config The configuration for the import to be performed. 6056 */ 6057 public static void notifyImportBeginning(Backend<?> backend, LDIFImportConfig config) 6058 { 6059 for (ImportTaskListener listener : directoryServer.importTaskListeners) 6060 { 6061 try 6062 { 6063 listener.processImportBegin(backend, config); 6064 } 6065 catch (Exception e) 6066 { 6067 logger.traceException(e); 6068 } 6069 } 6070 } 6071 6072 /** 6073 * Notifies the registered LDIF import task listeners that the server has 6074 * completed processing on an import task with the provided information. 6075 * 6076 * @param backend The backend in which the import was performed. 6077 * @param config The configuration for the import that was performed. 6078 * @param successful Indicates whether the import completed successfully. 6079 */ 6080 public static void notifyImportEnded(Backend<?> backend, LDIFImportConfig config, boolean successful) 6081 { 6082 for (ImportTaskListener listener : directoryServer.importTaskListeners) 6083 { 6084 try 6085 { 6086 listener.processImportEnd(backend, config, successful); 6087 } 6088 catch (Exception e) 6089 { 6090 logger.traceException(e); 6091 } 6092 } 6093 } 6094 6095 /** 6096 * Registers the provided initialization completed listener with the 6097 * Directory Server so that it will be notified when the server 6098 * initialization completes. 6099 * 6100 * @param listener The initialization competed listener to register with 6101 * the Directory Server. 6102 */ 6103 public static void registerInitializationCompletedListener( 6104 InitializationCompletedListener listener) { 6105 directoryServer.initializationCompletedListeners.add(listener); 6106 } 6107 6108 /** 6109 * Deregisters the provided initialization completed listener with the 6110 * Directory Server. 6111 * 6112 * @param listener The initialization completed listener to deregister with 6113 * the Directory Server. 6114 */ 6115 public static void deregisterInitializationCompletedListener( 6116 InitializationCompletedListener listener) { 6117 directoryServer.initializationCompletedListeners.remove(listener); 6118 } 6119 6120 /** 6121 * Registers the provided shutdown listener with the Directory Server so that 6122 * it will be notified when the server shuts down. 6123 * 6124 * @param listener The shutdown listener to register with the Directory 6125 * Server. 6126 */ 6127 public static void registerShutdownListener(ServerShutdownListener listener) 6128 { 6129 directoryServer.shutdownListeners.add(listener); 6130 } 6131 6132 /** 6133 * Deregisters the provided shutdown listener with the Directory Server. 6134 * 6135 * @param listener The shutdown listener to deregister with the Directory 6136 * Server. 6137 */ 6138 public static void deregisterShutdownListener(ServerShutdownListener listener) 6139 { 6140 directoryServer.shutdownListeners.remove(listener); 6141 } 6142 6143 /** 6144 * Initiates the Directory Server shutdown process. Note that once this has 6145 * started, it should not be interrupted. 6146 * 6147 * @param className The fully-qualified name of the Java class that 6148 * initiated the shutdown. 6149 * @param reason The human-readable reason that the directory server is 6150 * shutting down. 6151 */ 6152 public static void shutDown(String className, LocalizableMessage reason) 6153 { 6154 synchronized (directoryServer) 6155 { 6156 if (directoryServer.shuttingDown) 6157 { 6158 // We already know that the server is shutting down, so we don't need to 6159 // do anything. 6160 return; 6161 } 6162 6163 directoryServer.shuttingDown = true; 6164 } 6165 6166 // Send an alert notification that the server is shutting down. 6167 sendAlertNotification(directoryServer, ALERT_TYPE_SERVER_SHUTDOWN, 6168 NOTE_SERVER_SHUTDOWN.get(className, reason)); 6169 6170 // Create a shutdown monitor that will watch the rest of the shutdown 6171 // process to ensure that everything goes smoothly. 6172 ServerShutdownMonitor shutdownMonitor = new ServerShutdownMonitor(); 6173 shutdownMonitor.start(); 6174 6175 // Shut down the connection handlers. 6176 for (ConnectionHandler handler : directoryServer.connectionHandlers) 6177 { 6178 try 6179 { 6180 handler.finalizeConnectionHandler( 6181 INFO_CONNHANDLER_CLOSED_BY_SHUTDOWN.get()); 6182 } 6183 catch (Exception e) 6184 { 6185 logger.traceException(e); 6186 } 6187 } 6188 directoryServer.connectionHandlers.clear(); 6189 6190 if (directoryServer.workQueue != null) 6191 { 6192 directoryServer.workQueue.finalizeWorkQueue(reason); 6193 directoryServer.workQueue.waitUntilIdle(ServerShutdownMonitor.WAIT_TIME); 6194 } 6195 6196 // shutdown replication 6197 for (SynchronizationProvider provider : 6198 directoryServer.synchronizationProviders) 6199 { 6200 provider.finalizeSynchronizationProvider(); 6201 } 6202 6203 // Call the shutdown plugins, and then finalize all the plugins defined in 6204 // the server. 6205 if (directoryServer.pluginConfigManager != null) 6206 { 6207 directoryServer.pluginConfigManager.invokeShutdownPlugins(reason); 6208 directoryServer.pluginConfigManager.finalizePlugins(); 6209 } 6210 6211 // Deregister the shutdown hook. 6212 if (directoryServer.shutdownHook != null) 6213 { 6214 try 6215 { 6216 Runtime.getRuntime().removeShutdownHook(directoryServer.shutdownHook); 6217 } 6218 catch (Exception e) {} 6219 } 6220 6221 // Notify all the shutdown listeners. 6222 for (ServerShutdownListener shutdownListener : 6223 directoryServer.shutdownListeners) 6224 { 6225 try 6226 { 6227 shutdownListener.processServerShutdown(reason); 6228 } 6229 catch (Exception e) 6230 { 6231 logger.traceException(e); 6232 } 6233 } 6234 6235 // Shut down all of the alert handlers. 6236 for (AlertHandler alertHandler : directoryServer.alertHandlers) 6237 { 6238 alertHandler.finalizeAlertHandler(); 6239 } 6240 6241 // Deregister all of the JMX MBeans. 6242 if (directoryServer.mBeanServer != null) 6243 { 6244 Set mBeanSet = directoryServer.mBeanServer.queryMBeans(null, null); 6245 for (Object o : mBeanSet) 6246 { 6247 if (o instanceof DirectoryServerMBean) 6248 { 6249 try 6250 { 6251 DirectoryServerMBean mBean = (DirectoryServerMBean) o; 6252 directoryServer.mBeanServer.unregisterMBean(mBean.getObjectName()); 6253 } 6254 catch (Exception e) 6255 { 6256 logger.traceException(e); 6257 } 6258 } 6259 } 6260 } 6261 6262 // Finalize all of the SASL mechanism handlers. 6263 for (SASLMechanismHandler handler : 6264 directoryServer.saslMechanismHandlers.values()) 6265 { 6266 try 6267 { 6268 handler.finalizeSASLMechanismHandler(); 6269 } 6270 catch (Exception e) 6271 { 6272 logger.traceException(e); 6273 } 6274 } 6275 6276 // Finalize all of the extended operation handlers. 6277 for (ExtendedOperationHandler handler : 6278 directoryServer.extendedOperationHandlers.values()) 6279 { 6280 try 6281 { 6282 handler.finalizeExtendedOperationHandler(); 6283 } 6284 catch (Exception e) 6285 { 6286 logger.traceException(e); 6287 } 6288 } 6289 6290 // Finalize the password policy map. 6291 for (DN configEntryDN : directoryServer.authenticationPolicies.keySet()) 6292 { 6293 DirectoryServer.deregisterAuthenticationPolicy(configEntryDN); 6294 } 6295 6296 // Finalize password policies and their config manager. 6297 if (directoryServer.authenticationPolicyConfigManager != null) 6298 { 6299 directoryServer.authenticationPolicyConfigManager 6300 .finalizeAuthenticationPolicies(); 6301 } 6302 6303 // Finalize the access control handler 6304 AccessControlHandler accessControlHandler = 6305 AccessControlConfigManager.getInstance().getAccessControlHandler(); 6306 if (accessControlHandler != null) 6307 { 6308 accessControlHandler.finalizeAccessControlHandler(); 6309 } 6310 6311 // Perform any necessary cleanup work for the group manager. 6312 if (directoryServer.groupManager != null) 6313 { 6314 directoryServer.groupManager.finalizeGroupManager(); 6315 } 6316 6317 // Finalize the subentry manager. 6318 if (directoryServer.subentryManager != null) 6319 { 6320 directoryServer.subentryManager.finalizeSubentryManager(); 6321 } 6322 6323 // Shut down all the other components that may need special handling. 6324 // NYI 6325 6326 // Shut down the monitor providers. 6327 for (MonitorProvider monitor : directoryServer.monitorProviders.values()) 6328 { 6329 try 6330 { 6331 monitor.finalizeMonitorProvider(); 6332 } 6333 catch (Exception e) 6334 { 6335 logger.traceException(e); 6336 } 6337 } 6338 6339 // Shut down the backends. 6340 for (Backend<?> backend : directoryServer.backends.values()) 6341 { 6342 try 6343 { 6344 for (BackendInitializationListener listener : getBackendInitializationListeners()) 6345 { 6346 listener.performBackendPreFinalizationProcessing(backend); 6347 } 6348 6349 // Deregister all the local backend workflow elements that have been 6350 // registered with the server. 6351 LocalBackendWorkflowElement.removeAll(); 6352 6353 for (BackendInitializationListener listener : 6354 directoryServer.backendInitializationListeners) 6355 { 6356 listener.performBackendPostFinalizationProcessing(backend); 6357 } 6358 6359 backend.finalizeBackend(); 6360 6361 // Remove the shared lock for this backend. 6362 try 6363 { 6364 String lockFile = LockFileManager.getBackendLockFileName(backend); 6365 StringBuilder failureReason = new StringBuilder(); 6366 if (! LockFileManager.releaseLock(lockFile, failureReason)) 6367 { 6368 logger.warn(WARN_SHUTDOWN_CANNOT_RELEASE_SHARED_BACKEND_LOCK, backend.getBackendID(), failureReason); 6369 // FIXME -- Do we need to send an admin alert? 6370 } 6371 } 6372 catch (Exception e2) 6373 { 6374 logger.traceException(e2); 6375 6376 logger.warn(WARN_SHUTDOWN_CANNOT_RELEASE_SHARED_BACKEND_LOCK, 6377 backend.getBackendID(), stackTraceToSingleLineString(e2)); 6378 // FIXME -- Do we need to send an admin alert? 6379 } 6380 } 6381 catch (Exception e) 6382 { 6383 logger.traceException(e); 6384 } 6385 } 6386 6387 // Finalize the entry cache. 6388 EntryCache ec = DirectoryServer.getEntryCache(); 6389 if (ec != null) 6390 { 6391 ec.finalizeEntryCache(); 6392 } 6393 6394 // Release exclusive lock held on server.lock file 6395 try { 6396 String serverLockFileName = LockFileManager.getServerLockFileName(); 6397 StringBuilder failureReason = new StringBuilder(); 6398 if (!LockFileManager.releaseLock(serverLockFileName, failureReason)) { 6399 logger.info(NOTE_SERVER_SHUTDOWN, className, failureReason); 6400 } 6401 serverLocked = false; 6402 } catch (Exception e) { 6403 logger.traceException(e); 6404 } 6405 6406 // Force a new InternalClientConnection to be created on restart. 6407 InternalConnectionHandler.clearRootClientConnectionAtShutdown(); 6408 6409 // Log a final message indicating that the server is stopped (which should 6410 // be true for all practical purposes), and then shut down all the error 6411 // loggers. 6412 logger.info(NOTE_SERVER_STOPPED); 6413 6414 AccessLogger.getInstance().removeAllLogPublishers(); 6415 ErrorLogger.getInstance().removeAllLogPublishers(); 6416 DebugLogger.getInstance().removeAllLogPublishers(); 6417 6418 // Now that the loggers are disabled we can shutdown the timer. 6419 TimeThread.stop(); 6420 6421 // Just in case there's something that isn't shut down properly, wait for 6422 // the monitor to give the OK to stop. 6423 shutdownMonitor.waitForMonitor(); 6424 6425 // At this point, the server is no longer running. We should destroy the 6426 // handle to the previous instance, but we will want to get a new instance 6427 // in case the server is to be started again later in the same JVM. Before 6428 // doing that, destroy the previous instance. 6429 DirectoryEnvironmentConfig envConfig = directoryServer.environmentConfig; 6430 directoryServer.destroy(); 6431 directoryServer = getNewInstance(envConfig); 6432 } 6433 6434 /** 6435 * Destroy key structures in the current Directory Server instance in a manner 6436 * that can help detect any inappropriate cached references to server 6437 * components. 6438 */ 6439 private void destroy() 6440 { 6441 checkSchema = true; 6442 isBootstrapped = false; 6443 isRunning = false; 6444 lockdownMode = true; 6445 rejectUnauthenticatedRequests = true; 6446 shuttingDown = true; 6447 6448 configClass = null; 6449 configFile = null; 6450 configHandler = null; 6451 coreConfigManager = null; 6452 compressedSchema = null; 6453 cryptoManager = null; 6454 entryCache = null; 6455 environmentConfig = null; 6456 objectClassAttributeType = null; 6457 schemaDN = null; 6458 shutdownHook = null; 6459 workQueue = null; 6460 6461 if (baseDnRegistry != null) 6462 { 6463 baseDnRegistry.clear(); 6464 baseDnRegistry = null; 6465 } 6466 6467 if (backends != null) 6468 { 6469 backends.clear(); 6470 backends = null; 6471 } 6472 6473 if (schema != null) 6474 { 6475 schema.destroy(); 6476 schema = null; 6477 } 6478 } 6479 6480 /** 6481 * Causes the Directory Server to perform an in-core restart. This will 6482 * cause virtually all components of the Directory Server to shut down, and 6483 * once that has completed it will be restarted. 6484 * 6485 * @param className The fully-qualified name of the Java class that 6486 * initiated the shutdown. 6487 * @param reason The human-readable reason that the directory server is 6488 * shutting down. 6489 */ 6490 public static void restart(String className, LocalizableMessage reason) 6491 { 6492 restart(className, reason, directoryServer.environmentConfig); 6493 } 6494 6495 /** 6496 * Causes the Directory Server to perform an in-core restart. This will 6497 * cause virtually all components of the Directory Server to shut down, and 6498 * once that has completed it will be restarted. 6499 * 6500 * @param className The fully-qualified name of the Java class that 6501 * initiated the shutdown. 6502 * @param reason The human-readable reason that the directory server is 6503 * shutting down. 6504 * @param config The environment configuration to use for the server. 6505 */ 6506 public static void restart(String className, LocalizableMessage reason, 6507 DirectoryEnvironmentConfig config) 6508 { 6509 try 6510 { 6511 shutDown(className, reason); 6512 reinitialize(config); 6513 directoryServer.startServer(); 6514 } 6515 catch (Exception e) 6516 { 6517 System.err.println("ERROR: Unable to perform an in-core restart:"); 6518 e.printStackTrace(); 6519 System.err.println("Halting the JVM so that it must be manually " + 6520 "restarted."); 6521 6522 Runtime.getRuntime().halt(1); 6523 } 6524 } 6525 6526 /** 6527 * Reinitializes the server following a shutdown, preparing it for a call to 6528 * {@code startServer}. 6529 * 6530 * @return The new Directory Server instance created during the 6531 * re-initialization process. 6532 * 6533 * @throws InitializationException If a problem occurs while trying to 6534 * initialize the config handler or 6535 * bootstrap that server. 6536 */ 6537 public static DirectoryServer reinitialize() 6538 throws InitializationException 6539 { 6540 return reinitialize(directoryServer.environmentConfig); 6541 } 6542 6543 /** 6544 * Reinitializes the server following a shutdown, preparing it for a call to 6545 * {@code startServer}. 6546 * 6547 * @param config The environment configuration for the Directory Server. 6548 * 6549 * @return The new Directory Server instance created during the 6550 * re-initialization process. 6551 * 6552 * @throws InitializationException If a problem occurs while trying to 6553 * initialize the config handler or 6554 * bootstrap that server. 6555 */ 6556 public static DirectoryServer reinitialize(DirectoryEnvironmentConfig config) 6557 throws InitializationException 6558 { 6559 // Ensure that the timer thread has started. 6560 TimeThread.start(); 6561 6562 getNewInstance(config); 6563 directoryServer.bootstrapServer(); 6564 directoryServer.initializeConfiguration(); 6565 return directoryServer; 6566 } 6567 6568 /** 6569 * Retrieves the maximum number of concurrent client connections that may be 6570 * established. 6571 * 6572 * @return The maximum number of concurrent client connections that may be 6573 * established, or -1 if there is no limit. 6574 */ 6575 public static long getMaxAllowedConnections() 6576 { 6577 return directoryServer.maxAllowedConnections; 6578 } 6579 6580 /** 6581 * Specifies the maximum number of concurrent client connections that may be 6582 * established. A value that is less than or equal to zero will indicate that 6583 * no limit should be enforced. 6584 * 6585 * @param maxAllowedConnections The maximum number of concurrent client 6586 * connections that may be established. 6587 */ 6588 public static void setMaxAllowedConnections(long maxAllowedConnections) 6589 { 6590 if (maxAllowedConnections > 0) 6591 { 6592 directoryServer.maxAllowedConnections = maxAllowedConnections; 6593 } 6594 else 6595 { 6596 directoryServer.maxAllowedConnections = -1; 6597 } 6598 } 6599 6600 /** 6601 * Indicates that a new connection has been accepted and increments the 6602 * associated counters. 6603 * 6604 * @param clientConnection The client connection that has been established. 6605 * 6606 * @return The connection ID that should be used for this connection, or -1 6607 * if the connection has been rejected for some reason (e.g., the 6608 * maximum number of concurrent connections have already been 6609 * established). 6610 */ 6611 public static long newConnectionAccepted(ClientConnection clientConnection) 6612 { 6613 synchronized (directoryServer.establishedConnections) 6614 { 6615 if (directoryServer.lockdownMode) 6616 { 6617 InetAddress remoteAddress = clientConnection.getRemoteAddress(); 6618 if (remoteAddress != null && !remoteAddress.isLoopbackAddress()) 6619 { 6620 return -1; 6621 } 6622 } 6623 6624 final long maxAllowed = directoryServer.maxAllowedConnections; 6625 if (0 < maxAllowed && maxAllowed <= directoryServer.currentConnections) 6626 { 6627 return -1; 6628 } 6629 6630 directoryServer.establishedConnections.add(clientConnection); 6631 directoryServer.currentConnections++; 6632 6633 if (directoryServer.currentConnections > directoryServer.maxConnections) 6634 { 6635 directoryServer.maxConnections = directoryServer.currentConnections; 6636 } 6637 6638 return directoryServer.totalConnections++; 6639 } 6640 } 6641 6642 /** 6643 * Indicates that the specified client connection has been closed. 6644 * 6645 * @param clientConnection The client connection that has been closed. 6646 */ 6647 public static void connectionClosed(ClientConnection clientConnection) 6648 { 6649 synchronized (directoryServer.establishedConnections) 6650 { 6651 directoryServer.establishedConnections.remove(clientConnection); 6652 directoryServer.currentConnections--; 6653 } 6654 } 6655 6656 /** 6657 * Retrieves the number of client connections that are currently established. 6658 * 6659 * @return The number of client connections that are currently established. 6660 */ 6661 public static long getCurrentConnections() 6662 { 6663 return directoryServer.currentConnections; 6664 } 6665 6666 /** 6667 * Retrieves the maximum number of client connections that have been 6668 * established concurrently. 6669 * 6670 * @return The maximum number of client connections that have been 6671 * established concurrently. 6672 */ 6673 public static long getMaxConnections() 6674 { 6675 return directoryServer.maxConnections; 6676 } 6677 6678 /** 6679 * Retrieves the total number of client connections that have been established 6680 * since the Directory Server started. 6681 * 6682 * @return The total number of client connections that have been established 6683 * since the Directory Server started. 6684 */ 6685 public static long getTotalConnections() 6686 { 6687 return directoryServer.totalConnections; 6688 } 6689 6690 /** 6691 * Retrieves the full version string for the Directory Server. 6692 * 6693 * @return The full version string for the Directory Server. 6694 */ 6695 public static String getVersionString() 6696 { 6697 return FULL_VERSION_STRING; 6698 } 6699 6700 /** 6701 * Prints out the version string for the Directory Server. 6702 * 6703 * 6704 * @param outputStream The output stream to which the version information 6705 * should be written. 6706 * 6707 * @throws IOException If a problem occurs while attempting to write the 6708 * version information to the provided output stream. 6709 */ 6710 public static void printVersion(OutputStream outputStream) 6711 throws IOException 6712 { 6713 outputStream.write(PRINTABLE_VERSION_STRING.getBytes()); 6714 6715 // Print extensions' extra information 6716 String extensionInformation = 6717 ClassLoaderProvider.getInstance().printExtensionInformation(); 6718 if ( extensionInformation != null ) { 6719 outputStream.write(extensionInformation.getBytes()); 6720 } 6721 } 6722 6723 /** 6724 * Retrieves the default maximum number of entries that should be returned for 6725 * a search. 6726 * 6727 * @return The default maximum number of entries that should be returned for 6728 * a search. 6729 */ 6730 public static int getSizeLimit() 6731 { 6732 return directoryServer.sizeLimit; 6733 } 6734 6735 /** 6736 * Specifies the default maximum number of entries that should be returned for 6737 * a search. 6738 * 6739 * @param sizeLimit The default maximum number of entries that should be 6740 * returned for a search. 6741 */ 6742 public static void setSizeLimit(int sizeLimit) 6743 { 6744 directoryServer.sizeLimit = sizeLimit; 6745 } 6746 6747 /** 6748 * Retrieves the default maximum number of entries that should checked for 6749 * matches during a search. 6750 * 6751 * @return The default maximum number of entries that should checked for 6752 * matches during a search. 6753 */ 6754 public static int getLookthroughLimit() 6755 { 6756 return directoryServer.lookthroughLimit; 6757 } 6758 6759 /** 6760 * Specifies the default maximum number of entries that should be checked for 6761 * matches during a search. 6762 * 6763 * @param lookthroughLimit The default maximum number of entries that should 6764 * be check for matches during a search. 6765 */ 6766 public static void setLookthroughLimit(int lookthroughLimit) 6767 { 6768 directoryServer.lookthroughLimit = lookthroughLimit; 6769 } 6770 6771 /** 6772 * Specifies the maximum number of simultaneous persistent 6773 * searches that are allowed. 6774 * 6775 * @param maxPSearches The maximum number of simultaneous persistent 6776 * searches that are allowed. 6777 */ 6778 public static void setMaxPersistentSearchLimit(int maxPSearches) 6779 { 6780 directoryServer.maxPSearches = maxPSearches; 6781 } 6782 6783 /** 6784 * Registers a new persistent search by increasing the count 6785 * of active persistent searches. After receiving a persistent 6786 * search request, a Local or Remote WFE must call this method to 6787 * let the core server manage the count of concurrent persistent 6788 * searches. 6789 */ 6790 public static void registerPersistentSearch() 6791 { 6792 directoryServer.activePSearches.incrementAndGet(); 6793 } 6794 6795 /** 6796 * Deregisters a canceled persistent search. After a persistent 6797 * search is canceled, the handler must call this method to let 6798 * the core server manage the count of concurrent persistent 6799 * searches. 6800 */ 6801 public static void deregisterPersistentSearch() 6802 { 6803 directoryServer.activePSearches.decrementAndGet(); 6804 } 6805 6806 /** 6807 * Indicates whether a new persistent search is allowed. 6808 * 6809 * @return <CODE>true</CODE>if a new persistent search is allowed 6810 * or <CODE>false</CODE>f if not. 6811 */ 6812 public static boolean allowNewPersistentSearch() 6813 { 6814 //-1 indicates that there is no limit. 6815 return directoryServer.maxPSearches == -1 6816 || directoryServer.activePSearches.get() < directoryServer.maxPSearches; 6817 } 6818 6819 /** 6820 * Retrieves the default maximum length of time in seconds that should be 6821 * allowed when processing a search. 6822 * 6823 * @return The default maximum length of time in seconds that should be 6824 * allowed when processing a search. 6825 */ 6826 public static int getTimeLimit() 6827 { 6828 return directoryServer.timeLimit; 6829 } 6830 6831 /** 6832 * Specifies the default maximum length of time in seconds that should be 6833 * allowed when processing a search. 6834 * 6835 * @param timeLimit The default maximum length of time in seconds that 6836 * should be allowed when processing a search. 6837 */ 6838 public static void setTimeLimit(int timeLimit) 6839 { 6840 directoryServer.timeLimit = timeLimit; 6841 } 6842 6843 /** 6844 * Specifies whether to collect nanosecond resolution processing times for 6845 * operations. 6846 * 6847 * @param useNanoTime <code>true</code> if nanosecond resolution times 6848 * should be collected or <code>false</code> to 6849 * only collect in millisecond resolution. 6850 */ 6851 public static void setUseNanoTime(boolean useNanoTime) 6852 { 6853 directoryServer.useNanoTime = useNanoTime; 6854 } 6855 6856 /** 6857 * Retrieves whether operation processing times should be collected with 6858 * nanosecond resolution. 6859 * 6860 * @return <code>true</code> if nanosecond resolution times are collected 6861 * or <code>false</code> if only millisecond resolution times are 6862 * being collected. 6863 */ 6864 public static boolean getUseNanoTime() 6865 { 6866 return directoryServer.useNanoTime; 6867 } 6868 6869 /** 6870 * Retrieves the writability mode for the Directory Server. This will only 6871 * be applicable for user suffixes. 6872 * 6873 * @return The writability mode for the Directory Server. 6874 */ 6875 public static WritabilityMode getWritabilityMode() 6876 { 6877 return directoryServer.writabilityMode; 6878 } 6879 6880 /** 6881 * Specifies the writability mode for the Directory Server. This will only 6882 * be applicable for user suffixes. 6883 * 6884 * @param writabilityMode Specifies the writability mode for the Directory 6885 * Server. 6886 */ 6887 public static void setWritabilityMode(WritabilityMode writabilityMode) 6888 { 6889 directoryServer.writabilityMode = writabilityMode; 6890 } 6891 6892 /** 6893 * Indicates whether simple bind requests that contain a bind DN will also be 6894 * required to have a password. 6895 * 6896 * @return <CODE>true</CODE> if simple bind requests containing a bind DN 6897 * will be required to have a password, or <CODE>false</CODE> if not 6898 * (and therefore will be treated as anonymous binds). 6899 */ 6900 public static boolean bindWithDNRequiresPassword() 6901 { 6902 return directoryServer.bindWithDNRequiresPassword; 6903 } 6904 6905 /** 6906 * Specifies whether simple bind requests that contain a bind DN will also be 6907 * required to have a password. 6908 * 6909 * @param bindWithDNRequiresPassword Indicates whether simple bind requests 6910 * that contain a bind DN will also be 6911 * required to have a password. 6912 */ 6913 public static void setBindWithDNRequiresPassword(boolean 6914 bindWithDNRequiresPassword) 6915 { 6916 directoryServer.bindWithDNRequiresPassword = bindWithDNRequiresPassword; 6917 } 6918 6919 /** 6920 * Indicates whether an unauthenticated request should be rejected. 6921 * 6922 * @return <CODE>true</CODE>if an unauthenticated request should be 6923 * rejected, or <CODE>false</CODE>f if not. 6924 */ 6925 public static boolean rejectUnauthenticatedRequests() 6926 { 6927 return directoryServer.rejectUnauthenticatedRequests; 6928 } 6929 6930 /** 6931 * Specifies whether an unauthenticated request should be rejected. 6932 * 6933 * @param rejectUnauthenticatedRequests Indicates whether an 6934 * unauthenticated request should 6935 * be rejected. 6936 */ 6937 public static void setRejectUnauthenticatedRequests(boolean 6938 rejectUnauthenticatedRequests) 6939 { 6940 directoryServer.rejectUnauthenticatedRequests = 6941 rejectUnauthenticatedRequests; 6942 } 6943 6944 /** 6945 * Indicates whether the Directory Server is currently configured to operate 6946 * in the lockdown mode, in which all non-root requests will be rejected and 6947 * all connection attempts from non-loopback clients will be rejected. 6948 * 6949 * @return {@code true} if the Directory Server is currently configured to 6950 * operate in the lockdown mode, or {@code false} if not. 6951 */ 6952 public static boolean lockdownMode() 6953 { 6954 return directoryServer.lockdownMode; 6955 } 6956 6957 /** 6958 * Specifies whether the server should operate in lockdown mode. 6959 * 6960 * @param lockdownMode Indicates whether the Directory Server should operate 6961 * in lockdown mode. 6962 */ 6963 public static void setLockdownMode(boolean lockdownMode) 6964 { 6965 directoryServer.lockdownMode = lockdownMode; 6966 6967 if (lockdownMode) 6968 { 6969 LocalizableMessage message = WARN_DIRECTORY_SERVER_ENTERING_LOCKDOWN_MODE.get(); 6970 logger.warn(message); 6971 6972 sendAlertNotification(directoryServer, ALERT_TYPE_ENTERING_LOCKDOWN_MODE, 6973 message); 6974 } 6975 else 6976 { 6977 LocalizableMessage message = NOTE_DIRECTORY_SERVER_LEAVING_LOCKDOWN_MODE.get(); 6978 logger.info(message); 6979 6980 sendAlertNotification(directoryServer, ALERT_TYPE_LEAVING_LOCKDOWN_MODE, 6981 message); 6982 } 6983 } 6984 6985 /** 6986 * Sets the message to be displayed on the command-line when the user asks for 6987 * the usage. 6988 * @param msg the message to be displayed on the command-line when the user 6989 * asks for the usage. 6990 */ 6991 public static void setToolDescription (LocalizableMessage msg) 6992 { 6993 toolDescription = msg; 6994 } 6995 6996 /** 6997 * Retrieves the DN of the configuration entry with which this alert generator 6998 * is associated. 6999 * 7000 * @return The DN of the configuration entry with which this alert generator 7001 * is associated. 7002 */ 7003 @Override 7004 public DN getComponentEntryDN() 7005 { 7006 try 7007 { 7008 if (configHandler == null) 7009 { 7010 // The config handler hasn't been initialized yet. Just return the DN 7011 // of the root DSE. 7012 return DN.rootDN(); 7013 } 7014 7015 return configHandler.getConfigRootEntry().getDN(); 7016 } 7017 catch (Exception e) 7018 { 7019 logger.traceException(e); 7020 7021 // This could theoretically happen if an alert needs to be sent before the 7022 // configuration is initialized. In that case, just return an empty DN. 7023 return DN.rootDN(); 7024 } 7025 } 7026 7027 /** 7028 * Retrieves the fully-qualified name of the Java class for this alert 7029 * generator implementation. 7030 * 7031 * @return The fully-qualified name of the Java class for this alert 7032 * generator implementation. 7033 */ 7034 @Override 7035 public String getClassName() 7036 { 7037 return DirectoryServer.class.getName(); 7038 } 7039 7040 /** 7041 * Retrieves information about the set of alerts that this generator may 7042 * produce. The map returned should be between the notification type for a 7043 * particular notification and the human-readable description for that 7044 * notification. This alert generator must not generate any alerts with types 7045 * that are not contained in this list. 7046 * 7047 * @return Information about the set of alerts that this generator may 7048 * produce. 7049 */ 7050 @Override 7051 public Map<String, String> getAlerts() 7052 { 7053 Map<String, String> alerts = new LinkedHashMap<>(); 7054 7055 alerts.put(ALERT_TYPE_SERVER_STARTED, ALERT_DESCRIPTION_SERVER_STARTED); 7056 alerts.put(ALERT_TYPE_SERVER_SHUTDOWN, ALERT_DESCRIPTION_SERVER_SHUTDOWN); 7057 alerts.put(ALERT_TYPE_ENTERING_LOCKDOWN_MODE, 7058 ALERT_DESCRIPTION_ENTERING_LOCKDOWN_MODE); 7059 alerts.put(ALERT_TYPE_LEAVING_LOCKDOWN_MODE, 7060 ALERT_DESCRIPTION_LEAVING_LOCKDOWN_MODE); 7061 7062 return alerts; 7063 } 7064 7065 /** 7066 * Indicates whether the server is currently in the process of shutting down. 7067 * @return <CODE>true</CODE> if this server is currently in the process of 7068 * shutting down and <CODE>false</CODE> otherwise. 7069 */ 7070 public boolean isShuttingDown() 7071 { 7072 return shuttingDown; 7073 } 7074 7075 /** 7076 * Parses the provided command-line arguments and uses that information to 7077 * bootstrap and start the Directory Server. 7078 * 7079 * @param args The command-line arguments provided to this program. 7080 */ 7081 public static void main(String[] args) 7082 { 7083 // Define the arguments that may be provided to the server. 7084 BooleanArgument checkStartability = null; 7085 BooleanArgument quietMode = null; 7086 IntegerArgument timeout = null; 7087 BooleanArgument windowsNetStart = null; 7088 BooleanArgument displayUsage = null; 7089 BooleanArgument fullVersion = null; 7090 BooleanArgument noDetach = null; 7091 BooleanArgument systemInfo = null; 7092 BooleanArgument useLastKnownGoodConfig = null; 7093 StringArgument configClass = null; 7094 StringArgument configFile = null; 7095 7096 // Create the command-line argument parser for use with this program. 7097 LocalizableMessage theToolDescription = DirectoryServer.toolDescription; 7098 ArgumentParser argParser = 7099 new ArgumentParser("org.opends.server.core.DirectoryServer", 7100 theToolDescription, false); 7101 argParser.setShortToolDescription(REF_SHORT_DESC_START_DS.get()); 7102 7103 // Initialize all the command-line argument types and register them with the 7104 // parser. 7105 try 7106 { 7107 configClass = new StringArgument("configclass", 'C', "configClass", 7108 true, false, true, 7109 INFO_CONFIGCLASS_PLACEHOLDER.get(), 7110 ConfigFileHandler.class.getName(), null, 7111 INFO_DSCORE_DESCRIPTION_CONFIG_CLASS.get()); 7112 configClass.setHidden(true); 7113 argParser.addArgument(configClass); 7114 7115 configFile = new StringArgument("configfile", 'f', "configFile", 7116 true, false, true, 7117 INFO_CONFIGFILE_PLACEHOLDER.get(), null, 7118 null, 7119 INFO_DSCORE_DESCRIPTION_CONFIG_FILE.get()); 7120 configFile.setHidden(true); 7121 argParser.addArgument(configFile); 7122 7123 checkStartability = new BooleanArgument("checkstartability", null, 7124 "checkStartability", 7125 INFO_DSCORE_DESCRIPTION_CHECK_STARTABILITY.get()); 7126 checkStartability.setHidden(true); 7127 argParser.addArgument(checkStartability); 7128 7129 windowsNetStart = new BooleanArgument("windowsnetstart", null, "windowsNetStart", 7130 INFO_DSCORE_DESCRIPTION_WINDOWS_NET_START.get()); 7131 windowsNetStart.setHidden(true); 7132 argParser.addArgument(windowsNetStart); 7133 7134 fullVersion = new BooleanArgument("fullversion", 'F', "fullVersion", 7135 INFO_DSCORE_DESCRIPTION_FULLVERSION.get()); 7136 fullVersion.setHidden(true); 7137 argParser.addArgument(fullVersion); 7138 7139 systemInfo = new BooleanArgument("systeminfo", 's', "systemInfo", 7140 INFO_DSCORE_DESCRIPTION_SYSINFO.get()); 7141 argParser.addArgument(systemInfo); 7142 7143 useLastKnownGoodConfig = 7144 new BooleanArgument("lastknowngoodconfig", 'L', 7145 "useLastKnownGoodConfig", 7146 INFO_DSCORE_DESCRIPTION_LASTKNOWNGOODCFG.get()); 7147 argParser.addArgument(useLastKnownGoodConfig); 7148 7149 noDetach = new BooleanArgument("nodetach", 'N', "nodetach", 7150 INFO_DSCORE_DESCRIPTION_NODETACH.get()); 7151 argParser.addArgument(noDetach); 7152 7153 quietMode = CommonArguments.getQuiet(); 7154 argParser.addArgument(quietMode); 7155 7156 // Not used in this class, but required by the start-ds script 7157 // (see issue #3814) 7158 timeout = new IntegerArgument("timeout", 't', "timeout", true, false, 7159 true, INFO_SECONDS_PLACEHOLDER.get(), 7160 DEFAULT_TIMEOUT, 7161 null, true, 0, false, 7162 0, INFO_DSCORE_DESCRIPTION_TIMEOUT.get()); 7163 argParser.addArgument(timeout); 7164 7165 displayUsage = CommonArguments.getShowUsage(); 7166 argParser.addArgument(displayUsage); 7167 argParser.setUsageArgument(displayUsage); 7168 argParser.setVersionHandler(new DirectoryServerVersionHandler()); 7169 } 7170 catch (ArgumentException ae) 7171 { 7172 LocalizableMessage message = ERR_DSCORE_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()); 7173 System.err.println(message); 7174 System.exit(1); 7175 } 7176 7177 // Parse the command-line arguments provided to this program. 7178 try 7179 { 7180 argParser.parseArguments(args); 7181 } 7182 catch (ArgumentException ae) 7183 { 7184 argParser.displayMessageAndUsageReference(System.err, ERR_DSCORE_ERROR_PARSING_ARGS.get(ae.getMessage())); 7185 System.exit(1); 7186 } 7187 7188 // If we should just display usage information, then print it and exit. 7189 if (checkStartability.isPresent()) 7190 { 7191 // This option should only be used if a PID file already exists in the 7192 // server logs directory, and we need to check which of the following 7193 // conditions best describes the current usage: 7194 // - We're trying to start the server, but it's already running. The 7195 // attempt to start the server should fail, and the server process will 7196 // exit with a result code of 98. 7197 // - We're trying to start the server and it's not already running. We 7198 // won't start it in this invocation, but the script used to get to this 7199 // point should go ahead and overwrite the PID file and retry the 7200 // startup process. The server process will exit with a result code of 7201 // 99. 7202 // - We're not trying to start the server, but instead are trying to do 7203 // something else like display the version number. In that case, we 7204 // don't need to write the PID file at all and can just execute the 7205 // intended command. If that command was successful, then we'll have an 7206 // exit code of NOTHING_TO_DO (0). Otherwise, it will have an exit code 7207 // that is something other than NOTHING_TO_DO, SERVER_ALREADY_STARTED, 7208 // START_AS_DETACH, START_AS_NON_DETACH, START_AS_WINDOWS_SERVICE, 7209 // START_AS_DETACH_QUIET, START_AS_NON_DETACH_QUIET to indicate that a 7210 // problem occurred. 7211 if (argParser.usageOrVersionDisplayed()) 7212 { 7213 // We're just trying to display usage, and that's already been done so 7214 // exit with a code of zero. 7215 System.exit(NOTHING_TO_DO); 7216 } 7217 else if (fullVersion.isPresent() || systemInfo.isPresent()) 7218 { 7219 // We're not really trying to start, so rebuild the argument list 7220 // without the "--checkStartability" argument and try again. Exit with 7221 // whatever that exits with. 7222 List<String> newArgList = new LinkedList<>(); 7223 for (String arg : args) 7224 { 7225 if (!"--checkstartability".equalsIgnoreCase(arg)) 7226 { 7227 newArgList.add(arg); 7228 } 7229 } 7230 String[] newArgs = new String[newArgList.size()]; 7231 newArgList.toArray(newArgs); 7232 main(newArgs); 7233 System.exit(NOTHING_TO_DO); 7234 } 7235 else 7236 { 7237 System.exit(checkStartability(argParser)); 7238 } 7239 } 7240 else if (argParser.usageOrVersionDisplayed()) 7241 { 7242 System.exit(0); 7243 } 7244 else if (fullVersion.isPresent()) 7245 { 7246 printFullVersionInformation(); 7247 return; 7248 } 7249 else if (systemInfo.isPresent()) 7250 { 7251 RuntimeInformation.printInfo(); 7252 return; 7253 } 7254 else if (noDetach.isPresent() && timeout.isPresent()) { 7255 argParser.displayMessageAndUsageReference(System.err, ERR_DSCORE_ERROR_NODETACH_TIMEOUT.get()); 7256 System.exit(1); 7257 } 7258 7259 // At this point, we know that we're going to try to start the server. 7260 // Attempt to grab an exclusive lock for the Directory Server process. 7261 String lockFile = LockFileManager.getServerLockFileName(); 7262 try 7263 { 7264 StringBuilder failureReason = new StringBuilder(); 7265 if (! LockFileManager.acquireExclusiveLock(lockFile, failureReason)) 7266 { 7267 System.err.println(ERR_CANNOT_ACQUIRE_EXCLUSIVE_SERVER_LOCK.get(lockFile, failureReason)); 7268 System.exit(1); 7269 } 7270 } 7271 catch (Exception e) 7272 { 7273 logger.traceException(e); 7274 7275 System.err.println(ERR_CANNOT_ACQUIRE_EXCLUSIVE_SERVER_LOCK.get( 7276 lockFile, stackTraceToSingleLineString(e))); 7277 System.exit(1); 7278 } 7279 serverLocked = true; 7280 7281 // Create an environment configuration for the server and populate a number 7282 // of appropriate properties. 7283 DirectoryEnvironmentConfig environmentConfig = new DirectoryEnvironmentConfig(); 7284 try 7285 { 7286 environmentConfig.setProperty(PROPERTY_CONFIG_CLASS, configClass.getValue()); 7287 environmentConfig.setProperty(PROPERTY_CONFIG_FILE, configFile.getValue()); 7288 environmentConfig.setProperty(PROPERTY_USE_LAST_KNOWN_GOOD_CONFIG, 7289 String.valueOf(useLastKnownGoodConfig.isPresent())); 7290 } 7291 catch (Exception e) 7292 { 7293 // This shouldn't happen. For the methods we are using, the exception is 7294 // just a guard against making changes with the server running. 7295 System.err.println("WARNING: Unable to set environment properties in environment config : " 7296 + stackTraceToSingleLineString(e)); 7297 } 7298 7299 // Configure the JVM to delete the PID file on exit, if it exists. 7300 boolean pidFileMarkedForDeletion = false; 7301 boolean startingFileMarkedForDeletion = false; 7302 try 7303 { 7304 String pidFilePath; 7305 String startingFilePath; 7306 File instanceRoot = environmentConfig.getInstanceRoot(); 7307 if (instanceRoot == null) 7308 { 7309 pidFilePath = "logs/server.pid"; 7310 startingFilePath = "logs/server.starting"; 7311 } 7312 else 7313 { 7314 pidFilePath = instanceRoot.getAbsolutePath() + File.separator + "logs" 7315 + File.separator + "server.pid"; 7316 startingFilePath = instanceRoot.getAbsolutePath() + File.separator 7317 + "logs" + File.separator + "server.starting"; 7318 } 7319 7320 File pidFile = new File(pidFilePath); 7321 if (pidFile.exists()) 7322 { 7323 pidFile.deleteOnExit(); 7324 pidFileMarkedForDeletion = true; 7325 } 7326 7327 File startingFile = new File(startingFilePath); 7328 if (startingFile.exists()) 7329 { 7330 startingFile.deleteOnExit(); 7331 startingFileMarkedForDeletion = true; 7332 } 7333 } catch (Exception e) {} 7334 7335 // Redirect standard output and standard error to the server.out file. If 7336 // the server hasn't detached from the terminal, then also continue writing 7337 // to the original standard output and standard error. Also, configure the 7338 // JVM to delete the PID and server.starting files on exit, if they exist. 7339 PrintStream serverOutStream; 7340 try 7341 { 7342 File serverRoot = environmentConfig.getServerRoot(); 7343 if (serverRoot == null) 7344 { 7345 System.err.println("WARNING: Unable to determine server root in " + 7346 "order to redirect standard output and standard error."); 7347 } 7348 else 7349 { 7350 File instanceRoot = environmentConfig.getInstanceRoot(); 7351 File logDir = new File(instanceRoot.getAbsolutePath() + File.separator 7352 + "logs"); 7353 if (logDir.exists()) 7354 { 7355 FileOutputStream fos = 7356 new FileOutputStream(new File(logDir, "server.out"), true); 7357 serverOutStream = new PrintStream(fos); 7358 7359 if (noDetach.isPresent() && !quietMode.isPresent()) 7360 { 7361 MultiOutputStream multiStream = 7362 new MultiOutputStream(System.out, serverOutStream); 7363 serverOutStream = new PrintStream(multiStream); 7364 } 7365 7366 System.setOut(serverOutStream); 7367 System.setErr(serverOutStream); 7368 7369 if (! pidFileMarkedForDeletion) 7370 { 7371 File f = new File(logDir, "server.pid"); 7372 if (f.exists()) 7373 { 7374 f.deleteOnExit(); 7375 } 7376 } 7377 7378 if (! startingFileMarkedForDeletion) 7379 { 7380 File f = new File(logDir, "server.starting"); 7381 if (f.exists()) 7382 { 7383 f.deleteOnExit(); 7384 } 7385 } 7386 } 7387 else 7388 { 7389 System.err.println("WARNING: Unable to redirect standard output " + 7390 "and standard error because the logs directory " + 7391 logDir.getAbsolutePath() + " does not exist."); 7392 } 7393 } 7394 } 7395 catch (Exception e) 7396 { 7397 System.err.println("WARNING: Unable to redirect standard output and " + 7398 "standard error: " + stackTraceToSingleLineString(e)); 7399 } 7400 7401 // Install the default loggers so the startup messages 7402 // will be printed. 7403 ErrorLogPublisher startupErrorLogPublisher = 7404 TextErrorLogPublisher.getServerStartupTextErrorPublisher(new TextWriter.STDOUT()); 7405 ErrorLogger.getInstance().addLogPublisher(startupErrorLogPublisher); 7406 7407 DebugLogPublisher startupDebugLogPublisher = 7408 DebugLogger.getInstance().addPublisherIfRequired(new TextWriter.STDOUT()); 7409 7410 // Bootstrap and start the Directory Server. 7411 DirectoryServer theDirectoryServer = DirectoryServer.getInstance(); 7412 try 7413 { 7414 theDirectoryServer.setEnvironmentConfig(environmentConfig); 7415 theDirectoryServer.bootstrapServer(); 7416 theDirectoryServer.initializeConfiguration(configClass.getValue(), 7417 configFile.getValue()); 7418 } 7419 catch (InitializationException ie) 7420 { 7421 logger.traceException(ie); 7422 7423 LocalizableMessage message = ERR_DSCORE_CANNOT_BOOTSTRAP.get(ie.getMessage()); 7424 System.err.println(message); 7425 System.exit(1); 7426 } 7427 catch (Exception e) 7428 { 7429 LocalizableMessage message = ERR_DSCORE_CANNOT_BOOTSTRAP.get( 7430 stackTraceToSingleLineString(e)); 7431 System.err.println(message); 7432 System.exit(1); 7433 } 7434 7435 try 7436 { 7437 theDirectoryServer.startServer(); 7438 } 7439 catch (InitializationException ie) 7440 { 7441 logger.traceException(ie); 7442 7443 LocalizableMessage message = ERR_DSCORE_CANNOT_START.get(ie.getMessage()); 7444 shutDown(theDirectoryServer.getClass().getName(), message); 7445 } 7446 catch (ConfigException ce) 7447 { 7448 logger.traceException(ce); 7449 7450 LocalizableMessage message = ERR_DSCORE_CANNOT_START.get(ce.getMessage() + 7451 (ce.getCause() != null ? " " + ce.getCause().getLocalizedMessage() : "")); 7452 shutDown(theDirectoryServer.getClass().getName(), message); 7453 } 7454 catch (Exception e) 7455 { 7456 LocalizableMessage message = ERR_DSCORE_CANNOT_START.get( 7457 stackTraceToSingleLineString(e)); 7458 shutDown(theDirectoryServer.getClass().getName(), message); 7459 } 7460 7461 ErrorLogger.getInstance().removeLogPublisher(startupErrorLogPublisher); 7462 if (startupDebugLogPublisher != null) 7463 { 7464 DebugLogger.getInstance().removeLogPublisher(startupDebugLogPublisher); 7465 } 7466 } 7467 7468 /** 7469 * Construct the DN of a monitor provider entry. 7470 * @param provider The monitor provider for which a DN is desired. 7471 * @return The DN of the monitor provider entry. 7472 */ 7473 public static DN getMonitorProviderDN(MonitorProvider provider) 7474 { 7475 String monitorName = provider.getMonitorInstanceName(); 7476 try 7477 { 7478 // Get a complete DN which could be a tree naming schema 7479 return DN.valueOf("cn="+monitorName+","+DN_MONITOR_ROOT); 7480 } 7481 catch (DirectoryException e) 7482 { 7483 // Cannot reach this point. 7484 throw new RuntimeException(); 7485 } 7486 } 7487 7488 /** 7489 * Gets the class loader to be used with this directory server 7490 * application. 7491 * <p> 7492 * The class loader will automatically load classes from plugins 7493 * where required. 7494 * 7495 * @return Returns the class loader to be used with this directory 7496 * server application. 7497 */ 7498 public static ClassLoader getClassLoader() 7499 { 7500 return ClassLoaderProvider.getInstance().getClassLoader(); 7501 } 7502 7503 /** 7504 * Loads the named class using this directory server application's 7505 * class loader. 7506 * <p> 7507 * This method provided as a convenience and is equivalent to 7508 * calling: 7509 * 7510 * <pre> 7511 * Class.forName(name, true, DirectoryServer.getClassLoader()); 7512 * </pre> 7513 * 7514 * @param name 7515 * The fully qualified name of the desired class. 7516 * @return Returns the class object representing the desired class. 7517 * @throws LinkageError 7518 * If the linkage fails. 7519 * @throws ExceptionInInitializerError 7520 * If the initialization provoked by this method fails. 7521 * @throws ClassNotFoundException 7522 * If the class cannot be located by the specified class 7523 * loader. 7524 * @see Class#forName(String, boolean, ClassLoader) 7525 */ 7526 public static Class<?> loadClass(String name) throws LinkageError, 7527 ExceptionInInitializerError, ClassNotFoundException 7528 { 7529 return Class.forName(name, true, DirectoryServer.getClassLoader()); 7530 } 7531 7532 /** 7533 * Returns the error code that we return when we are checking the startability 7534 * of the server. 7535 * If there are conflicting arguments (like asking to run the server in non 7536 * detach mode when the server is configured to run as a window service) it 7537 * returns CHECK_ERROR (1). 7538 * @param argParser the ArgumentParser with the arguments already parsed. 7539 * @return the error code that we return when we are checking the startability 7540 * of the server. 7541 */ 7542 private static int checkStartability(ArgumentParser argParser) 7543 { 7544 int returnValue; 7545 boolean isServerRunning; 7546 7547 BooleanArgument noDetach = 7548 (BooleanArgument)argParser.getArgumentForLongID("nodetach"); 7549 BooleanArgument quietMode = 7550 (BooleanArgument)argParser.getArgumentForLongID(ArgumentConstants.OPTION_LONG_QUIET); 7551 BooleanArgument windowsNetStart = 7552 (BooleanArgument)argParser.getArgumentForLongID("windowsnetstart"); 7553 7554 boolean noDetachPresent = noDetach.isPresent(); 7555 boolean windowsNetStartPresent = windowsNetStart.isPresent(); 7556 7557 // We're trying to start the server, so see if it's already running by 7558 // trying to grab an exclusive lock on the server lock file. If it 7559 // succeeds, then the server isn't running and we can try to start. 7560 // Otherwise, the server is running and this attempt should fail. 7561 String lockFile = LockFileManager.getServerLockFileName(); 7562 try 7563 { 7564 StringBuilder failureReason = new StringBuilder(); 7565 if (LockFileManager.acquireExclusiveLock(lockFile, failureReason)) 7566 { 7567 // The server isn't running, so it can be started. 7568 LockFileManager.releaseLock(lockFile, failureReason); 7569 isServerRunning = false; 7570 } 7571 else 7572 { 7573 // The server's already running. 7574 System.err.println(ERR_CANNOT_ACQUIRE_EXCLUSIVE_SERVER_LOCK.get(lockFile, failureReason)); 7575 isServerRunning = true; 7576 } 7577 } 7578 catch (Exception e) 7579 { 7580 // We'll treat this as if the server is running because we won't 7581 // be able to start it anyway. 7582 LocalizableMessage message = ERR_CANNOT_ACQUIRE_EXCLUSIVE_SERVER_LOCK.get(lockFile, 7583 getExceptionMessage(e)); 7584 System.err.println(message); 7585 isServerRunning = true; 7586 } 7587 7588 boolean configuredAsService = isRunningAsWindowsService(); 7589 7590 if (isServerRunning) 7591 { 7592 if (configuredAsService && !windowsNetStartPresent) 7593 { 7594 returnValue = START_AS_WINDOWS_SERVICE; 7595 } 7596 else 7597 { 7598 returnValue = SERVER_ALREADY_STARTED; 7599 } 7600 } 7601 else 7602 { 7603 if (configuredAsService) 7604 { 7605 if (noDetachPresent) 7606 { 7607 // Conflicting arguments 7608 returnValue = CHECK_ERROR; 7609 LocalizableMessage message = ERR_DSCORE_ERROR_NODETACH_AND_WINDOW_SERVICE.get(); 7610 System.err.println(message); 7611 7612 } 7613 else 7614 { 7615 if (windowsNetStartPresent) 7616 { 7617 // start-ds.bat is being called through net start, so return 7618 // START_AS_DETACH_CALLED_FROM_WINDOWS_SERVICE so that the batch 7619 // file actually starts the server. 7620 returnValue = START_AS_DETACH_CALLED_FROM_WINDOWS_SERVICE; 7621 } 7622 else 7623 { 7624 returnValue = START_AS_WINDOWS_SERVICE; 7625 } 7626 } 7627 } 7628 else 7629 { 7630 if (noDetachPresent) 7631 { 7632 if (quietMode.isPresent()) 7633 { 7634 returnValue = START_AS_NON_DETACH_QUIET; 7635 } 7636 else 7637 { 7638 returnValue = START_AS_NON_DETACH; 7639 } 7640 } 7641 else if (quietMode.isPresent()) 7642 { 7643 returnValue = START_AS_DETACH_QUIET; 7644 } 7645 else 7646 { 7647 returnValue = START_AS_DETACH; 7648 } 7649 } 7650 } 7651 return returnValue; 7652 } 7653 7654 /** 7655 * Returns true if this server is configured to run as a windows service. 7656 * @return <CODE>true</CODE> if this server is configured to run as a windows 7657 * service and <CODE>false</CODE> otherwise. 7658 */ 7659 public static boolean isRunningAsWindowsService() 7660 { 7661 return OperatingSystem.isWindows() 7662 && serviceState() == SERVICE_STATE_ENABLED; 7663 } 7664 7665 // TODO JNR remove error CoreMessages.ERR_REGISTER_WORKFLOW_ELEMENT_ALREADY_EXISTS 7666 7667 /** Print messages for start-ds "-F" option (full version information). */ 7668 private static void printFullVersionInformation() { 7669 /* 7670 * This option is used by the upgrade to identify the server build and it 7671 * can eventually also be used to be sent to the support in case of an 7672 * issue. Since this is not a public interface and since it is better 7673 * to always have it in English for the support team, the message is 7674 * not localized. 7675 */ 7676 String separator = ": "; 7677 System.out.println(getVersionString()); 7678 System.out.println(SetupUtils.BUILD_ID+separator+BUILD_ID); 7679 System.out.println(SetupUtils.MAJOR_VERSION+separator+MAJOR_VERSION); 7680 System.out.println(SetupUtils.MINOR_VERSION+separator+MINOR_VERSION); 7681 System.out.println(SetupUtils.POINT_VERSION+separator+POINT_VERSION); 7682 System.out.println(SetupUtils.VERSION_QUALIFIER+separator+ 7683 VERSION_QUALIFIER); 7684 if (BUILD_NUMBER > 0) 7685 { 7686 System.out.println(SetupUtils.BUILD_NUMBER+separator+ 7687 new DecimalFormat("000").format(BUILD_NUMBER)); 7688 } 7689 System.out.println(SetupUtils.REVISION+separator+REVISION); 7690 System.out.println(SetupUtils.URL_REPOSITORY+separator+URL_REPOSITORY); 7691 System.out.println(SetupUtils.FIX_IDS+separator+FIX_IDS); 7692 System.out.println(SetupUtils.DEBUG_BUILD+separator+DEBUG_BUILD); 7693 System.out.println(SetupUtils.BUILD_OS+separator+BUILD_OS); 7694 System.out.println(SetupUtils.BUILD_USER+separator+BUILD_USER); 7695 System.out.println(SetupUtils.BUILD_JAVA_VERSION+separator+ 7696 BUILD_JAVA_VERSION); 7697 System.out.println(SetupUtils.BUILD_JAVA_VENDOR+separator+ 7698 BUILD_JAVA_VENDOR); 7699 System.out.println(SetupUtils.BUILD_JVM_VERSION+separator+ 7700 BUILD_JVM_VERSION); 7701 System.out.println(SetupUtils.BUILD_JVM_VENDOR+separator+BUILD_JVM_VENDOR); 7702 7703 // Print extensions' extra information 7704 String extensionInformation = 7705 ClassLoaderProvider.getInstance().printExtensionInformation(); 7706 if ( extensionInformation != null ) { 7707 System.out.print(extensionInformation); 7708 } 7709 } 7710 7711 /** 7712 * Sets the threshold capacity beyond which internal cached buffers used for 7713 * encoding and decoding entries and protocol messages will be trimmed after 7714 * use. 7715 * 7716 * @param maxInternalBufferSize 7717 * The threshold capacity beyond which internal cached buffers used 7718 * for encoding and decoding entries and protocol messages will be 7719 * trimmed after use. 7720 */ 7721 public static void setMaxInternalBufferSize(int maxInternalBufferSize) 7722 { 7723 directoryServer.maxInternalBufferSize = maxInternalBufferSize; 7724 } 7725 7726 /** 7727 * Returns the threshold capacity beyond which internal cached buffers used 7728 * for encoding and decoding entries and protocol messages will be trimmed 7729 * after use. 7730 * 7731 * @return The threshold capacity beyond which internal cached buffers used 7732 * for encoding and decoding entries and protocol messages will be 7733 * trimmed after use. 7734 */ 7735 public static int getMaxInternalBufferSize() 7736 { 7737 return directoryServer.maxInternalBufferSize; 7738 } 7739 7740 /** 7741 * Returns the lock manager which will be used for coordinating access to LDAP entries. 7742 * 7743 * @return the lock manager which will be used for coordinating access to LDAP entries. 7744 */ 7745 public static LockManager getLockManager() 7746 { 7747 return directoryServer.lockManager; 7748 } 7749}