001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.server.ldap; 021 022 023import java.io.IOException; 024import java.security.KeyStore; 025import java.util.ArrayList; 026import java.util.Collection; 027import java.util.HashMap; 028import java.util.HashSet; 029import java.util.Iterator; 030import java.util.List; 031import java.util.Map; 032import java.util.Set; 033 034import javax.net.ssl.KeyManagerFactory; 035import javax.net.ssl.TrustManager; 036import javax.net.ssl.TrustManagerFactory; 037 038import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory; 039import org.apache.directory.api.ldap.model.constants.Loggers; 040import org.apache.directory.api.ldap.model.constants.SaslQoP; 041import org.apache.directory.api.ldap.model.exception.LdapConfigurationException; 042import org.apache.directory.api.ldap.model.exception.LdapException; 043import org.apache.directory.api.ldap.model.message.AbandonRequest; 044import org.apache.directory.api.ldap.model.message.AddRequest; 045import org.apache.directory.api.ldap.model.message.AddResponse; 046import org.apache.directory.api.ldap.model.message.BindRequest; 047import org.apache.directory.api.ldap.model.message.BindResponse; 048import org.apache.directory.api.ldap.model.message.CompareRequest; 049import org.apache.directory.api.ldap.model.message.CompareResponse; 050import org.apache.directory.api.ldap.model.message.DeleteRequest; 051import org.apache.directory.api.ldap.model.message.DeleteResponse; 052import org.apache.directory.api.ldap.model.message.ExtendedRequest; 053import org.apache.directory.api.ldap.model.message.ExtendedResponse; 054import org.apache.directory.api.ldap.model.message.IntermediateResponse; 055import org.apache.directory.api.ldap.model.message.ModifyDnRequest; 056import org.apache.directory.api.ldap.model.message.ModifyDnResponse; 057import org.apache.directory.api.ldap.model.message.ModifyRequest; 058import org.apache.directory.api.ldap.model.message.ModifyResponse; 059import org.apache.directory.api.ldap.model.message.SearchRequest; 060import org.apache.directory.api.ldap.model.message.SearchResultDone; 061import org.apache.directory.api.ldap.model.message.SearchResultEntry; 062import org.apache.directory.api.ldap.model.message.SearchResultReference; 063import org.apache.directory.api.ldap.model.message.UnbindRequest; 064import org.apache.directory.api.ldap.model.message.extended.NoticeOfDisconnect; 065import org.apache.directory.server.core.api.DirectoryService; 066import org.apache.directory.server.core.api.partition.PartitionNexus; 067import org.apache.directory.server.core.security.CertificateUtil; 068import org.apache.directory.server.i18n.I18n; 069import org.apache.directory.server.ldap.handlers.LdapRequestHandler; 070import org.apache.directory.server.ldap.handlers.LdapResponseHandler; 071import org.apache.directory.server.ldap.handlers.extended.StartTlsHandler; 072import org.apache.directory.server.ldap.handlers.request.AbandonRequestHandler; 073import org.apache.directory.server.ldap.handlers.request.AddRequestHandler; 074import org.apache.directory.server.ldap.handlers.request.BindRequestHandler; 075import org.apache.directory.server.ldap.handlers.request.CompareRequestHandler; 076import org.apache.directory.server.ldap.handlers.request.DeleteRequestHandler; 077import org.apache.directory.server.ldap.handlers.request.ExtendedRequestHandler; 078import org.apache.directory.server.ldap.handlers.request.ModifyDnRequestHandler; 079import org.apache.directory.server.ldap.handlers.request.ModifyRequestHandler; 080import org.apache.directory.server.ldap.handlers.request.SearchRequestHandler; 081import org.apache.directory.server.ldap.handlers.request.UnbindRequestHandler; 082import org.apache.directory.server.ldap.handlers.response.AddResponseHandler; 083import org.apache.directory.server.ldap.handlers.response.BindResponseHandler; 084import org.apache.directory.server.ldap.handlers.response.CompareResponseHandler; 085import org.apache.directory.server.ldap.handlers.response.DeleteResponseHandler; 086import org.apache.directory.server.ldap.handlers.response.ExtendedResponseHandler; 087import org.apache.directory.server.ldap.handlers.response.IntermediateResponseHandler; 088import org.apache.directory.server.ldap.handlers.response.ModifyDnResponseHandler; 089import org.apache.directory.server.ldap.handlers.response.ModifyResponseHandler; 090import org.apache.directory.server.ldap.handlers.response.SearchResultDoneHandler; 091import org.apache.directory.server.ldap.handlers.response.SearchResultEntryHandler; 092import org.apache.directory.server.ldap.handlers.response.SearchResultReferenceHandler; 093import org.apache.directory.server.ldap.handlers.sasl.MechanismHandler; 094import org.apache.directory.server.ldap.handlers.ssl.LdapsInitializer; 095import org.apache.directory.server.ldap.replication.consumer.PingerThread; 096import org.apache.directory.server.ldap.replication.consumer.ReplicationConsumer; 097import org.apache.directory.server.ldap.replication.consumer.ReplicationStatusEnum; 098import org.apache.directory.server.ldap.replication.provider.ReplicationRequestHandler; 099import org.apache.directory.server.protocol.shared.DirectoryBackedService; 100import org.apache.directory.server.protocol.shared.transport.TcpTransport; 101import org.apache.directory.server.protocol.shared.transport.Transport; 102import org.apache.directory.server.protocol.shared.transport.UdpTransport; 103import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; 104import org.apache.mina.core.filterchain.IoFilterChainBuilder; 105import org.apache.mina.core.future.WriteFuture; 106import org.apache.mina.core.service.IoHandler; 107import org.apache.mina.core.session.IoEventType; 108import org.apache.mina.core.session.IoSession; 109import org.apache.mina.filter.codec.ProtocolCodecFactory; 110import org.apache.mina.filter.codec.ProtocolCodecFilter; 111import org.apache.mina.filter.executor.ExecutorFilter; 112import org.apache.mina.filter.executor.UnorderedThreadPoolExecutor; 113import org.apache.mina.handler.demux.MessageHandler; 114import org.apache.mina.transport.socket.AbstractSocketSessionConfig; 115import org.apache.mina.transport.socket.SocketAcceptor; 116import org.slf4j.Logger; 117import org.slf4j.LoggerFactory; 118import org.slf4j.MDC; 119 120 121/** 122 * An LDAP protocol provider implementation which dynamically associates 123 * handlers. 124 * 125 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 126 */ 127public class LdapServer extends DirectoryBackedService 128{ 129 /** logger for this class */ 130 private static final Logger LOG = LoggerFactory.getLogger( LdapServer.class ); 131 132 /** Logger for the replication consumer */ 133 private static final Logger CONSUMER_LOG = LoggerFactory.getLogger( Loggers.CONSUMER_LOG.getName() ); 134 135 /** Value (0) for configuration where size limit is unlimited. */ 136 public static final long NO_SIZE_LIMIT = 0; 137 138 /** Value (0) for configuration where time limit is unlimited. */ 139 public static final int NO_TIME_LIMIT = 0; 140 141 /** the constant service name of this ldap protocol provider **/ 142 public static final String SERVICE_NAME = "ldap"; 143 144 /** The default maximum size limit. */ 145 private static final long MAX_SIZE_LIMIT_DEFAULT = 100; 146 147 /** The default maximum time limit. */ 148 private static final int MAX_TIME_LIMIT_DEFAULT = 10000; 149 150 /** The default service pid. */ 151 private static final String SERVICE_PID_DEFAULT = "org.apache.directory.server.ldap"; 152 153 /** The default service name. */ 154 private static final String SERVICE_NAME_DEFAULT = "ApacheDS LDAP Service"; 155 156 /** the session manager for this LdapServer */ 157 private LdapSessionManager ldapSessionManager = new LdapSessionManager(); 158 159 /** a set of supported controls */ 160 private Set<String> supportedControls; 161 162 /** 163 * The maximum size limit. 164 * @see {@link LdapServer#MAX_SIZE_LIMIT_DEFAULT } 165 */ 166 private long maxSizeLimit = MAX_SIZE_LIMIT_DEFAULT; 167 168 /** 169 * The maximum time limit. 170 * @see {@link LdapServer#MAX_TIME_LIMIT_DEFAULT } 171 */ 172 private int maxTimeLimit = MAX_TIME_LIMIT_DEFAULT; 173 174 /** The maximum size for an incoming PDU */ 175 private int maxPDUSize = Integer.MAX_VALUE; 176 177 /** If LDAPS is activated : the external Keystore file, if defined */ 178 private String keystoreFile; 179 180 /** If LDAPS is activated : the certificate password */ 181 private String certificatePassword; 182 183 /** The extended operation handlers. */ 184 private final Collection<ExtendedOperationHandler<? extends ExtendedRequest, ? extends ExtendedResponse>> extendedOperationHandlers = 185 new ArrayList<>(); 186 187 /** The supported authentication mechanisms. */ 188 private Map<String, MechanismHandler> saslMechanismHandlers = new HashMap<>(); 189 190 /** The name of this host, validated during SASL negotiation. */ 191 private String saslHost = "ldap.example.com"; 192 193 /** The service principal, used by GSSAPI. */ 194 private String saslPrincipal = "ldap/ldap.example.com@EXAMPLE.COM"; 195 196 /** The quality of protection (QoP), used by DIGEST-MD5 and GSSAPI. */ 197 private Set<String> saslQop; 198 private String saslQopString; 199 200 /** The list of realms serviced by this host. */ 201 private List<String> saslRealms; 202 203 /** The protocol handlers */ 204 // MessageReceived handlers 205 private LdapRequestHandler<AbandonRequest> abandonRequestHandler; 206 private LdapRequestHandler<AddRequest> addRequestHandler; 207 private LdapRequestHandler<BindRequest> bindRequestHandler; 208 private LdapRequestHandler<CompareRequest> compareRequestHandler; 209 private LdapRequestHandler<DeleteRequest> deleteRequestHandler; 210 private ExtendedRequestHandler extendedRequestHandler; 211 private LdapRequestHandler<ModifyRequest> modifyRequestHandler; 212 private LdapRequestHandler<ModifyDnRequest> modifyDnRequestHandler; 213 private LdapRequestHandler<SearchRequest> searchRequestHandler; 214 private LdapRequestHandler<UnbindRequest> unbindRequestHandler; 215 216 // MessageSent handlers 217 private LdapResponseHandler<AddResponse> addResponseHandler; 218 private LdapResponseHandler<BindResponse> bindResponseHandler; 219 private LdapResponseHandler<CompareResponse> compareResponseHandler; 220 private LdapResponseHandler<DeleteResponse> deleteResponseHandler; 221 private ExtendedResponseHandler extendedResponseHandler; 222 private LdapResponseHandler<ModifyResponse> modifyResponseHandler; 223 private LdapResponseHandler<IntermediateResponse> intermediateResponseHandler; 224 private LdapResponseHandler<ModifyDnResponse> modifyDnResponseHandler; 225 private LdapResponseHandler<SearchResultEntry> searchResultEntryHandler; 226 private LdapResponseHandler<SearchResultReference> searchResultReferenceHandler; 227 private LdapResponseHandler<SearchResultDone> searchResultDoneHandler; 228 229 /** the underlying provider codec factory */ 230 private ProtocolCodecFactory codecFactory = LdapApiServiceFactory.getSingleton().getProtocolCodecFactory(); 231 232 /** the MINA protocol handler */ 233 private final LdapProtocolHandler handler = new LdapProtocolHandler( this ); 234 235 /** tracks start state of the server */ 236 private boolean started; 237 238 /** 239 * Whether or not confidentiality (TLS secured connection) is required: 240 * disabled by default. 241 */ 242 private boolean confidentialityRequired; 243 244 private List<IoFilterChainBuilder> chainBuilders = new ArrayList<>(); 245 246 /** The handler responsible for the replication */ 247 private ReplicationRequestHandler replicationReqHandler; 248 249 /** The list of replication consumers */ 250 private List<ReplicationConsumer> replConsumers; 251 252 private KeyManagerFactory keyManagerFactory; 253 private TrustManager[] trustManagers; 254 255 /** the time interval between subsequent pings to each replication provider */ 256 private int pingerSleepTime; 257 258 /** 259 * the list of cipher suites to be used in LDAPS and StartTLS 260 * @deprecated See the {@link TcpTransport} class that contains this list 261 **/ 262 @Deprecated 263 private List<String> enabledCipherSuites = new ArrayList<>(); 264 265 266 /** 267 * Creates an LDAP protocol provider. 268 */ 269 public LdapServer() 270 { 271 super.setEnabled( true ); 272 super.setServiceId( SERVICE_PID_DEFAULT ); 273 super.setServiceName( SERVICE_NAME_DEFAULT ); 274 275 saslQop = new HashSet<>(); 276 saslQop.add( SaslQoP.AUTH.getValue() ); 277 saslQop.add( SaslQoP.AUTH_INT.getValue() ); 278 saslQop.add( SaslQoP.AUTH_CONF.getValue() ); 279 saslQopString = SaslQoP.AUTH.getValue() + ',' + SaslQoP.AUTH_INT.getValue() + ',' 280 + SaslQoP.AUTH_CONF.getValue(); 281 282 saslRealms = new ArrayList<>(); 283 saslRealms.add( "example.com" ); 284 285 this.supportedControls = new HashSet<>(); 286 } 287 288 289 /** 290 * Install the LDAP request handlers. 291 */ 292 private void installDefaultHandlers() 293 { 294 if ( getAbandonRequestHandler() == null ) 295 { 296 setAbandonHandler( new AbandonRequestHandler() ); 297 } 298 299 if ( getAddRequestHandler() == null ) 300 { 301 setAddHandlers( new AddRequestHandler(), new AddResponseHandler() ); 302 } 303 304 if ( getBindRequestHandler() == null ) 305 { 306 BindRequestHandler bindRequestHandler = new BindRequestHandler(); 307 bindRequestHandler.setSaslMechanismHandlers( saslMechanismHandlers ); 308 309 setBindHandlers( bindRequestHandler, new BindResponseHandler() ); 310 } 311 312 if ( getCompareRequestHandler() == null ) 313 { 314 setCompareHandlers( new CompareRequestHandler(), new CompareResponseHandler() ); 315 } 316 317 if ( getDeleteRequestHandler() == null ) 318 { 319 setDeleteHandlers( new DeleteRequestHandler(), new DeleteResponseHandler() ); 320 } 321 322 if ( getExtendedRequestHandler() == null ) 323 { 324 setExtendedHandlers( new ExtendedRequestHandler(), new ExtendedResponseHandler() ); 325 } 326 327 if ( getIntermediateResponseHandler() == null ) 328 { 329 setIntermediateHandler( new IntermediateResponseHandler() ); 330 } 331 332 if ( getModifyRequestHandler() == null ) 333 { 334 setModifyHandlers( new ModifyRequestHandler(), new ModifyResponseHandler() ); 335 } 336 337 if ( getModifyDnRequestHandler() == null ) 338 { 339 setModifyDnHandlers( new ModifyDnRequestHandler(), new ModifyDnResponseHandler() ); 340 } 341 342 if ( getSearchRequestHandler() == null ) 343 { 344 setSearchHandlers( new SearchRequestHandler(), 345 new SearchResultEntryHandler(), 346 new SearchResultReferenceHandler(), 347 new SearchResultDoneHandler() ); 348 } 349 350 if ( getUnbindRequestHandler() == null ) 351 { 352 setUnbindHandler( new UnbindRequestHandler() ); 353 } 354 } 355 356 357 /** 358 * reloads the SSL context by replacing the existing SslFilter 359 * with a new SslFilter after reloading the keystore. 360 * 361 * Note: should be called to reload the keystore after changing the digital certificate. 362 * @throws Exception If the SSLContext can't be reloaded 363 */ 364 public void reloadSslContext() throws Exception 365 { 366 if ( !started ) 367 { 368 return; 369 } 370 371 LOG.info( "reloading SSL context..." ); 372 373 keyManagerFactory = CertificateUtil.loadKeyStore( keystoreFile, certificatePassword ); 374 375 String sslFilterName = "sslFilter"; 376 377 for ( IoFilterChainBuilder chainBuilder : chainBuilders ) 378 { 379 DefaultIoFilterChainBuilder dfcb = ( ( DefaultIoFilterChainBuilder ) chainBuilder ); 380 381 if ( dfcb.contains( sslFilterName ) ) 382 { 383 // Get the TcpTransport 384 TcpTransport tcpTransport = null; 385 386 for ( Transport transport : getTransports() ) 387 { 388 if ( transport instanceof TcpTransport ) 389 { 390 tcpTransport = ( TcpTransport ) transport; 391 break; 392 } 393 } 394 395 DefaultIoFilterChainBuilder newChain = ( DefaultIoFilterChainBuilder ) LdapsInitializer 396 .init( this, tcpTransport ); 397 dfcb.replace( sslFilterName, newChain.get( sslFilterName ) ); 398 newChain = null; 399 } 400 } 401 402 StartTlsHandler handler = ( StartTlsHandler ) getExtendedOperationHandler( StartTlsHandler.EXTENSION_OID ); 403 404 if ( handler != null ) 405 { 406 handler.setLdapServer( this ); 407 } 408 409 LOG.info( "reloaded SSL context successfully" ); 410 } 411 412 413 /** 414 * @throws IOException if we cannot bind to the specified port 415 * @throws Exception if the LDAP server cannot be started 416 */ 417 @Override 418 public void start() throws Exception 419 { 420 if ( !isEnabled() ) 421 { 422 return; 423 } 424 425 keyManagerFactory = CertificateUtil.loadKeyStore( keystoreFile, certificatePassword ); 426 427 if ( trustManagers == null ) 428 { 429 TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() ); 430 trustManagerFactory.init( ( KeyStore ) null ); 431 trustManagers = trustManagerFactory.getTrustManagers(); 432 } 433 434 /* 435 * The server is now initialized, we can 436 * install the default requests handlers, which need 437 * access to the DirectoryServer instance. 438 */ 439 installDefaultHandlers(); 440 441 PartitionNexus nexus = getDirectoryService().getPartitionNexus(); 442 443 for ( ExtendedOperationHandler<? extends ExtendedRequest, ? extends ExtendedResponse> h : extendedOperationHandlers ) 444 { 445 LOG.info( "Added Extended Request Handler: {}", h.getOid() ); 446 h.setLdapServer( this ); 447 nexus.registerSupportedExtensions( h.getExtensionOids() ); 448 } 449 450 nexus.registerSupportedSaslMechanisms( saslMechanismHandlers.keySet() ); 451 452 // Install the replication handler if we have one 453 startReplicationProducer(); 454 455 for ( Transport transport : transports ) 456 { 457 if ( !( transport instanceof TcpTransport ) ) 458 { 459 LOG.warn( "Cannot listen on an UDP transport : {}", transport ); 460 continue; 461 } 462 463 IoFilterChainBuilder chain; 464 465 if ( transport.isSSLEnabled() ) 466 { 467 chain = LdapsInitializer.init( this, ( TcpTransport ) transport ); 468 } 469 else 470 { 471 chain = new DefaultIoFilterChainBuilder(); 472 } 473 474 // Inject the codec into the chain 475 ( ( DefaultIoFilterChainBuilder ) chain ).addLast( "codec", new ProtocolCodecFilter( this 476 .getProtocolCodecFactory() ) ); 477 478 // Now inject an ExecutorFilter for the write operations 479 // We use the same number of thread than the number of IoProcessor 480 // (NOTE : this has to be double checked) 481 ( ( DefaultIoFilterChainBuilder ) chain ).addLast( "executor", new ExecutorFilter( 482 new UnorderedThreadPoolExecutor( transport.getNbThreads() ), IoEventType.MESSAGE_RECEIVED ) ); 483 484 /* 485 // Trace all the incoming and outgoing message to the console 486 ( ( DefaultIoFilterChainBuilder ) chain ).addLast( "logger", new IoFilterAdapter() 487 { 488 public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception 489 { 490 System.out.println( ">>> Message received : " + message ); 491 nextFilter.messageReceived(session, message); 492 } 493 494 public void filterWrite(NextFilter nextFilter, IoSession session, 495 WriteRequest writeRequest) throws Exception 496 { 497 System.out.println( "<<< Message sent : " + writeRequest.getMessage() ); 498 nextFilter.filterWrite(session, writeRequest); 499 } 500 }); 501 */ 502 503 startNetwork( transport, chain ); 504 } 505 506 // And start the replication consumers on this server 507 // these should be started only after starting the network see DIRSERVER-1894 508 startReplicationConsumers(); 509 510 started = true; 511 512 LOG.info( "Ldap service started." ); 513 } 514 515 516 /** 517 * Install the replication handler if we have one 518 */ 519 public void startReplicationProducer() 520 { 521 if ( replicationReqHandler != null ) 522 { 523 replicationReqHandler.start( this ); 524 ( ( SearchRequestHandler ) getSearchRequestHandler() ).setReplicationReqHandler( replicationReqHandler ); 525 } 526 } 527 528 529 /** 530 * {@inheritDoc} 531 */ 532 @Override 533 public void stop() 534 { 535 try 536 { 537 for ( Transport transport : transports ) 538 { 539 if ( !( transport instanceof TcpTransport ) ) 540 { 541 continue; 542 } 543 544 // we should unbind the service before we begin sending the notice 545 // of disconnect so new connections are not formed while we process 546 List<WriteFuture> writeFutures = new ArrayList<>(); 547 548 // If the socket has already been unbound as with a successful 549 // GracefulShutdownRequest then this will complain that the service 550 // is not bound - this is ok because the GracefulShutdown has already 551 // sent notices to to the existing active sessions 552 List<IoSession> sessions; 553 554 try 555 { 556 sessions = new ArrayList<>( getSocketAcceptor( transport ).getManagedSessions().values() ); 557 } 558 catch ( IllegalArgumentException e ) 559 { 560 LOG.warn( "Seems like the LDAP service ({}) has already been unbound.", getPort() ); 561 return; 562 } 563 564 565 // Kill the chain executor 566 ExecutorFilter executorFilter = ( ExecutorFilter ) transport.getAcceptor().getFilterChain().get( "executor" ); 567 ( ( UnorderedThreadPoolExecutor ) executorFilter.getExecutor() ).shutdownNow(); 568 569 // Shutdown the transport 570 getSocketAcceptor( transport ).dispose(); 571 572 if ( LOG.isInfoEnabled() ) 573 { 574 LOG.info( "Unbind of an LDAP service ({}) is complete.", getPort() ); 575 LOG.info( "Sending notice of disconnect to existing clients sessions." ); 576 } 577 578 // Send Notification of Disconnection messages to all connected clients. 579 if ( sessions != null ) 580 { 581 for ( IoSession session : sessions ) 582 { 583 writeFutures.add( session.write( NoticeOfDisconnect.UNAVAILABLE ) ); 584 } 585 } 586 587 // And close the connections when the NoDs are sent. 588 Iterator<IoSession> sessionIt = sessions.iterator(); 589 590 for ( WriteFuture future : writeFutures ) 591 { 592 future.await( 1000L ); 593 sessionIt.next().closeNow(); 594 } 595 596 if ( replicationReqHandler != null ) 597 { 598 replicationReqHandler.stop(); 599 } 600 } 601 602 // Stop the replication consumers 603 stopConsumers(); 604 } 605 catch ( Exception e ) 606 { 607 LOG.warn( "Failed to sent NoD.", e ); 608 } 609 610 started = false; 611 LOG.info( "Ldap service stopped." ); 612 } 613 614 615 private void startNetwork( Transport transport, IoFilterChainBuilder chainBuilder ) throws Exception 616 { 617 if ( transport.getBackLog() < 0 ) 618 { 619 // Set the backlog to the default value when it's below 0 620 transport.setBackLog( 50 ); 621 } 622 623 chainBuilders.add( chainBuilder ); 624 625 try 626 { 627 SocketAcceptor acceptor = getSocketAcceptor( transport ); 628 629 // Now, configure the acceptor 630 // Disable the disconnection of the clients on unbind 631 acceptor.setCloseOnDeactivation( false ); 632 633 // No Nagle's algorithm 634 acceptor.getSessionConfig().setTcpNoDelay( true ); 635 636 // Inject the chain 637 acceptor.setFilterChainBuilder( chainBuilder ); 638 639 // Inject the protocol handler 640 acceptor.setHandler( getHandler() ); 641 642 ( ( AbstractSocketSessionConfig ) acceptor.getSessionConfig() ).setReadBufferSize( 64 * 1024 ); 643 ( ( AbstractSocketSessionConfig ) acceptor.getSessionConfig() ).setSendBufferSize( 64 * 1024 ); 644 645 // Bind to the configured address 646 acceptor.bind(); 647 648 // We are done ! 649 started = true; 650 651 if ( LOG.isInfoEnabled() ) 652 { 653 LOG.info( "Successful bind of an LDAP Service ({}) is completed.", transport.getPort() ); 654 } 655 } 656 catch ( IOException e ) 657 { 658 String msg = I18n.err( I18n.ERR_171, transport.getPort() ); 659 LdapConfigurationException lce = new LdapConfigurationException( msg ); 660 lce.setCause( e ); 661 LOG.error( msg, e ); 662 throw lce; 663 } 664 } 665 666 667 /** 668 * Starts the replication consumers 669 * 670 * @throws LdapException If the consumer can't be started 671 */ 672 public void startReplicationConsumers() throws Exception 673 { 674 if ( ( replConsumers != null ) && !replConsumers.isEmpty() ) 675 { 676 final PingerThread pingerThread = new PingerThread( pingerSleepTime ); 677 pingerThread.start(); 678 679 for ( final ReplicationConsumer consumer : replConsumers ) 680 { 681 consumer.init( getDirectoryService() ); 682 683 Runnable consumerTask = new Runnable() 684 { 685 @Override 686 public void run() 687 { 688 try 689 { 690 while ( true ) 691 { 692 if ( CONSUMER_LOG.isDebugEnabled() ) 693 { 694 MDC.put( "Replica", consumer.getId() ); 695 } 696 697 LOG.info( "starting the replication consumer with {}", consumer ); 698 CONSUMER_LOG.info( "starting the replication consumer with {}", consumer ); 699 boolean isConnected = consumer.connect( ReplicationConsumer.NOW ); 700 701 if ( isConnected ) 702 { 703 pingerThread.addConsumer( consumer ); 704 705 // We are now connected, start the replication 706 ReplicationStatusEnum status = null; 707 708 do 709 { 710 status = consumer.startSync(); 711 } 712 while ( status == ReplicationStatusEnum.REFRESH_REQUIRED ); 713 714 if ( status == ReplicationStatusEnum.STOPPED ) 715 { 716 // Exit the loop 717 break; 718 } 719 } 720 } 721 } 722 catch ( Exception e ) 723 { 724 LOG.error( "Failed to start consumer {}", consumer ); 725 CONSUMER_LOG.error( "Failed to start consumer {}", consumer ); 726 throw new RuntimeException( e ); 727 } 728 } 729 }; 730 731 Thread consumerThread = new Thread( consumerTask ); 732 consumerThread.setDaemon( true ); 733 consumerThread.start(); 734 } 735 } 736 } 737 738 739 /** 740 * stops the replication consumers 741 */ 742 private void stopConsumers() 743 { 744 if ( replConsumers != null ) 745 { 746 for ( ReplicationConsumer consumer : replConsumers ) 747 { 748 LOG.info( "stopping the consumer with id {}", consumer.getId() ); 749 consumer.stop(); 750 } 751 } 752 } 753 754 755 public String getName() 756 { 757 return SERVICE_NAME; 758 } 759 760 761 public IoHandler getHandler() 762 { 763 return handler; 764 } 765 766 767 public LdapSessionManager getLdapSessionManager() 768 { 769 return ldapSessionManager; 770 } 771 772 773 public ProtocolCodecFactory getProtocolCodecFactory() 774 { 775 return codecFactory; 776 } 777 778 779 // ------------------------------------------------------------------------ 780 // Configuration Methods 781 // ------------------------------------------------------------------------ 782 783 /** 784 * Registers the specified {@link ExtendedOperationHandler} to this 785 * protocol provider to provide a specific LDAP extended operation. 786 * 787 * @param eoh an extended operation handler 788 * @throws Exception on failure to add the handler 789 */ 790 public void addExtendedOperationHandler( ExtendedOperationHandler<? extends ExtendedRequest, 791 ? extends ExtendedResponse> eoh ) throws LdapException 792 { 793 if ( started ) 794 { 795 eoh.setLdapServer( this ); 796 PartitionNexus nexus = getDirectoryService().getPartitionNexus(); 797 nexus.registerSupportedExtensions( eoh.getExtensionOids() ); 798 } 799 else 800 { 801 extendedOperationHandlers.add( eoh ); 802 } 803 } 804 805 806 /** 807 * Deregister an {@link ExtendedOperationHandler} with the specified <tt>oid</tt> 808 * from this protocol provider. 809 * 810 * @param oid the numeric identifier for the extended operation associated with 811 * the handler to remove 812 */ 813 public void removeExtendedOperationHandler( String oid ) 814 { 815 // need to do something like this to make this work right 816 // DefaultPartitionNexus nexus = getDirectoryService().getPartitionNexus(); 817 // nexus.unregisterSupportedExtensions( eoh.getExtensionOids() ); 818 819 ExtendedOperationHandler<?, ?> handler = null; 820 821 for ( ExtendedOperationHandler<?, ?> extendedOperationHandler : extendedOperationHandlers ) 822 { 823 if ( extendedOperationHandler.getOid().equals( oid ) ) 824 { 825 handler = extendedOperationHandler; 826 break; 827 } 828 } 829 830 extendedOperationHandlers.remove( handler ); 831 } 832 833 834 /** 835 * Returns an {@link ExtendedOperationHandler} with the specified <tt>oid</tt> 836 * which is registered to this protocol provider. 837 * 838 * @param oid the oid of the extended request of associated with the extended 839 * request handler 840 * @return the exnteded operation handler 841 */ 842 public ExtendedOperationHandler<? extends ExtendedRequest, ? extends ExtendedResponse> getExtendedOperationHandler( 843 String oid ) 844 { 845 for ( ExtendedOperationHandler<? extends ExtendedRequest, ? extends ExtendedResponse> 846 extendedOperationHandler : extendedOperationHandlers ) 847 { 848 if ( extendedOperationHandler.getOid().equals( oid ) ) 849 { 850 return extendedOperationHandler; 851 } 852 } 853 854 return null; 855 } 856 857 858 /** 859 * Sets the mode for this LdapServer to accept requests with or without a 860 * TLS secured connection via either StartTLS extended operations or using 861 * LDAPS. 862 * 863 * @param confidentialityRequired true to require confidentiality 864 */ 865 public void setConfidentialityRequired( boolean confidentialityRequired ) 866 { 867 this.confidentialityRequired = confidentialityRequired; 868 } 869 870 871 /** 872 * Gets whether or not TLS secured connections are required to perform 873 * operations on this LdapServer. 874 * 875 * @return true if TLS secured connections are required, false otherwise 876 */ 877 public boolean isConfidentialityRequired() 878 { 879 return confidentialityRequired; 880 } 881 882 883 /** 884 * Returns <tt>true</tt> if LDAPS is enabled. 885 * 886 * @param transport The LDAP transport 887 * @return <tt>true</tt> if LDAPS is enabled. 888 */ 889 public boolean isEnableLdaps( Transport transport ) 890 { 891 return transport.isSSLEnabled(); 892 } 893 894 895 /** 896 * Sets the maximum size limit in number of entries to return for search. 897 * 898 * @param maxSizeLimit the maximum number of entries to return for search 899 */ 900 public void setMaxSizeLimit( long maxSizeLimit ) 901 { 902 this.maxSizeLimit = maxSizeLimit; 903 } 904 905 906 /** 907 * Returns the maximum size limit in number of entries to return for search. 908 * 909 * @return The maximum size limit. 910 */ 911 public long getMaxSizeLimit() 912 { 913 return maxSizeLimit; 914 } 915 916 917 /** 918 * Sets the maximum time limit in milliseconds to conduct a search. 919 * 920 * @param maxTimeLimit the maximum length of time in milliseconds for search 921 */ 922 public void setMaxTimeLimit( int maxTimeLimit ) 923 { 924 this.maxTimeLimit = maxTimeLimit; //TODO review the time parameters used all over the server and convert to seconds 925 } 926 927 928 /** 929 * Returns the maximum time limit in milliseconds to conduct a search. 930 * 931 * @return The maximum time limit in milliseconds for search 932 */ 933 public int getMaxTimeLimit() 934 { 935 return maxTimeLimit; 936 } 937 938 939 /** 940 * Gets the {@link ExtendedOperationHandler}s. 941 * 942 * @return A collection of {@link ExtendedOperationHandler}s. 943 */ 944 public Collection<ExtendedOperationHandler<? extends ExtendedRequest, ? extends ExtendedResponse>> getExtendedOperationHandlers() 945 { 946 return new ArrayList<>( 947 extendedOperationHandlers ); 948 } 949 950 951 /** 952 * Sets the {@link ExtendedOperationHandler}s. 953 * 954 * @param handlers A collection of {@link ExtendedOperationHandler}s. 955 */ 956 public void setExtendedOperationHandlers( 957 Collection<ExtendedOperationHandler<ExtendedRequest, ExtendedResponse>> handlers ) 958 { 959 this.extendedOperationHandlers.clear(); 960 this.extendedOperationHandlers.addAll( handlers ); 961 } 962 963 964 /** 965 * Returns the FQDN of this SASL host, validated during SASL negotiation. 966 * 967 * @return The FQDN of this SASL host, validated during SASL negotiation. 968 */ 969 public String getSaslHost() 970 { 971 return saslHost; 972 } 973 974 975 /** 976 * Sets the FQDN of this SASL host, validated during SASL negotiation. 977 * 978 * @param saslHost The FQDN of this SASL host, validated during SASL negotiation. 979 */ 980 public void setSaslHost( String saslHost ) 981 { 982 this.saslHost = saslHost; 983 } 984 985 986 /** 987 * Returns the Kerberos principal name for this LDAP service, used by GSSAPI. 988 * 989 * @return The Kerberos principal name for this LDAP service, used by GSSAPI. 990 */ 991 public String getSaslPrincipal() 992 { 993 return saslPrincipal; 994 } 995 996 997 /** 998 * Sets the Kerberos principal name for this LDAP service, used by GSSAPI. 999 * 1000 * @param saslPrincipal The Kerberos principal name for this LDAP service, used by GSSAPI. 1001 */ 1002 public void setSaslPrincipal( String saslPrincipal ) 1003 { 1004 this.saslPrincipal = saslPrincipal; 1005 } 1006 1007 1008 /** 1009 * Returns the quality-of-protection, used by DIGEST-MD5 and GSSAPI. 1010 * 1011 * @return The quality-of-protection, used by DIGEST-MD5 and GSSAPI. 1012 */ 1013 public String getSaslQopString() 1014 { 1015 return saslQopString; 1016 } 1017 1018 1019 /** 1020 * Returns the Set of quality-of-protection, used by DIGEST-MD5 and GSSAPI. 1021 * 1022 * @return The quality-of-protection, used by DIGEST-MD5 and GSSAPI. 1023 */ 1024 public Set<String> getSaslQop() 1025 { 1026 return saslQop; 1027 } 1028 1029 1030 /** 1031 * Returns the realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI. 1032 * 1033 * @return The realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI. 1034 */ 1035 public List<String> getSaslRealms() 1036 { 1037 return saslRealms; 1038 } 1039 1040 1041 /** 1042 * Sets the realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI. 1043 * 1044 * @param saslRealms The realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI. 1045 */ 1046 public void setSaslRealms( List<String> saslRealms ) 1047 { 1048 this.saslRealms = saslRealms; 1049 } 1050 1051 1052 /** 1053 * @return the supported SASL mechanisms 1054 */ 1055 public Map<String, MechanismHandler> getSaslMechanismHandlers() 1056 { 1057 return saslMechanismHandlers; 1058 } 1059 1060 1061 public void setSaslMechanismHandlers( Map<String, MechanismHandler> saslMechanismHandlers ) 1062 { 1063 this.saslMechanismHandlers = saslMechanismHandlers; 1064 } 1065 1066 1067 public MechanismHandler addSaslMechanismHandler( String mechanism, MechanismHandler handler ) 1068 { 1069 return this.saslMechanismHandlers.put( mechanism, handler ); 1070 } 1071 1072 1073 public MechanismHandler removeSaslMechanismHandler( String mechanism ) 1074 { 1075 return this.saslMechanismHandlers.remove( mechanism ); 1076 } 1077 1078 1079 public MechanismHandler getMechanismHandler( String mechanism ) 1080 { 1081 return this.saslMechanismHandlers.get( mechanism ); 1082 } 1083 1084 1085 public Set<String> getSupportedMechanisms() 1086 { 1087 return saslMechanismHandlers.keySet(); 1088 } 1089 1090 1091 @Override 1092 public void setDirectoryService( DirectoryService directoryService ) 1093 { 1094 super.setDirectoryService( directoryService ); 1095 Iterator<String> itr = directoryService.getLdapCodecService().registeredRequestControls(); 1096 1097 while ( itr.hasNext() ) 1098 { 1099 supportedControls.add( itr.next() ); 1100 } 1101 1102 itr = directoryService.getLdapCodecService().registeredResponseControls(); 1103 1104 while ( itr.hasNext() ) 1105 { 1106 supportedControls.add( itr.next() ); 1107 } 1108 } 1109 1110 1111 public Set<String> getSupportedControls() 1112 { 1113 return supportedControls; 1114 } 1115 1116 1117 /** 1118 * @return The MessageReceived handler for the AbandonRequest 1119 */ 1120 public MessageHandler<AbandonRequest> getAbandonRequestHandler() 1121 { 1122 return abandonRequestHandler; 1123 } 1124 1125 1126 /** 1127 * Inject the MessageReceived handler into the IoHandler 1128 * 1129 * @param abandonRequestdHandler The AbandonRequest message received handler 1130 */ 1131 public void setAbandonHandler( LdapRequestHandler<AbandonRequest> abandonRequestdHandler ) 1132 { 1133 this.handler.removeReceivedMessageHandler( AbandonRequest.class ); 1134 this.abandonRequestHandler = abandonRequestdHandler; 1135 this.abandonRequestHandler.setLdapServer( this ); 1136 this.handler.addReceivedMessageHandler( AbandonRequest.class, this.abandonRequestHandler ); 1137 } 1138 1139 1140 /** 1141 * @return The MessageReceived handler for the AddRequest 1142 */ 1143 public LdapRequestHandler<AddRequest> getAddRequestHandler() 1144 { 1145 return addRequestHandler; 1146 } 1147 1148 1149 /** 1150 * @return The MessageSent handler for the AddResponse 1151 */ 1152 public LdapResponseHandler<AddResponse> getAddResponseHandler() 1153 { 1154 return addResponseHandler; 1155 } 1156 1157 1158 /** 1159 * Inject the MessageReceived and MessageSent handler into the IoHandler 1160 * 1161 * @param addRequestHandler The AddRequest message received handler 1162 * @param addResponseHandler The AddResponse message sent handler 1163 */ 1164 public void setAddHandlers( LdapRequestHandler<AddRequest> addRequestHandler, 1165 LdapResponseHandler<AddResponse> addResponseHandler ) 1166 { 1167 this.handler.removeReceivedMessageHandler( AddRequest.class ); 1168 this.addRequestHandler = addRequestHandler; 1169 this.addRequestHandler.setLdapServer( this ); 1170 this.handler.addReceivedMessageHandler( AddRequest.class, this.addRequestHandler ); 1171 1172 this.handler.removeSentMessageHandler( AddResponse.class ); 1173 this.addResponseHandler = addResponseHandler; 1174 this.addResponseHandler.setLdapServer( this ); 1175 this.handler.addSentMessageHandler( AddResponse.class, this.addResponseHandler ); 1176 } 1177 1178 1179 /** 1180 * @return The MessageReceived handler for the BindRequest 1181 */ 1182 public LdapRequestHandler<BindRequest> getBindRequestHandler() 1183 { 1184 return bindRequestHandler; 1185 } 1186 1187 1188 /** 1189 * @return The MessageSent handler for the BindResponse 1190 */ 1191 public LdapResponseHandler<BindResponse> getBindResponseHandler() 1192 { 1193 return bindResponseHandler; 1194 } 1195 1196 1197 /** 1198 * Inject the MessageReceived and MessageSent handler into the IoHandler 1199 * 1200 * @param bindRequestHandler The BindRequest message received handler 1201 * @param bindResponseHandler The BindResponse message sent handler 1202 */ 1203 public void setBindHandlers( LdapRequestHandler<BindRequest> bindRequestHandler, 1204 LdapResponseHandler<BindResponse> bindResponseHandler ) 1205 { 1206 handler.removeReceivedMessageHandler( BindRequest.class ); 1207 this.bindRequestHandler = bindRequestHandler; 1208 this.bindRequestHandler.setLdapServer( this ); 1209 handler.addReceivedMessageHandler( BindRequest.class, this.bindRequestHandler ); 1210 1211 handler.removeSentMessageHandler( BindResponse.class ); 1212 this.bindResponseHandler = bindResponseHandler; 1213 this.bindResponseHandler.setLdapServer( this ); 1214 handler.addSentMessageHandler( BindResponse.class, this.bindResponseHandler ); 1215 } 1216 1217 1218 /** 1219 * @return The MessageReceived handler for the CompareRequest 1220 */ 1221 public LdapRequestHandler<CompareRequest> getCompareRequestHandler() 1222 { 1223 return compareRequestHandler; 1224 } 1225 1226 1227 /** 1228 * @return The MessageSent handler for the CompareResponse 1229 */ 1230 public LdapResponseHandler<CompareResponse> getCompareResponseHandler() 1231 { 1232 return compareResponseHandler; 1233 } 1234 1235 1236 /** 1237 * Inject the MessageReceived and MessageSent handler into the IoHandler 1238 * 1239 * @param compareRequestHandler The CompareRequest message received handler 1240 * @param compareResponseHandler The CompareResponse message sent handler 1241 */ 1242 public void setCompareHandlers( LdapRequestHandler<CompareRequest> compareRequestHandler, 1243 LdapResponseHandler<CompareResponse> compareResponseHandler ) 1244 { 1245 handler.removeReceivedMessageHandler( CompareRequest.class ); 1246 this.compareRequestHandler = compareRequestHandler; 1247 this.compareRequestHandler.setLdapServer( this ); 1248 this.handler.addReceivedMessageHandler( CompareRequest.class, this.compareRequestHandler ); 1249 1250 handler.removeReceivedMessageHandler( CompareResponse.class ); 1251 this.compareResponseHandler = compareResponseHandler; 1252 this.compareResponseHandler.setLdapServer( this ); 1253 this.handler.addSentMessageHandler( CompareResponse.class, this.compareResponseHandler ); 1254 } 1255 1256 1257 /** 1258 * @return The MessageReceived handler for the DeleteRequest 1259 */ 1260 public LdapRequestHandler<DeleteRequest> getDeleteRequestHandler() 1261 { 1262 return deleteRequestHandler; 1263 } 1264 1265 1266 /** 1267 * @return The MessageSent handler for the DeleteResponse 1268 */ 1269 public LdapResponseHandler<DeleteResponse> getDeleteResponseHandler() 1270 { 1271 return deleteResponseHandler; 1272 } 1273 1274 1275 /** 1276 * Inject the MessageReceived and MessageSent handler into the IoHandler 1277 * 1278 * @param deleteRequestHandler The DeleteRequest message received handler 1279 * @param deleteResponseHandler The DeleteResponse message sent handler 1280 */ 1281 public void setDeleteHandlers( LdapRequestHandler<DeleteRequest> deleteRequestHandler, 1282 LdapResponseHandler<DeleteResponse> deleteResponseHandler ) 1283 { 1284 handler.removeReceivedMessageHandler( DeleteRequest.class ); 1285 this.deleteRequestHandler = deleteRequestHandler; 1286 this.deleteRequestHandler.setLdapServer( this ); 1287 this.handler.addReceivedMessageHandler( DeleteRequest.class, this.deleteRequestHandler ); 1288 1289 handler.removeSentMessageHandler( DeleteResponse.class ); 1290 this.deleteResponseHandler = deleteResponseHandler; 1291 this.deleteResponseHandler.setLdapServer( this ); 1292 this.handler.addSentMessageHandler( DeleteResponse.class, this.deleteResponseHandler ); 1293 } 1294 1295 1296 /** 1297 * @return The MessageReceived handler for the ExtendedRequest 1298 */ 1299 public LdapRequestHandler<ExtendedRequest> getExtendedRequestHandler() 1300 { 1301 return extendedRequestHandler; 1302 } 1303 1304 1305 /** 1306 * @return The MessageSent handler for the ExtendedResponse 1307 */ 1308 public LdapResponseHandler<ExtendedResponse> getExtendedResponseHandler() 1309 { 1310 return extendedResponseHandler; 1311 } 1312 1313 1314 /** 1315 * Inject the MessageReceived and MessageSent handler into the IoHandler 1316 * 1317 * @param extendedRequestHandler The ExtendedRequest message received handler 1318 * @param extendedResponseHandler The ExtendedResponse message sent handler 1319 */ 1320 @SuppressWarnings( 1321 { "unchecked", "rawtypes" }) 1322 public void setExtendedHandlers( ExtendedRequestHandler extendedRequestHandler, 1323 ExtendedResponseHandler extendedResponseHandler ) 1324 { 1325 handler.removeReceivedMessageHandler( ExtendedRequest.class ); 1326 this.extendedRequestHandler = extendedRequestHandler; 1327 this.extendedRequestHandler.setLdapServer( this ); 1328 this.handler.addReceivedMessageHandler( ExtendedRequest.class, 1329 this.extendedRequestHandler ); 1330 1331 handler.removeSentMessageHandler( ExtendedResponse.class ); 1332 this.extendedResponseHandler = extendedResponseHandler; 1333 this.extendedResponseHandler.setLdapServer( this ); 1334 this.handler.addSentMessageHandler( ExtendedResponse.class, this.extendedResponseHandler ); 1335 } 1336 1337 1338 /** 1339 * @return The MessageSent handler for the IntermediateResponse 1340 */ 1341 public LdapResponseHandler<IntermediateResponse> getIntermediateResponseHandler() 1342 { 1343 return intermediateResponseHandler; 1344 } 1345 1346 1347 /** 1348 * Inject the MessageReceived and MessageSent handler into the IoHandler 1349 * 1350 * @param intermediateResponseHandler The IntermediateResponse message sent handler 1351 */ 1352 public void setIntermediateHandler( LdapResponseHandler<IntermediateResponse> intermediateResponseHandler ) 1353 { 1354 handler.removeSentMessageHandler( IntermediateResponse.class ); 1355 this.intermediateResponseHandler = intermediateResponseHandler; 1356 this.intermediateResponseHandler.setLdapServer( this ); 1357 this.handler.addSentMessageHandler( IntermediateResponse.class, this.intermediateResponseHandler ); 1358 } 1359 1360 1361 /** 1362 * @return The MessageReceived handler for the ModifyRequest 1363 */ 1364 public LdapRequestHandler<ModifyRequest> getModifyRequestHandler() 1365 { 1366 return modifyRequestHandler; 1367 } 1368 1369 1370 /** 1371 * @return The MessageSent handler for the ModifyResponse 1372 */ 1373 public LdapResponseHandler<ModifyResponse> getModifyResponseHandler() 1374 { 1375 return modifyResponseHandler; 1376 } 1377 1378 1379 /** 1380 * Inject the MessageReceived and MessageSent handler into the IoHandler 1381 * 1382 * @param modifyRequestHandler The ModifyRequest message received handler 1383 * @param modifyResponseHandler The ModifyResponse message sent handler 1384 */ 1385 public void setModifyHandlers( LdapRequestHandler<ModifyRequest> modifyRequestHandler, 1386 LdapResponseHandler<ModifyResponse> modifyResponseHandler ) 1387 { 1388 handler.removeReceivedMessageHandler( ModifyRequest.class ); 1389 this.modifyRequestHandler = modifyRequestHandler; 1390 this.modifyRequestHandler.setLdapServer( this ); 1391 this.handler.addReceivedMessageHandler( ModifyRequest.class, this.modifyRequestHandler ); 1392 1393 handler.removeSentMessageHandler( ModifyResponse.class ); 1394 this.modifyResponseHandler = modifyResponseHandler; 1395 this.modifyResponseHandler.setLdapServer( this ); 1396 this.handler.addSentMessageHandler( ModifyResponse.class, this.modifyResponseHandler ); 1397 } 1398 1399 1400 /** 1401 * @return The MessageSent handler for the ModifyDnRequest 1402 */ 1403 public LdapRequestHandler<ModifyDnRequest> getModifyDnRequestHandler() 1404 { 1405 return modifyDnRequestHandler; 1406 } 1407 1408 1409 /** 1410 * @return The MessageSent handler for the ModifyDnResponse 1411 */ 1412 public LdapResponseHandler<ModifyDnResponse> getModifyDnResponseHandler() 1413 { 1414 return modifyDnResponseHandler; 1415 } 1416 1417 1418 /** 1419 * Inject the MessageReceived and MessageSent handler into the IoHandler 1420 * 1421 * @param modifyDnRequestHandler The ModifyDnRequest message received handler 1422 * @param modifyDnResponseHandler The ModifyDnResponse message sent handler 1423 */ 1424 public void setModifyDnHandlers( LdapRequestHandler<ModifyDnRequest> modifyDnRequestHandler, 1425 LdapResponseHandler<ModifyDnResponse> modifyDnResponseHandler ) 1426 { 1427 handler.removeReceivedMessageHandler( ModifyDnRequest.class ); 1428 this.modifyDnRequestHandler = modifyDnRequestHandler; 1429 this.modifyDnRequestHandler.setLdapServer( this ); 1430 this.handler.addReceivedMessageHandler( ModifyDnRequest.class, this.modifyDnRequestHandler ); 1431 1432 handler.removeSentMessageHandler( ModifyDnResponse.class ); 1433 this.modifyDnResponseHandler = modifyDnResponseHandler; 1434 this.modifyDnResponseHandler.setLdapServer( this ); 1435 this.handler.addSentMessageHandler( ModifyDnResponse.class, this.modifyDnResponseHandler ); 1436 } 1437 1438 1439 /** 1440 * @return The MessageReceived handler for the SearchRequest 1441 */ 1442 public LdapRequestHandler<SearchRequest> getSearchRequestHandler() 1443 { 1444 return searchRequestHandler; 1445 } 1446 1447 1448 /** 1449 * @return The MessageSent handler for the SearchResultEntry 1450 */ 1451 public LdapResponseHandler<SearchResultEntry> getSearchResultEntryHandler() 1452 { 1453 return searchResultEntryHandler; 1454 } 1455 1456 1457 /** 1458 * @return The MessageSent handler for the SearchResultReference 1459 */ 1460 public LdapResponseHandler<SearchResultReference> getSearchResultReferenceHandler() 1461 { 1462 return searchResultReferenceHandler; 1463 } 1464 1465 1466 /** 1467 * @return The MessageSent handler for the SearchResultDone 1468 */ 1469 public LdapResponseHandler<SearchResultDone> getSearchResultDoneHandler() 1470 { 1471 return searchResultDoneHandler; 1472 } 1473 1474 1475 /** 1476 * Inject the MessageReceived and MessageSent handler into the IoHandler 1477 * 1478 * @param searchRequestHandler The SearchRequest message received handler 1479 * @param searchResultEntryHandler The SearchResultEntry message sent handler 1480 * @param searchResultReferenceHandler The SearchResultReference message sent handler 1481 * @param searchResultDoneHandler The SearchResultDone message sent handler 1482 */ 1483 public void setSearchHandlers( LdapRequestHandler<SearchRequest> searchRequestHandler, 1484 LdapResponseHandler<SearchResultEntry> searchResultEntryHandler, 1485 LdapResponseHandler<SearchResultReference> searchResultReferenceHandler, 1486 LdapResponseHandler<SearchResultDone> searchResultDoneHandler 1487 ) 1488 { 1489 this.handler.removeReceivedMessageHandler( SearchRequest.class ); 1490 this.searchRequestHandler = searchRequestHandler; 1491 this.searchRequestHandler.setLdapServer( this ); 1492 this.handler.addReceivedMessageHandler( SearchRequest.class, this.searchRequestHandler ); 1493 1494 this.handler.removeSentMessageHandler( SearchResultEntry.class ); 1495 this.searchResultEntryHandler = searchResultEntryHandler; 1496 this.searchResultEntryHandler.setLdapServer( this ); 1497 this.handler.addSentMessageHandler( SearchResultEntry.class, this.searchResultEntryHandler ); 1498 1499 this.handler.removeSentMessageHandler( SearchResultReference.class ); 1500 this.searchResultReferenceHandler = searchResultReferenceHandler; 1501 this.searchResultReferenceHandler.setLdapServer( this ); 1502 this.handler.addSentMessageHandler( SearchResultReference.class, this.searchResultReferenceHandler ); 1503 1504 this.handler.removeSentMessageHandler( SearchResultDone.class ); 1505 this.searchResultDoneHandler = searchResultDoneHandler; 1506 this.searchResultDoneHandler.setLdapServer( this ); 1507 this.handler.addSentMessageHandler( SearchResultDone.class, this.searchResultDoneHandler ); 1508 } 1509 1510 1511 /** 1512 * @return The MessageReceived handler for the UnbindRequest 1513 */ 1514 public LdapRequestHandler<UnbindRequest> getUnbindRequestHandler() 1515 { 1516 return unbindRequestHandler; 1517 } 1518 1519 1520 /** 1521 * Inject the MessageReceived handler into the IoHandler 1522 * 1523 * @param unbindRequestHandler The UnbindRequest message received handler 1524 */ 1525 public void setUnbindHandler( LdapRequestHandler<UnbindRequest> unbindRequestHandler ) 1526 { 1527 this.handler.removeReceivedMessageHandler( UnbindRequest.class ); 1528 this.unbindRequestHandler = unbindRequestHandler; 1529 this.unbindRequestHandler.setLdapServer( this ); 1530 this.handler.addReceivedMessageHandler( UnbindRequest.class, this.unbindRequestHandler ); 1531 } 1532 1533 1534 /** 1535 * @return The underlying TCP transport port, or -1 if no transport has been 1536 * initialized 1537 */ 1538 public int getPort() 1539 { 1540 if ( transports == null ) 1541 { 1542 return -1; 1543 } 1544 1545 for ( Transport transport : transports ) 1546 { 1547 if ( transport instanceof UdpTransport ) 1548 { 1549 continue; 1550 } 1551 1552 if ( !transport.isSSLEnabled() ) 1553 { 1554 return transport.getPort(); 1555 } 1556 } 1557 1558 return -1; 1559 } 1560 1561 1562 /** 1563 * @return The underlying SSL enabled TCP transport port, or -1 if no transport has been 1564 * initialized 1565 */ 1566 public int getPortSSL() 1567 { 1568 if ( transports == null ) 1569 { 1570 return -1; 1571 } 1572 1573 for ( Transport transport : transports ) 1574 { 1575 if ( transport instanceof UdpTransport ) 1576 { 1577 continue; 1578 } 1579 1580 if ( transport.isSSLEnabled() ) 1581 { 1582 return transport.getPort(); 1583 } 1584 } 1585 1586 return -1; 1587 } 1588 1589 1590 @Override 1591 public boolean isStarted() 1592 { 1593 return started; 1594 } 1595 1596 1597 /** 1598 */ 1599 @Override 1600 public void setStarted( boolean started ) 1601 { 1602 this.started = started; 1603 } 1604 1605 1606 /** 1607 * @return The keystore path 1608 */ 1609 public String getKeystoreFile() 1610 { 1611 return keystoreFile; 1612 } 1613 1614 1615 /** 1616 * Set the external keystore path 1617 * @param keystoreFile The external keystore path 1618 */ 1619 public void setKeystoreFile( String keystoreFile ) 1620 { 1621 this.keystoreFile = keystoreFile; 1622 } 1623 1624 1625 /** 1626 * @return The certificate password 1627 */ 1628 public String getCertificatePassword() 1629 { 1630 return certificatePassword; 1631 } 1632 1633 1634 /** 1635 * Set the certificate password. 1636 * @param certificatePassword the certificate password 1637 */ 1638 public void setCertificatePassword( String certificatePassword ) 1639 { 1640 this.certificatePassword = certificatePassword; 1641 } 1642 1643 1644 public void setReplicationReqHandler( ReplicationRequestHandler replicationProvider ) 1645 { 1646 this.replicationReqHandler = replicationProvider; 1647 } 1648 1649 1650 public ReplicationRequestHandler getReplicationReqHandler() 1651 { 1652 return replicationReqHandler; 1653 } 1654 1655 1656 public void setReplConsumers( List<ReplicationConsumer> replConsumers ) 1657 { 1658 this.replConsumers = replConsumers; 1659 } 1660 1661 1662 /** 1663 * @return the key manager factory of the server keystore 1664 */ 1665 public KeyManagerFactory getKeyManagerFactory() 1666 { 1667 return keyManagerFactory; 1668 } 1669 1670 /** 1671 * @return the trust managers of the server 1672 */ 1673 public TrustManager[] getTrustManagers() 1674 { 1675 return trustManagers; 1676 } 1677 1678 public void setTrustManagers( TrustManager[] trustManagers ) 1679 { 1680 this.trustManagers = trustManagers; 1681 } 1682 1683 /** 1684 * @return The maximum allowed size for an incoming PDU 1685 */ 1686 public int getMaxPDUSize() 1687 { 1688 return maxPDUSize; 1689 } 1690 1691 1692 /** 1693 * Set the maximum allowed size for an incoming PDU 1694 * @param maxPDUSize A positive number of bytes for the PDU. A negative or 1695 * null value will be transformed to {@link Integer#MAX_VALUE} 1696 */ 1697 public void setMaxPDUSize( int maxPDUSize ) 1698 { 1699 if ( maxPDUSize <= 0 ) 1700 { 1701 maxPDUSize = Integer.MAX_VALUE; 1702 } 1703 1704 this.maxPDUSize = maxPDUSize; 1705 } 1706 1707 1708 /** 1709 * @return the number of seconds pinger thread sleeps between subsequent pings 1710 */ 1711 public int getReplPingerSleepTime() 1712 { 1713 return pingerSleepTime; 1714 } 1715 1716 1717 /** 1718 * The number of seconds pinger thread should sleep before pinging the providers 1719 * 1720 * @param pingerSleepTime The delay between 2 pings 1721 */ 1722 public void setReplPingerSleepTime( int pingerSleepTime ) 1723 { 1724 this.pingerSleepTime = pingerSleepTime; 1725 } 1726 1727 1728 /** 1729 * Gives the list of enabled cipher suites 1730 * <br> 1731 * This method has been deprecated, please set this list in the TcpTransport class 1732 * <br> 1733 * 1734 * @return The list of ciphers that can be used 1735 * @deprecated Set this list in the {@link TcpTransport} class 1736 */ 1737 @Deprecated 1738 public List<String> getEnabledCipherSuites() 1739 { 1740 return enabledCipherSuites; 1741 } 1742 1743 1744 /** 1745 * Sets the list of cipher suites to be used in LDAPS and StartTLS 1746 * <br> 1747 * This method has been deprecated, please set this list in the TcpTransport class 1748 * <br> 1749 * 1750 * @param enabledCipherSuites if null the default cipher suites will be used 1751 * @deprecated Get this list from the {@link TcpTransport} class 1752 */ 1753 @Deprecated 1754 public void setEnabledCipherSuites( List<String> enabledCipherSuites ) 1755 { 1756 this.enabledCipherSuites = enabledCipherSuites; 1757 } 1758 1759 1760 /** 1761 * @see Object#toString() 1762 */ 1763 @Override 1764 public String toString() 1765 { 1766 StringBuilder sb = new StringBuilder(); 1767 1768 sb.append( "LdapServer[" ).append( getServiceName() ).append( "], listening on :" ).append( '\n' ); 1769 1770 if ( getTransports() != null ) 1771 { 1772 for ( Transport transport : getTransports() ) 1773 { 1774 sb.append( " " ).append( transport ).append( '\n' ); 1775 } 1776 } 1777 1778 return sb.toString(); 1779 } 1780}