You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@directory.apache.org by Jan Zelmer <Ja...@gmx.net> on 2019/06/25 14:49:16 UTC

Password Expired Response Control

Hi,

I work for a bank in germany, and we are using ForgeRock Directory Service (aka OpenDJ). We use it for storing authentication, authorisation and personal information.
We have several Java applications in our pipeline and decided to use your API because it is actively maintained and allows far more control than the sun JNDI libs.

We now got the problem, that people should be able to reset their passwords, without knowing their old ones. (We authenticate and authorise via other means)
So, at first we use an application bind with password-reset capabilites to reset and generate a temporary password, with that we bind the user and immediately change the password to the user desired one.
There is one problem: your api will crash during the bind request with a Null Pointer Exception.

I found that the api is not able to decode the control: 2.16.840.1.113730.3.4.4 (taken from here https://docs.ldap.com/specs/draft-vchu-ldap-pwd-policy-00.txt); can not find the according factory and stop processing the message.
The control is just about the expired password.

After digging your code, I implemented missing factory and control. (and manually registered that factory). Now my code works :)

For the first time sending on this mail list, I don't want to attach a zip. So heres the code in plain text. (I can't access git, because of proxy, ssl interception and stuff)
Feel free to tell me your definition of Done and any comments, so I can satisfy those.

Kind Regards,
Jan Zelmer
Magdeburg,
Germany

Interface:
import org.apache.directory.api.ldap.model.message.Control;

public interface PasswordExpiredResponse extends Control {

    /** This control OID */
    String OID = "2.16.840.1.113730.3.4.4";

}

Implementation:
import org.apache.directory.api.ldap.model.message.controls.AbstractControl;

public class PasswordExpiredResponseImpl extends AbstractControl implements PasswordExpiredResponse {


    public PasswordExpiredResponseImpl() {
        super(OID);
    }


    /**
     * Return a String representing this PasswordExpiredControl.
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append( "    Password Expired Response Control\n" );
        sb.append( "        oid : " ).append( getOid() ).append( '\n' );
        sb.append( "        critical : " ).append( isCritical() ).append( '\n' );
        return sb.toString();
    }

}

Factory:
import org.apache.directory.api.asn1.DecoderException;
import org.apache.directory.api.ldap.codec.api.AbstractControlFactory;
import org.apache.directory.api.ldap.codec.api.LdapApiService;
import org.apache.directory.api.ldap.model.message.Control;
import org.apache.directory.api.util.Strings;

public class PasswordExpiredResponseFactory extends AbstractControlFactory<PasswordExpiredResponse> {

    /**
     * Creates a new instance of PasswordExpiredResponseFactory.
     *
     * @param codec The LDAP codec.
     */
    public PasswordExpiredResponseFactory( LdapApiService codec )
    {
        super( codec, PasswordExpiredResponse.OID );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Control newControl() {
        return new PasswordExpiredResponseImpl();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void decodeValue( Control control, byte[] controlBytes ) throws DecoderException {
        try {
             if (!Strings.utf8ToString( controlBytes ).equals("0")){
                 throw new DecoderException("An error occurred during decoding the response message: found a non zero value" +
                         "for the password expired control value. According to the ldap reference guide, only values of zero are valid.");
            }
        }
        catch ( RuntimeException re ) {
            throw new DecoderException( re.getMessage() );
        }
    }
}


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@directory.apache.org
For additional commands, e-mail: dev-help@directory.apache.org


Re: Password Expired Response Control

Posted by Emmanuel Lécharny <el...@gmail.com>.
Ok, the code has been injected into the master code base.


Please pull it and give it a try.


Thanks !


On 25/06/2019 18:25, Emmanuel Lécharny wrote:
> Also I would need the PDU sent back by the server that includes the 
> control. The fact is that the RFC draft is not necessarily well 
> implemented by Forgerock, as the value you expect to get is "0" while 
> the draft mentions it's an OCTET STRING containing the number of 
> seconds before expiration, which would be something like 0x04 0x01 
> 0x00 (and even that is wrong, because the RFC draft is frankly broken, 
> and it should be something like 0x02 0x01 0x00).
>
>
> ATM, I will assume it contains a value with just 0x30 ("0").
>
>
> On 25/06/2019 16:49, Jan Zelmer wrote:
>> Hi,
>>
>> I work for a bank in germany, and we are using ForgeRock Directory 
>> Service (aka OpenDJ). We use it for storing authentication, 
>> authorisation and personal information.
>> We have several Java applications in our pipeline and decided to use 
>> your API because it is actively maintained and allows far more 
>> control than the sun JNDI libs.
>>
>> We now got the problem, that people should be able to reset their 
>> passwords, without knowing their old ones. (We authenticate and 
>> authorise via other means)
>> So, at first we use an application bind with password-reset 
>> capabilites to reset and generate a temporary password, with that we 
>> bind the user and immediately change the password to the user desired 
>> one.
>> There is one problem: your api will crash during the bind request 
>> with a Null Pointer Exception.
>>
>> I found that the api is not able to decode the control: 
>> 2.16.840.1.113730.3.4.4 (taken from here 
>> https://docs.ldap.com/specs/draft-vchu-ldap-pwd-policy-00.txt); can 
>> not find the according factory and stop processing the message.
>> The control is just about the expired password.
>>
>> After digging your code, I implemented missing factory and control. 
>> (and manually registered that factory). Now my code works :)
>>
>> For the first time sending on this mail list, I don't want to attach 
>> a zip. So heres the code in plain text. (I can't access git, because 
>> of proxy, ssl interception and stuff)
>> Feel free to tell me your definition of Done and any comments, so I 
>> can satisfy those.
>>
>> Kind Regards,
>> Jan Zelmer
>> Magdeburg,
>> Germany
>>
>> Interface:
>> import org.apache.directory.api.ldap.model.message.Control;
>>
>> public interface PasswordExpiredResponse extends Control {
>>
>>      /** This control OID */
>>      String OID = "2.16.840.1.113730.3.4.4";
>>
>> }
>>
>> Implementation:
>> import 
>> org.apache.directory.api.ldap.model.message.controls.AbstractControl;
>>
>> public class PasswordExpiredResponseImpl extends AbstractControl 
>> implements PasswordExpiredResponse {
>>
>>
>>      public PasswordExpiredResponseImpl() {
>>          super(OID);
>>      }
>>
>>
>>      /**
>>       * Return a String representing this PasswordExpiredControl.
>>       */
>>      @Override
>>      public String toString() {
>>          StringBuilder sb = new StringBuilder();
>>          sb.append( "    Password Expired Response Control\n" );
>>          sb.append( "        oid : " ).append( getOid() ).append( 
>> '\n' );
>>          sb.append( "        critical : " ).append( isCritical() 
>> ).append( '\n' );
>>          return sb.toString();
>>      }
>>
>> }
>>
>> Factory:
>> import org.apache.directory.api.asn1.DecoderException;
>> import org.apache.directory.api.ldap.codec.api.AbstractControlFactory;
>> import org.apache.directory.api.ldap.codec.api.LdapApiService;
>> import org.apache.directory.api.ldap.model.message.Control;
>> import org.apache.directory.api.util.Strings;
>>
>> public class PasswordExpiredResponseFactory extends 
>> AbstractControlFactory<PasswordExpiredResponse> {
>>
>>      /**
>>       * Creates a new instance of PasswordExpiredResponseFactory.
>>       *
>>       * @param codec The LDAP codec.
>>       */
>>      public PasswordExpiredResponseFactory( LdapApiService codec )
>>      {
>>          super( codec, PasswordExpiredResponse.OID );
>>      }
>>
>>      /**
>>       * {@inheritDoc}
>>       */
>>      @Override
>>      public Control newControl() {
>>          return new PasswordExpiredResponseImpl();
>>      }
>>
>>      /**
>>       * {@inheritDoc}
>>       */
>>      @Override
>>      public void decodeValue( Control control, byte[] controlBytes ) 
>> throws DecoderException {
>>          try {
>>               if (!Strings.utf8ToString( controlBytes ).equals("0")){
>>                   throw new DecoderException("An error occurred 
>> during decoding the response message: found a non zero value" +
>>                           "for the password expired control value. 
>> According to the ldap reference guide, only values of zero are valid.");
>>              }
>>          }
>>          catch ( RuntimeException re ) {
>>              throw new DecoderException( re.getMessage() );
>>          }
>>      }
>> }
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@directory.apache.org
>> For additional commands, e-mail: dev-help@directory.apache.org
>>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@directory.apache.org
For additional commands, e-mail: dev-help@directory.apache.org


Re: Aw: Re: Password Expired Response Control

Posted by Emmanuel Lécharny <el...@gmail.com>.
On 26/06/2019 15:26, Ludovic Poitou wrote:
> That Internet draft (draft-vchu-ldap-pwd-policy-00.txt) is a piece of 
> memory of how Netscape Directory Server 4.x was doing password policy.
> The controls are the only piece that are still implemented in 
> ForgeRock DS, and it’s siblings (OUD, Ping Directory…), but they are 
> also still implemented in Oracle DSEE and Red-Hat Directory, mostly 
> because they were unsolicited and many clients are still able to deal 
> with them.
> I would be surprised if the control returned value with ForgeRock DS 
> actually differs from Sun/Oracle DSEE, as we used the same test suite 
> to validate the returned controls. But it’s very possible that it’s 
> not really compliant with the ASN.1 description of the control.


Many thanks Ludovic.

ATM, I'm basing the LDAP API code to deal with a single byte for this 
control value (aka 0x30, '0'). This is not ASN.1 compliant, but all in 
all, who cares ? The control value is anyway supposed to be opaque, so I 
guess it's fine as soon as all the implementers did the same.



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@directory.apache.org
For additional commands, e-mail: dev-help@directory.apache.org


Re: Aw: Re: Password Expired Response Control

Posted by Ludovic Poitou <lu...@gmail.com>.
That Internet draft (draft-vchu-ldap-pwd-policy-00.txt) is a piece of
memory of how Netscape Directory Server 4.x was doing password policy.
The controls are the only piece that are still implemented in ForgeRock DS,
and it’s siblings (OUD, Ping Directory…), but they are also still
implemented in Oracle DSEE and Red-Hat Directory, mostly because they were
unsolicited and many clients are still able to deal with them.
I would be surprised if the control returned value with ForgeRock DS
actually differs from Sun/Oracle DSEE, as we used the same test suite to
validate the returned controls. But it’s very possible that it’s not really
compliant with the ASN.1 description of the control.

My 2 cents,

Ludo

—
Ludovic Poitou
http://ludopoitou.com

From: Jan Zelmer <ja...@gmx.net> <ja...@gmx.net>
Reply: Jan Zelmer <ja...@gmx.net> <ja...@gmx.net>
Date: 26 June 2019 at 15:11:42
To: dev@directory.apache.org <de...@directory.apache.org>
<de...@directory.apache.org>
Subject:  Aw: Re: Password Expired Response Control

Hi,

thank you for your effort :), I will have a look if the new version fixes
my problem.

Okay, I will create a Jira for this: DIRAPI-348

For the specification, I will contact the vendor and try to get a statement
to this matter.
It sounds awful to add functionality which is over a decade outdated.

I think there is a confusion regarding the control: 2.16.840.1.113730.3.4.4
states that a password is expired. There is a different control for telling
the user that its password expires during the expiry warning intervall:
2.16.840.1.113730.3.4.5. This will return an octet string to indicate the
time in seconds until the password expires.
https://docs.ldap.com/specs/draft-vchu-ldap-pwd-policy-00.txt 12.2 Bind
Operations
It could be, that I will run into this problem eventually.

Kind Regards,
Jan

> Gesendet: Dienstag, 25. Juni 2019 um 18:25 Uhr
> Von: "Emmanuel Lécharny" <el...@gmail.com>
> An: dev@directory.apache.org
> Betreff: Re: Password Expired Response Control
>
>I'll review your code (If you could create a JIRA with the classes
>attached, that would help everyone tracking this addition).
>
>Side note : the RFC draft you are pointing out has expired for more than
>2 decades... I'm not sure anyone but OpenDJ is implementing it. I think
>it has been overseeded by
>https://tools.ietf.org/html/draft-behera-ldap-password-policy-10.
>
> Also I would need the PDU sent back by the server that includes the
> control. The fact is that the RFC draft is not necessarily well
> implemented by Forgerock, as the value you expect to get is "0" while
> the draft mentions it's an OCTET STRING containing the number of seconds
> before expiration, which would be something like 0x04 0x01 0x00 (and
> even that is wrong, because the RFC draft is frankly broken, and it
> should be something like 0x02 0x01 0x00).
>
>
> ATM, I will assume it contains a value with just 0x30 ("0").
>
>
> On 25/06/2019 16:49, Jan Zelmer wrote:
> > Hi,
> >
> > I work for a bank in germany, and we are using ForgeRock Directory
Service (aka OpenDJ). We use it for storing authentication, authorisation
and personal information.
> > We have several Java applications in our pipeline and decided to use
your API because it is actively maintained and allows far more control than
the sun JNDI libs.
> >
> > We now got the problem, that people should be able to reset their
passwords, without knowing their old ones. (We authenticate and authorise
via other means)
> > So, at first we use an application bind with password-reset capabilites
to reset and generate a temporary password, with that we bind the user and
immediately change the password to the user desired one.
> > There is one problem: your api will crash during the bind request with
a Null Pointer Exception.
> >
> > I found that the api is not able to decode the control:
2.16.840.1.113730.3.4.4 (taken from here
https://docs.ldap.com/specs/draft-vchu-ldap-pwd-policy-00.txt); can not
find the according factory and stop processing the message.
> > The control is just about the expired password.
> >
> > After digging your code, I implemented missing factory and control.
(and manually registered that factory). Now my code works :)
> >
> > For the first time sending on this mail list, I don't want to attach a
zip. So heres the code in plain text. (I can't access git, because of
proxy, ssl interception and stuff)
> > Feel free to tell me your definition of Done and any comments, so I can
satisfy those.
> >
> > Kind Regards,
> > Jan Zelmer
> > Magdeburg,
> > Germany
> >
> > Interface:
> > import org.apache.directory.api.ldap.model.message.Control;
> >
> > public interface PasswordExpiredResponse extends Control {
> >
> > /** This control OID */
> > String OID = "2.16.840.1.113730.3.4.4";
> >
> > }
> >
> > Implementation:
> > import
org.apache.directory.api.ldap.model.message.controls.AbstractControl;
> >
> > public class PasswordExpiredResponseImpl extends AbstractControl
implements PasswordExpiredResponse {
> >
> >
> > public PasswordExpiredResponseImpl() {
> > super(OID);
> > }
> >
> >
> > /**
> > * Return a String representing this PasswordExpiredControl.
> > */
> > @Override
> > public String toString() {
> > StringBuilder sb = new StringBuilder();
> > sb.append( " Password Expired Response Control\n" );
> > sb.append( " oid : " ).append( getOid() ).append( '\n' );
> > sb.append( " critical : " ).append( isCritical() ).append( '\n' );
> > return sb.toString();
> > }
> >
> > }
> >
> > Factory:
> > import org.apache.directory.api.asn1.DecoderException;
> > import org.apache.directory.api.ldap.codec.api.AbstractControlFactory;
> > import org.apache.directory.api.ldap.codec.api.LdapApiService;
> > import org.apache.directory.api.ldap.model.message.Control;
> > import org.apache.directory.api.util.Strings;
> >
> > public class PasswordExpiredResponseFactory extends
AbstractControlFactory<PasswordExpiredResponse> {
> >
> > /**
> > * Creates a new instance of PasswordExpiredResponseFactory.
> > *
> > * @param codec The LDAP codec.
> > */
> > public PasswordExpiredResponseFactory( LdapApiService codec )
> > {
> > super( codec, PasswordExpiredResponse.OID );
> > }
> >
> > /**
> > * {@inheritDoc}
> > */
> > @Override
> > public Control newControl() {
> > return new PasswordExpiredResponseImpl();
> > }
> >
> > /**
> > * {@inheritDoc}
> > */
> > @Override
> > public void decodeValue( Control control, byte[] controlBytes ) throws
DecoderException {
> > try {
> > if (!Strings.utf8ToString( controlBytes ).equals("0")){
> > throw new DecoderException("An error occurred during decoding the
response message: found a non zero value" +
> > "for the password expired control value. According to the ldap
reference guide, only values of zero are valid.");
> > }
> > }
> > catch ( RuntimeException re ) {
> > throw new DecoderException( re.getMessage() );
> > }
> > }
> > }
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe@directory.apache.org
> > For additional commands, e-mail: dev-help@directory.apache.org
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@directory.apache.org
> For additional commands, e-mail: dev-help@directory.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@directory.apache.org
For additional commands, e-mail: dev-help@directory.apache.org

Aw: Re: Password Expired Response Control

Posted by Jan Zelmer <Ja...@gmx.net>.
Hi,

thank you for your effort :), I will have a look if the new version fixes my problem.

Okay, I will create a Jira for this: DIRAPI-348

For the specification, I will contact the vendor and try to get a statement to this matter.
It sounds awful to add functionality which is over a decade outdated.

I think there is a confusion regarding the control: 2.16.840.1.113730.3.4.4 states that a password is expired. There is a different control for telling the user that its password expires during the expiry warning intervall: 2.16.840.1.113730.3.4.5. This will return an octet string to indicate the time in seconds until the password expires. https://docs.ldap.com/specs/draft-vchu-ldap-pwd-policy-00.txt 12.2 Bind Operations
It could be, that I will run into this problem eventually.

Kind Regards,
Jan

> Gesendet: Dienstag, 25. Juni 2019 um 18:25 Uhr
> Von: "Emmanuel Lécharny" <el...@gmail.com>
> An: dev@directory.apache.org
> Betreff: Re: Password Expired Response Control
>
>I'll review your code (If you could create a JIRA with the classes
>attached, that would help everyone tracking this addition).
>
>Side note : the RFC draft you are pointing out has expired for more than
>2 decades... I'm not sure anyone but OpenDJ is implementing it. I think
>it has been overseeded by
>https://tools.ietf.org/html/draft-behera-ldap-password-policy-10.
>
> Also I would need the PDU sent back by the server that includes the 
> control. The fact is that the RFC draft is not necessarily well 
> implemented by Forgerock, as the value you expect to get is "0" while 
> the draft mentions it's an OCTET STRING containing the number of seconds 
> before expiration, which would be something like 0x04 0x01 0x00 (and 
> even that is wrong, because the RFC draft is frankly broken, and it 
> should be something like 0x02 0x01 0x00).
> 
> 
> ATM, I will assume it contains a value with just 0x30 ("0").
> 
> 
> On 25/06/2019 16:49, Jan Zelmer wrote:
> > Hi,
> >
> > I work for a bank in germany, and we are using ForgeRock Directory Service (aka OpenDJ). We use it for storing authentication, authorisation and personal information.
> > We have several Java applications in our pipeline and decided to use your API because it is actively maintained and allows far more control than the sun JNDI libs.
> >
> > We now got the problem, that people should be able to reset their passwords, without knowing their old ones. (We authenticate and authorise via other means)
> > So, at first we use an application bind with password-reset capabilites to reset and generate a temporary password, with that we bind the user and immediately change the password to the user desired one.
> > There is one problem: your api will crash during the bind request with a Null Pointer Exception.
> >
> > I found that the api is not able to decode the control: 2.16.840.1.113730.3.4.4 (taken from here https://docs.ldap.com/specs/draft-vchu-ldap-pwd-policy-00.txt); can not find the according factory and stop processing the message.
> > The control is just about the expired password.
> >
> > After digging your code, I implemented missing factory and control. (and manually registered that factory). Now my code works :)
> >
> > For the first time sending on this mail list, I don't want to attach a zip. So heres the code in plain text. (I can't access git, because of proxy, ssl interception and stuff)
> > Feel free to tell me your definition of Done and any comments, so I can satisfy those.
> >
> > Kind Regards,
> > Jan Zelmer
> > Magdeburg,
> > Germany
> >
> > Interface:
> > import org.apache.directory.api.ldap.model.message.Control;
> >
> > public interface PasswordExpiredResponse extends Control {
> >
> >      /** This control OID */
> >      String OID = "2.16.840.1.113730.3.4.4";
> >
> > }
> >
> > Implementation:
> > import org.apache.directory.api.ldap.model.message.controls.AbstractControl;
> >
> > public class PasswordExpiredResponseImpl extends AbstractControl implements PasswordExpiredResponse {
> >
> >
> >      public PasswordExpiredResponseImpl() {
> >          super(OID);
> >      }
> >
> >
> >      /**
> >       * Return a String representing this PasswordExpiredControl.
> >       */
> >      @Override
> >      public String toString() {
> >          StringBuilder sb = new StringBuilder();
> >          sb.append( "    Password Expired Response Control\n" );
> >          sb.append( "        oid : " ).append( getOid() ).append( '\n' );
> >          sb.append( "        critical : " ).append( isCritical() ).append( '\n' );
> >          return sb.toString();
> >      }
> >
> > }
> >
> > Factory:
> > import org.apache.directory.api.asn1.DecoderException;
> > import org.apache.directory.api.ldap.codec.api.AbstractControlFactory;
> > import org.apache.directory.api.ldap.codec.api.LdapApiService;
> > import org.apache.directory.api.ldap.model.message.Control;
> > import org.apache.directory.api.util.Strings;
> >
> > public class PasswordExpiredResponseFactory extends AbstractControlFactory<PasswordExpiredResponse> {
> >
> >      /**
> >       * Creates a new instance of PasswordExpiredResponseFactory.
> >       *
> >       * @param codec The LDAP codec.
> >       */
> >      public PasswordExpiredResponseFactory( LdapApiService codec )
> >      {
> >          super( codec, PasswordExpiredResponse.OID );
> >      }
> >
> >      /**
> >       * {@inheritDoc}
> >       */
> >      @Override
> >      public Control newControl() {
> >          return new PasswordExpiredResponseImpl();
> >      }
> >
> >      /**
> >       * {@inheritDoc}
> >       */
> >      @Override
> >      public void decodeValue( Control control, byte[] controlBytes ) throws DecoderException {
> >          try {
> >               if (!Strings.utf8ToString( controlBytes ).equals("0")){
> >                   throw new DecoderException("An error occurred during decoding the response message: found a non zero value" +
> >                           "for the password expired control value. According to the ldap reference guide, only values of zero are valid.");
> >              }
> >          }
> >          catch ( RuntimeException re ) {
> >              throw new DecoderException( re.getMessage() );
> >          }
> >      }
> > }
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe@directory.apache.org
> > For additional commands, e-mail: dev-help@directory.apache.org
> >
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@directory.apache.org
> For additional commands, e-mail: dev-help@directory.apache.org
> 
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@directory.apache.org
For additional commands, e-mail: dev-help@directory.apache.org


Re: Password Expired Response Control

Posted by Emmanuel Lécharny <el...@gmail.com>.
Also I would need the PDU sent back by the server that includes the 
control. The fact is that the RFC draft is not necessarily well 
implemented by Forgerock, as the value you expect to get is "0" while 
the draft mentions it's an OCTET STRING containing the number of seconds 
before expiration, which would be something like 0x04 0x01 0x00 (and 
even that is wrong, because the RFC draft is frankly broken, and it 
should be something like 0x02 0x01 0x00).


ATM, I will assume it contains a value with just 0x30 ("0").


On 25/06/2019 16:49, Jan Zelmer wrote:
> Hi,
>
> I work for a bank in germany, and we are using ForgeRock Directory Service (aka OpenDJ). We use it for storing authentication, authorisation and personal information.
> We have several Java applications in our pipeline and decided to use your API because it is actively maintained and allows far more control than the sun JNDI libs.
>
> We now got the problem, that people should be able to reset their passwords, without knowing their old ones. (We authenticate and authorise via other means)
> So, at first we use an application bind with password-reset capabilites to reset and generate a temporary password, with that we bind the user and immediately change the password to the user desired one.
> There is one problem: your api will crash during the bind request with a Null Pointer Exception.
>
> I found that the api is not able to decode the control: 2.16.840.1.113730.3.4.4 (taken from here https://docs.ldap.com/specs/draft-vchu-ldap-pwd-policy-00.txt); can not find the according factory and stop processing the message.
> The control is just about the expired password.
>
> After digging your code, I implemented missing factory and control. (and manually registered that factory). Now my code works :)
>
> For the first time sending on this mail list, I don't want to attach a zip. So heres the code in plain text. (I can't access git, because of proxy, ssl interception and stuff)
> Feel free to tell me your definition of Done and any comments, so I can satisfy those.
>
> Kind Regards,
> Jan Zelmer
> Magdeburg,
> Germany
>
> Interface:
> import org.apache.directory.api.ldap.model.message.Control;
>
> public interface PasswordExpiredResponse extends Control {
>
>      /** This control OID */
>      String OID = "2.16.840.1.113730.3.4.4";
>
> }
>
> Implementation:
> import org.apache.directory.api.ldap.model.message.controls.AbstractControl;
>
> public class PasswordExpiredResponseImpl extends AbstractControl implements PasswordExpiredResponse {
>
>
>      public PasswordExpiredResponseImpl() {
>          super(OID);
>      }
>
>
>      /**
>       * Return a String representing this PasswordExpiredControl.
>       */
>      @Override
>      public String toString() {
>          StringBuilder sb = new StringBuilder();
>          sb.append( "    Password Expired Response Control\n" );
>          sb.append( "        oid : " ).append( getOid() ).append( '\n' );
>          sb.append( "        critical : " ).append( isCritical() ).append( '\n' );
>          return sb.toString();
>      }
>
> }
>
> Factory:
> import org.apache.directory.api.asn1.DecoderException;
> import org.apache.directory.api.ldap.codec.api.AbstractControlFactory;
> import org.apache.directory.api.ldap.codec.api.LdapApiService;
> import org.apache.directory.api.ldap.model.message.Control;
> import org.apache.directory.api.util.Strings;
>
> public class PasswordExpiredResponseFactory extends AbstractControlFactory<PasswordExpiredResponse> {
>
>      /**
>       * Creates a new instance of PasswordExpiredResponseFactory.
>       *
>       * @param codec The LDAP codec.
>       */
>      public PasswordExpiredResponseFactory( LdapApiService codec )
>      {
>          super( codec, PasswordExpiredResponse.OID );
>      }
>
>      /**
>       * {@inheritDoc}
>       */
>      @Override
>      public Control newControl() {
>          return new PasswordExpiredResponseImpl();
>      }
>
>      /**
>       * {@inheritDoc}
>       */
>      @Override
>      public void decodeValue( Control control, byte[] controlBytes ) throws DecoderException {
>          try {
>               if (!Strings.utf8ToString( controlBytes ).equals("0")){
>                   throw new DecoderException("An error occurred during decoding the response message: found a non zero value" +
>                           "for the password expired control value. According to the ldap reference guide, only values of zero are valid.");
>              }
>          }
>          catch ( RuntimeException re ) {
>              throw new DecoderException( re.getMessage() );
>          }
>      }
> }
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@directory.apache.org
> For additional commands, e-mail: dev-help@directory.apache.org
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@directory.apache.org
For additional commands, e-mail: dev-help@directory.apache.org