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.handlers.sasl;
021
022
023import javax.security.sasl.SaslServer;
024
025import org.apache.commons.lang3.exception.ExceptionUtils;
026import org.apache.directory.api.ldap.model.exception.LdapAuthenticationException;
027import org.apache.directory.api.ldap.model.exception.LdapException;
028import org.apache.directory.api.ldap.model.exception.LdapOperationException;
029import org.apache.directory.api.ldap.model.message.BindRequest;
030import org.apache.directory.api.ldap.model.message.BindResponse;
031import org.apache.directory.api.ldap.model.message.LdapResult;
032import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
033import org.apache.directory.api.ldap.model.name.Dn;
034import org.apache.directory.server.core.api.CoreSession;
035import org.apache.directory.server.core.api.OperationEnum;
036import org.apache.directory.server.core.api.interceptor.context.BindOperationContext;
037import org.apache.directory.server.ldap.LdapProtocolUtils;
038import org.apache.directory.server.ldap.LdapSession;
039import org.slf4j.Logger;
040import org.slf4j.LoggerFactory;
041
042
043/**
044 * A Dummy mechanism handler for Simple mechanism: not really used but needed
045 * for the mechanism map.
046 *
047 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
048 */
049public class SimpleMechanismHandler implements MechanismHandler
050{
051    /** The logger instance */
052    private static final Logger LOG = LoggerFactory.getLogger( SimpleMechanismHandler.class );
053
054
055    @Override
056    public SaslServer handleMechanism( LdapSession ldapSession, BindRequest bindRequest ) throws Exception
057    {
058        // create a new Bind context, with a null session, as we don't have
059        // any context yet.
060        BindOperationContext bindContext = new BindOperationContext( null );
061
062        // Stores the Dn of the user to check, and its password
063        bindContext.setDn( bindRequest.getDn() );
064        bindContext.setCredentials( bindRequest.getCredentials() );
065        bindContext.setInterceptors( ldapSession.getLdapServer().getDirectoryService()
066            .getInterceptors( OperationEnum.BIND ) );
067
068        // Stores the request controls into the operation context
069        LdapProtocolUtils.setRequestControls( bindContext, bindRequest );
070
071        try
072        {
073            CoreSession adminSession = ldapSession.getLdapServer().getDirectoryService().getAdminSession();
074
075            // And call the OperationManager bind operation.
076            adminSession.getDirectoryService().getOperationManager().bind( bindContext );
077
078            // As a result, store the created session in the Core Session
079            ldapSession.setCoreSession( bindContext.getSession() );
080
081            // Return the successful response
082            BindResponse response = ( BindResponse ) bindRequest.getResultResponse();
083            response.getLdapResult().setResultCode( ResultCodeEnum.SUCCESS );
084            LdapProtocolUtils.setResponseControls( bindContext, response );
085
086            // Write it back to the client
087            ldapSession.getIoSession().write( response );
088            LOG.debug( "Returned SUCCESS message: {}.", response );
089        }
090        catch ( LdapException e )
091        {
092            // Something went wrong. Write back an error message
093            ResultCodeEnum code = null;
094            LdapResult result = bindRequest.getResultResponse().getLdapResult();
095
096            if ( e instanceof LdapOperationException )
097            {
098                code = ( ( LdapOperationException ) e ).getResultCode();
099                result.setResultCode( code );
100            }
101            else
102            {
103                code = ResultCodeEnum.getBestEstimate( e, bindRequest.getType() );
104                result.setResultCode( code );
105            }
106
107            String msg = "Bind failed: " + e.getLocalizedMessage();
108
109            if ( LOG.isDebugEnabled() )
110            {
111                msg += ":\n" + ExceptionUtils.getStackTrace( e );
112                msg += "\n\nBindRequest = \n" + bindRequest.toString();
113            }
114
115            Dn name = null;
116
117            if ( e instanceof LdapAuthenticationException )
118            {
119                name = ( ( LdapAuthenticationException ) e ).getResolvedDn();
120            }
121
122            if ( ( name != null )
123                && ( ( code == ResultCodeEnum.NO_SUCH_OBJECT ) || ( code == ResultCodeEnum.ALIAS_PROBLEM )
124                    || ( code == ResultCodeEnum.INVALID_DN_SYNTAX ) || ( code == ResultCodeEnum.ALIAS_DEREFERENCING_PROBLEM ) ) )
125            {
126                result.setMatchedDn( name );
127            }
128
129            result.setDiagnosticMessage( msg );
130            ldapSession.getIoSession().write( bindRequest.getResultResponse() );
131        }
132
133        return null;
134    }
135
136
137    /**
138     * {@inheritDoc}
139     */
140    @Override
141    public void init( LdapSession ldapSession )
142    {
143        // Do nothing
144    }
145
146
147    /**
148     * {@inheritDoc}
149     */
150    @Override
151    public void cleanup( LdapSession ldapSession )
152    {
153        ldapSession.clearSaslProperties();
154    }
155}