Package org.apache.directory.server.ldap

Source Code of org.apache.directory.server.ldap.LdapServer$AdsKeyStore

/*
*  Licensed to the Apache Software Foundation (ASF) under one
*  or more contributor license agreements.  See the NOTICE file
*  distributed with this work for additional information
*  regarding copyright ownership.  The ASF licenses this file
*  to you under the Apache License, Version 2.0 (the
*  "License"); you may not use this file except in compliance
*  with the License.  You may obtain a copy of the License at
*    http://www.apache.org/licenses/LICENSE-2.0
*  Unless required by applicable law or agreed to in writing,
*  software distributed under the License is distributed on an
*  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
*  KIND, either express or implied.  See the License for the
*  specific language governing permissions and limitations
*  under the License.
*/
package org.apache.directory.server.ldap;


import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreSpi;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.directory.server.core.DirectoryService;
import org.apache.directory.server.core.partition.PartitionNexus;
import org.apache.directory.server.core.security.CoreKeyStoreSpi;
import org.apache.directory.server.i18n.I18n;
import org.apache.directory.server.ldap.handlers.AbandonHandler;
import org.apache.directory.server.ldap.handlers.AddHandler;
import org.apache.directory.server.ldap.handlers.BindHandler;
import org.apache.directory.server.ldap.handlers.CompareHandler;
import org.apache.directory.server.ldap.handlers.DeleteHandler;
import org.apache.directory.server.ldap.handlers.ExtendedHandler;
import org.apache.directory.server.ldap.handlers.LdapRequestHandler;
import org.apache.directory.server.ldap.handlers.ModifyDnHandler;
import org.apache.directory.server.ldap.handlers.ModifyHandler;
import org.apache.directory.server.ldap.handlers.SearchHandler;
import org.apache.directory.server.ldap.handlers.UnbindHandler;
import org.apache.directory.server.ldap.handlers.bind.MechanismHandler;
import org.apache.directory.server.ldap.handlers.extended.StartTlsHandler;
import org.apache.directory.server.ldap.handlers.ssl.LdapsInitializer;
import org.apache.directory.server.ldap.replication.ReplicationConsumer;
import org.apache.directory.server.ldap.replication.ReplicationRequestHandler;
import org.apache.directory.server.protocol.shared.DirectoryBackedService;
import org.apache.directory.server.protocol.shared.transport.TcpTransport;
import org.apache.directory.server.protocol.shared.transport.Transport;
import org.apache.directory.server.protocol.shared.transport.UdpTransport;
import org.apache.directory.shared.ldap.codec.api.LdapApiServiceFactory;
import org.apache.directory.shared.ldap.extras.controls.SyncDoneValue;
import org.apache.directory.shared.ldap.extras.controls.SyncInfoValue;
import org.apache.directory.shared.ldap.extras.controls.SyncRequestValue;
import org.apache.directory.shared.ldap.extras.controls.SyncStateValue;
import org.apache.directory.shared.ldap.model.constants.SaslQoP;
import org.apache.directory.shared.ldap.model.exception.LdapConfigurationException;
import org.apache.directory.shared.ldap.model.message.AbandonRequest;
import org.apache.directory.shared.ldap.model.message.AddRequest;
import org.apache.directory.shared.ldap.model.message.BindRequest;
import org.apache.directory.shared.ldap.model.message.CompareRequest;
import org.apache.directory.shared.ldap.model.message.DeleteRequest;
import org.apache.directory.shared.ldap.model.message.ExtendedRequest;
import org.apache.directory.shared.ldap.model.message.ExtendedResponse;
import org.apache.directory.shared.ldap.model.message.ModifyDnRequest;
import org.apache.directory.shared.ldap.model.message.ModifyRequest;
import org.apache.directory.shared.ldap.model.message.SearchRequest;
import org.apache.directory.shared.ldap.model.message.UnbindRequest;
import org.apache.directory.shared.ldap.model.message.controls.Cascade;
import org.apache.directory.shared.ldap.model.message.controls.EntryChange;
import org.apache.directory.shared.ldap.model.message.controls.ManageDsaIT;
import org.apache.directory.shared.ldap.model.message.controls.PagedResults;
import org.apache.directory.shared.ldap.model.message.controls.PersistentSearch;
import org.apache.directory.shared.ldap.model.message.controls.Subentries;
import org.apache.directory.shared.ldap.model.message.extended.NoticeOfDisconnect;
import org.apache.directory.shared.util.Strings;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.filterchain.IoFilterChainBuilder;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IoEventType;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.executor.UnorderedThreadPoolExecutor;
import org.apache.mina.handler.demux.MessageHandler;
import org.apache.mina.transport.socket.AbstractSocketSessionConfig;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
* An LDAP protocol provider implementation which dynamically associates
* handlers.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class LdapServer extends DirectoryBackedService
{
    private static final long serialVersionUID = 3757127143811666817L;

    /** logger for this class */
    private static final Logger LOG = LoggerFactory.getLogger( LdapServer.class.getName() );

    /** Value (0) for configuration where size limit is unlimited. */
    public static final long NO_SIZE_LIMIT = 0;

    /** Value (0) for configuration where time limit is unlimited. */
    public static final int NO_TIME_LIMIT = 0;

    /** the constant service name of this ldap protocol provider **/
    public static final String SERVICE_NAME = "ldap";

    /** The default maximum size limit. */
    private static final long MAX_SIZE_LIMIT_DEFAULT = 100;

    /** The default maximum time limit. */
    private static final int MAX_TIME_LIMIT_DEFAULT = 10000;

    /** The default service pid. */
    private static final String SERVICE_PID_DEFAULT = "org.apache.directory.server.ldap";

    /** The default service name. */
    private static final String SERVICE_NAME_DEFAULT = "ApacheDS LDAP Service";

    /** the session manager for this LdapServer */
    private LdapSessionManager ldapSessionManager = new LdapSessionManager();

    /** a set of supported controls */
    private Set<String> supportedControls;

    /**
     * The maximum size limit.
     * @see {@link LdapServer#MAX_SIZE_LIMIT_DEFAULT }
     */
    private long maxSizeLimit = MAX_SIZE_LIMIT_DEFAULT;

    /**
     * The maximum time limit.
     * @see {@link LdapServer#MAX_TIME_LIMIT_DEFAULT }
     */
    private int maxTimeLimit = MAX_TIME_LIMIT_DEFAULT;

    /** If LDAPS is activated : the external Keystore file, if defined */
    private String keystoreFile;

    /** If LDAPS is activated : the certificate password */
    private String certificatePassword;

    /** The extended operation handlers. */
    private final Collection<ExtendedOperationHandler> extendedOperationHandlers = new ArrayList<ExtendedOperationHandler>();

    /** The supported authentication mechanisms. */
    private Map<String, MechanismHandler> saslMechanismHandlers = new HashMap<String, MechanismHandler>();

    /** The name of this host, validated during SASL negotiation. */
    private String saslHost = "ldap.example.com";

    /** The service principal, used by GSSAPI. */
    private String saslPrincipal = "ldap/ldap.example.com@EXAMPLE.COM";

    /** The quality of protection (QoP), used by DIGEST-MD5 and GSSAPI. */
    private Set<String> saslQop;
    private String saslQopString;

    /** The list of realms serviced by this host. */
    private List<String> saslRealms;

    /** The protocol handlers */
    private LdapRequestHandler<AbandonRequest> abandonHandler;
    private LdapRequestHandler<AddRequest> addHandler;
    private LdapRequestHandler<BindRequest> bindHandler;
    private LdapRequestHandler<CompareRequest> compareHandler;
    private LdapRequestHandler<DeleteRequest> deleteHandler;
    private ExtendedHandler extendedHandler;
    private LdapRequestHandler<ModifyRequest> modifyHandler;
    private LdapRequestHandler<ModifyDnRequest> modifyDnHandler;
    private LdapRequestHandler<SearchRequest> searchHandler;
    private LdapRequestHandler<UnbindRequest> unbindHandler;

    /** the underlying provider codec factory */
    private ProtocolCodecFactory codecFactory = LdapApiServiceFactory.getSingleton().getProtocolCodecFactory();

    /** the MINA protocol handler */
    private final LdapProtocolHandler handler = new LdapProtocolHandler( this );

    /** tracks start state of the server */
    private boolean started;

    /**
     * Whether or not confidentiality (TLS secured connection) is required:
     * disabled by default.
     */
    private boolean confidentialityRequired;

    private KeyStore keyStore = null;

    private List<IoFilterChainBuilder> chainBuilders = new ArrayList<IoFilterChainBuilder>();

    private ReplicationRequestHandler replicationReqHandler;

    private List<ReplicationConsumer> replConsumers;


    /**
     * Creates an LDAP protocol provider.
     */
    public LdapServer()
    {
        super.setEnabled( true );
        super.setServiceId( SERVICE_PID_DEFAULT );
        super.setServiceName( SERVICE_NAME_DEFAULT );

        saslQop = new HashSet<String>();
        saslQop.add( SaslQoP.AUTH.getValue() );
        saslQop.add( SaslQoP.AUTH_INT.getValue() );
        saslQop.add( SaslQoP.AUTH_CONF.getValue() );
        saslQopString = SaslQoP.AUTH.getValue() + ',' + SaslQoP.AUTH_INT.getValue() + ',' + SaslQoP.AUTH_CONF.getValue();

        saslRealms = new ArrayList<String>();
        saslRealms.add( "example.com" );

        this.supportedControls = new HashSet<String>();
        this.supportedControls.add( PersistentSearch.OID );
        this.supportedControls.add( EntryChange.OID );
        this.supportedControls.add( Subentries.OID );
        this.supportedControls.add( ManageDsaIT.OID );
        this.supportedControls.add( Cascade.OID );
        this.supportedControls.add( PagedResults.OID );
        // Replication controls
        this.supportedControls.add( SyncDoneValue.OID );
        this.supportedControls.add( SyncInfoValue.OID );
        this.supportedControls.add( SyncRequestValue.OID );
        this.supportedControls.add( SyncStateValue.OID );
    }


    /**
     * Install the LDAP request handlers.
     */
    private void installDefaultHandlers()
    {
        if ( getAbandonHandler() == null )
        {
            setAbandonHandler( new AbandonHandler() );
        }

        if ( getAddHandler() == null )
        {
            setAddHandler( new AddHandler() );
        }

        if ( getBindHandler() == null )
        {
            BindHandler handler = new BindHandler();
            handler.setSaslMechanismHandlers( saslMechanismHandlers );
            setBindHandler( handler );
        }

        if ( getCompareHandler() == null )
        {
            setCompareHandler( new CompareHandler() );
        }

        if ( getDeleteHandler() == null )
        {
            setDeleteHandler( new DeleteHandler() );
        }

        if ( getExtendedHandler() == null )
        {
            setExtendedHandler( new ExtendedHandler() );
        }

        if ( getModifyHandler() == null )
        {
            setModifyHandler( new ModifyHandler() );
        }

        if ( getModifyDnHandler() == null )
        {
            setModifyDnHandler( new ModifyDnHandler() );
        }

        if ( getSearchHandler() == null )
        {
            setSearchHandler( new SearchHandler() );
        }

        if ( getUnbindHandler() == null )
        {
            setUnbindHandler( new UnbindHandler() );
        }
    }

    private class AdsKeyStore extends KeyStore
    {
        public AdsKeyStore( KeyStoreSpi keyStoreSpi, Provider provider, String type )
        {
            super( keyStoreSpi, provider, type );
        }
    }


    /**
     * loads the digital certificate either from a keystore file or from the admin entry in DIT
     */
    // This will suppress PMD.EmptyCatchBlock warnings in this method
    @SuppressWarnings("PMD.EmptyCatchBlock")
    private void loadKeyStore() throws Exception
    {
        if ( Strings.isEmpty(keystoreFile) )
        {
            Provider provider = Security.getProvider( "SUN" );
            LOG.debug( "provider = {}", provider );
            CoreKeyStoreSpi coreKeyStoreSpi = new CoreKeyStoreSpi( getDirectoryService() );
            keyStore = new KeyStore( coreKeyStoreSpi, provider, "JKS" )
            {
            };

            try
            {
                keyStore.load( null, null );
            }
            catch ( Exception e )
            {
                // nothing really happens with this keystore
            }
        }
        else
        {
            keyStore = KeyStore.getInstance( KeyStore.getDefaultType() );
            FileInputStream fis = null;
            try
            {
                fis = new FileInputStream( keystoreFile );
                keyStore.load( fis, null );
            }
            finally
            {
                if ( fis != null )
                {
                    fis.close();
                }
            }
        }
    }


    /**
     * reloads the SSL context by replacing the existing SslFilter
     * with a new SslFilter after reloading the keystore.
     *
     * Note: should be called to reload the keystore after changing the digital certificate.
     */
    public void reloadSslContext() throws Exception
    {
        if ( !started )
        {
            return;
        }

        LOG.info( "reloading SSL context..." );

        loadKeyStore();

        String sslFilterName = "sslFilter";
        for ( IoFilterChainBuilder chainBuilder : chainBuilders )
        {
            DefaultIoFilterChainBuilder dfcb = ( ( DefaultIoFilterChainBuilder ) chainBuilder );
            if ( dfcb.contains( sslFilterName ) )
            {
                DefaultIoFilterChainBuilder newChain = ( DefaultIoFilterChainBuilder ) LdapsInitializer.init( keyStore,
                    certificatePassword );
                dfcb.replace( sslFilterName, newChain.get( sslFilterName ) );
                newChain = null;
            }
        }

        StartTlsHandler handler = ( StartTlsHandler ) getExtendedOperationHandler( StartTlsHandler.EXTENSION_OID );
        if ( handler != null )
        {
            //FIXME dirty hack. IMO StartTlsHandler's code requires a cleanup
            // cause the keystore loading and sslcontext creation code is duplicated
            // both in the LdapService as well as StatTlsHandler
            handler.setLdapServer( this );
        }

        LOG.info( "reloaded SSL context successfully" );
    }


    /**
     * @throws IOException if we cannot bind to the specified port
     * @throws Exception if the LDAP server cannot be started
     */
    public void start() throws Exception
    {
        if ( !isEnabled() )
        {
            return;
        }

        for ( Transport transport : transports )
        {
            if ( !( transport instanceof TcpTransport ) )
            {
                LOG.warn( "Cannot listen on an UDP transport : {}", transport );
                continue;
            }

            IoFilterChainBuilder chain;

            if ( transport.isSSLEnabled() )
            {
                loadKeyStore();
                chain = LdapsInitializer.init( keyStore, certificatePassword );
            }
            else
            {
                chain = new DefaultIoFilterChainBuilder();
            }

            // Inject the codec into the chain
            ( ( DefaultIoFilterChainBuilder ) chain ).addLast( "codec", new ProtocolCodecFilter( this
                .getProtocolCodecFactory() ) );

            // Now inject an ExecutorFilter for the write operations
            // We use the same number of thread than the number of IoProcessor
            // (NOTE : this has to be double checked)
            ( ( DefaultIoFilterChainBuilder ) chain ).addLast( "executor", new ExecutorFilter(
                new UnorderedThreadPoolExecutor( transport.getNbThreads() ), IoEventType.MESSAGE_RECEIVED ) );

            /*
            // Trace all the incoming and outgoing message to the console
            ( ( DefaultIoFilterChainBuilder ) chain ).addLast( "logger", new IoFilterAdapter()
                {
                    public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception
                    {
                        System.out.println( ">>> Message received : " + message );
                        nextFilter.messageReceived(session, message);
                    }

                    public void filterWrite(NextFilter nextFilter, IoSession session,
                            WriteRequest writeRequest) throws Exception
                    {
                        System.out.println( "<<< Message sent : " + writeRequest.getMessage() );
                        nextFilter.filterWrite(session, writeRequest);
                    }
                });
            */

            startNetwork( transport, chain );
        }
       
        /*
         * The server is now initialized, we can
         * install the default requests handlers, which need
         * access to the DirectoryServer instance.
         */
        installDefaultHandlers();

        PartitionNexus nexus = getDirectoryService().getPartitionNexus();

        for ( ExtendedOperationHandler h : extendedOperationHandlers )
        {
            LOG.info( "Added Extended Request Handler: " + h.getOid() );
            h.setLdapServer( this );
            nexus.registerSupportedExtensions( h.getExtensionOids() );
        }

        nexus.registerSupportedSaslMechanisms( saslMechanismHandlers.keySet() );

        // Install the replication handler if we have one
        startReplicationProducer();

        // And start the replication consumers on this server
        startReplicationConsumers();

        started = true;

        LOG.info( "Ldap service started." );
    }
   

    /**
     * Install the replication handler if we have one
     */
    public void startReplicationProducer()
    {
        if ( replicationReqHandler != null )
        {
            replicationReqHandler.start( this );
            ( ( SearchHandler ) getSearchHandler() ).setReplicationReqHandler( replicationReqHandler );
        }
    }


    /**
     * {@inheritDoc}
     */
    public void stop()
    {
        try
        {
            for ( Transport transport : transports )
            {
                if ( !( transport instanceof TcpTransport ) )
                {
                    continue;
                }

                // we should unbind the service before we begin sending the notice
                // of disconnect so new connections are not formed while we process
                List<WriteFuture> writeFutures = new ArrayList<WriteFuture>();

                // If the socket has already been unbound as with a successful
                // GracefulShutdownRequest then this will complain that the service
                // is not bound - this is ok because the GracefulShutdown has already
                // sent notices to to the existing active sessions
                List<IoSession> sessions;

                try
                {
                    sessions = new ArrayList<IoSession>( getSocketAcceptor( transport ).getManagedSessions().values() );
                }
                catch ( IllegalArgumentException e )
                {
                    LOG.warn( "Seems like the LDAP service (" + getPort() + ") has already been unbound." );
                    return;
                }

                getSocketAcceptor( transport ).dispose();

                if ( LOG.isInfoEnabled() )
                {
                    LOG.info( "Unbind of an LDAP service (" + getPort() + ") is complete." );
                    LOG.info( "Sending notice of disconnect to existing clients sessions." );
                }

                // Send Notification of Disconnection messages to all connected clients.
                if ( sessions != null )
                {
                    for ( IoSession session : sessions )
                    {
                        writeFutures.add( session.write( NoticeOfDisconnect.UNAVAILABLE ) );
                    }
                }

                // And close the connections when the NoDs are sent.
                Iterator<IoSession> sessionIt = sessions.iterator();

                for ( WriteFuture future : writeFutures )
                {
                    future.await( 1000L );
                    sessionIt.next().close( true );
                }

                if ( replicationReqHandler != null )
                {
                    replicationReqHandler.stop();
                }
            }

            stopConsumers();
        }
        catch ( Exception e )
        {
            LOG.warn( "Failed to sent NoD.", e );
        }

        started = false;
        LOG.info( "Ldap service stopped." );
    }


    private void startNetwork( Transport transport, IoFilterChainBuilder chainBuilder ) throws Exception
    {
        if ( transport.getBackLog() < 0 )
        {
            // Set the backlog to the default value when it's below 0
            transport.setBackLog( 50 );
        }

        chainBuilders.add( chainBuilder );

        try
        {
            SocketAcceptor acceptor = getSocketAcceptor( transport );

            // Now, configure the acceptor
            // Disable the disconnection of the clients on unbind
            acceptor.setCloseOnDeactivation( false );

            // No Nagle's algorithm
            acceptor.getSessionConfig().setTcpNoDelay( true );

            // Inject the chain
            acceptor.setFilterChainBuilder( chainBuilder );

            // Inject the protocol handler
            acceptor.setHandler( getHandler() );

            ( ( AbstractSocketSessionConfig ) acceptor.getSessionConfig() ).setReadBufferSize( 64 * 1024 );
            ( ( AbstractSocketSessionConfig ) acceptor.getSessionConfig() ).setSendBufferSize( 64 * 1024 );

            // Bind to the configured address
            acceptor.bind();

            // We are done !
            started = true;

            if ( LOG.isInfoEnabled() )
            {
                LOG.info( "Successful bind of an LDAP Service (" + transport.getPort() + ") is completed." );
            }
        }
        catch ( IOException e )
        {
            String msg = I18n.err( I18n.ERR_171, transport.getPort() );
            LdapConfigurationException lce = new LdapConfigurationException( msg );
            lce.setCause( e );
            LOG.error( msg, e );
            throw lce;
        }
    }


    /**
     * starts the replication consumers
     */
    public void startReplicationConsumers() throws Exception
    {
        if ( replConsumers != null )
        {
            for ( final ReplicationConsumer consumer : replConsumers )
            {
                Runnable consumerTask = new Runnable()
                {
                    public void run()
                    {
                        try
                        {
                            LOG.info( "starting the replication consumer with config {}", consumer );
                            consumer.init( getDirectoryService() );
                            consumer.start();
                        }
                        catch ( Exception e )
                        {
                            LOG.error( "Failed to start the consumer with config {}", consumer );
                            throw new RuntimeException( e );
                        }
                    }
                };

                Thread consumerThread = new Thread( consumerTask );
                consumerThread.setDaemon( true );
                consumerThread.start();
            }
        }
    }


    /**
     * stops the replication consumers
     */
    private void stopConsumers()
    {
        if ( replConsumers != null )
        {
            for ( ReplicationConsumer consumer : replConsumers )
            {
                LOG.info( "stopping the consumer with id {}", consumer.getId() );
                consumer.stop();
            }
        }
    }


    public String getName()
    {
        return SERVICE_NAME;
    }


    public IoHandler getHandler()
    {
        return handler;
    }


    public LdapSessionManager getLdapSessionManager()
    {
        return ldapSessionManager;
    }


    public ProtocolCodecFactory getProtocolCodecFactory()
    {
        return codecFactory;
    }


    // ------------------------------------------------------------------------
    // Configuration Methods
    // ------------------------------------------------------------------------

    /**
     * Registers the specified {@link ExtendedOperationHandler} to this
     * protocol provider to provide a specific LDAP extended operation.
     *
     * @param eoh an extended operation handler
     * @throws Exception on failure to add the handler
     */
    public void addExtendedOperationHandler( ExtendedOperationHandler eoh ) throws Exception
    {
        if ( started )
        {
            eoh.setLdapServer( this );
            PartitionNexus nexus = getDirectoryService().getPartitionNexus();
            nexus.registerSupportedExtensions( eoh.getExtensionOids() );
        }
        else
        {
            extendedOperationHandlers.add( eoh );
        }
    }


    /**
     * Deregisteres an {@link ExtendedOperationHandler} with the specified <tt>oid</tt>
     * from this protocol provider.
     *
     * @param oid the numeric identifier for the extended operation associated with
     * the handler to remove
     */
    public void removeExtendedOperationHandler( String oid )
    {
        // need to do something like this to make this work right
        //            DefaultPartitionNexus nexus = getDirectoryService().getPartitionNexus();
        //            nexus.unregisterSupportedExtensions( eoh.getExtensionOids() );

        ExtendedOperationHandler handler = null;
        for ( ExtendedOperationHandler h : extendedOperationHandlers )
        {
            if ( h.getOid().equals( oid ) )
            {
                handler = h;
                break;
            }
        }
        extendedOperationHandlers.remove( handler );
    }


    /**
     * Returns an {@link ExtendedOperationHandler} with the specified <tt>oid</tt>
     * which is registered to this protocol provider.
     *
     * @param oid the oid of the extended request of associated with the extended
     * request handler
     * @return the exnteded operation handler
     */
    public ExtendedOperationHandler<ExtendedRequest<ExtendedResponse>,ExtendedResponse>
        getExtendedOperationHandler( String oid )
    {
        for ( ExtendedOperationHandler<ExtendedRequest<ExtendedResponse>, ExtendedResponse> h : extendedOperationHandlers )
        {
            if ( h.getOid().equals( oid ) )
            {
                return h;
            }
        }

        return null;
    }


    /**
     * Sets the mode for this LdapServer to accept requests with or without a
     * TLS secured connection via either StartTLS extended operations or using
     * LDAPS.
     *
     * @param confidentialityRequired true to require confidentiality
     */
    public void setConfidentialityRequired( boolean confidentialityRequired )
    {
        this.confidentialityRequired = confidentialityRequired;
    }


    /**
     * Gets whether or not TLS secured connections are required to perform
     * operations on this LdapServer.
     *
     * @return true if TLS secured connections are required, false otherwise
     */
    public boolean isConfidentialityRequired()
    {
        return confidentialityRequired;
    }


    /**
     * Returns <tt>true</tt> if LDAPS is enabled.
     *
     * @return True if LDAPS is enabled.
     */
    public boolean isEnableLdaps( Transport transport )
    {
        return transport.isSSLEnabled();
    }


    /**
     * Sets the maximum size limit in number of entries to return for search.
     *
     * @param maxSizeLimit the maximum number of entries to return for search
     */
    public void setMaxSizeLimit( long maxSizeLimit )
    {
        this.maxSizeLimit = maxSizeLimit;
    }


    /**
     * Returns the maximum size limit in number of entries to return for search.
     *
     * @return The maximum size limit.
     */
    public long getMaxSizeLimit()
    {
        return maxSizeLimit;
    }


    /**
     * Sets the maximum time limit in milliseconds to conduct a search.
     *
     * @param maxTimeLimit the maximum length of time in milliseconds for search
     */
    public void setMaxTimeLimit( int maxTimeLimit )
    {
        this.maxTimeLimit = maxTimeLimit;
    }


    /**
     * Returns the maximum time limit in milliseconds to conduct a search.
     *
     * @return The maximum time limit in milliseconds for search
     */
    public int getMaxTimeLimit()
    {
        return maxTimeLimit;
    }


    /**
     * Gets the {@link ExtendedOperationHandler}s.
     *
     * @return A collection of {@link ExtendedOperationHandler}s.
     */
    public Collection<ExtendedOperationHandler> getExtendedOperationHandlers()
    {
        return new ArrayList<ExtendedOperationHandler>( extendedOperationHandlers );
    }


    /**
     * Sets the {@link ExtendedOperationHandler}s.
     *
     * @param handlers A collection of {@link ExtendedOperationHandler}s.
     */
    public void setExtendedOperationHandlers( Collection<ExtendedOperationHandler> handlers )
    {
        this.extendedOperationHandlers.clear();
        this.extendedOperationHandlers.addAll( handlers );
    }


    /**
     * Returns the FQDN of this SASL host, validated during SASL negotiation.
     *
     * @return The FQDN of this SASL host, validated during SASL negotiation.
     */
    public String getSaslHost()
    {
        return saslHost;
    }


    /**
     * Sets the FQDN of this SASL host, validated during SASL negotiation.
     *
     * @param saslHost The FQDN of this SASL host, validated during SASL negotiation.
     */
    public void setSaslHost( String saslHost )
    {
        this.saslHost = saslHost;
    }


    /**
     * Returns the Kerberos principal name for this LDAP service, used by GSSAPI.
     *
     * @return The Kerberos principal name for this LDAP service, used by GSSAPI.
     */
    public String getSaslPrincipal()
    {
        return saslPrincipal;
    }


    /**
     * Sets the Kerberos principal name for this LDAP service, used by GSSAPI.
     *
     * @param saslPrincipal The Kerberos principal name for this LDAP service, used by GSSAPI.
     */
    public void setSaslPrincipal( String saslPrincipal )
    {
        this.saslPrincipal = saslPrincipal;
    }


    /**
     * Returns the quality-of-protection, used by DIGEST-MD5 and GSSAPI.
     *
     * @return The quality-of-protection, used by DIGEST-MD5 and GSSAPI.
     */
    public String getSaslQopString()
    {
        return saslQopString;
    }


    /**
     * Returns the Set of quality-of-protection, used by DIGEST-MD5 and GSSAPI.
     *
     * @return The quality-of-protection, used by DIGEST-MD5 and GSSAPI.
     */
    public Set<String> getSaslQop()
    {
        return saslQop;
    }


    /**
     * Returns the realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI.
     *
     * @return The realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI.
     */
    public List<String> getSaslRealms()
    {
        return saslRealms;
    }


    /**
     * Sets the realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI.
     *
    * @param saslRealms The realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI.
     */
    public void setSaslRealms( List<String> saslRealms )
    {
        this.saslRealms = saslRealms;
    }


    /**
     */
    public Map<String, MechanismHandler> getSaslMechanismHandlers()
    {
        return saslMechanismHandlers;
    }


    public void setSaslMechanismHandlers( Map<String, MechanismHandler> saslMechanismHandlers )
    {
        this.saslMechanismHandlers = saslMechanismHandlers;
    }


    public MechanismHandler addSaslMechanismHandler( String mechanism, MechanismHandler handler )
    {
        return this.saslMechanismHandlers.put( mechanism, handler );
    }


    public MechanismHandler removeSaslMechanismHandler( String mechanism )
    {
        return this.saslMechanismHandlers.remove( mechanism );
    }


    public MechanismHandler getMechanismHandler( String mechanism )
    {
        return this.saslMechanismHandlers.get( mechanism );
    }


    public Set<String> getSupportedMechanisms()
    {
        return saslMechanismHandlers.keySet();
    }


    public void setDirectoryService( DirectoryService directoryService )
    {
        super.setDirectoryService( directoryService );
    }


    public Set<String> getSupportedControls()
    {
        return supportedControls;
    }


    /**
     */
    public void setSupportedControls( Set<String> supportedControls )
    {
        this.supportedControls = supportedControls;
    }


    public MessageHandler<AbandonRequest> getAbandonHandler()
    {
        return abandonHandler;
    }


    /**
     * @param abandonHandler The AbandonRequest handler
     */
    public void setAbandonHandler( LdapRequestHandler<AbandonRequest> abandonHandler )
    {
        this.handler.removeReceivedMessageHandler( AbandonRequest.class );
        this.abandonHandler = abandonHandler;
        this.abandonHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( AbandonRequest.class, this.abandonHandler );
    }


    public LdapRequestHandler<AddRequest> getAddHandler()
    {
        return addHandler;
    }


    /**
     * @param addHandler The AddRequest handler
     */
    public void setAddHandler( LdapRequestHandler<AddRequest> addHandler )
    {
        this.handler.removeReceivedMessageHandler( AddRequest.class );
        this.addHandler = addHandler;
        this.addHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( AddRequest.class, this.addHandler );
    }


    public LdapRequestHandler<BindRequest> getBindHandler()
    {
        return bindHandler;
    }


    /**
     * @param bindHandler The BindRequest handler
     */
    public void setBindHandler( LdapRequestHandler<BindRequest> bindHandler )
    {
        this.bindHandler = bindHandler;
        this.bindHandler.setLdapServer( this );

        handler.removeReceivedMessageHandler( BindRequest.class );
        handler.addReceivedMessageHandler( BindRequest.class, this.bindHandler );
    }


    public LdapRequestHandler<CompareRequest> getCompareHandler()
    {
        return compareHandler;
    }


    /**
     * @param compareHandler The CompareRequest handler
     */
    public void setCompareHandler( LdapRequestHandler<CompareRequest> compareHandler )
    {
        this.handler.removeReceivedMessageHandler( CompareRequest.class );
        this.compareHandler = compareHandler;
        this.compareHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( CompareRequest.class, this.compareHandler );
    }


    public LdapRequestHandler<DeleteRequest> getDeleteHandler()
    {
        return deleteHandler;
    }


    /**
     * @param deleteHandler The DeleteRequest handler
     */
    public void setDeleteHandler( LdapRequestHandler<DeleteRequest> deleteHandler )
    {
        this.handler.removeReceivedMessageHandler( DeleteRequest.class );
        this.deleteHandler = deleteHandler;
        this.deleteHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( DeleteRequest.class, this.deleteHandler );
    }


    public LdapRequestHandler<ExtendedRequest<ExtendedResponse>> getExtendedHandler()
    {
        return extendedHandler;
    }


    /**
     * @param extendedHandler The ExtendedRequest handler
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void setExtendedHandler( ExtendedHandler extendedHandler )
    {
        this.handler.removeReceivedMessageHandler( ExtendedRequest.class );
        this.extendedHandler = extendedHandler;
        this.extendedHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( ExtendedRequest.class, ( LdapRequestHandler ) this.extendedHandler );
    }


    public LdapRequestHandler<ModifyRequest> getModifyHandler()
    {
        return modifyHandler;
    }


    /**
     * @param modifyHandler The ModifyRequest handler
     */
    public void setModifyHandler( LdapRequestHandler<ModifyRequest> modifyHandler )
    {
        this.handler.removeReceivedMessageHandler( ModifyRequest.class );
        this.modifyHandler = modifyHandler;
        this.modifyHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( ModifyRequest.class, this.modifyHandler );
    }


    public LdapRequestHandler<ModifyDnRequest> getModifyDnHandler()
    {
        return modifyDnHandler;
    }


    /**
     * @param modifyDnHandler The ModifyDNRequest handler
     */
    public void setModifyDnHandler( LdapRequestHandler<ModifyDnRequest> modifyDnHandler )
    {
        this.handler.removeReceivedMessageHandler( ModifyDnRequest.class );
        this.modifyDnHandler = modifyDnHandler;
        this.modifyDnHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( ModifyDnRequest.class, this.modifyDnHandler );
    }


    public LdapRequestHandler<SearchRequest> getSearchHandler()
    {
        return searchHandler;
    }


    /**
     * @param searchHandler The SearchRequest handler
     */
    public void setSearchHandler( LdapRequestHandler<SearchRequest> searchHandler )
    {
        this.handler.removeReceivedMessageHandler( SearchRequest.class );
        this.searchHandler = searchHandler;
        this.searchHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( SearchRequest.class, this.searchHandler );
    }


    public LdapRequestHandler<UnbindRequest> getUnbindHandler()
    {
        return unbindHandler;
    }


    /**
     * @return The underlying TCP transport port, or -1 if no transport has been
     * initialized
     */
    public int getPort()
    {
        if ( transports == null )
        {
            return -1;
        }

        for ( Transport transport : transports )
        {
            if ( transport instanceof UdpTransport )
            {
                continue;
            }

            if ( !transport.isSSLEnabled() )
            {
                return transport.getPort();
            }
        }

        return -1;
    }


    /**
     * @return The underlying SSL enabled TCP transport port, or -1 if no transport has been
     * initialized
     */
    public int getPortSSL()
    {
        if ( transports == null )
        {
            return -1;
        }

        for ( Transport transport : transports )
        {
            if ( transport instanceof UdpTransport )
            {
                continue;
            }

            if ( transport.isSSLEnabled() )
            {
                return transport.getPort();
            }
        }

        return -1;
    }


    /**
     * @param unbindHandler The UnbindRequest handler
     */
    public void setUnbindHandler( LdapRequestHandler<UnbindRequest> unbindHandler )
    {
        this.handler.removeReceivedMessageHandler( UnbindRequest.class );
        this.unbindHandler = unbindHandler;
        this.unbindHandler.setLdapServer( this );
        this.handler.addReceivedMessageHandler( UnbindRequest.class, this.unbindHandler );
    }


    public boolean isStarted()
    {
        return started;
    }


    /**
     */
    public void setStarted( boolean started )
    {
        this.started = started;
    }


    /**
     * @return The keystore path
     */
    public String getKeystoreFile()
    {
        return keystoreFile;
    }


    /**
     * Set the external keystore path
     * @param keystoreFile The external keystore path
     */
    public void setKeystoreFile( String keystoreFile )
    {
        this.keystoreFile = keystoreFile;
    }


    /**
     * @return The certificate passord
     */
    public String getCertificatePassword()
    {
        return certificatePassword;
    }


    /**
     * Set the certificate passord.
     * @param certificatePassword the certificate passord
     */
    public void setCertificatePassword( String certificatePassword )
    {
        this.certificatePassword = certificatePassword;
    }


    public void setReplicationReqHandler( ReplicationRequestHandler replicationProvider )
    {
        this.replicationReqHandler = replicationProvider;
    }


    public void setReplConsumers( List<ReplicationConsumer> replConsumers )
    {
        this.replConsumers = replConsumers;
    }


    /**
     * @see Object#toString()
     */
    public String toString()
    {
        StringBuilder sb = new StringBuilder();

        sb.append( "LdapServer[" ).append( getServiceName() ).append( "], listening on :" ).append( '\n' );

        if ( getTransports() != null )
        {
            for ( Transport transport : getTransports() )
            {
                sb.append( "    " ).append( transport ).append( '\n' );
            }
        }

        return sb.toString();
    }
}
TOP

Related Classes of org.apache.directory.server.ldap.LdapServer$AdsKeyStore

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.