private void modifyUserPassword()

in protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/PwdModifyHandler.java [104:344]


    private void modifyUserPassword( CoreSession userSession, Entry userEntry, Dn userDn, 
        byte[] oldPassword, byte[] newPassword, PasswordModifyRequest req )
    {
        IoSession ioSession = ( ( DefaultCoreSession ) userSession ).getIoSession();

        if ( newPassword == null )
        {
            // We don't support password generation on ApacheDS
            writeResult( ioSession, req, ResultCodeEnum.UNWILLING_TO_PERFORM, 
                "Cannot change a password for user " + userDn + ", exception : null new password" );

            return;
        }
        
        // Get the user password attribute
        Attribute userPassword = userEntry.get( SchemaConstants.USER_PASSWORD_AT );
        
        if ( userPassword == null )
        {
            // We can't modify the password
            writeResult( ioSession, req, ResultCodeEnum.UNWILLING_TO_PERFORM, 
                "Cannot change a password for user " + userDn + ", the user has no existing password" );

            return;
        }
        
        if ( userPassword.contains( newPassword ) )
        {
           // Ok, we are done : just return success
            PasswordModifyResponseImpl pmrl = new PasswordModifyResponseImpl(
                req.getMessageId(), ResultCodeEnum.SUCCESS );

            Control ppolicyControl = req.getControl( PasswordPolicyRequest.OID );

            if ( ppolicyControl != null )
            {
                pmrl.addControl( ppolicyControl );
            }

            ioSession.write( pmrl );

            return;
        }
        
        if ( oldPassword == null )
        {
            // We are modifying the password on behalf of another user. ACI will
            // protect such modification if it's not allowed. In any case, we just 
            // modify the existing userPassword attribute, adding the password
            ModifyRequest modifyRequest = new ModifyRequestImpl();
            modifyRequest.setName( userDn );

            Control ppolicyControl = req.getControl( PasswordPolicyRequest.OID );
            
            if ( ppolicyControl != null )
            {
                modifyRequest.addControl( ppolicyControl );
            }
            
            try
            {
                Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
                    userPassword.getAttributeType(), newPassword );
    
                modifyRequest.addModification( modification );
                ResultCodeEnum errorCode = null;
                String errorMessage = null;

                try
                {
                    userSession.modify( modifyRequest );

                    if ( LOG.isDebugEnabled() )
                    {
                        LOG.debug( "Password modified for user {}", userDn );
                    }

                    // Ok, all done
                    PasswordModifyResponseImpl pmrl = new PasswordModifyResponseImpl(
                        req.getMessageId(), ResultCodeEnum.SUCCESS );

                    ppolicyControl = modifyRequest.getResultResponse().getControl( PasswordPolicyRequest.OID );

                    if ( ppolicyControl != null )
                    {
                        pmrl.addControl( ppolicyControl );
                    }

                    ioSession.write( pmrl );

                    return;
                }
                catch ( LdapOperationException loe )
                {
                    errorCode = loe.getResultCode();
                    errorMessage = loe.getMessage();
                }
                catch ( LdapException le )
                {
                    // this exception means something else must be wrong
                    errorCode = ResultCodeEnum.OTHER;
                    errorMessage = le.getMessage();
                }

                // We can't modify the password
                LOG.error( "Cannot modify the password for user {}, exception : {}", userDn, errorMessage );
                PasswordModifyResponseImpl errorPmrl = new PasswordModifyResponseImpl(
                    req.getMessageId(), errorCode, "Cannot modify the password for user "
                        + userDn + ", exception : " + errorMessage );

                ppolicyControl = modifyRequest.getResultResponse().getControl( PasswordPolicyRequest.OID );

                if ( ppolicyControl != null )
                {
                    errorPmrl.addControl( ppolicyControl );
                }

                ioSession.write( errorPmrl );
                
                return;
            }
            catch ( LdapInvalidAttributeValueException liave )
            {
                // Nothing to do, this will never be a problem
            }
        }
        else
        {
            // We are changing the password of the current user, check the password
            boolean valid = false;
            Attribute modifiedPassword = new DefaultAttribute( userPassword.getAttributeType() );
            
            for ( Value value : userPassword )
            {
                if ( !valid )
                {
                    valid = PasswordUtil.compareCredentials( oldPassword, value.getBytes() );
                }
                
                try
                {
                    if ( valid )
                    {
                        modifiedPassword.add( newPassword );
                    }
                    else
                    { 
                        modifiedPassword.add( value );
                    }
                }
                catch ( LdapInvalidAttributeValueException e )
                {
                    // Nothing to do, this will never be a problem
                }
            }
            
            // At this point, we have what is needed to modify the password, if the oldPassword
            // was valid
            if ( valid )
            {
                ModifyRequest modifyRequest = new ModifyRequestImpl();
                modifyRequest.setName( userDn );

                Control ppolicyControl = req.getControl( PasswordPolicyRequest.OID );
                
                if ( ppolicyControl != null )
                {
                    modifyRequest.addControl( ppolicyControl );
                }
                
                Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
                    modifiedPassword );

                modifyRequest.addModification( modification );

                ResultCodeEnum errorCode = null;
                String errorMessage = null;

                try
                {
                    userSession.modify( modifyRequest );

                    if ( LOG.isDebugEnabled() )
                    {
                        LOG.debug( "Password modified for user {}", userDn );
                    }

                    // Ok, all done
                    PasswordModifyResponseImpl pmrl = new PasswordModifyResponseImpl(
                        req.getMessageId(), ResultCodeEnum.SUCCESS );

                    ppolicyControl = modifyRequest.getResultResponse().getControl( PasswordPolicyRequest.OID );

                    if ( ppolicyControl != null )
                    {
                        pmrl.addControl( ppolicyControl );
                    }

                    ioSession.write( pmrl );

                    return;
                }
                catch ( LdapOperationException loe )
                {
                    errorCode = loe.getResultCode();
                    errorMessage = loe.getMessage();
                }
                catch ( LdapException le )
                {
                    // this exception means something else must be wrong
                    errorCode = ResultCodeEnum.OTHER;
                    errorMessage = le.getMessage();
                }

                // We can't modify the password
                LOG.error( "Cannot modify the password for user {}, exception : {}", userDn, errorMessage );
                PasswordModifyResponseImpl errorPmrl = new PasswordModifyResponseImpl(
                    req.getMessageId(), errorCode, "Cannot modify the password for user "
                        + userDn + ", exception : " + errorMessage );

                ppolicyControl = modifyRequest.getResultResponse().getControl( PasswordPolicyRequest.OID );

                if ( ppolicyControl != null )
                {
                    errorPmrl.addControl( ppolicyControl );
                }

                ioSession.write( errorPmrl );
                
                return;
            }
            else
            {
                // Too bad, the old password is invalid
                writeResult( ioSession, req, ResultCodeEnum.INVALID_CREDENTIALS, 
                    "Cannot change a password for user " + userDn + ", invalid credentials" );

                return;
            }
        }
    }