public void handleSimpleAuth()

in protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/request/BindRequestHandler.java [91:293]


    public void handleSimpleAuth( LdapSession ldapSession, BindRequest bindRequest ) throws Exception
    {
        DirectoryService directoryService = ldapServer.getDirectoryService();
        BindResponse bindResponse = ( BindResponse ) bindRequest.getResultResponse();

        // if the user is already bound, we have to unbind him
        if ( ldapSession.isAuthenticated() )
        {
            // We already have a bound session for this user. We have to
            // abandon it first.
            ldapSession.getCoreSession().unbind();
        }

        // Set the status to SimpleAuthPending
        ldapSession.setSimpleAuthPending();

        // Now, bind the user

        // create a new Bind context, with a null session, as we don't have
        // any context yet.
        BindOperationContext bindContext = new BindOperationContext( null );

        // Stores the Dn of the user to check, and its password
        Dn bindDn = bindRequest.getDn();

        if ( bindDn == null )
        {
            String name = bindRequest.getName();

            try
            {
                bindDn = new Dn( directoryService.getSchemaManager(), name );
                bindRequest.setDn( bindDn );
            }
            catch ( LdapInvalidDnException e )
            {
                // This might still be a valid DN (Windows AD binding for instance)
                LOG.debug( "Unable to convert the name to a DN." );
            }
        }

        bindContext.setDn( bindRequest.getDn() );
        bindContext.setCredentials( bindRequest.getCredentials() );
        bindContext.setIoSession( ldapSession.getIoSession() );
        bindContext.setInterceptors( directoryService.getInterceptors( OperationEnum.BIND ) );

        // Stores the request controls into the operation context
        LdapProtocolUtils.setRequestControls( bindContext, bindRequest );

        try
        {
            /*
             * Referral handling as specified by RFC 3296 here:
             *
             *      http://www.faqs.org/rfcs/rfc3296.html
             *
             * See section 5.6.1 where if the bind principal Dn is a referral
             * we return an invalidCredentials result response.  Optionally we
             * could support delegated authentication in the future with this
             * potential.  See the following JIRA for more on this possibility:
             *
             *      https://issues.apache.org/jira/browse/DIRSERVER-1217
             *
             * NOTE: if this is done then this handler should extend the
             * a modified form of the ReferralAwareRequestHandler so it can
             * detect conditions where ancestors of the Dn are referrals
             * and delegate appropriately.
             */
            Entry principalEntry = null;

            try
            {
                principalEntry = directoryService.getAdminSession().lookup( bindRequest.getDn(), 
                    SchemaConstants.ALL_USER_ATTRIBUTES, SchemaConstants.ALL_OPERATIONAL_ATTRIBUTES );
            }
            catch ( Exception le )
            {
                // this is OK, it may be a delegated authentication, and in this case
                // the entry is not present locally
            }

            if ( principalEntry == null )
            {
                LOG.info( "The {} principalDN cannot be found in the server : bind failure.", bindRequest.getName() );
            }
            else if ( ( ( ClonedServerEntry ) principalEntry ).getOriginalEntry().contains(
                SchemaConstants.OBJECT_CLASS_AT,
                SchemaConstants.REFERRAL_OC ) )
            {
                LOG.info( "Bind principalDn points to referral." );
                LdapResult result = bindResponse.getLdapResult();
                result.setDiagnosticMessage( "Bind principalDn points to referral." );
                result.setResultCode( ResultCodeEnum.INVALID_CREDENTIALS );

                // Reset the session now
                ldapSession.setAnonymous();

                // Write the response
                ldapSession.getIoSession().write( bindResponse );

                return;
            }
            else
            { 
                bindContext.setPrincipal( principalEntry );
            }

            // TODO - might cause issues since lookups are not returning all
            // attributes right now - this is an optimization that can be
            // enabled later after determining whether or not this will cause
            // issues.
            // reuse the looked up entry so we don't incur another lookup
            // opContext.setEntry( principalEntry );

            // And call the OperationManager bind operation.
            bindContext.setInterceptors( directoryService.getInterceptors( OperationEnum.BIND ) );
            directoryService.getOperationManager().bind( bindContext );

            // As a result, store the created session in the Core Session
            CoreSession coreSession = bindContext.getSession();
            ldapSession.setCoreSession( coreSession );

            // Store the IoSession in the coreSession
            ( ( DefaultCoreSession ) coreSession ).setIoSession( bindContext.getIoSession() );

            // And set the current state accordingly
            if ( !ldapSession.getCoreSession().isAnonymous() )
            {
                ldapSession.setAuthenticated();
            }
            else
            {
                ldapSession.setAnonymous();
            }

            // Return the successful response
            bindResponse.addAllControls( bindContext.getResponseControls() );
            sendBindSuccess( ldapSession, bindResponse, null );
        }
        catch ( Exception e )
        {
            // Something went wrong. Write back an error message
            // For BindRequest, it should be an InvalidCredentials,
            // no matter what kind of exception we got.
            ResultCodeEnum code = null;
            LdapResult result = bindResponse.getLdapResult();

            if ( e instanceof LdapUnwillingToPerformException )
            {
                code = ResultCodeEnum.UNWILLING_TO_PERFORM;
                result.setResultCode( code );
            }
            else if ( e instanceof LdapInvalidDnException )
            {
                code = ResultCodeEnum.INVALID_DN_SYNTAX;
                result.setResultCode( code );
            }
            else
            {
                code = ResultCodeEnum.INVALID_CREDENTIALS;
                result.setResultCode( code );
            }

            String msg = code.toString() + ": Bind failed: " + e.getLocalizedMessage();

            if ( LOG.isDebugEnabled() )
            {
                msg += ":\n" + ExceptionUtils.getStackTrace( e );
                msg += "\n\nBindRequest = \n" + bindRequest.toString();
            }

            Dn dn = null;

            if ( e instanceof LdapAuthenticationException )
            {
                dn = ( ( LdapAuthenticationException ) e ).getResolvedDn();
            }

            if ( ( dn != null )
                && ( ( code == ResultCodeEnum.NO_SUCH_OBJECT ) || ( code == ResultCodeEnum.ALIAS_PROBLEM )
                    || ( code == ResultCodeEnum.INVALID_DN_SYNTAX ) || ( code == ResultCodeEnum.ALIAS_DEREFERENCING_PROBLEM ) ) )
            {
                result.setMatchedDn( dn );
            }

            result.setDiagnosticMessage( msg );
            bindResponse.addAllControls( bindContext.getResponseControls() );

            // Before writing the response, be sure the session is set to anonymous
            ldapSession.setAnonymous();

            // Write the response
            ldapSession.getIoSession().write( bindResponse );
        }
        finally
        {
            // Reset LDAP session bind status to anonymous if authentication failed
            if ( !ldapSession.isAuthenticated() )
            {
                ldapSession.setAnonymous();
            }
        }
    }