invalidateAuthenticatorCaches( modifyContext.getDn() );
return;
}
// handle the case where pwdPolicySubentry AT is about to be deleted in thid modify()
PasswordPolicyConfiguration policyConfig = getPwdPolicy( modifyContext.getOriginalEntry() );
boolean isPPolicyReqCtrlPresent = modifyContext.hasRequestControl( PasswordPolicy.OID );
Dn userDn = modifyContext.getSession().getAuthenticatedPrincipal().getDn();
PwdModDetailsHolder pwdModDetails = null;
if ( policyConfig.isPwdSafeModify() || pwdResetSet.contains( userDn ) || ( policyConfig.getPwdMinAge() > 0 ) )
{
pwdModDetails = getPwdModDetails( modifyContext, policyConfig );
}
if ( ( pwdModDetails != null ) && pwdModDetails.isPwdModPresent() )
{
if ( pwdResetSet.contains( userDn ) )
{
if ( pwdModDetails.isOtherModExists() )
{
if ( isPPolicyReqCtrlPresent )
{
PasswordPolicyDecorator responseControl =
new PasswordPolicyDecorator( directoryService.getLdapCodecService(), true );
responseControl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.CHANGE_AFTER_RESET );
modifyContext.addResponseControl( responseControl );
}
throw new LdapNoPermissionException();
}
}
if ( policyConfig.isPwdSafeModify() )
{
if ( pwdModDetails.isAddOrReplace() && !pwdModDetails.isDelete() )
{
LOG.debug( "trying to update password attribute without the supplying the old password" );
if ( isPPolicyReqCtrlPresent )
{
PasswordPolicyDecorator responseControl =
new PasswordPolicyDecorator( directoryService.getLdapCodecService(), true );
responseControl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.MUST_SUPPLY_OLD_PASSWORD );
modifyContext.addResponseControl( responseControl );
}
throw new LdapNoPermissionException();
}
}
if ( !policyConfig.isPwdAllowUserChange() && !modifyContext.getSession().isAnAdministrator() )
{
if ( isPPolicyReqCtrlPresent )
{
PasswordPolicyDecorator responseControl =
new PasswordPolicyDecorator( directoryService.getLdapCodecService(), true );
responseControl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.PASSWORD_MOD_NOT_ALLOWED );
modifyContext.addResponseControl( responseControl );
}
throw new LdapNoPermissionException();
}
Entry entry = modifyContext.getEntry();
if ( isPwdTooYoung( entry, policyConfig ) )
{
if ( isPPolicyReqCtrlPresent )
{
PasswordPolicyDecorator responseControl =
new PasswordPolicyDecorator( directoryService.getLdapCodecService(), true );
responseControl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.PASSWORD_TOO_YOUNG );
modifyContext.addResponseControl( responseControl );
}
throw new LdapOperationException( ResultCodeEnum.CONSTRAINT_VIOLATION,
"password is too young to update" );
}
byte[] newPassword = null;
if ( ( pwdModDetails != null ) )
{
newPassword = pwdModDetails.getNewPwd();
try
{
String userName = entry.getDn().getRdn().getUpValue().getString();
check( userName, newPassword, policyConfig );
}
catch ( PasswordPolicyException e )
{
if ( isPPolicyReqCtrlPresent )
{
PasswordPolicyDecorator responseControl =
new PasswordPolicyDecorator( directoryService.getLdapCodecService(), true );
responseControl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.get( e.getErrorCode() ) );
modifyContext.addResponseControl( responseControl );
}
// throw exception if userPassword quality checks fail
throw new LdapOperationException( ResultCodeEnum.CONSTRAINT_VIOLATION, e.getMessage(), e );
}
}
int histSize = policyConfig.getPwdInHistory();
Modification pwdRemHistMod = null;
Modification pwdAddHistMod = null;
String pwdChangedTime = DateUtils.getGeneralizedTime();
if ( histSize > 0 )
{
Attribute pwdHistoryAt = entry.get( PWD_HISTORY_AT );
Set<PasswordHistory> pwdHistSet = new TreeSet<PasswordHistory>();
for ( Value<?> value : pwdHistoryAt )
{
PasswordHistory pwdh = new PasswordHistory( Strings.utf8ToString( value.getBytes() ) );
boolean matched = Arrays.equals( newPassword, pwdh.getPassword() );
if ( matched )
{
if ( isPPolicyReqCtrlPresent )
{
PasswordPolicyDecorator responseControl =
new PasswordPolicyDecorator( directoryService.getLdapCodecService(), true );
responseControl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.PASSWORD_IN_HISTORY );
modifyContext.addResponseControl( responseControl );
}
throw new LdapOperationException( ResultCodeEnum.CONSTRAINT_VIOLATION,
"invalid reuse of password present in password history" );
}
pwdHistSet.add( pwdh );
}
PasswordHistory newPwdHist = new PasswordHistory( pwdChangedTime, newPassword );
pwdHistSet.add( newPwdHist );
pwdHistoryAt = new DefaultAttribute( pwdHistoryAt.getAttributeType() );
pwdHistoryAt.add( newPwdHist.getHistoryValue() );
pwdAddHistMod = new DefaultModification( ADD_ATTRIBUTE, pwdHistoryAt );
if ( pwdHistSet.size() > histSize )
{
pwdHistoryAt = new DefaultAttribute( pwdHistoryAt.getAttributeType() );
PasswordHistory remPwdHist = ( PasswordHistory ) pwdHistSet.toArray()[histSize - 1];
pwdHistoryAt.add( remPwdHist.getHistoryValue() );
pwdRemHistMod = new DefaultModification( REMOVE_ATTRIBUTE, pwdHistoryAt );
}
}
next.modify( modifyContext );
invalidateAuthenticatorCaches( modifyContext.getDn() );
List<Modification> mods = new ArrayList<Modification>();
if ( ( policyConfig.getPwdMinAge() > 0 ) || ( policyConfig.getPwdMaxAge() > 0 ) )
{
Attribute pwdChangedTimeAt = new DefaultAttribute( AT_PWD_CHANGED_TIME );
pwdChangedTimeAt.add( pwdChangedTime );
Modification pwdChangedTimeMod = new DefaultModification( REPLACE_ATTRIBUTE, pwdChangedTimeAt );
mods.add( pwdChangedTimeMod );
}
if ( pwdAddHistMod != null )
{
mods.add( pwdAddHistMod );
}
if ( pwdRemHistMod != null )
{
mods.add( pwdRemHistMod );
}
boolean removeFromPwdResetSet = false;
if ( policyConfig.isPwdMustChange() )
{
Attribute pwdMustChangeAt = new DefaultAttribute( AT_PWD_RESET );
Modification pwdMustChangeMod = null;
if ( modifyContext.getSession().isAnAdministrator() )