You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2011/11/12 19:24:43 UTC
svn commit: r1201297 [5/9] - in /directory/apacheds/branches/apacheds-txns:
all/ apache-felix/ core-annotations/ core-api/
core-api/src/main/java/org/apache/directory/server/core/api/
core-api/src/main/java/org/apache/directory/server/core/api/intercep...
Modified: directory/apacheds/branches/apacheds-txns/interceptors/admin/src/main/java/org/apache/directory/server/core/admin/AdministrativePointInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/interceptors/admin/src/main/java/org/apache/directory/server/core/admin/AdministrativePointInterceptor.java?rev=1201297&r1=1201296&r2=1201297&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/interceptors/admin/src/main/java/org/apache/directory/server/core/admin/AdministrativePointInterceptor.java (original)
+++ directory/apacheds/branches/apacheds-txns/interceptors/admin/src/main/java/org/apache/directory/server/core/admin/AdministrativePointInterceptor.java Sat Nov 12 18:24:38 2011
@@ -34,6 +34,7 @@ import org.apache.directory.server.const
import org.apache.directory.server.core.shared.DefaultCoreSession;
import org.apache.directory.server.core.api.CoreSession;
import org.apache.directory.server.core.api.DirectoryService;
+import org.apache.directory.server.core.api.InterceptorEnum;
import org.apache.directory.server.core.api.LdapPrincipal;
import org.apache.directory.server.core.api.administrative.AccessControlAAP;
import org.apache.directory.server.core.api.administrative.AccessControlAdministrativePoint;
@@ -54,8 +55,6 @@ import org.apache.directory.server.core.
import org.apache.directory.server.core.api.entry.ClonedServerEntry;
import org.apache.directory.server.core.api.filtering.EntryFilteringCursor;
import org.apache.directory.server.core.api.interceptor.BaseInterceptor;
-import org.apache.directory.server.core.api.interceptor.Interceptor;
-import org.apache.directory.server.core.api.interceptor.NextInterceptor;
import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext;
import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext;
@@ -184,6 +183,16 @@ public class AdministrativePointIntercep
/** A lock to guarantee the AP cache consistency */
private ReentrantReadWriteLock mutex = new ReentrantReadWriteLock();
+
+ /**
+ * Creates a new instance of a AdministrativePointInterceptor.
+ */
+ public AdministrativePointInterceptor()
+ {
+ super( InterceptorEnum.ADMINISTRATIVE_POINT_INTERCEPTOR );
+ }
+
+
/**
* Get a read-lock on the AP cache.
* No read operation can be done on the AP cache if this
@@ -247,7 +256,7 @@ public class AdministrativePointIntercep
SubschemaAdministrativePoint ssAap = new SubschemaAAP( dn, uuid );
directoryService.getSubschemaAPCache().add( dn, ssAap );
- // TODO : Here, we have to update the children, removing any
+ // TODO : Here, we have to update the children, removing any
// reference to any other underlying AP
// If it's an AAP, we can get out immediately
@@ -264,8 +273,8 @@ public class AdministrativePointIntercep
AccessControlAdministrativePoint sap = new AccessControlSAP( dn, uuid );
directoryService.getAccessControlAPCache().add( dn, sap );
- // TODO : Here, we have to update the children, removing any
- // reference to any other underlying AccessControl IAP or SAP
+ // TODO : Here, we have to update the children, removing any
+ // reference to any other underlying AccessControl IAP or SAP
continue;
}
@@ -284,9 +293,9 @@ public class AdministrativePointIntercep
CollectiveAttributeAdministrativePoint sap = new CollectiveAttributeSAP( dn, uuid );
directoryService.getCollectiveAttributeAPCache().add( dn, sap );
- // TODO : Here, we have to update the children, removing any
- // reference to any other underlying CollectiveAttribute IAP or SAP
-
+ // TODO : Here, we have to update the children, removing any
+ // reference to any other underlying CollectiveAttribute IAP or SAP
+
continue;
}
@@ -304,8 +313,8 @@ public class AdministrativePointIntercep
SubschemaAdministrativePoint sap = new SubschemaSAP( dn, uuid );
directoryService.getSubschemaAPCache().add( dn, sap );
- // TODO : Here, we have to update the children, removing any
- // reference to any other underlying Subschema IAP or SAP
+ // TODO : Here, we have to update the children, removing any
+ // reference to any other underlying Subschema IAP or SAP
continue;
}
@@ -316,9 +325,9 @@ public class AdministrativePointIntercep
TriggerExecutionAdministrativePoint sap = new TriggerExecutionSAP( dn, uuid );
directoryService.getTriggerExecutionAPCache().add( dn, sap );
- // TODO : Here, we have to update the children, removing any
+ // TODO : Here, we have to update the children, removing any
// reference to any other underlying TriggerExecution IAP or SAP
-
+
continue;
}
@@ -360,7 +369,7 @@ public class AdministrativePointIntercep
// The SS AAP
SubschemaAdministrativePoint ssAap = new SubschemaAAP( dn, uuid );
ssapCache.add( dn, ssAap );
-
+
// If it's an AAP, we can get out immediately
return;
}
@@ -450,7 +459,7 @@ public class AdministrativePointIntercep
// The SS AAP
ssapCache.remove( dn );
-
+
return;
}
@@ -487,7 +496,7 @@ public class AdministrativePointIntercep
}
}
-
+
private AdministrativePoint getParent( AdministrativePoint ap, List<AdministrativePoint> aps,
AdministrativeRole role, DnNode<List<AdministrativePoint>> currentNode )
{
@@ -525,7 +534,7 @@ public class AdministrativePointIntercep
/**
* Find the parent for the given administrative point. If the AP is an AAP, the parent will be the closest
- * AAP or the closest SAP. If we have a SAP between the added AAP and a AAP, then
+ * AAP or the closest SAP. If we have a SAP between the added AAP and a AAP, then
*/
private AdministrativePoint findParent( AdministrativePoint ap, DnNode<List<AdministrativePoint>> currentNode )
{
@@ -612,7 +621,7 @@ public class AdministrativePointIntercep
throw new LdapUnwillingToPerformException( message );
}
- // If we are trying to add an AAP, we have to check that
+ // If we are trying to add an AAP, we have to check that
// it's the only role in the AdminPoint AT
if ( isAutonomousAreaRole( roleStr ) )
{
@@ -629,7 +638,7 @@ public class AdministrativePointIntercep
return;
}
}
-
+
// Check that we don't have already an AAP in the AdminPoint AT when we try to
// add a role
if ( adminPoint.contains( SchemaConstants.AUTONOMOUS_AREA ) )
@@ -667,24 +676,24 @@ public class AdministrativePointIntercep
throw new LdapUnwillingToPerformException( message );
}
- // Now we are trying to delete an Administrative point. We have to check that
+ // Now we are trying to delete an Administrative point. We have to check that
// we only have one role if the deleted role is an AAP
if ( isAutonomousAreaRole( roleStr ) )
{
- // We know have to check that removing the AAP, we will not
+ // We know have to check that removing the AAP, we will not
// left any pending IAP. We should check for the 3 potential IAPs :
// AccessControl, CollectiveAttribute and TriggerExecution.
// If the removed AP has a parent, no need to go any further :
// the children IAPs will depend on this parent.
-
+
// Process the ACs
DnNode<AccessControlAdministrativePoint> acAps = directoryService.getAccessControlAPCache();
-
+
if ( !acAps.hasParent( dn ) )
{
// No parent, check for any IAP
List<AccessControlAdministrativePoint> children = acAps.getDescendantElements( dn );
-
+
for ( AccessControlAdministrativePoint child : children )
{
if ( child.isInner() )
@@ -696,15 +705,15 @@ public class AdministrativePointIntercep
}
}
}
-
+
// Process the CAs
DnNode<CollectiveAttributeAdministrativePoint> caAps = directoryService.getCollectiveAttributeAPCache();
-
+
if ( !acAps.hasParent( dn ) )
{
// No parent, check for any IAP
List<CollectiveAttributeAdministrativePoint> children = caAps.getDescendantElements( dn );
-
+
for ( CollectiveAttributeAdministrativePoint child : children )
{
if ( child.isInner() )
@@ -716,15 +725,15 @@ public class AdministrativePointIntercep
}
}
}
-
+
// Process the TEs
DnNode<TriggerExecutionAdministrativePoint> teAps = directoryService.getTriggerExecutionAPCache();
-
+
if ( !acAps.hasParent( dn ) )
{
// No parent, check for any IAP
List<TriggerExecutionAdministrativePoint> children = teAps.getDescendantElements( dn );
-
+
for ( TriggerExecutionAdministrativePoint child : children )
{
if ( child.isInner() )
@@ -740,14 +749,6 @@ public class AdministrativePointIntercep
}
- /**
- * Creates an Administrative service interceptor.
- */
- public AdministrativePointInterceptor()
- {
- }
-
-
//-------------------------------------------------------------------------------------------
// Helper methods
//-------------------------------------------------------------------------------------------
@@ -783,7 +784,7 @@ public class AdministrativePointIntercep
entries.add( entry );
}
-
+
results.close();
}
catch ( Exception e )
@@ -826,11 +827,10 @@ public class AdministrativePointIntercep
/**
* Update The Administrative Points cache, removing the given AdminPoint
*/
- private void deleteAdminPointCache( Attribute adminPoint, DeleteOperationContext deleteContext )
- throws LdapException
+ private void deleteAdminPointCache( Attribute adminPoint, DeleteOperationContext deleteContext ) throws LdapException
{
Dn dn = deleteContext.getDn();
-
+
// Remove the APs in the AP cache
for ( Value<?> value : adminPoint )
{
@@ -897,7 +897,7 @@ public class AdministrativePointIntercep
private boolean isAccessControlInnerRole( String role )
{
return role.equalsIgnoreCase( SchemaConstants.ACCESS_CONTROL_INNER_AREA ) ||
- role.equals( SchemaConstants.ACCESS_CONTROL_INNER_AREA_OID );
+ role.equals( SchemaConstants.ACCESS_CONTROL_INNER_AREA_OID );
}
@@ -907,7 +907,7 @@ public class AdministrativePointIntercep
private boolean isAccessControlSpecificRole( String role )
{
return role.equalsIgnoreCase( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA ) ||
- role.equals( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA_OID );
+ role.equals( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA_OID );
}
@@ -917,7 +917,7 @@ public class AdministrativePointIntercep
private boolean isCollectiveAttributeInnerRole( String role )
{
return role.equalsIgnoreCase( SchemaConstants.COLLECTIVE_ATTRIBUTE_INNER_AREA ) ||
- role.equals( SchemaConstants.COLLECTIVE_ATTRIBUTE_INNER_AREA_OID );
+ role.equals( SchemaConstants.COLLECTIVE_ATTRIBUTE_INNER_AREA_OID );
}
@@ -927,7 +927,7 @@ public class AdministrativePointIntercep
private boolean isCollectiveAttributeSpecificRole( String role )
{
return role.equalsIgnoreCase( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA ) ||
- role.equals( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA_OID );
+ role.equals( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA_OID );
}
@@ -937,7 +937,7 @@ public class AdministrativePointIntercep
private boolean isTriggerExecutionInnerRole( String role )
{
return role.equalsIgnoreCase( SchemaConstants.TRIGGER_EXECUTION_INNER_AREA ) ||
- role.equals( SchemaConstants.TRIGGER_EXECUTION_INNER_AREA_OID );
+ role.equals( SchemaConstants.TRIGGER_EXECUTION_INNER_AREA_OID );
}
@@ -947,7 +947,7 @@ public class AdministrativePointIntercep
private boolean isTriggerExecutionSpecificRole( String role )
{
return role.equalsIgnoreCase( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA ) ||
- role.equals( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA_OID );
+ role.equals( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA_OID );
}
@@ -957,7 +957,7 @@ public class AdministrativePointIntercep
private boolean isSubschemaSpecficRole( String role )
{
return role.equalsIgnoreCase( SchemaConstants.SUB_SCHEMA_ADMIN_SPECIFIC_AREA ) ||
- role.equals( SchemaConstants.SUB_SCHEMA_ADMIN_SPECIFIC_AREA_OID );
+ role.equals( SchemaConstants.SUB_SCHEMA_ADMIN_SPECIFIC_AREA_OID );
}
@@ -967,7 +967,7 @@ public class AdministrativePointIntercep
private boolean isAutonomousAreaRole( String role )
{
return role.equalsIgnoreCase( SchemaConstants.AUTONOMOUS_AREA ) ||
- role.equals( SchemaConstants.AUTONOMOUS_AREA_OID );
+ role.equals( SchemaConstants.AUTONOMOUS_AREA_OID );
}
@@ -984,7 +984,7 @@ public class AdministrativePointIntercep
private boolean hasAccessControlSpecificRole( Attribute adminPoint )
{
return adminPoint.contains( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA ) ||
- adminPoint.contains( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA_OID );
+ adminPoint.contains( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA_OID );
}
@@ -997,14 +997,14 @@ public class AdministrativePointIntercep
private boolean hasCollectiveAttributeSpecificRole( Attribute adminPoint )
{
return adminPoint.contains( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA ) ||
- adminPoint.contains( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA_OID );
+ adminPoint.contains( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA_OID );
}
private boolean hasTriggerExecutionSpecificRole( Attribute adminPoint )
{
return adminPoint.contains( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA ) ||
- adminPoint.contains( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA_OID );
+ adminPoint.contains( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA_OID );
}
@@ -1067,16 +1067,15 @@ public class AdministrativePointIntercep
* Check that the IAPs (if any) have a parent. We will check for each kind or role :
* AC, CA and TE.
*/
- private void checkIAPHasParent( String role, Attribute adminPoint, Dn dn )
- throws LdapUnwillingToPerformException
+ private void checkIAPHasParent( String role, Attribute adminPoint, Dn dn ) throws LdapUnwillingToPerformException
{
// Check for the AC role
if ( isAccessControlInnerRole( role ) )
{
DnNode<AccessControlAdministrativePoint> acCache = directoryService.getAccessControlAPCache();
-
+
DnNode<AccessControlAdministrativePoint> parent = acCache.getNode( dn );
-
+
if ( parent == null )
{
// We don't have any AC administrativePoint in the tree, this is an error
@@ -1088,9 +1087,9 @@ public class AdministrativePointIntercep
else if ( isCollectiveAttributeInnerRole( role ) )
{
DnNode<CollectiveAttributeAdministrativePoint> caCache = directoryService.getCollectiveAttributeAPCache();
-
+
boolean hasAP = caCache.hasParentElement( dn );
-
+
if ( !hasAP )
{
// We don't have any AC administrativePoint in the tree, this is an error
@@ -1102,9 +1101,9 @@ public class AdministrativePointIntercep
else if ( isTriggerExecutionInnerRole( role ) )
{
DnNode<TriggerExecutionAdministrativePoint> caCache = directoryService.getTriggerExecutionAPCache();
-
+
DnNode<TriggerExecutionAdministrativePoint> parent = caCache.getNode( dn );
-
+
if ( parent == null )
{
// We don't have any AC administrativePoint in the tree, this is an error
@@ -1148,7 +1147,7 @@ public class AdministrativePointIntercep
// get the list of all the AAPs
List<Entry> administrativePoints = getAdministrativePoints();
-
+
lockWrite();
addAdminPointCache( administrativePoints );
unlock();
@@ -1181,12 +1180,11 @@ public class AdministrativePointIntercep
* <ul>
* <li>If it's an AA, then the added role should be the only one</li>
* <li>It's not possible to add IA and SA at the same time</li>
- *
- * @param next The next {@link Interceptor} in the chain
* @param addContext The {@link AddOperationContext} instance
+ *
* @throws LdapException If we had some error while processing the Add operation
*/
- public void add( NextInterceptor next, AddOperationContext addContext ) throws LdapException
+ public void add( AddOperationContext addContext ) throws LdapException
{
LOG.debug( ">>> Entering into the Administrative Interceptor, addRequest" );
Entry entry = addContext.getEntry();
@@ -1198,7 +1196,7 @@ public class AdministrativePointIntercep
if ( adminPoint == null )
{
// Nope, go on.
- next.add( addContext );
+ next( addContext );
LOG.debug( "Exit from Administrative Interceptor, no AP in the added entry" );
@@ -1209,7 +1207,7 @@ public class AdministrativePointIntercep
// Protect the AP caches against concurrent access
lockWrite();
-
+
// Loop on all the added roles to check if they are valid
for ( Value<?> role : adminPoint )
{
@@ -1217,7 +1215,7 @@ public class AdministrativePointIntercep
}
// Ok, we are golden.
- next.add( addContext );
+ next( addContext );
String apUuid = entry.get( ENTRY_UUID_AT ).getString();
@@ -1226,7 +1224,7 @@ public class AdministrativePointIntercep
// Release the APCaches lock
unlock();
-
+
LOG.debug( "Added an Administrative Point at {}", dn );
return;
@@ -1234,11 +1232,11 @@ public class AdministrativePointIntercep
/**
- * We have to check that we can remove the associated AdministrativePoint : <br/>
+ * We have to check that we can remove the associated AdministrativePoint : <br/>
* <ul>
* <li> if we remove an AAP, no descendant IAP should remain orphan</li>
* <li> If we remove a SAP, no descendant IAP should remain orphan</li>
- * </ul>
+ * </ul>
* {@inheritDoc}
*/
public void delete( DeleteOperationContext deleteContext ) throws LdapException
@@ -1261,10 +1259,10 @@ public class AdministrativePointIntercep
}
LOG.debug( "Deletion of an administrative point at {} for the role {}", dn, adminPoint );
-
+
// Protect the AP caches against concurrent access
lockWrite();
-
+
// Check that the removed AdministrativeRoles are valid. We don't have to do
// any other check, as the deleted entry has no children.
for ( Value<?> role : adminPoint )
@@ -1285,7 +1283,7 @@ public class AdministrativePointIntercep
// Release the APCaches lock
unlock();
-
+
LOG.debug( "Deleted an Administrative Point at {}", dn );
return;
@@ -1303,7 +1301,7 @@ public class AdministrativePointIntercep
*
* {@inheritDoc}
*/
- public void modify( NextInterceptor next, ModifyOperationContext modifyContext ) throws LdapException
+ public void modify( ModifyOperationContext modifyContext ) throws LdapException
{
LOG.debug( ">>> Entering into the Administrative Interceptor, modifyRequest" );
// We have to check that the modification is acceptable
@@ -1329,7 +1327,7 @@ public class AdministrativePointIntercep
DnNode<CollectiveAttributeAdministrativePoint> caapCacheCopy = directoryService.getCollectiveAttributeAPCache().clone();
DnNode<TriggerExecutionAdministrativePoint> teapCacheCopy = directoryService.getTriggerExecutionAPCache().clone();
DnNode<SubschemaAdministrativePoint> ssapCacheCopy = directoryService.getSubschemaAPCache().clone();
-
+
// Loop on the modification to select the AdministrativeRole and process it :
// we will create a new AT containing all the roles after having applied the modifications
// on it
@@ -1425,14 +1423,14 @@ public class AdministrativePointIntercep
// At this point, we have a new AdministrativeRole AT, and we need to get the lists of
// added roles and removed roles, in order to process them
- next.modify( modifyContext );
+ next( modifyContext );
}
/**
* {@inheritDoc}
*/
- public void move( NextInterceptor next, MoveOperationContext moveContext ) throws LdapException
+ public void move( MoveOperationContext moveContext ) throws LdapException
{
LOG.debug( ">>> Entering into the Administrative Interceptor, moveRequest" );
Entry entry = moveContext.getOriginalEntry();
@@ -1443,7 +1441,7 @@ public class AdministrativePointIntercep
if ( adminPoint == null )
{
// Nope, go on.
- next.move( moveContext );
+ next( moveContext );
LOG.debug( "Exit from Administrative Interceptor" );
@@ -1460,8 +1458,7 @@ public class AdministrativePointIntercep
/**
* {@inheritDoc}
*/
- public void moveAndRename( NextInterceptor next, MoveAndRenameOperationContext moveAndRenameContext )
- throws LdapException
+ public void moveAndRename( MoveAndRenameOperationContext moveAndRenameContext ) throws LdapException
{
LOG.debug( ">>> Entering into the Administrative Interceptor, moveAndRenameRequest" );
Entry entry = moveAndRenameContext.getOriginalEntry();
@@ -1472,7 +1469,7 @@ public class AdministrativePointIntercep
if ( adminPoint == null )
{
// Nope, go on.
- next.moveAndRename( moveAndRenameContext );
+ next( moveAndRenameContext );
LOG.debug( "Exit from Administrative Interceptor" );
@@ -1489,7 +1486,7 @@ public class AdministrativePointIntercep
/**
* {@inheritDoc}
*/
- public void rename( NextInterceptor next, RenameOperationContext renameContext ) throws LdapException
+ public void rename( RenameOperationContext renameContext ) throws LdapException
{
LOG.debug( ">>> Entering into the Administrative Interceptor, renameRequest" );
Entry entry = renameContext.getEntry();
@@ -1500,7 +1497,7 @@ public class AdministrativePointIntercep
if ( adminPoint == null )
{
// Nope, go on.
- next.rename( renameContext );
+ next( renameContext );
LOG.debug( "Exit from Administrative Interceptor" );
Propchange: directory/apacheds/branches/apacheds-txns/interceptors/authn/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Nov 12 18:24:38 2011
@@ -1 +1 @@
-/directory/apacheds/trunk/interceptors/authn:1183435-1200383
+/directory/apacheds/trunk/interceptors/authn:1183435-1201283
Modified: directory/apacheds/branches/apacheds-txns/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AbstractAuthenticator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AbstractAuthenticator.java?rev=1201297&r1=1201296&r2=1201297&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AbstractAuthenticator.java (original)
+++ directory/apacheds/branches/apacheds-txns/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AbstractAuthenticator.java Sat Nov 12 18:24:38 2011
@@ -6,16 +6,16 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
- * under the License.
- *
+ * under the License.
+ *
*/
package org.apache.directory.server.core.authn;
@@ -32,6 +32,7 @@ import static org.apache.directory.share
import java.util.Date;
import org.apache.directory.server.core.api.DirectoryService;
+import org.apache.directory.server.core.api.InterceptorEnum;
import org.apache.directory.server.core.api.authn.ppolicy.PasswordPolicyConfiguration;
import org.apache.directory.server.core.api.authn.ppolicy.PasswordPolicyException;
import org.apache.directory.shared.ldap.model.constants.AuthenticationLevel;
@@ -116,7 +117,7 @@ public abstract class AbstractAuthentica
/**
* Calls {@link #doDestroy()} method, and clears default properties
* (<tt>factoryConfiguration</tt> and <tt>configuration</tt>).
- * Please put your deinitialization code into {@link #doDestroy()}.
+ * Please put your deinitialization code into {@link #doDestroy()}.
*/
public final void destroy()
{
@@ -157,7 +158,8 @@ public abstract class AbstractAuthentica
return;
}
- AuthenticationInterceptor authenticationInterceptor = (AuthenticationInterceptor)directoryService.getInterceptor( AuthenticationInterceptor.class.getSimpleName() );
+ AuthenticationInterceptor authenticationInterceptor = (AuthenticationInterceptor)directoryService.getInterceptor(
+ InterceptorEnum.AUTHENTICATION_INTERCEPTOR.getName() );
PasswordPolicyConfiguration pPolicyConfig = authenticationInterceptor.getPwdPolicy( userEntry );
// check for locked out account
@@ -203,7 +205,7 @@ public abstract class AbstractAuthentica
if( System.currentTimeMillis() < pwdStartTime.getTime() )
{
- throw new PasswordPolicyException( "account is locked, will be activated after " + pwdStartTime, ACCOUNT_LOCKED.getValue() );
+ throw new PasswordPolicyException( "account is locked, will be activated after " + pwdStartTime, ACCOUNT_LOCKED.getValue() );
}
}
Modified: directory/apacheds/branches/apacheds-txns/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java?rev=1201297&r1=1201296&r2=1201297&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java (original)
+++ directory/apacheds/branches/apacheds-txns/interceptors/authn/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java Sat Nov 12 18:24:38 2011
@@ -43,20 +43,21 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.apache.directory.server.core.shared.DefaultCoreSession;
import org.apache.directory.server.core.api.CoreSession;
import org.apache.directory.server.core.api.DirectoryService;
+import org.apache.directory.server.core.api.InterceptorEnum;
import org.apache.directory.server.core.api.LdapPrincipal;
+import org.apache.directory.server.core.api.authn.ppolicy.PasswordPolicyConfiguration;
+import org.apache.directory.server.core.api.authn.ppolicy.PasswordPolicyException;
import org.apache.directory.server.core.api.filtering.EntryFilteringCursor;
import org.apache.directory.server.core.api.interceptor.BaseInterceptor;
import org.apache.directory.server.core.api.interceptor.Interceptor;
-import org.apache.directory.server.core.api.interceptor.NextInterceptor;
import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
import org.apache.directory.server.core.api.interceptor.context.BindOperationContext;
import org.apache.directory.server.core.api.interceptor.context.CompareOperationContext;
import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext;
-import org.apache.directory.server.core.api.interceptor.context.EntryOperationContext;
-import org.apache.directory.server.core.api.interceptor.context.GetRootDSEOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.HasEntryOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.GetRootDseOperationContext;
import org.apache.directory.server.core.api.interceptor.context.ListOperationContext;
import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext;
@@ -66,9 +67,8 @@ import org.apache.directory.server.core.
import org.apache.directory.server.core.api.interceptor.context.RenameOperationContext;
import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
import org.apache.directory.server.core.api.interceptor.context.UnbindOperationContext;
-import org.apache.directory.server.core.api.authn.ppolicy.PasswordPolicyConfiguration;
-import org.apache.directory.server.core.api.authn.ppolicy.PasswordPolicyException;
import org.apache.directory.server.core.authn.ppolicy.PpolicyConfigContainer;
+import org.apache.directory.server.core.shared.DefaultCoreSession;
import org.apache.directory.server.i18n.I18n;
import org.apache.directory.shared.ldap.extras.controls.ppolicy.PasswordPolicy;
import org.apache.directory.shared.ldap.extras.controls.ppolicy.PasswordPolicyErrorEnum;
@@ -177,6 +177,7 @@ public class AuthenticationInterceptor e
*/
public AuthenticationInterceptor()
{
+ super( InterceptorEnum.AUTHENTICATION_INTERCEPTOR );
}
@@ -323,7 +324,10 @@ public class AuthenticationInterceptor e
}
- public void add( NextInterceptor next, AddOperationContext addContext ) throws LdapException
+ /**
+ * {@inheritDoc}
+ */
+ public void add( AddOperationContext addContext ) throws LdapException
{
if ( IS_DEBUG )
{
@@ -337,7 +341,7 @@ public class AuthenticationInterceptor e
if ( !directoryService.isPwdPolicyEnabled() )
{
- next.add( addContext );
+ next( addContext );
return;
}
@@ -397,365 +401,305 @@ public class AuthenticationInterceptor e
}
}
- next.add( addContext );
- }
-
-
- public void delete( DeleteOperationContext deleteContext ) throws LdapException
- {
- if ( IS_DEBUG )
- {
- LOG.debug( "Operation Context: {}", deleteContext );
- }
-
- checkAuthenticated( deleteContext );
- checkPwdReset( deleteContext );
- next( deleteContext );
- invalidateAuthenticatorCaches( deleteContext.getDn() );
+ next( addContext );
}
/**
* {@inheritDoc}
*/
- public Entry getRootDSE( GetRootDSEOperationContext getRootDseContext ) throws LdapException
+ public void bind( BindOperationContext bindContext ) throws LdapException
{
if ( IS_DEBUG )
{
- LOG.debug( "Operation Context: {}", getRootDseContext );
+ LOG.debug( "Operation Context: {}", bindContext );
}
- checkAuthenticated( getRootDseContext );
- checkPwdReset( getRootDseContext );
-
- return next( getRootDseContext );
- }
+ if ( ( bindContext.getSession() != null ) && ( bindContext.getSession().getEffectivePrincipal() != null ) )
+ {
+ // null out the credentials
+ bindContext.setCredentials( null );
+ }
+ // pick the first matching authenticator type
+ AuthenticationLevel level = bindContext.getAuthenticationLevel();
- /**
- * {@inheritDoc}
- */
- public boolean hasEntry( EntryOperationContext hasEntryContext ) throws LdapException
- {
- if ( IS_DEBUG )
+ if ( level == AuthenticationLevel.UNAUTHENT )
{
- LOG.debug( "Operation Context: {}", hasEntryContext );
+ // This is a case where the Bind request contains a Dn, but no password.
+ // We don't check the Dn, we just return a UnwillingToPerform error
+ // Cf RFC 4513, chap. 5.1.2
+ throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, "Cannot Bind for Dn "
+ + bindContext.getDn().getName() );
}
- checkAuthenticated( hasEntryContext );
- checkPwdReset( hasEntryContext );
+ Collection<Authenticator> authenticators = getAuthenticators( level );
- return next( hasEntryContext );
- }
+ if ( authenticators == null )
+ {
+ LOG.debug( "No authenticators found, delegating bind to the nexus." );
+ // as a last resort try binding via the nexus
+ next( bindContext );
- /**
- * {@inheritDoc}
- */
- public EntryFilteringCursor list( ListOperationContext listContext ) throws LdapException
- {
- if ( IS_DEBUG )
- {
- LOG.debug( "Operation Context: {}", listContext );
- }
+ LOG.debug( "Nexus succeeded on bind operation." );
- checkAuthenticated( listContext );
- checkPwdReset( listContext );
+ // bind succeeded if we got this far
+ // TODO - authentication level not being set
+ LdapPrincipal principal = new LdapPrincipal( schemaManager, bindContext.getDn(), AuthenticationLevel.SIMPLE );
+ CoreSession session = new DefaultCoreSession( principal, directoryService );
+ bindContext.setSession( session );
- return next( listContext );
- }
+ // remove creds so there is no security risk
+ bindContext.setCredentials( null );
+ return;
+ }
+ boolean isPPolicyReqCtrlPresent = bindContext.hasRequestControl( PasswordPolicy.OID );
+ PasswordPolicyDecorator pwdRespCtrl =
+ new PasswordPolicyDecorator( directoryService.getLdapCodecService(), true );
- public Entry lookup( LookupOperationContext lookupContext ) throws LdapException
- {
- if ( IS_DEBUG )
+ boolean authenticated = false;
+ PasswordPolicyException ppe = null;
+
+ // TODO : we should refactor that.
+ // try each authenticator
+ for ( Authenticator authenticator : authenticators )
{
- LOG.debug( "Operation Context: {}", lookupContext );
- }
+ try
+ {
+ // perform the authentication
+ LdapPrincipal principal = authenticator.authenticate( bindContext );
- checkAuthenticated( lookupContext );
- checkPwdReset( lookupContext );
+ LdapPrincipal clonedPrincipal = ( LdapPrincipal ) ( principal.clone() );
- return next( lookupContext );
- }
+ // remove creds so there is no security risk
+ bindContext.setCredentials( null );
+ clonedPrincipal.setUserPassword( StringConstants.EMPTY_BYTES );
+ // authentication was successful
+ CoreSession session = new DefaultCoreSession( clonedPrincipal, directoryService );
+ bindContext.setSession( session );
- private void invalidateAuthenticatorCaches( Dn principalDn )
- {
- for ( AuthenticationLevel authMech : authenticatorsMapByType.keySet() )
- {
- Collection<Authenticator> authenticators = getAuthenticators( authMech );
+ authenticated = true;
- // try each authenticator
- for ( Authenticator authenticator : authenticators )
+ // break out of the loop if the authentication succeeded
+ break;
+ }
+ catch ( PasswordPolicyException e )
{
- authenticator.invalidateCache( principalDn );
+ ppe = e;
+ break;
+ }
+ catch ( LdapAuthenticationException e )
+ {
+ // authentication failed, try the next authenticator
+ if ( LOG.isInfoEnabled() )
+ {
+ LOG.info( "Authenticator {} failed to authenticate: {}", authenticator, bindContext );
+ }
+ }
+ catch ( Exception e )
+ {
+ // Log other exceptions than LdapAuthenticationException
+ if ( LOG.isWarnEnabled() )
+ {
+ LOG.info( "Unexpected failure for Authenticator {} : {}", authenticator, bindContext );
+ }
}
}
- }
-
- public void modify( NextInterceptor next, ModifyOperationContext modifyContext ) throws LdapException
- {
- if ( IS_DEBUG )
+ if ( ppe != null )
{
- LOG.debug( "Operation Context: {}", modifyContext );
+ if ( isPPolicyReqCtrlPresent )
+ {
+ pwdRespCtrl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.get( ppe.getErrorCode() ) );
+ bindContext.addResponseControl( pwdRespCtrl );
+ }
+
+ throw ppe;
}
- checkAuthenticated( modifyContext );
+ Dn dn = bindContext.getDn();
+ Entry userEntry = bindContext.getEntry();
+ PasswordPolicyConfiguration policyConfig = getPwdPolicy( userEntry );
- if ( ! directoryService.isPwdPolicyEnabled() )
+ // check if the user entry is null, it will be null
+ // in cases of anonymous bind
+ if ( authenticated && ( userEntry == null ) && directoryService.isAllowAnonymousAccess() )
{
- next.modify( modifyContext );
- invalidateAuthenticatorCaches( modifyContext.getDn() );
return;
}
- // handle the case where pwdPolicySubentry AT is about to be deleted in thid modify()
- PasswordPolicyConfiguration policyConfig = getPwdPolicy( modifyContext.getEntry() );
-
- boolean isPPolicyReqCtrlPresent = modifyContext.hasRequestControl( PasswordPolicy.OID );
- Dn userDn = modifyContext.getSession().getAuthenticatedPrincipal().getDn();
-
- PwdModDetailsHolder pwdModDetails = null;
-
- pwdModDetails = getPwdModDetails( modifyContext, policyConfig );
-
- if ( pwdModDetails.isPwdModPresent() )
+ if ( !authenticated )
{
- if ( pwdResetSet.contains( userDn ) )
+ if ( LOG.isInfoEnabled() )
{
- 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();
- }
+ LOG.info( "Cannot bind to the server " );
}
- if ( policyConfig.isPwdSafeModify() )
+ if ( ( policyConfig != null ) && ( userEntry != null ) )
{
- 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 );
- }
+ Attribute pwdFailTimeAt = userEntry.get( PWD_FAILURE_TIME_AT );
- throw new LdapNoPermissionException();
+ if ( pwdFailTimeAt == null )
+ {
+ pwdFailTimeAt = new DefaultAttribute( AT_PWD_FAILURE_TIME );
}
- }
-
- if ( !policyConfig.isPwdAllowUserChange() && !modifyContext.getSession().isAnAdministrator() )
- {
- if ( isPPolicyReqCtrlPresent )
+ else
{
- PasswordPolicyDecorator responseControl =
- new PasswordPolicyDecorator( directoryService.getLdapCodecService(), true );
- responseControl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.PASSWORD_MOD_NOT_ALLOWED );
- modifyContext.addResponseControl( responseControl );
+ PasswordUtil.purgeFailureTimes( policyConfig, pwdFailTimeAt );
}
- throw new LdapNoPermissionException();
- }
+ String failureTime = DateUtils.getGeneralizedTime();
+ pwdFailTimeAt.add( failureTime );
+ Modification pwdFailTimeMod = new DefaultModification( ADD_ATTRIBUTE, pwdFailTimeAt );
- Entry entry = modifyContext.getEntry();
+ List<Modification> mods = new ArrayList<Modification>();
+ mods.add( pwdFailTimeMod );
- if ( isPwdTooYoung( entry, policyConfig ) )
- {
- if ( isPPolicyReqCtrlPresent )
+ int numFailures = pwdFailTimeAt.size();
+
+ if ( policyConfig.isPwdLockout() && ( numFailures >= policyConfig.getPwdMaxFailure() ) )
{
- PasswordPolicyDecorator responseControl =
- new PasswordPolicyDecorator( directoryService.getLdapCodecService(), true );
- responseControl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.PASSWORD_TOO_YOUNG );
- modifyContext.addResponseControl( responseControl );
- }
+ Attribute pwdAccountLockedTimeAt = new DefaultAttribute( AT_PWD_ACCOUNT_LOCKED_TIME );
- throw new LdapOperationException( ResultCodeEnum.CONSTRAINT_VIOLATION,
- "password is too young to update" );
- }
+ // if zero, lockout permanently, only admin can unlock it
+ if ( policyConfig.getPwdLockoutDuration() == 0 )
+ {
+ pwdAccountLockedTimeAt.add( "000001010000Z" );
+ }
+ else
+ {
+ pwdAccountLockedTimeAt.add( failureTime );
+ }
- byte[] newPassword = null;
+ Modification pwdAccountLockedMod = new DefaultModification( ADD_ATTRIBUTE, pwdAccountLockedTimeAt );
+ mods.add( pwdAccountLockedMod );
- if ( ( pwdModDetails != null ) )
- {
- newPassword = pwdModDetails.getNewPwd();
-
- try
- {
- String userName = entry.getDn().getRdn().getUpValue().getString();
- check( userName, newPassword, policyConfig );
+ pwdRespCtrl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.ACCOUNT_LOCKED );
}
- catch ( PasswordPolicyException e )
+ else if ( policyConfig.getPwdMinDelay() > 0 )
{
- if ( isPPolicyReqCtrlPresent )
+ int numDelay = numFailures * policyConfig.getPwdMinDelay();
+ int maxDelay = policyConfig.getPwdMaxDelay();
+ if ( numDelay > maxDelay )
{
- PasswordPolicyDecorator responseControl =
- new PasswordPolicyDecorator( directoryService.getLdapCodecService(), true );
- responseControl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.get( e.getErrorCode() ) );
- modifyContext.addResponseControl( responseControl );
+ numDelay = maxDelay;
}
- // 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 );
-
- if ( pwdHistoryAt == null )
- {
- pwdHistoryAt = new DefaultAttribute( AT_PWD_HISTORY );
- }
-
- List<PasswordHistory> pwdHistLst = new ArrayList<PasswordHistory>();
-
- for ( Value<?> value : pwdHistoryAt )
- {
- PasswordHistory pwdh = new PasswordHistory( Strings.utf8ToString( value.getBytes() ) );
-
- boolean matched = Arrays.equals( newPassword, pwdh.getPassword() );
-
- if ( matched )
+ try
{
- 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" );
+ Thread.sleep( numDelay * 1000 );
+ }
+ catch ( InterruptedException e )
+ {
+ LOG.warn(
+ "Interrupted while delaying to send the failed authentication response for the user {}",
+ dn, e );
}
-
- pwdHistLst.add( pwdh );
- }
-
- if ( pwdHistLst.size() >= histSize )
- {
- // see the javadoc of PasswordHistory
- Collections.sort( pwdHistLst );
-
- // remove the oldest value
- PasswordHistory remPwdHist = ( PasswordHistory ) pwdHistLst.toArray()[histSize - 1];
- Attribute tempAt = new DefaultAttribute( AT_PWD_HISTORY );
- tempAt.add( remPwdHist.getHistoryValue() );
- pwdRemHistMod = new DefaultModification( REMOVE_ATTRIBUTE, tempAt );
}
- pwdHistoryAt.clear();
- PasswordHistory newPwdHist = new PasswordHistory( pwdChangedTime, newPassword );
- pwdHistoryAt.clear();
- pwdHistoryAt.add( newPwdHist.getHistoryValue() );
- pwdAddHistMod = new DefaultModification( ADD_ATTRIBUTE, pwdHistoryAt );
+ //adminSession.modify( dn, Collections.singletonList( pwdFailTimeMod ) );
+ ModifyOperationContext bindModCtx = new ModifyOperationContext( adminSession );
+ bindModCtx.setDn( dn );
+ bindModCtx.setModItems( mods );
+ directoryService.getPartitionNexus().modify( bindModCtx );
}
- next.modify( modifyContext );
-
- invalidateAuthenticatorCaches( modifyContext.getDn() );
-
+ String upDn = ( dn == null ? "" : dn.getName() );
+ throw new LdapAuthenticationException( I18n.err( I18n.ERR_229, upDn ) );
+ }
+ else if ( policyConfig != null )
+ {
List<Modification> mods = new ArrayList<Modification>();
- if ( ( policyConfig.getPwdMinAge() > 0 ) || ( policyConfig.getPwdMaxAge() > 0 ) )
+ if ( policyConfig.getPwdMaxIdle() > 0 )
{
- Attribute pwdChangedTimeAt = new DefaultAttribute( AT_PWD_CHANGED_TIME );
- pwdChangedTimeAt.add( pwdChangedTime );
- Modification pwdChangedTimeMod = new DefaultModification( REPLACE_ATTRIBUTE, pwdChangedTimeAt );
- mods.add( pwdChangedTimeMod );
+ Attribute pwdLastSuccesTimeAt = new DefaultAttribute( AT_PWD_LAST_SUCCESS );
+ pwdLastSuccesTimeAt.add( DateUtils.getGeneralizedTime() );
+ Modification pwdLastSuccesTimeMod = new DefaultModification( REPLACE_ATTRIBUTE, pwdLastSuccesTimeAt );
+ mods.add( pwdLastSuccesTimeMod );
}
- if ( pwdAddHistMod != null )
+ Attribute pwdFailTimeAt = userEntry.get( AT_PWD_FAILURE_TIME );
+
+ if ( pwdFailTimeAt != null )
{
- mods.add( pwdAddHistMod );
+ Modification pwdFailTimeMod = new DefaultModification( REMOVE_ATTRIBUTE, pwdFailTimeAt );
+ mods.add( pwdFailTimeMod );
}
- if ( pwdRemHistMod != null )
+ Attribute pwdAccLockedTimeAt = userEntry.get( AT_PWD_ACCOUNT_LOCKED_TIME );
+
+ if ( pwdAccLockedTimeAt != null )
{
- mods.add( pwdRemHistMod );
+ Modification pwdAccLockedTimeMod = new DefaultModification( REMOVE_ATTRIBUTE, pwdAccLockedTimeAt );
+ mods.add( pwdAccLockedTimeMod );
}
- boolean removeFromPwdResetSet = false;
-
- if ( policyConfig.isPwdMustChange() )
+ // checking the expiration time *after* performing authentication, do we need to care about millisecond precision?
+ if ( ( policyConfig.getPwdMaxAge() > 0 ) && ( policyConfig.getPwdGraceAuthNLimit() > 0 ) )
{
- Attribute pwdMustChangeAt = new DefaultAttribute( AT_PWD_RESET );
- Modification pwdMustChangeMod = null;
+ Attribute pwdChangeTimeAttr = userEntry.get( PWD_CHANGED_TIME_AT );
- if ( modifyContext.getSession().isAnAdministrator() )
- {
- pwdMustChangeAt.add( "TRUE" );
- pwdMustChangeMod = new DefaultModification( REPLACE_ATTRIBUTE, pwdMustChangeAt );
- }
- else
+ if ( pwdChangeTimeAttr != null )
{
- pwdMustChangeMod = new DefaultModification( REMOVE_ATTRIBUTE, pwdMustChangeAt );
- removeFromPwdResetSet = true;
- }
+ boolean expired = PasswordUtil.isPwdExpired( pwdChangeTimeAttr.getString(),
+ policyConfig.getPwdMaxAge() );
- mods.add( pwdMustChangeMod );
- }
+ if ( expired )
+ {
+ Attribute pwdGraceUseAttr = userEntry.get( PWD_GRACE_USE_TIME_AT );
+ int numGraceAuth = 0;
- Attribute pwdFailureTimeAt = entry.get( PWD_FAILURE_TIME_AT );
+ if ( pwdGraceUseAttr != null )
+ {
+ numGraceAuth = policyConfig.getPwdGraceAuthNLimit() - ( pwdGraceUseAttr.size() + 1 );
+ }
+ else
+ {
+ pwdGraceUseAttr = new DefaultAttribute( AT_PWD_GRACE_USE_TIME );
+ numGraceAuth = policyConfig.getPwdGraceAuthNLimit() - 1;
+ }
- if ( pwdFailureTimeAt != null )
- {
- mods.add( new DefaultModification( REMOVE_ATTRIBUTE, pwdFailureTimeAt ) );
- }
+ pwdRespCtrl.getResponse().setGraceAuthNsRemaining( numGraceAuth );
- Attribute pwdGraceUseTimeAt = entry.get( PWD_GRACE_USE_TIME_AT );
+ pwdGraceUseAttr.add( DateUtils.getGeneralizedTime() );
+ Modification pwdGraceUseMod = new DefaultModification( ADD_ATTRIBUTE, pwdGraceUseAttr );
+ mods.add( pwdGraceUseMod );
+ }
+ }
+ }
- if ( pwdGraceUseTimeAt != null )
+ if ( !mods.isEmpty() )
{
- mods.add( new DefaultModification( REMOVE_ATTRIBUTE, pwdGraceUseTimeAt ) );
+ //adminSession.modify( dn, mods );
+ ModifyOperationContext bindModCtx = new ModifyOperationContext( adminSession );
+ bindModCtx.setDn( dn );
+ bindModCtx.setModItems( mods );
+ directoryService.getPartitionNexus().modify( bindModCtx );
}
- directoryService.getAdminSession().modify( modifyContext.getDn(), mods );
-
- if ( removeFromPwdResetSet )
+ if ( isPPolicyReqCtrlPresent )
{
- pwdResetSet.remove( userDn );
- }
- }
- else
- {
- next.modify( modifyContext );
- invalidateAuthenticatorCaches( modifyContext.getDn() );
- }
- }
+ int expiryWarnTime = getPwdTimeBeforeExpiry( userEntry, policyConfig );
+ if ( expiryWarnTime > 0 )
+ {
+ pwdRespCtrl.getResponse().setTimeBeforeExpiration( expiryWarnTime );
+ }
- public void rename( NextInterceptor next, RenameOperationContext renameContext ) throws LdapException
- {
- if ( IS_DEBUG )
- {
- LOG.debug( "Operation Context: {}", renameContext );
- }
+ if ( isPwdMustReset( userEntry ) )
+ {
+ pwdRespCtrl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.CHANGE_AFTER_RESET );
+ pwdResetSet.add( dn );
+ }
- checkAuthenticated( renameContext );
- checkPwdReset( renameContext );
- next.rename( renameContext );
- invalidateAuthenticatorCaches( renameContext.getDn() );
+ bindContext.addResponseControl( pwdRespCtrl );
+ }
+ }
}
@@ -778,367 +722,430 @@ public class AuthenticationInterceptor e
}
- public void moveAndRename( NextInterceptor next, MoveAndRenameOperationContext moveAndRenameContext )
- throws LdapException
- {
+ /**
+ * {@inheritDoc}
+ */
+ public void delete( DeleteOperationContext deleteContext ) throws LdapException
+ {
if ( IS_DEBUG )
{
- LOG.debug( "Operation Context: {}", moveAndRenameContext );
+ LOG.debug( "Operation Context: {}", deleteContext );
}
- checkAuthenticated( moveAndRenameContext );
- checkPwdReset( moveAndRenameContext );
- next.moveAndRename( moveAndRenameContext );
- invalidateAuthenticatorCaches( moveAndRenameContext.getDn() );
- }
+ checkAuthenticated( deleteContext );
+ checkPwdReset( deleteContext );
+ next( deleteContext );
+ invalidateAuthenticatorCaches( deleteContext.getDn() );
+ }
/**
* {@inheritDoc}
*/
- public void move( NextInterceptor next, MoveOperationContext moveContext ) throws LdapException
+ public Entry getRootDse( GetRootDseOperationContext getRootDseContext ) throws LdapException
{
if ( IS_DEBUG )
{
- LOG.debug( "Operation Context: {}", moveContext );
+ LOG.debug( "Operation Context: {}", getRootDseContext );
}
- checkAuthenticated( moveContext );
- checkPwdReset( moveContext );
- next.move( moveContext );
- invalidateAuthenticatorCaches( moveContext.getDn() );
+ checkAuthenticated( getRootDseContext );
+ checkPwdReset( getRootDseContext );
+
+ return next( getRootDseContext );
}
- public EntryFilteringCursor search( NextInterceptor next, SearchOperationContext searchContext )
- throws LdapException
- {
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasEntry( HasEntryOperationContext hasEntryContext ) throws LdapException
+ {
if ( IS_DEBUG )
{
- LOG.debug( "Operation Context: {}", searchContext );
+ LOG.debug( "Operation Context: {}", hasEntryContext );
}
- checkAuthenticated( searchContext );
- checkPwdReset( searchContext );
+ checkAuthenticated( hasEntryContext );
+ checkPwdReset( hasEntryContext );
- return next.search( searchContext );
- }
+ return next( hasEntryContext );
+ }
/**
- * Check if the current operation has a valid PrincipalDN or not.
- *
- * @param operation the operation type
- * @throws Exception
+ * {@inheritDoc}
*/
- private void checkAuthenticated( OperationContext operation ) throws LdapException
+ public EntryFilteringCursor list( ListOperationContext listContext ) throws LdapException
{
- if ( operation.getSession().isAnonymous() && !directoryService.isAllowAnonymousAccess()
- && !operation.getDn().isEmpty() )
+ if ( IS_DEBUG )
{
- String msg = I18n.err( I18n.ERR_5, operation.getName() );
- LOG.error( msg );
- throw new LdapNoPermissionException( msg );
+ LOG.debug( "Operation Context: {}", listContext );
}
+
+ checkAuthenticated( listContext );
+ checkPwdReset( listContext );
+
+ return next( listContext );
}
- public void bind( BindOperationContext bindContext ) throws LdapException
+ /**
+ * {@inheritDoc}
+ */
+ public Entry lookup( LookupOperationContext lookupContext ) throws LdapException
{
if ( IS_DEBUG )
{
- LOG.debug( "Operation Context: {}", bindContext );
+ LOG.debug( "Operation Context: {}", lookupContext );
}
- if ( ( bindContext.getSession() != null ) && ( bindContext.getSession().getEffectivePrincipal() != null ) )
- {
- // null out the credentials
- bindContext.setCredentials( null );
- }
+ checkAuthenticated( lookupContext );
+ checkPwdReset( lookupContext );
- // pick the first matching authenticator type
- AuthenticationLevel level = bindContext.getAuthenticationLevel();
+ return next( lookupContext );
+ }
- if ( level == AuthenticationLevel.UNAUTHENT )
+
+ private void invalidateAuthenticatorCaches( Dn principalDn )
+ {
+ for ( AuthenticationLevel authMech : authenticatorsMapByType.keySet() )
{
- // This is a case where the Bind request contains a Dn, but no password.
- // We don't check the Dn, we just return a UnwillingToPerform error
- // Cf RFC 4513, chap. 5.1.2
- throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, "Cannot Bind for Dn "
- + bindContext.getDn().getName() );
+ Collection<Authenticator> authenticators = getAuthenticators( authMech );
+
+ // try each authenticator
+ for ( Authenticator authenticator : authenticators )
+ {
+ authenticator.invalidateCache( principalDn );
+ }
}
+ }
- Collection<Authenticator> authenticators = getAuthenticators( level );
- if ( authenticators == null )
+ /**
+ * {@inheritDoc}
+ */
+ public void modify( ModifyOperationContext modifyContext ) throws LdapException
+ {
+ if ( IS_DEBUG )
{
- LOG.debug( "No authenticators found, delegating bind to the nexus." );
-
- // as a last resort try binding via the nexus
- next( bindContext );
+ LOG.debug( "Operation Context: {}", modifyContext );
+ }
- LOG.debug( "Nexus succeeded on bind operation." );
+ checkAuthenticated( modifyContext );
- // bind succeeded if we got this far
- // TODO - authentication level not being set
- LdapPrincipal principal = new LdapPrincipal( schemaManager, bindContext.getDn(), AuthenticationLevel.SIMPLE );
- CoreSession session = new DefaultCoreSession( principal, directoryService );
- bindContext.setSession( session );
- // remove creds so there is no security risk
- bindContext.setCredentials( null );
+ if ( ! directoryService.isPwdPolicyEnabled() )
+ {
+ next( modifyContext );
+ invalidateAuthenticatorCaches( modifyContext.getDn() );
return;
}
- boolean isPPolicyReqCtrlPresent = bindContext.hasRequestControl( PasswordPolicy.OID );
- PasswordPolicyDecorator pwdRespCtrl =
- new PasswordPolicyDecorator( directoryService.getLdapCodecService(), true );
+ // handle the case where pwdPolicySubentry AT is about to be deleted in thid modify()
+ PasswordPolicyConfiguration policyConfig = getPwdPolicy( modifyContext.getEntry() );
- boolean authenticated = false;
- PasswordPolicyException ppe = null;
+ boolean isPPolicyReqCtrlPresent = modifyContext.hasRequestControl( PasswordPolicy.OID );
+ Dn userDn = modifyContext.getSession().getAuthenticatedPrincipal().getDn();
- // TODO : we should refactor that.
- // try each authenticator
- for ( Authenticator authenticator : authenticators )
+ PwdModDetailsHolder pwdModDetails = null;
+
+ pwdModDetails = getPwdModDetails( modifyContext, policyConfig );
+
+ if ( pwdModDetails.isPwdModPresent() )
{
- try
+ if ( pwdResetSet.contains( userDn ) )
{
- // perform the authentication
- LdapPrincipal principal = authenticator.authenticate( bindContext );
-
- LdapPrincipal clonedPrincipal = ( LdapPrincipal ) ( principal.clone() );
+ if ( pwdModDetails.isOtherModExists() )
+ {
+ if ( isPPolicyReqCtrlPresent )
+ {
+ PasswordPolicyDecorator responseControl =
+ new PasswordPolicyDecorator( directoryService.getLdapCodecService(), true );
+ responseControl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.CHANGE_AFTER_RESET );
+ modifyContext.addResponseControl( responseControl );
+ }
- // remove creds so there is no security risk
- bindContext.setCredentials( null );
- clonedPrincipal.setUserPassword( StringConstants.EMPTY_BYTES );
+ throw new LdapNoPermissionException();
+ }
+ }
- // authentication was successful
- CoreSession session = new DefaultCoreSession( clonedPrincipal, directoryService );
- bindContext.setSession( session );
+ if ( policyConfig.isPwdSafeModify() )
+ {
+ if ( pwdModDetails.isAddOrReplace() && !pwdModDetails.isDelete() )
+ {
+ LOG.debug( "trying to update password attribute without the supplying the old password" );
- authenticated = true;
+ if ( isPPolicyReqCtrlPresent )
+ {
+ PasswordPolicyDecorator responseControl =
+ new PasswordPolicyDecorator( directoryService.getLdapCodecService(), true );
+ responseControl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.MUST_SUPPLY_OLD_PASSWORD );
+ modifyContext.addResponseControl( responseControl );
+ }
- // break out of the loop if the authentication succeeded
- break;
+ throw new LdapNoPermissionException();
+ }
}
- catch ( PasswordPolicyException e )
+
+ if ( !policyConfig.isPwdAllowUserChange() && !modifyContext.getSession().isAnAdministrator() )
{
- ppe = e;
- break;
+ if ( isPPolicyReqCtrlPresent )
+ {
+ PasswordPolicyDecorator responseControl =
+ new PasswordPolicyDecorator( directoryService.getLdapCodecService(), true );
+ responseControl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.PASSWORD_MOD_NOT_ALLOWED );
+ modifyContext.addResponseControl( responseControl );
+ }
+
+ throw new LdapNoPermissionException();
}
- catch ( LdapAuthenticationException e )
+
+ Entry entry = modifyContext.getEntry();
+
+ if ( isPwdTooYoung( entry, policyConfig ) )
{
- // authentication failed, try the next authenticator
- if ( LOG.isInfoEnabled() )
+ if ( isPPolicyReqCtrlPresent )
{
- LOG.info( "Authenticator {} failed to authenticate: {}", authenticator, bindContext );
+ 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" );
}
- catch ( Exception e )
+
+ byte[] newPassword = null;
+
+ if ( ( pwdModDetails != null ) )
{
- // Log other exceptions than LdapAuthenticationException
- if ( LOG.isWarnEnabled() )
+ newPassword = pwdModDetails.getNewPwd();
+
+ try
{
- LOG.info( "Unexpected failure for Authenticator {} : {}", authenticator, bindContext );
+ 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 );
}
}
- }
- if ( ppe != null )
- {
- if ( isPPolicyReqCtrlPresent )
+ int histSize = policyConfig.getPwdInHistory();
+ Modification pwdRemHistMod = null;
+ Modification pwdAddHistMod = null;
+ String pwdChangedTime = DateUtils.getGeneralizedTime();
+
+ if ( histSize > 0 )
{
- pwdRespCtrl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.get( ppe.getErrorCode() ) );
- bindContext.addResponseControl( pwdRespCtrl );
+ Attribute pwdHistoryAt = entry.get( PWD_HISTORY_AT );
+
+ if ( pwdHistoryAt == null )
+ {
+ pwdHistoryAt = new DefaultAttribute( AT_PWD_HISTORY );
+ }
+
+ List<PasswordHistory> pwdHistLst = new ArrayList<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" );
+ }
+
+ pwdHistLst.add( pwdh );
+ }
+
+ if ( pwdHistLst.size() >= histSize )
+ {
+ // see the javadoc of PasswordHistory
+ Collections.sort( pwdHistLst );
+
+ // remove the oldest value
+ PasswordHistory remPwdHist = ( PasswordHistory ) pwdHistLst.toArray()[histSize - 1];
+ Attribute tempAt = new DefaultAttribute( AT_PWD_HISTORY );
+ tempAt.add( remPwdHist.getHistoryValue() );
+ pwdRemHistMod = new DefaultModification( REMOVE_ATTRIBUTE, tempAt );
+ }
+
+ pwdHistoryAt.clear();
+ PasswordHistory newPwdHist = new PasswordHistory( pwdChangedTime, newPassword );
+ pwdHistoryAt.clear();
+ pwdHistoryAt.add( newPwdHist.getHistoryValue() );
+ pwdAddHistMod = new DefaultModification( ADD_ATTRIBUTE, pwdHistoryAt );
}
- throw ppe;
- }
-
- Dn dn = bindContext.getDn();
- Entry userEntry = bindContext.getEntry();
+ next( modifyContext );
- PasswordPolicyConfiguration policyConfig = getPwdPolicy( userEntry );
+ invalidateAuthenticatorCaches( modifyContext.getDn() );
- // check if the user entry is null, it will be null
- // in cases of anonymous bind
- if ( authenticated && ( userEntry == null ) && directoryService.isAllowAnonymousAccess() )
- {
- return;
- }
+ List<Modification> mods = new ArrayList<Modification>();
- if ( !authenticated )
- {
- if ( LOG.isInfoEnabled() )
+ if ( ( policyConfig.getPwdMinAge() > 0 ) || ( policyConfig.getPwdMaxAge() > 0 ) )
{
- LOG.info( "Cannot bind to the server " );
+ Attribute pwdChangedTimeAt = new DefaultAttribute( AT_PWD_CHANGED_TIME );
+ pwdChangedTimeAt.add( pwdChangedTime );
+ Modification pwdChangedTimeMod = new DefaultModification( REPLACE_ATTRIBUTE, pwdChangedTimeAt );
+ mods.add( pwdChangedTimeMod );
}
- if ( ( policyConfig != null ) && ( userEntry != null ) )
+ if ( pwdAddHistMod != null )
{
- Attribute pwdFailTimeAt = userEntry.get( PWD_FAILURE_TIME_AT );
-
- if ( pwdFailTimeAt == null )
- {
- pwdFailTimeAt = new DefaultAttribute( AT_PWD_FAILURE_TIME );
- }
- else
- {
- PasswordUtil.purgeFailureTimes( policyConfig, pwdFailTimeAt );
- }
+ mods.add( pwdAddHistMod );
+ }
- String failureTime = DateUtils.getGeneralizedTime();
- pwdFailTimeAt.add( failureTime );
- Modification pwdFailTimeMod = new DefaultModification( ADD_ATTRIBUTE, pwdFailTimeAt );
+ if ( pwdRemHistMod != null )
+ {
+ mods.add( pwdRemHistMod );
+ }
- List<Modification> mods = new ArrayList<Modification>();
- mods.add( pwdFailTimeMod );
+ boolean removeFromPwdResetSet = false;
- int numFailures = pwdFailTimeAt.size();
+ if ( policyConfig.isPwdMustChange() )
+ {
+ Attribute pwdMustChangeAt = new DefaultAttribute( AT_PWD_RESET );
+ Modification pwdMustChangeMod = null;
- if ( policyConfig.isPwdLockout() && ( numFailures >= policyConfig.getPwdMaxFailure() ) )
+ if ( modifyContext.getSession().isAnAdministrator() )
{
- Attribute pwdAccountLockedTimeAt = new DefaultAttribute( AT_PWD_ACCOUNT_LOCKED_TIME );
-
- // if zero, lockout permanently, only admin can unlock it
- if ( policyConfig.getPwdLockoutDuration() == 0 )
- {
- pwdAccountLockedTimeAt.add( "000001010000Z" );
- }
- else
- {
- pwdAccountLockedTimeAt.add( failureTime );
- }
-
- Modification pwdAccountLockedMod = new DefaultModification( ADD_ATTRIBUTE, pwdAccountLockedTimeAt );
- mods.add( pwdAccountLockedMod );
-
- pwdRespCtrl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.ACCOUNT_LOCKED );
+ pwdMustChangeAt.add( "TRUE" );
+ pwdMustChangeMod = new DefaultModification( REPLACE_ATTRIBUTE, pwdMustChangeAt );
}
- else if ( policyConfig.getPwdMinDelay() > 0 )
+ else
{
- int numDelay = numFailures * policyConfig.getPwdMinDelay();
- int maxDelay = policyConfig.getPwdMaxDelay();
- if ( numDelay > maxDelay )
- {
- numDelay = maxDelay;
- }
-
- try
- {
- Thread.sleep( numDelay * 1000 );
- }
- catch ( InterruptedException e )
- {
- LOG.warn(
- "Interrupted while delaying to send the failed authentication response for the user {}",
- dn, e );
- }
+ pwdMustChangeMod = new DefaultModification( REMOVE_ATTRIBUTE, pwdMustChangeAt );
+ removeFromPwdResetSet = true;
}
- //adminSession.modify( dn, Collections.singletonList( pwdFailTimeMod ) );
- ModifyOperationContext bindModCtx = new ModifyOperationContext( adminSession );
- bindModCtx.setDn( dn );
- bindModCtx.setModItems( mods );
- directoryService.getPartitionNexus().modify( bindModCtx );
+ mods.add( pwdMustChangeMod );
}
- String upDn = ( dn == null ? "" : dn.getName() );
- throw new LdapAuthenticationException( I18n.err( I18n.ERR_229, upDn ) );
- }
- else if ( policyConfig != null )
- {
- List<Modification> mods = new ArrayList<Modification>();
+ Attribute pwdFailureTimeAt = entry.get( PWD_FAILURE_TIME_AT );
- if ( policyConfig.getPwdMaxIdle() > 0 )
+ if ( pwdFailureTimeAt != null )
{
- Attribute pwdLastSuccesTimeAt = new DefaultAttribute( AT_PWD_LAST_SUCCESS );
- pwdLastSuccesTimeAt.add( DateUtils.getGeneralizedTime() );
- Modification pwdLastSuccesTimeMod = new DefaultModification( REPLACE_ATTRIBUTE, pwdLastSuccesTimeAt );
- mods.add( pwdLastSuccesTimeMod );
+ mods.add( new DefaultModification( REMOVE_ATTRIBUTE, pwdFailureTimeAt ) );
}
- Attribute pwdFailTimeAt = userEntry.get( AT_PWD_FAILURE_TIME );
+ Attribute pwdGraceUseTimeAt = entry.get( PWD_GRACE_USE_TIME_AT );
- if ( pwdFailTimeAt != null )
+ if ( pwdGraceUseTimeAt != null )
{
- Modification pwdFailTimeMod = new DefaultModification( REMOVE_ATTRIBUTE, pwdFailTimeAt );
- mods.add( pwdFailTimeMod );
+ mods.add( new DefaultModification( REMOVE_ATTRIBUTE, pwdGraceUseTimeAt ) );
}
- Attribute pwdAccLockedTimeAt = userEntry.get( AT_PWD_ACCOUNT_LOCKED_TIME );
+ directoryService.getAdminSession().modify( modifyContext.getDn(), mods );
- if ( pwdAccLockedTimeAt != null )
+ if ( removeFromPwdResetSet )
{
- Modification pwdAccLockedTimeMod = new DefaultModification( REMOVE_ATTRIBUTE, pwdAccLockedTimeAt );
- mods.add( pwdAccLockedTimeMod );
+ pwdResetSet.remove( userDn );
}
+ }
+ else
+ {
+ next( modifyContext );
+ invalidateAuthenticatorCaches( modifyContext.getDn() );
+ }
+ }
- // checking the expiration time *after* performing authentication, do we need to care about millisecond precision?
- if ( ( policyConfig.getPwdMaxAge() > 0 ) && ( policyConfig.getPwdGraceAuthNLimit() > 0 ) )
- {
- Attribute pwdChangeTimeAttr = userEntry.get( PWD_CHANGED_TIME_AT );
- if ( pwdChangeTimeAttr != null )
- {
- boolean expired = PasswordUtil.isPwdExpired( pwdChangeTimeAttr.getString(),
- policyConfig.getPwdMaxAge() );
+ /**
+ * {@inheritDoc}
+ */
+ public void move( MoveOperationContext moveContext ) throws LdapException
+ {
+ if ( IS_DEBUG )
+ {
+ LOG.debug( "Operation Context: {}", moveContext );
+ }
- if ( expired )
- {
- Attribute pwdGraceUseAttr = userEntry.get( PWD_GRACE_USE_TIME_AT );
- int numGraceAuth = 0;
+ checkAuthenticated( moveContext );
+ checkPwdReset( moveContext );
+ next( moveContext );
+ invalidateAuthenticatorCaches( moveContext.getDn() );
+ }
- if ( pwdGraceUseAttr != null )
- {
- numGraceAuth = policyConfig.getPwdGraceAuthNLimit() - ( pwdGraceUseAttr.size() + 1 );
- }
- else
- {
- pwdGraceUseAttr = new DefaultAttribute( AT_PWD_GRACE_USE_TIME );
- numGraceAuth = policyConfig.getPwdGraceAuthNLimit() - 1;
- }
- pwdRespCtrl.getResponse().setGraceAuthNsRemaining( numGraceAuth );
+ /**
+ * {@inheritDoc}
+ */
+ public void moveAndRename( MoveAndRenameOperationContext moveAndRenameContext ) throws LdapException
+ {
+ if ( IS_DEBUG )
+ {
+ LOG.debug( "Operation Context: {}", moveAndRenameContext );
+ }
- pwdGraceUseAttr.add( DateUtils.getGeneralizedTime() );
- Modification pwdGraceUseMod = new DefaultModification( ADD_ATTRIBUTE, pwdGraceUseAttr );
- mods.add( pwdGraceUseMod );
- }
- }
- }
+ checkAuthenticated( moveAndRenameContext );
+ checkPwdReset( moveAndRenameContext );
+ next( moveAndRenameContext );
+ invalidateAuthenticatorCaches( moveAndRenameContext.getDn() );
+ }
- if ( !mods.isEmpty() )
- {
- //adminSession.modify( dn, mods );
- ModifyOperationContext bindModCtx = new ModifyOperationContext( adminSession );
- bindModCtx.setDn( dn );
- bindModCtx.setModItems( mods );
- directoryService.getPartitionNexus().modify( bindModCtx );
- }
- if ( isPPolicyReqCtrlPresent )
- {
- int expiryWarnTime = getPwdTimeBeforeExpiry( userEntry, policyConfig );
+ /**
+ * {@inheritDoc}
+ */
+ public void rename( RenameOperationContext renameContext ) throws LdapException
+ {
+ if ( IS_DEBUG )
+ {
+ LOG.debug( "Operation Context: {}", renameContext );
+ }
- if ( expiryWarnTime > 0 )
- {
- pwdRespCtrl.getResponse().setTimeBeforeExpiration( expiryWarnTime );
- }
+ checkAuthenticated( renameContext );
+ checkPwdReset( renameContext );
+ next( renameContext );
+ invalidateAuthenticatorCaches( renameContext.getDn() );
+ }
- if ( isPwdMustReset( userEntry ) )
- {
- pwdRespCtrl.getResponse().setPasswordPolicyError( PasswordPolicyErrorEnum.CHANGE_AFTER_RESET );
- pwdResetSet.add( dn );
- }
- bindContext.addResponseControl( pwdRespCtrl );
- }
+ /**
+ * {@inheritDoc}
+ */
+ public EntryFilteringCursor search( SearchOperationContext searchContext ) throws LdapException
+ {
+ if ( IS_DEBUG )
+ {
+ LOG.debug( "Operation Context: {}", searchContext );
}
+
+ checkAuthenticated( searchContext );
+ checkPwdReset( searchContext );
+
+ return next( searchContext );
}
- @Override
+ /**
+ * {@inheritDoc}
+ */
public void unbind( UnbindOperationContext unbindContext ) throws LdapException
{
next( unbindContext );
@@ -1154,6 +1161,24 @@ public class AuthenticationInterceptor e
/**
+ * Check if the current operation has a valid PrincipalDN or not.
+ *
+ * @param operation the operation type
+ * @throws Exception
+ */
+ private void checkAuthenticated( OperationContext operation ) throws LdapException
+ {
+ if ( operation.getSession().isAnonymous() && !directoryService.isAllowAnonymousAccess()
+ && !operation.getDn().isEmpty() )
+ {
+ String msg = I18n.err( I18n.ERR_5, operation.getName() );
+ LOG.error( msg );
+ throw new LdapNoPermissionException( msg );
+ }
+ }
+
+
+ /**
* Initialize the PasswordPolicy attributeTypes
*
* @throws LdapException If the initialization failed
@@ -1187,7 +1212,6 @@ public class AuthenticationInterceptor e
// ---------- private methods ----------------
-
private void check( String username, byte[] password, PasswordPolicyConfiguration policyConfig ) throws LdapException
{
final int qualityVal = policyConfig.getPwdCheckQuality();
Propchange: directory/apacheds/branches/apacheds-txns/interceptors/authz/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Nov 12 18:24:38 2011
@@ -1 +1 @@
-/directory/apacheds/trunk/interceptors/authz:1183435-1200383
+/directory/apacheds/trunk/interceptors/authz:1183435-1201283