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