Hi - We're using API M32 and a server version a few releases back.

We use the grace logins to raise errors (to change the password) before it's 
actually expired & locked. 

In the password policy we set the attribute ads-pwdgraceauthnlimit=4.  The user 
then gets 4 more attempts to login after the password is expired but before 
it's locked out. You'll need to raise an error or warning so that they do it 
but a valid password gives them a few more logins. The PasswordPolicyResponse  
getGraceAuthNRemaining()  method indicates how many grace logins are left for 
the user.  We were not able to get the safe password function working, we just 
bind with the creds one last time before resetting the password using an admin 
bind. (This isn't ideal however because it uses one of the user's grace logins. 
So with the grace value set to 4, we only allow 3 grace logins, saving the last 
one for the password reset).

 Here are some code snips and hope it helps. 

/**Determine if user password is expired and all grace logins are used from 
PasswordPolicyResponse code. 
         * @param ctrl The PasswordPolicyResponse object containing the 
response code
         * @return true when the password and grace logins are expired and the 
user cannot login, false otherwise.
         */
        public static boolean isPasswordExpiredLocked(PasswordPolicyResponse 
ctrl)
        {
                if (ctrl != null){
                        // two grace logins are needed. One to login, one to 
change the password. 
                        // Account must lock if only one grace login remains 
because there are no binds left to change it.
                        
                        // Password is forced to change, but there are no 
expire warnings, ok.
                        if (PasswordPolicyErrorEnum.CHANGE_AFTER_RESET == 
ctrl.getPasswordPolicyError() &&
                                        ctrl.getGraceAuthNRemaining() == -1 )
                        {
                                return false;
                        }

                        // Password is expired and there are no grace logins to 
clear it, fail.
                        if ((ctrl.getTimeBeforeExpiration() == -1  && 
ctrl.getGraceAuthNRemaining() <= 1)  
                                         || 
PasswordPolicyErrorEnum.PASSWORD_EXPIRED == ctrl.getPasswordPolicyError()) // 
need to set expired flag.
                        { 
                                return true;
                        }
                }
                return false;
        }
        

        /**Determine if user password must change from PasswordPolicyResponse 
code. 
         * @param ctrl The PasswordPolicyResponse object containing the 
response code
         * @return true when the password must change, false otherwise.
         */
        public static boolean isPasswordMustChange(PasswordPolicyResponse ctrl)
        {
                if (ctrl != null){
                        if (ctrl.getTimeBeforeExpiration() == -1 || 
                                        (ctrl.getGraceAuthNRemaining() <= 2 && 
ctrl.getGraceAuthNRemaining() > -1)) // need to reset before LAST 2 logins
                        { 
                                //System.out.println("Password must change. 
Expired in " + ctrl.getTimeBeforeExpiration()+ " seconds, " +  
ctrl.getGraceLoginsRemaining() + " logins remain . ");
                                return true;
                        }
                        if (PasswordPolicyErrorEnum.CHANGE_AFTER_RESET == 
ctrl.getPasswordPolicyError())
                        {
                                //System.out.println("Password was changed by 
admin and must change. ");
                                return true;
                        }
                        if (PasswordPolicyErrorEnum.PASSWORD_EXPIRED == 
ctrl.getPasswordPolicyError())
                        {
                                //System.out.println("Password has expired and 
must change. ");
                                return true;
                        }
                }
                return false;
        }

//here's our relevant config

dn: 
ads-pwdId=internal,ou=passwordPolicies,ads-interceptorId=authenticationInterceptor,ou=interceptors,ads-directoryServiceId=default,ou=config
objectClass: top
objectClass: ads-base
objectClass: ads-passwordPolicy
ads-pwdId: internal
ads-pwdSafeModify: FALSE  // never got this to work. Password reset using admin 
bind.
ads-pwdMaxAge: 5184000  // 60 days
ads-pwdFailureCountInterval: 30
ads-pwdAttribute: userPassword
ads-pwdMaxFailure: 5
ads-pwdLockout: TRUE
ads-pwdMustChange: FALSE
ads-pwdLockoutDuration: 0 // lock indefinitely.
ads-pwdMinLength: 6
ads-pwdInHistory: 5
ads-pwdExpireWarning: 345600  // 4 days
ads-pwdMinAge: 0
ads-pwdAllowUserChange: TRUE
ads-pwdGraceAuthNLimit: 4 // allow 4 logins after expired (raising an error 
each time)
ads-pwdCheckQuality: 1
ads-pwdMaxLength: 0 
ads-pwdGraceExpire: 0
ads-pwdMinDelay: 0
ads-pwdMaxDelay: 0
ads-pwdMaxIdle: 0
ads-enabled: FALSE



-----Original Message-----
From: Mike Davis [mailto:mda...@rez1.com] 
Sent: Wednesday, November 02, 2016 7:36 AM
To: users@directory.apache.org
Subject: Re: [ApacheDS | LDAP API] changing expired passwords



Thanks for the quick response. 


I have not set any of the grace login parameters at this time.




Get Outlook for Android



From: Emmanuel Lécharny

Sent: Wednesday, November 2, 4:00 AM

Subject: Re: [ApacheDS | LDAP API] changing expired passwords

To: users@directory.apache.org



Hi ! Le 01/11/16 à 22:03, Mike Davis a écrit : > I've run into an issue with 
either Apache DS or the Apache LDAP API, or > both. > > > > Here's the 
scenario. > > > > I have a user whose password is expired. I want to force the 
user to > change their password. However, I can't distinguish between a case 
where > the user knows the password and where the user doesn't. I always get a 
> PasswordException with > 
passwordPolicyError=PasswordPolicyErrorEnum.PASSWORD_EXPIRED and > resultCode = 
ResultCodeEnum.INVALID_CREDENTIALS. > > > > On top of that, the 
LdapConnectionTemplate.modifyPassword() method that > takes old and new 
password doesn't work, because the library is attempting > to bind with the 
users old password, and we just get the same > PasswordException as above. If I 
use the 'asAdmin' flag, then the old > password is never checked. > > > > I 
don't want to change the password as admin, because I have no way to > validate 
the user knows his old password. You should not be forced to use the admin flag 
to change an expired password. There is a paramter (pwdGraceUseTime) that let 
the user tries up a given delay to change an expired password. What is the 
value you have set for this parameter ? However, teh default should be 
infinite. I suspect there is a bug that should be fixed urgently... 
Hi !


Le 01/11/16 à 22:03, Mike Davis a écrit :
> I've run into an issue with either Apache DS or the Apache LDAP API, 
> or both.
>
>  
>
> Here's the scenario.
>
>  
>
> I have a user whose password is expired. I want to force the user to 
> change their password. However, I can't distinguish between a case 
> where the user knows the password and where the user doesn't. I always 
> get a PasswordException with 
> passwordPolicyError=PasswordPolicyErrorEnum.PASSWORD_EXPIRED  and 
> resultCode = ResultCodeEnum.INVALID_CREDENTIALS.
>
>  
>
> On top of that, the LdapConnectionTemplate.modifyPassword() method 
> that takes old and new password doesn't work, because the library is 
> attempting to bind with the users old password, and we just get the 
> same PasswordException as above. If I use the 'asAdmin' flag, then the 
> old password is never checked.
>
>  
>
> I don't want to change the password as admin, because I have no way to 
> validate the user knows his old password.

You should not be forced to use the admin flag to change an expired password. 
There is a paramter (pwdGraceUseTime) that let the user tries up a given delay 
to change an expired password. What is the value you have set for this 
parameter ?

However, teh default should be infinite. I suspect there is a bug that should 
be fixed urgently...

Reply via email to