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 2010/07/29 00:38:17 UTC
svn commit: r980257 [1/2] - in /directory/apacheds/trunk:
core-api/src/main/java/org/apache/directory/server/core/interceptor/
core/src/main/java/org/apache/directory/server/core/
core/src/main/java/org/apache/directory/server/core/admin/ core/src/main...
Author: elecharny
Date: Wed Jul 28 22:38:17 2010
New Revision: 980257
URL: http://svn.apache.org/viewvc?rev=980257&view=rev
Log:
Added the AdminInterceptor
Added:
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/admin/
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/admin/AdministrativeInterceptor.java
Modified:
directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/interceptor/InterceptorChain.java
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/SimpleAuthenticator.java
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authz/support/ACDFEngine.java
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authz/support/MaxImmSubFilter.java
directory/apacheds/trunk/interceptor-kerberos/src/main/java/org/apache/directory/server/core/kerberos/KeyDerivationInterceptor.java
Modified: directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/interceptor/InterceptorChain.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/interceptor/InterceptorChain.java?rev=980257&r1=980256&r2=980257&view=diff
==============================================================================
--- directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/interceptor/InterceptorChain.java (original)
+++ directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/interceptor/InterceptorChain.java Wed Jul 28 22:38:17 2010
@@ -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.interceptor;
@@ -549,8 +549,8 @@ public class InterceptorChain
/**
- * Eagerly populates fields of operation contexts so multiple Interceptors
- * in the processing pathway can reuse this value without performing a
+ * Eagerly populates fields of operation contexts so multiple Interceptors
+ * in the processing pathway can reuse this value without performing a
* redundant lookup operation.
*
* @param opContext the operation context to populate with cached fields
@@ -559,19 +559,19 @@ public class InterceptorChain
@SuppressWarnings("PMD.EmptyCatchBlock")
private void eagerlyPopulateFields( OperationContext opContext ) throws LdapException
{
- // If the entry field is not set for ops other than add for example
+ // If the entry field is not set for ops other than add for example
// then we set the entry but don't freak if we fail to do so since it
// may not exist in the first place
if ( opContext.getEntry() == null )
{
// We have to use the admin session here, otherwise we may have
- // trouble reading the entry due to insufficient access rights
+ // trouble reading the entry due to insufficient access rights
CoreSession adminSession = opContext.getSession().getDirectoryService().getAdminSession();
-
+
Entry foundEntry = adminSession.lookup( opContext.getDn(),
SchemaConstants.ALL_OPERATIONAL_ATTRIBUTES_ARRAY );
-
+
if ( foundEntry != null )
{
if ( foundEntry instanceof DefaultEntry )
@@ -597,12 +597,12 @@ public class InterceptorChain
private Entry getOriginalEntry( OperationContext opContext ) throws LdapException
{
// We have to use the admin session here, otherwise we may have
- // trouble reading the entry due to insufficient access rights
+ // trouble reading the entry due to insufficient access rights
CoreSession adminSession = opContext.getSession().getDirectoryService().getAdminSession();
-
+
Entry foundEntry = adminSession.lookup( opContext.getDn(),
SchemaConstants.ALL_OPERATIONAL_ATTRIBUTES_ARRAY );
-
+
if ( foundEntry != null )
{
return foundEntry;
@@ -616,7 +616,7 @@ public class InterceptorChain
}
}
-
+
public void delete( DeleteOperationContext deleteContext ) throws LdapException
{
Element entry = getStartingEntry();
@@ -818,7 +818,7 @@ public class InterceptorChain
Interceptor head = entry.interceptor;
NextInterceptor next = entry.nextInterceptor;
eagerlyPopulateFields( renameContext );
-
+
try
{
head.rename( next, renameContext );
@@ -840,7 +840,7 @@ public class InterceptorChain
Interceptor head = entry.interceptor;
NextInterceptor next = entry.nextInterceptor;
Entry originalEntry = getOriginalEntry( moveContext );
-
+
moveContext.setOriginalEntry( originalEntry );
try
@@ -924,14 +924,14 @@ public class InterceptorChain
}
OperationContext opContext = InvocationStack.getInstance().peek();
-
+
if ( !opContext.hasBypass() )
{
return Element.this.nextEntry;
}
Element next = Element.this.nextEntry;
-
+
while ( next != tail )
{
if ( opContext.isBypassed( next.getName() ) )
Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java?rev=980257&r1=980256&r2=980257&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java Wed Jul 28 22:38:17 2010
@@ -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;
@@ -38,6 +38,7 @@ import java.util.UUID;
import javax.naming.directory.Attributes;
import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.core.admin.AdministrativeInterceptor;
import org.apache.directory.server.core.authn.AuthenticationInterceptor;
import org.apache.directory.server.core.authz.AciAuthorizationInterceptor;
import org.apache.directory.server.core.authz.DefaultAuthorizationInterceptor;
@@ -103,22 +104,22 @@ import org.slf4j.LoggerFactory;
/**
* Default implementation of {@link DirectoryService}.
- *
+ *
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class DefaultDirectoryService implements DirectoryService
{
/** The logger */
private static final Logger LOG = LoggerFactory.getLogger( DefaultDirectoryService.class );
-
+
private SchemaService schemaService;
-
+
/** A reference on the SchemaManager */
private SchemaManager schemaManager;
-
+
/** the root nexus */
private DefaultPartitionNexus partitionNexus;
-
+
/** whether or not server is started for the first time */
private boolean firstStart;
@@ -130,34 +131,34 @@ public class DefaultDirectoryService imp
/** the change log service */
private ChangeLog changeLog;
-
+
/** the journal service */
private Journal journal;
-
- /**
- * the interface used to perform various operations on this
+
+ /**
+ * the interface used to perform various operations on this
* DirectoryService
*/
private OperationManager operationManager = new DefaultOperationManager( this );
/** the distinguished name of the administrative user */
private DN adminDn;
-
+
/** session used as admin for internal operations */
private CoreSession adminSession;
-
+
/** The referral manager */
private ReferralManager referralManager;
-
+
/** A flag to tell if the userPassword attribute's value must be hidden */
private boolean passwordHidden = false;
-
+
/** The service's CSN factory */
private CsnFactory csnFactory;
-
+
/** The directory instance replication ID */
private int replicaId;
-
+
/** The replication configuration structure */
private ReplicationConfiguration replicationConfig;
@@ -168,20 +169,20 @@ public class DefaultDirectoryService imp
"changes are made by the admin user.\n Furthermore the used controls are not at " +
"all taken into account";
-
+
/** The delay to wait between each sync on disk */
private long syncPeriodMillis;
-
+
/** The default delay to wait between sync on disk : 15 seconds */
private static final long DEFAULT_SYNC_PERIOD = 15000;
/** */
private Thread workerThread;
-
+
/** The sync worker thread */
private SynchWorker worker = new SynchWorker();
-
+
/** The default timeLimit : 100 entries */
public static final int MAX_SIZE_LIMIT_DEFAULT = 100;
@@ -190,62 +191,62 @@ public class DefaultDirectoryService imp
/** The instance Id */
private String instanceId;
-
+
/** The server working directory */
private File workingDirectory = new File( "server-work" );
-
- /**
+
+ /**
* A flag used to shutdown the VM when stopping the server. Useful
* when the server is standalone. If the server is embedded, we don't
* want to shutdown the VM
*/
private boolean exitVmOnShutdown = true; // allow by default
-
+
/** A flag used to indicate that a shutdown hook has been installed */
private boolean shutdownHookEnabled = true; // allow by default
-
+
/** Manage anonymous access to entries other than the RootDSE */
private boolean allowAnonymousAccess = true; // allow by default
-
+
/** Manage the basic access control checks */
private boolean accessControlEnabled; // off by default
-
+
/** Manage the operational attributes denormalization */
private boolean denormalizeOpAttrsEnabled; // off by default
-
+
/** The list of declared interceptors */
private List<Interceptor> interceptors;
-
+
/** The System partition */
private Partition systemPartition;
-
+
/** The set of all declared partitions */
private Set<Partition> partitions = new HashSet<Partition>();
-
+
/** A list of LDIF entries to inject at startup */
private List<? extends LdifEntry> testEntries = new ArrayList<LdifEntry>(); // List<Attributes>
-
+
/** The event service */
private EventService eventService;
-
+
/** The maximum size for an incoming PDU */
private int maxPDUSize = Integer.MAX_VALUE;
/** the value of last successful add/update operation's CSN */
private String contextCsn;
-
+
/** lock file for directory service's working directory */
private RandomAccessFile lockFile = null;
-
+
private static final String LOCK_FILE_NAME = ".dirservice.lock";
-
+
/**
* The synchronizer thread. It flush data on disk periodically.
*/
class SynchWorker implements Runnable
{
final Object lock = new Object();
-
+
/** A flag to stop the thread */
boolean stop;
@@ -280,13 +281,13 @@ public class DefaultDirectoryService imp
}
}
}
-
-
+
+
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
-
-
+
+
/**
* Creates a new instance of the directory service.
*/
@@ -304,8 +305,8 @@ public class DefaultDirectoryService imp
// ------------------------------------------------------------------------
// C O N F I G U R A T I O N M E T H O D S
// ------------------------------------------------------------------------
-
-
+
+
public void setInstanceId( String instanceId )
{
this.instanceId = instanceId;
@@ -341,16 +342,16 @@ public class DefaultDirectoryService imp
Set<Partition> cloned = new HashSet<Partition>();
cloned.addAll( partitions );
Set<String> names = new HashSet<String>();
-
+
for ( Partition partition : cloned )
{
String id = partition.getId();
-
+
if ( names.contains( id ) )
{
LOG.warn( "Encountered duplicate partition {} identifier.", id );
}
-
+
names.add( id );
}
@@ -425,14 +426,14 @@ public class DefaultDirectoryService imp
*
* @param interceptors the interceptors to be used in the server.
*/
- public void setInterceptors( List<Interceptor> interceptors )
+ public void setInterceptors( List<Interceptor> interceptors )
{
Set<String> names = new HashSet<String>();
-
+
for ( Interceptor interceptor : interceptors )
{
String name = interceptor.getName();
-
+
if ( names.contains( name ) )
{
LOG.warn( "Encountered duplicate definitions for {} interceptor", interceptor.getName() );
@@ -630,6 +631,7 @@ public class DefaultDirectoryService imp
list.add( new ReferralInterceptor() );
list.add( new AciAuthorizationInterceptor() );
list.add( new DefaultAuthorizationInterceptor() );
+ list.add( new AdministrativeInterceptor() );
list.add( new ExceptionInterceptor() );
list.add( new ChangeLogInterceptor() );
list.add( new OperationalAttributeInterceptor() );
@@ -643,25 +645,25 @@ public class DefaultDirectoryService imp
setInterceptors( list );
}
-
+
public CoreSession getAdminSession()
{
return adminSession;
}
-
-
- public CoreSession getSession()
+
+
+ public CoreSession getSession()
{
return new DefaultCoreSession( new LdapPrincipal(), this );
}
-
-
+
+
public CoreSession getSession( LdapPrincipal principal )
{
return new DefaultCoreSession( principal, this );
}
-
-
+
+
public CoreSession getSession( DN principalDn, byte[] credentials ) throws LdapException
{
if ( ! started )
@@ -673,12 +675,12 @@ public class DefaultDirectoryService imp
bindContext.setCredentials( credentials );
bindContext.setDn( principalDn );
operationManager.bind( bindContext );
-
+
return bindContext.getSession();
}
-
-
- public CoreSession getSession( DN principalDn, byte[] credentials, String saslMechanism, String saslAuthId )
+
+
+ public CoreSession getSession( DN principalDn, byte[] credentials, String saslMechanism, String saslAuthId )
throws Exception
{
if ( ! started )
@@ -691,7 +693,7 @@ public class DefaultDirectoryService imp
bindContext.setDn( principalDn );
bindContext.setSaslMechanism( saslMechanism );
operationManager.bind( bindContext );
-
+
return bindContext.getSession();
}
@@ -704,7 +706,7 @@ public class DefaultDirectoryService imp
}
Tag latest = changeLog.getLatest();
-
+
if ( null != latest )
{
if ( latest.getRevision() < changeLog.getCurrentRevision() )
@@ -723,7 +725,7 @@ public class DefaultDirectoryService imp
/**
- * We handle the ModDN/ModRDN operation for the revert here.
+ * We handle the ModDN/ModRDN operation for the revert here.
*/
private void moddn( DN oldDn, DN newDn, boolean delOldRdn ) throws LdapException
{
@@ -747,7 +749,7 @@ public class DefaultDirectoryService imp
* RDN name change or a move operation. If the two names are the same
* except for the RDN then it is a simple modifyRdn operation. If the
* names differ in size or have a different baseDN then the operation is
- * a move operation. Furthermore if the RDN in the move operation
+ * a move operation. Furthermore if the RDN in the move operation
* changes it is both an RDN change and a move operation.
*/
if ( ( oldDn.size() == newDn.size() ) && oldBase.equals( newBase ) )
@@ -769,8 +771,8 @@ public class DefaultDirectoryService imp
}
}
}
-
-
+
+
public long revert( long revision ) throws LdapException
{
if ( changeLog == null || ! changeLog.isEnabled() )
@@ -801,7 +803,7 @@ public class DefaultDirectoryService imp
*
* First of all just stop using JNDI and construct the operations to
* feed into the interceptor pipeline.
- *
+ *
* TODO review this code.
*/
@@ -809,42 +811,42 @@ public class DefaultDirectoryService imp
{
LOG.warn( PARTIAL_IMPL_WARNING );
cursor.afterLast();
-
+
while ( cursor.previous() ) // apply ldifs in reverse order
{
ChangeLogEvent event = cursor.get();
List<LdifEntry> reverses = event.getReverseLdifs();
-
+
for ( LdifEntry reverse:reverses )
{
switch( reverse.getChangeType().getChangeType() )
{
case ChangeType.ADD_ORDINAL :
- adminSession.add(
- new DefaultEntry( schemaManager, reverse.getEntry() ), true );
+ adminSession.add(
+ new DefaultEntry( schemaManager, reverse.getEntry() ), true );
break;
-
+
case ChangeType.DELETE_ORDINAL :
adminSession.delete( reverse.getDn(), true );
break;
-
+
case ChangeType.MODIFY_ORDINAL :
List<Modification> mods = reverse.getModificationItems();
-
+
adminSession.modify( reverse.getDn(), mods, true );
break;
-
+
case ChangeType.MODDN_ORDINAL :
// NO BREAK - both ModDN and ModRDN handling is the same
-
+
case ChangeType.MODRDN_ORDINAL :
DN forwardDn = event.getForwardLdif().getDn();
DN reverseDn = reverse.getDn();
-
+
moddn( reverseDn, forwardDn, reverse.isDeleteOldRdn() );
-
+
break;
-
+
default:
LOG.error( I18n.err( I18n.ERR_75 ) );
throw new NotImplementedException( I18n.err( I18n.ERR_76, reverse.getChangeType() ) );
@@ -860,18 +862,19 @@ public class DefaultDirectoryService imp
}
catch ( Exception e )
{
+ e.printStackTrace();
throw new LdapOperationException( e.getMessage() );
}
return changeLog.getCurrentRevision();
}
-
+
public OperationManager getOperationManager()
{
return operationManager;
}
-
+
/**
* @throws Exception if the LDAP server cannot be started
@@ -884,7 +887,7 @@ public class DefaultDirectoryService imp
}
lockWorkDir();
-
+
if ( shutdownHookEnabled )
{
Runtime.getRuntime().addShutdownHook( new Thread( new Runnable()
@@ -913,7 +916,7 @@ public class DefaultDirectoryService imp
initialize();
showSecurityWarnings();
-
+
// Start the sync thread if required
if ( syncPeriodMillis > 0 )
{
@@ -926,7 +929,7 @@ public class DefaultDirectoryService imp
loc.setDn( systemPartition.getSuffix() );
loc.setAttrsId( new String[]{ "+" } );
ClonedServerEntry entry = systemPartition.lookup( loc );
-
+
EntryAttribute cntextCsnAt = entry.get( SchemaConstants.CONTEXT_CSN_AT );
if( cntextCsnAt != null )
{
@@ -967,7 +970,7 @@ public class DefaultDirectoryService imp
// --------------------------------------------------------------------
changeLog.sync();
changeLog.destroy();
-
+
// --------------------------------------------------------------------
// Shutdown the journal if enabled
// --------------------------------------------------------------------
@@ -982,19 +985,19 @@ public class DefaultDirectoryService imp
partitionNexus.sync();
partitionNexus.destroy();
-
+
// --------------------------------------------------------------------
// Shutdown the sync thread
// --------------------------------------------------------------------
if ( workerThread != null )
{
worker.stop = true;
-
+
synchronized ( worker.lock )
{
worker.lock.notify();
}
-
+
while ( workerThread.isAlive() )
{
LOG.info( "Waiting for SynchWorkerThread to die." );
@@ -1002,12 +1005,12 @@ public class DefaultDirectoryService imp
}
}
-
+
// --------------------------------------------------------------------
// And shutdown the server
// --------------------------------------------------------------------
interceptorChain.destroy();
-
+
if ( lockFile != null )
{
try
@@ -1020,12 +1023,12 @@ public class DefaultDirectoryService imp
LOG.warn( "couldn't delete the lock file {}", LOCK_FILE_NAME );
}
}
-
+
started = false;
setDefaultInterceptorConfigurations();
}
-
+
/**
* @return The referral manager
*/
@@ -1042,8 +1045,8 @@ public class DefaultDirectoryService imp
{
this.referralManager = referralManager;
}
-
-
+
+
/**
* @return the SchemaManager
*/
@@ -1051,8 +1054,8 @@ public class DefaultDirectoryService imp
{
return schemaManager;
}
-
-
+
+
/**
* Set the SchemaManager instance.
*
@@ -1100,11 +1103,11 @@ public class DefaultDirectoryService imp
}
- public Entry newEntry( DN dn )
+ public Entry newEntry( DN dn )
{
return new DefaultEntry( schemaManager, dn );
}
-
+
/**
* Returns true if we had to create the bootstrap entries on the first
@@ -1117,7 +1120,7 @@ public class DefaultDirectoryService imp
private boolean createBootstrapEntries() throws Exception
{
boolean firstStart = false;
-
+
// -------------------------------------------------------------------
// create admin entry
// -------------------------------------------------------------------
@@ -1130,8 +1133,8 @@ public class DefaultDirectoryService imp
firstStart = true;
Entry serverEntry = new DefaultEntry( schemaManager, adminDn );
-
- serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
+
+ serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
SchemaConstants.TOP_OC,
SchemaConstants.PERSON_OC,
SchemaConstants.ORGANIZATIONAL_PERSON_OC,
@@ -1157,14 +1160,14 @@ public class DefaultDirectoryService imp
// -------------------------------------------------------------------
DN userDn = new DN( ServerDNConstants.USERS_SYSTEM_DN, schemaManager );
-
+
if ( !partitionNexus.hasEntry( new EntryOperationContext( adminSession, userDn ) ) )
{
firstStart = true;
Entry serverEntry = new DefaultEntry( schemaManager, userDn );
-
- serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
+
+ serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
SchemaConstants.TOP_OC,
SchemaConstants.ORGANIZATIONAL_UNIT_OC );
@@ -1182,14 +1185,14 @@ public class DefaultDirectoryService imp
// -------------------------------------------------------------------
DN groupDn = new DN( ServerDNConstants.GROUPS_SYSTEM_DN, schemaManager );
-
+
if ( !partitionNexus.hasEntry( new EntryOperationContext( adminSession, groupDn ) ) )
{
firstStart = true;
Entry serverEntry = new DefaultEntry( schemaManager, groupDn );
-
- serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
+
+ serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
SchemaConstants.TOP_OC,
SchemaConstants.ORGANIZATIONAL_UNIT_OC );
@@ -1207,14 +1210,14 @@ public class DefaultDirectoryService imp
// -------------------------------------------------------------------
DN name = new DN( ServerDNConstants.ADMINISTRATORS_GROUP_DN, schemaManager );
-
+
if ( !partitionNexus.hasEntry( new EntryOperationContext( adminSession, name ) ) )
{
firstStart = true;
Entry serverEntry = new DefaultEntry( schemaManager, name );
-
- serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
+
+ serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
SchemaConstants.TOP_OC,
SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC );
@@ -1233,7 +1236,7 @@ public class DefaultDirectoryService imp
// -------------------------------------------------------------------
DN configurationDn = new DN( "ou=configuration,ou=system", schemaManager );
-
+
if ( !partitionNexus.hasEntry( new EntryOperationContext( adminSession, configurationDn ) ) )
{
firstStart = true;
@@ -1255,7 +1258,7 @@ public class DefaultDirectoryService imp
// -------------------------------------------------------------------
DN partitionsDn = new DN( "ou=partitions,ou=configuration,ou=system", schemaManager );
-
+
if ( !partitionNexus.hasEntry( new EntryOperationContext( adminSession, partitionsDn ) ) )
{
firstStart = true;
@@ -1276,7 +1279,7 @@ public class DefaultDirectoryService imp
// -------------------------------------------------------------------
DN servicesDn = new DN( "ou=services,ou=configuration,ou=system", schemaManager );
-
+
if ( !partitionNexus.hasEntry( new EntryOperationContext( adminSession, servicesDn ) ) )
{
firstStart = true;
@@ -1298,7 +1301,7 @@ public class DefaultDirectoryService imp
// -------------------------------------------------------------------
DN interceptorsDn = new DN( "ou=interceptors,ou=configuration,ou=system", schemaManager );
-
+
if ( !partitionNexus.hasEntry( new EntryOperationContext( adminSession, interceptorsDn ) ) )
{
firstStart = true;
@@ -1320,14 +1323,14 @@ public class DefaultDirectoryService imp
// -------------------------------------------------------------------
DN sysPrefRootDn = new DN( ServerDNConstants.SYSPREFROOT_SYSTEM_DN, schemaManager );
-
+
if ( !partitionNexus.hasEntry( new EntryOperationContext( adminSession, sysPrefRootDn ) ) )
{
firstStart = true;
Entry serverEntry = new DefaultEntry( schemaManager, sysPrefRootDn );
- serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
- SchemaConstants.TOP_OC,
+ serverEntry.put( SchemaConstants.OBJECT_CLASS_AT,
+ SchemaConstants.TOP_OC,
SchemaConstants.ORGANIZATIONAL_UNIT_OC,
SchemaConstants.EXTENSIBLE_OBJECT_OC );
@@ -1354,11 +1357,11 @@ public class DefaultDirectoryService imp
boolean needToChangeAdminPassword = false;
DN adminDn = new DN( ServerDNConstants.ADMIN_SYSTEM_DN, schemaManager );
-
+
Entry adminEntry = partitionNexus.lookup( new LookupOperationContext( adminSession, adminDn ) );
Value<?> userPassword = adminEntry.get( SchemaConstants.USER_PASSWORD_AT ).get();
needToChangeAdminPassword = Arrays.equals( PartitionNexus.ADMIN_PASSWORD_BYTES, userPassword.getBytes() );
-
+
if ( needToChangeAdminPassword )
{
LOG.warn( "You didn't change the admin password of directory service " + "instance '" + instanceId + "'. "
@@ -1371,7 +1374,7 @@ public class DefaultDirectoryService imp
* Adds test entries into the core.
*
* @todo this may no longer be needed when JNDI is not used for bootstrapping
- *
+ *
* @throws Exception if the creation of test entries fails.
*/
private void createTestEntries() throws Exception
@@ -1386,7 +1389,7 @@ public class DefaultDirectoryService imp
try
{
- getAdminSession().add( new DefaultEntry( schemaManager, entry ) );
+ getAdminSession().add( new DefaultEntry( schemaManager, entry ) );
}
catch ( Exception e )
{
@@ -1421,7 +1424,7 @@ public class DefaultDirectoryService imp
adminDn = new DN( ServerDNConstants.ADMIN_SYSTEM_DN, schemaManager );
adminSession = new DefaultCoreSession( new LdapPrincipal( adminDn, AuthenticationLevel.STRONG ), this );
-
+
// @TODO - NOTE: Need to find a way to instantiate without dependency on DPN
partitionNexus = new DefaultPartitionNexus( new DefaultEntry( schemaManager, DN.EMPTY_DN ) );
partitionNexus.setDirectoryService( this );
@@ -1430,7 +1433,7 @@ public class DefaultDirectoryService imp
// --------------------------------------------------------------------
// Create all the bootstrap entries before initializing chain
// --------------------------------------------------------------------
-
+
firstStart = createBootstrapEntries();
interceptorChain = new InterceptorChain();
@@ -1439,18 +1442,18 @@ public class DefaultDirectoryService imp
// --------------------------------------------------------------------
// Initialize the changeLog if it's enabled
// --------------------------------------------------------------------
-
+
if ( changeLog.isEnabled() )
{
changeLog.init( this );
-
+
if( changeLog.isExposed() && changeLog.isTagSearchSupported() )
{
String clSuffix = ( ( TaggableSearchableChangeLogStore ) changeLog.getChangeLogStore() ).getPartition().getSuffix().getName();
partitionNexus.getRootDSE( null ).add( SchemaConstants.CHANGELOG_CONTEXT_AT, clSuffix );
}
}
-
+
// --------------------------------------------------------------------
// Initialize the journal if it's enabled
// --------------------------------------------------------------------
@@ -1464,11 +1467,11 @@ public class DefaultDirectoryService imp
LOG.debug( "<--- DefaultDirectoryService initialized" );
}
}
-
-
+
+
/**
* Read an entry (without DN)
- *
+ *
* @param text The ldif format file
* @return An entry.
*/
@@ -1534,10 +1537,10 @@ public class DefaultDirectoryService imp
return entry;
}
-
+
/**
* Create a new Entry
- *
+ *
* @param ldif The String representing the attributes, as a LDIF file
* @param dn The DN for this new entry
*/
@@ -1547,9 +1550,9 @@ public class DefaultDirectoryService imp
{
Entry entry = readEntry( ldif );
DN newDn = new DN( dn );
-
+
entry.setDn( newDn );
-
+
// TODO Let's get rid of this Attributes crap
Entry serverEntry = new DefaultEntry( schemaManager, entry );
return serverEntry;
@@ -1573,8 +1576,8 @@ public class DefaultDirectoryService imp
{
this.eventService = eventService;
}
-
-
+
+
/**
* {@inheritDoc}
*/
@@ -1582,8 +1585,8 @@ public class DefaultDirectoryService imp
{
return passwordHidden;
}
-
-
+
+
/**
* {@inheritDoc}
*/
@@ -1603,7 +1606,7 @@ public class DefaultDirectoryService imp
/**
- * Set the maximum allowed size for an incoming PDU
+ * Set the maximum allowed size for an incoming PDU
* @param maxPDUSize A positive number of bytes for the PDU. A negative or
* null value will be transformed to {@link Integer#MAX_VALUE}
*/
@@ -1613,11 +1616,11 @@ public class DefaultDirectoryService imp
{
maxPDUSize = Integer.MAX_VALUE;
}
-
+
this.maxPDUSize = maxPDUSize;
}
-
-
+
+
/**
* {@inheritDoc}
*/
@@ -1630,7 +1633,7 @@ public class DefaultDirectoryService imp
return interceptor;
}
}
-
+
return null;
}
@@ -1674,10 +1677,10 @@ public class DefaultDirectoryService imp
public void setReplicationConfiguration( ReplicationConfiguration replicationConfig )
{
this.replicationConfig = replicationConfig;
-
+
}
-
-
+
+
/**
* @return the replication configuration for this DirectoryService
*/
@@ -1685,8 +1688,8 @@ public class DefaultDirectoryService imp
{
return replicationConfig;
}
-
-
+
+
/**
* {@inheritDoc}
*/
@@ -1721,8 +1724,8 @@ public class DefaultDirectoryService imp
{
this.contextCsn = lastKnownCsn;
}
-
-
+
+
/**
* checks if the working directory is already in use by some other directory service, if yes
* then throws a runtime exception else will obtain the lock on the working directory
@@ -1730,7 +1733,7 @@ public class DefaultDirectoryService imp
private void lockWorkDir()
{
FileLock fileLock = null;
-
+
try
{
lockFile = new RandomAccessFile( workingDirectory.getAbsolutePath() + File.separator + LOCK_FILE_NAME, "rw" );
@@ -1753,13 +1756,13 @@ public class DefaultDirectoryService imp
// shouldn't happen, but log anyway
LOG.error( "failed to lock the work directory", e );
}
-
+
if ( ( fileLock == null ) || ( !fileLock.isValid() ) )
{
String message = "the working directory " + workingDirectory + " has been locked by another directory service.";
LOG.error( message );
throw new RuntimeException( message );
}
-
+
}
}
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/admin/AdministrativeInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/admin/AdministrativeInterceptor.java?rev=980257&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/admin/AdministrativeInterceptor.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/admin/AdministrativeInterceptor.java Wed Jul 28 22:38:17 2010
@@ -0,0 +1,509 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * 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.
+ *
+ */
+package org.apache.directory.server.core.admin;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.naming.directory.SearchControls;
+
+import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.core.DefaultCoreSession;
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.LdapPrincipal;
+import org.apache.directory.server.core.authn.Authenticator;
+import org.apache.directory.server.core.filtering.EntryFilteringCursor;
+import org.apache.directory.server.core.interceptor.BaseInterceptor;
+import org.apache.directory.server.core.interceptor.NextInterceptor;
+import org.apache.directory.server.core.interceptor.context.AddOperationContext;
+import org.apache.directory.server.core.interceptor.context.DeleteOperationContext;
+import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
+import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext;
+import org.apache.directory.server.core.interceptor.context.MoveOperationContext;
+import org.apache.directory.server.core.interceptor.context.RenameOperationContext;
+import org.apache.directory.server.core.interceptor.context.SearchOperationContext;
+import org.apache.directory.server.core.partition.PartitionNexus;
+import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.entry.DefaultEntryAttribute;
+import org.apache.directory.shared.ldap.entry.Entry;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.entry.Modification;
+import org.apache.directory.shared.ldap.entry.StringValue;
+import org.apache.directory.shared.ldap.entry.Value;
+import org.apache.directory.shared.ldap.exception.LdapAttributeInUseException;
+import org.apache.directory.shared.ldap.exception.LdapException;
+import org.apache.directory.shared.ldap.exception.LdapInvalidAttributeValueException;
+import org.apache.directory.shared.ldap.exception.LdapNoSuchAttributeException;
+import org.apache.directory.shared.ldap.exception.LdapOperationException;
+import org.apache.directory.shared.ldap.exception.LdapUnwillingToPerformException;
+import org.apache.directory.shared.ldap.filter.EqualityNode;
+import org.apache.directory.shared.ldap.filter.ExprNode;
+import org.apache.directory.shared.ldap.message.AliasDerefMode;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.apache.directory.shared.ldap.name.DN;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.schema.SchemaManager;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An interceptor to manage the Administrative model
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class AdministrativeInterceptor extends BaseInterceptor
+{
+ /** A ogger for this class */
+ private static final Logger LOG = LoggerFactory.getLogger( AdministrativeInterceptor.class );
+
+ /**
+ * Speedup for logs
+ */
+ private static final boolean IS_DEBUG = LOG.isDebugEnabled();
+
+ /** A reference to the DirectoryService instance */
+ private DirectoryService directoryService;
+
+ /** A reference to the SchemaManager instance */
+ private SchemaManager schemaManager;
+
+ /** A reference to the nexus for direct backend operations */
+ private PartitionNexus nexus;
+
+ /** A reference to the AdministrativeRole AT */
+ private static AttributeType ADMINISTRATIVE_ROLE_AT;
+
+ /** The possible roles */
+ private static final Set<String> ROLES = new HashSet<String>();
+
+ static
+ {
+ ROLES.add( SchemaConstants.AUTONOMOUS_AREA.toLowerCase() );
+ ROLES.add( SchemaConstants.AUTONOMOUS_AREA_OID );
+ ROLES.add( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA.toLowerCase() );
+ ROLES.add( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA_OID );
+ ROLES.add( SchemaConstants.ACCESS_CONTROL_INNER_AREA.toLowerCase() );
+ ROLES.add( SchemaConstants.ACCESS_CONTROL_INNER_AREA_OID );
+ ROLES.add( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA.toLowerCase() );
+ ROLES.add( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA_OID );
+ ROLES.add( SchemaConstants.COLLECTIVE_ATTRIBUTE_INNER_AREA.toLowerCase() );
+ ROLES.add( SchemaConstants.COLLECTIVE_ATTRIBUTE_INNER_AREA_OID );
+ ROLES.add( SchemaConstants.SUB_SCHEMA_ADMIN_SPECIFIC_AREA.toLowerCase() );
+ ROLES.add( SchemaConstants.SUB_SCHEMA_ADMIN_SPECIFIC_AREA_OID );
+ ROLES.add( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA.toLowerCase() );
+ ROLES.add( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA_OID );
+ ROLES.add( SchemaConstants.TRIGGER_EXECUTION_INNER_AREA.toLowerCase() );
+ ROLES.add( SchemaConstants.TRIGGER_EXECUTION_INNER_AREA_OID );
+ }
+
+ /**
+ * Creates an Administrative service interceptor.
+ */
+ public AdministrativeInterceptor()
+ {
+ }
+
+ //-------------------------------------------------------------------------------------------
+ // Helper methods
+ //-------------------------------------------------------------------------------------------
+ private List<Entry> getAdministrativePoints( String adminRoleType ) throws LdapException
+ {
+ List<Entry> entries = new ArrayList<Entry>();
+
+ DN adminDn = new DN( ServerDNConstants.ADMIN_SYSTEM_DN, schemaManager );
+
+ CoreSession adminSession = new DefaultCoreSession(
+ new LdapPrincipal( adminDn, AuthenticationLevel.STRONG ), directoryService );
+
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+ controls.setReturningAttributes(
+ new String[]
+ {
+ SchemaConstants.ADMINISTRATIVE_ROLE_AT,
+ SchemaConstants.ENTRY_UUID_AT
+ } );
+
+ ExprNode filter = new EqualityNode<String>( ADMINISTRATIVE_ROLE_AT, new StringValue(
+ adminRoleType ) );
+
+ SearchOperationContext searchOperationContext = new SearchOperationContext( adminSession, DN.EMPTY_DN, filter,
+ controls );
+ searchOperationContext.setAliasDerefMode( AliasDerefMode.NEVER_DEREF_ALIASES );
+
+ EntryFilteringCursor results = nexus.search( searchOperationContext );
+
+ try
+ {
+ while ( results.next() )
+ {
+ Entry entry = results.get();
+
+ entries.add( entry );
+ }
+ }
+ catch ( Exception e )
+ {
+ throw new LdapOperationException( e.getMessage() );
+ }
+
+ return entries;
+ }
+
+
+ /**
+ * Tells if a given role is a valid administrative role. We check the lower cased
+ * and trimmed value, and also the OID value.
+ */
+ private boolean isValidRole( String role )
+ {
+ return ROLES.contains( StringTools.toLowerCase( StringTools.trim( role ) ) );
+ }
+
+
+ //-------------------------------------------------------------------------------------------
+ // Interceptor initialization
+ //-------------------------------------------------------------------------------------------
+ /**
+ * Registers and initializes all {@link Authenticator}s to this service.
+ */
+ public void init( DirectoryService directoryService ) throws LdapException
+ {
+ LOG.debug( "Initializing the AdministrativeInterceptor" );
+
+ this.directoryService = directoryService;
+
+ schemaManager = directoryService.getSchemaManager();
+ nexus = directoryService.getPartitionNexus();
+
+ ADMINISTRATIVE_ROLE_AT = schemaManager.getAttributeType( SchemaConstants.ADMINISTRATIVE_ROLE_AT );
+
+ // Load all the AdministratvePoint :
+ // Autonomous Administrative Point first, then Specific
+ // administrative point, finally the Inner administrative Point
+ DN adminDn = new DN( ServerDNConstants.ADMIN_SYSTEM_DN, schemaManager );
+
+ CoreSession adminSession = new DefaultCoreSession(
+ new LdapPrincipal( adminDn, AuthenticationLevel.STRONG ), directoryService );
+
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+ controls.setReturningAttributes( new String[] { SchemaConstants.ADMINISTRATIVE_ROLE_AT } );
+
+ // get the list of all the AAPs
+ List<Entry> autonomousSAPs = getAdministrativePoints( SchemaConstants.AUTONOMOUS_AREA );
+
+ // get the list of all the specific APs
+ List<Entry> accessControlSAPs = getAdministrativePoints( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA );
+ List<Entry> collectiveAttributeSAPs = getAdministrativePoints( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA );
+ List<Entry> subSchemaSAPs = getAdministrativePoints( SchemaConstants.SUB_SCHEMA_ADMIN_SPECIFIC_AREA );
+ List<Entry> triggerExecutionSAPs = getAdministrativePoints( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA );
+
+ // get the list of all the inner APs
+ List<Entry> accessControlIAPs = getAdministrativePoints( SchemaConstants.ACCESS_CONTROL_INNER_AREA );
+ List<Entry> collectiveAttributeIAPs = getAdministrativePoints( SchemaConstants.COLLECTIVE_ATTRIBUTE_INNER_AREA );
+ List<Entry> triggerExecutionIAPs = getAdministrativePoints( SchemaConstants.TRIGGER_EXECUTION_INNER_AREA );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void destroy()
+ {
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void add( NextInterceptor next, AddOperationContext addContext ) throws LdapException
+ {
+ Entry entry = addContext.getEntry();
+
+ // Check if we are adding an Administrative Point
+ EntryAttribute adminPoint = entry.get( ADMINISTRATIVE_ROLE_AT );
+
+ if ( adminPoint == null )
+ {
+ // Nope, go on.
+ next.add( addContext );
+
+ LOG.debug( "Exit from Administrative Interceptor" );
+
+ return;
+ }
+
+ LOG.debug( "Addition of an administrative point at {} for the role {}", entry.getDn(), adminPoint );
+
+ // Now we are trying to add an Administrative point. We have to check that the added
+ // AP is correct if it's a AAP : it has to have all the required SAP
+ // Note :
+ if ( adminPoint.contains( SchemaConstants.AUTONOMOUS_AREA ) )
+ {
+ if ( ( adminPoint.contains( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA ) ||
+ adminPoint.contains( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA_OID ) ) &&
+ ( adminPoint.contains( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA ) ||
+ adminPoint.contains( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA_OID ) ) &&
+ ( adminPoint.contains( SchemaConstants.SUB_SCHEMA_ADMIN_SPECIFIC_AREA ) ||
+ adminPoint.contains( SchemaConstants.SUB_SCHEMA_ADMIN_SPECIFIC_AREA_OID ) ) &&
+ ( adminPoint.contains( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA ) ||
+ adminPoint.contains( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA_OID ) ) )
+ {
+ // Ok, we have all the four needed specific area, we can add the AAP
+ LOG.debug( "Adding an Autonomous Administrative Point at {}", entry.getDn() );
+
+ next.add( addContext );
+
+ LOG.debug( "Added an Autonomous Administrative Point at {}", entry.getDn() );
+
+ return;
+ }
+ else
+ {
+ String message = "Cannot add an Autonomous Administratve Point when some of the" +
+ " specific areas are missing : " + adminPoint;
+ LOG.error( message );
+ throw new LdapUnwillingToPerformException( message );
+ }
+ }
+
+ // check that we can't mix Inner and Specific areas
+ if ( ( ( adminPoint.contains( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA ) ||
+ adminPoint.contains( SchemaConstants.ACCESS_CONTROL_SPECIFIC_AREA_OID ) ) &&
+ ( adminPoint.contains( SchemaConstants.ACCESS_CONTROL_INNER_AREA ) ||
+ adminPoint.contains( SchemaConstants.ACCESS_CONTROL_INNER_AREA_OID ) ) ) ||
+ ( ( adminPoint.contains( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA ) ||
+ adminPoint.contains( SchemaConstants.COLLECTIVE_ATTRIBUTE_SPECIFIC_AREA_OID ) ) &&
+ ( adminPoint.contains( SchemaConstants.COLLECTIVE_ATTRIBUTE_INNER_AREA ) ||
+ adminPoint.contains( SchemaConstants.COLLECTIVE_ATTRIBUTE_INNER_AREA_OID ) ) ) ||
+ ( ( adminPoint.contains( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA ) ||
+ adminPoint.contains( SchemaConstants.TRIGGER_EXECUTION_SPECIFIC_AREA_OID ) ) &&
+ ( adminPoint.contains( SchemaConstants.TRIGGER_EXECUTION_INNER_AREA ) ||
+ adminPoint.contains( SchemaConstants.TRIGGER_EXECUTION_INNER_AREA_OID ) ) ) )
+ {
+ // This is inconsistant
+ String message = "Cannot add a specific Administratve Point and the same" +
+ " inner Administrative point at the same time : " + adminPoint;
+ LOG.error( message );
+ throw new LdapUnwillingToPerformException( message );
+ }
+
+ // Ok, we are golden.
+ next.add( addContext );
+
+ LOG.debug( "Added an Autonomous Administrative Point at {}", entry.getDn() );
+
+ return;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void delete( NextInterceptor next, DeleteOperationContext deleteContext ) throws LdapException
+ {
+ next.delete( deleteContext );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void modify( NextInterceptor next, ModifyOperationContext modifyContext ) throws LdapException
+ {
+ // We have to check that the modification is acceptable
+ List<Modification> modifications = modifyContext.getModItems();
+
+ EntryAttribute modifiedAdminRole = (modifyContext.getEntry()).getOriginalEntry().get( ADMINISTRATIVE_ROLE_AT );
+
+ for ( Modification modification : modifications )
+ {
+ EntryAttribute attribute = modification.getAttribute();
+
+ if ( attribute.getAttributeType() != ADMINISTRATIVE_ROLE_AT )
+ {
+ continue;
+ }
+
+ // Ok, we have a modification impacting the administrative role
+ // Apply it to a virtual AdministrativeRole attribute
+ switch ( modification.getOperation() )
+ {
+ case ADD_ATTRIBUTE :
+ if ( modifiedAdminRole == null )
+ {
+ // Create the attribute
+ modifiedAdminRole = new DefaultEntryAttribute( ADMINISTRATIVE_ROLE_AT, attribute.get() );
+ break;
+ }
+
+ for ( Value<?> value : attribute )
+ {
+ if ( !isValidRole( value.getString() ) )
+ {
+ // Not a valid role : we will throw an exception
+ String msg = "Invalid role : " + value.getString();
+ LOG.error( msg );
+ throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, msg );
+ }
+
+ // At this point, we know that the attribute's syntax is correct
+ // We just have to check that the current attribute does not
+ // contains the value already
+ if ( modifiedAdminRole.contains( value ) )
+ {
+ // This is an error.
+ String msg = I18n.err( I18n.ERR_54, value );
+ LOG.error( msg );
+ throw new LdapAttributeInUseException( msg );
+ }
+
+ // Add the role to the modified attribute
+ modifiedAdminRole.add( value );
+ }
+
+ break;
+
+ case REMOVE_ATTRIBUTE :
+ if ( modifiedAdminRole == null )
+ {
+ // We can't remove a value when the attribute does not exist.
+ String msg = "Cannot remove the administrative role, it does not exist";
+ LOG.error( msg );
+ throw new LdapNoSuchAttributeException( msg );
+ }
+
+ // It may be a complete removal
+ if ( attribute.size() == 0 )
+ {
+ // Complete removal
+ modifiedAdminRole = null;
+ break;
+ }
+
+ // Now deal with the values to remove
+ for ( Value<?> value : attribute )
+ {
+ if ( !isValidRole( value.getString() ) )
+ {
+ // Not a valid role : we will throw an exception
+ String msg = "Invalid role : " + value.getString();
+ LOG.error( msg );
+ throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, msg );
+ }
+
+ if ( !modifiedAdminRole.contains( value ) )
+ {
+ // We can't remove a value if it does not exist !
+ String msg = "Cannot remove the administrative role value" + value + ", it does not exist";
+ LOG.error( msg );
+ throw new LdapNoSuchAttributeException( msg );
+ }
+
+ modifiedAdminRole.remove( value );
+ }
+
+ break;
+
+ case REPLACE_ATTRIBUTE :
+ if ( modifiedAdminRole == null )
+ {
+ // We have to create the attribute
+ // We can't remove a value when the attribute does not exist.
+ String msg = "Cannot remove the administrative role, it does not exist";
+ LOG.error( msg );
+ throw new LdapNoSuchAttributeException( msg );
+ }
+
+ // It may be a complete removal
+ if ( attribute.size() == 0 )
+ {
+ // Complete removal
+ modifiedAdminRole = null;
+ break;
+ }
+
+ // Now replace the existing attributes with the new ones if they are valid
+ modifiedAdminRole.clear();
+
+ for ( Value<?> value : attribute )
+ {
+ if ( !isValidRole( value.getString() ) )
+ {
+ // Not a valid role : we will throw an exception
+ String msg = "Invalid role : " + value.getString();
+ LOG.error( msg );
+ throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, msg );
+ }
+
+ if ( modifiedAdminRole.contains( value ) )
+ {
+ // We can't add a value if it already exists !
+ String msg = "Cannot add the administrative role value" + value + ", it already exists";
+ LOG.error( msg );
+ throw new LdapAttributeInUseException( msg );
+ }
+
+ modifiedAdminRole.add( value );
+ }
+
+ break;
+ }
+ }
+
+ next.modify( modifyContext );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void move( NextInterceptor next, MoveOperationContext moveContext ) throws LdapException
+ {
+ next.move( moveContext );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void moveAndRename( NextInterceptor next, MoveAndRenameOperationContext moveAndRenameContext )
+ throws LdapException
+ {
+ next.moveAndRename( moveAndRenameContext );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rename( NextInterceptor next, RenameOperationContext renameContext )
+ throws LdapException
+ {
+ next.rename( renameContext );
+ }
+}
Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java?rev=980257&r1=980256&r2=980257&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java Wed Jul 28 22:38:17 2010
@@ -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;
@@ -51,6 +51,7 @@ import org.apache.directory.server.core.
import org.apache.directory.server.core.DefaultCoreSession;
import org.apache.directory.server.core.DirectoryService;
import org.apache.directory.server.core.LdapPrincipal;
+import org.apache.directory.server.core.admin.AdministrativeInterceptor;
import org.apache.directory.server.core.authz.AciAuthorizationInterceptor;
import org.apache.directory.server.core.authz.DefaultAuthorizationInterceptor;
import org.apache.directory.server.core.collective.CollectiveAttributeInterceptor;
@@ -128,10 +129,12 @@ public class AuthenticationInterceptor e
private Set<Authenticator> authenticators;
private final Map<AuthenticationLevel, Collection<Authenticator>> authenticatorsMapByType = new HashMap<AuthenticationLevel, Collection<Authenticator>>();
+ /** A reference to the DirectoryService instance */
private DirectoryService directoryService;
private PasswordPolicyConfiguration policyConfig;
+ /** A reference to the SchemaManager instance */
private SchemaManager schemaManager;
private CoreSession adminSession;
@@ -164,7 +167,9 @@ public class AuthenticationInterceptor e
c.add( NormalizationInterceptor.class.getName() );
c.add( AuthenticationInterceptor.class.getName() );
c.add( AciAuthorizationInterceptor.class.getName() );
+ c.add( AdministrativeInterceptor.class.getName() );
c.add( DefaultAuthorizationInterceptor.class.getName() );
+ c.add( AdministrativeInterceptor.class.getName() );
c.add( ExceptionInterceptor.class.getName() );
c.add( OperationalAttributeInterceptor.class.getName() );
c.add( SchemaInterceptor.class.getName() );
@@ -341,7 +346,7 @@ public class AuthenticationInterceptor e
addContext.addResponseControl( responseControl );
}
- // throw exception if userPassword quality checks fail
+ // throw exception if userPassword quality checks fail
throw new LdapOperationException( ResultCodeEnum.CONSTRAINT_VIOLATION, e.getMessage() );
}
@@ -564,7 +569,7 @@ public class AuthenticationInterceptor e
modifyContext.addResponseControl( responseControl );
}
- // throw exception if userPassword quality checks fail
+ // throw exception if userPassword quality checks fail
throw new LdapOperationException( ResultCodeEnum.CONSTRAINT_VIOLATION, e.getMessage() );
}
}
@@ -1216,7 +1221,7 @@ public class AuthenticationInterceptor e
/**
* The password does not contain three letter (or more) tokens from the user's account name.
- *
+ *
* If the account name is less than three characters long, this check is not performed
* because the rate at which passwords would be rejected is too high. For each token that is
* three or more characters long, that token is searched for in the password; if it is present,
@@ -1282,7 +1287,7 @@ public class AuthenticationInterceptor e
/**
* checks if the password is too young
- *
+ *
* @param userEntry the user's entry
* @return true if the password is young, false otherwise
* @throws LdapException
Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/SimpleAuthenticator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/SimpleAuthenticator.java?rev=980257&r1=980256&r2=980257&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/SimpleAuthenticator.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/SimpleAuthenticator.java Wed Jul 28 22:38:17 2010
@@ -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;
@@ -23,7 +23,6 @@ package org.apache.directory.server.core
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -35,6 +34,7 @@ import javax.naming.Context;
import org.apache.commons.collections.map.LRUMap;
import org.apache.commons.lang.ArrayUtils;
import org.apache.directory.server.core.LdapPrincipal;
+import org.apache.directory.server.core.admin.AdministrativeInterceptor;
import org.apache.directory.server.core.authz.AciAuthorizationInterceptor;
import org.apache.directory.server.core.authz.DefaultAuthorizationInterceptor;
import org.apache.directory.server.core.collective.CollectiveAttributeInterceptor;
@@ -68,9 +68,9 @@ import org.apache.directory.shared.ldap.
* contained within the <code>userPassword</code> attribute in DIT. If the
* password is stored with a one-way encryption applied (e.g. SHA), the password
* is hashed the same way before comparison.
- *
+ *
* We use a cache to speedup authentication, where the DN/password are stored.
- *
+ *
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class SimpleAuthenticator extends AbstractAuthenticator
@@ -86,19 +86,19 @@ public class SimpleAuthenticator extends
/**
* A cache to store passwords. It's a speedup, we will be able to avoid backend lookups.
- *
- * Note that the backend also use a cache mechanism, but for performance gain, it's good
+ *
+ * Note that the backend also use a cache mechanism, but for performance gain, it's good
* to manage a cache here. The main problem is that when a user modify his password, we will
* have to update it at three different places :
* - in the backend,
* - in the partition cache,
* - in this cache.
- *
+ *
* The update of the backend and partition cache is already correctly handled, so we will
* just have to offer an access to refresh the local cache.
- *
+ *
* We need to be sure that frequently used passwords be always in cache, and not discarded.
- * We will use a LRU cache for this purpose.
+ * We will use a LRU cache for this purpose.
*/
private final LRUMap credentialCache;
@@ -118,6 +118,7 @@ public class SimpleAuthenticator extends
c.add( AuthenticationInterceptor.class.getName() );
c.add( AciAuthorizationInterceptor.class.getName() );
c.add( DefaultAuthorizationInterceptor.class.getName() );
+ c.add( AdministrativeInterceptor.class.getName() );
c.add( ExceptionInterceptor.class.getName() );
c.add( OperationalAttributeInterceptor.class.getName() );
c.add( SchemaInterceptor.class.getName() );
@@ -154,19 +155,19 @@ public class SimpleAuthenticator extends
/**
* A private class to store all informations about the existing
* password found in the cache or get from the backend.
- *
+ *
* This is necessary as we have to compute :
* - the used algorithm
* - the salt if any
* - the password itself.
- *
- * If we have a on-way encrypted password, it is stored using this
+ *
+ * If we have a on-way encrypted password, it is stored using this
* format :
* {<algorithm>}<encrypted password>
* where the encrypted password format can be :
* - MD5/SHA : base64([<salt (4 or 8 bytes)>]<password>)
- * - crypt : <salt (2 btytes)><password>
- *
+ * - crypt : <salt (2 btytes)><password>
+ *
* Algorithm are currently MD5, SMD5, SHA, SSHA, CRYPT and empty
*/
private class EncryptionMethod
@@ -360,10 +361,10 @@ public class SimpleAuthenticator extends
/**
* Decompose the stored password in an algorithm, an eventual salt
* and the password itself.
- *
+ *
* If the algorithm is SHA, SSHA, MD5 or SMD5, the part following the algorithm
* is base64 encoded
- *
+ *
* @param encryptionMethod The structure to feed
* @return The password
* @param credentials the credentials to split
@@ -387,14 +388,14 @@ public class SimpleAuthenticator extends
}
catch ( UnsupportedEncodingException uee )
{
- // do nothing
+ // do nothing
return credentials;
}
case HASH_METHOD_SMD5:
try
{
- // The password is associated with a salt. Decompose it
+ // The password is associated with a salt. Decompose it
// in two parts, after having decoded the password.
// The salt will be stored into the EncryptionMethod structure
// The salt is at the end of the credentials, and is 8 bytes long
@@ -410,14 +411,14 @@ public class SimpleAuthenticator extends
}
catch ( UnsupportedEncodingException uee )
{
- // do nothing
+ // do nothing
return credentials;
}
case HASH_METHOD_SSHA:
try
{
- // The password is associated with a salt. Decompose it
+ // The password is associated with a salt. Decompose it
// in two parts, after having decoded the password.
// The salt will be stored into the EncryptionMethod structure
// The salt is at the end of the credentials, and is 8 bytes long
@@ -433,12 +434,12 @@ public class SimpleAuthenticator extends
}
catch ( UnsupportedEncodingException uee )
{
- // do nothing
+ // do nothing
return credentials;
}
case HASH_METHOD_CRYPT:
- // The password is associated with a salt. Decompose it
+ // The password is associated with a salt. Decompose it
// in two parts, storing the salt into the EncryptionMethod structure.
// The salt comes first, not like for SSHA and SMD5, and is 2 bytes long
encryptionMethod.salt = new byte[2];
@@ -469,7 +470,7 @@ public class SimpleAuthenticator extends
try
{
/*
- * NOTE: at this point the BindOperationContext does not has a
+ * NOTE: at this point the BindOperationContext does not has a
* null session since the user has not yet authenticated so we
* cannot use lookup() yet. This is a very special
* case where we cannot rely on the bindContext to perform a new
@@ -479,7 +480,7 @@ public class SimpleAuthenticator extends
bindContext.getDn() );
lookupContext.setByPassed( USERLOOKUP_BYPASS );
lookupContext.setAttrsId( new String[]{ "+" } );
-
+
userEntry = getDirectoryService().getOperationManager().lookup( lookupContext );
if ( userEntry == null )
@@ -505,7 +506,7 @@ public class SimpleAuthenticator extends
EntryAttribute userPasswordAttr = userEntry.get( SchemaConstants.USER_PASSWORD_AT );
bindContext.setEntry( new ClonedServerEntry( userEntry ) );
-
+
// ---- assert that credentials match
if ( userPasswordAttr == null )
{
@@ -525,7 +526,7 @@ public class SimpleAuthenticator extends
* The method returns null, if the argument is not in this form. It returns
* XYZ, if XYZ is an algorithm known to the MessageDigest class of
* java.security.
- *
+ *
* @param password a byte[]
* @return included message digest alorithm, if any
* @throws IllegalArgumentException if the algorithm cannot be identified
@@ -568,16 +569,16 @@ public class SimpleAuthenticator extends
* encoded. The method returns a String which looks like "{XYZ}bbbbbbb",
* whereas XYZ is the name of the algorithm, and bbbbbbb is the Base64
* encoded value of XYZ applied to the password.
- *
+ *
* @param algorithm
* an algorithm which is supported by
* java.security.MessageDigest, e.g. SHA
* @param password
* password value, a byte[]
- *
+ *
* @return a digested password, which looks like
* {SHA}LhkDrSoM6qr0fW6hzlfOJQW61tc=
- *
+ *
* @throws IllegalArgumentException
* if password is neither a String nor a byte[], or algorithm is
* not known to java.security.MessageDigest class
Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authz/support/ACDFEngine.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authz/support/ACDFEngine.java?rev=980257&r1=980256&r2=980257&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authz/support/ACDFEngine.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authz/support/ACDFEngine.java Wed Jul 28 22:38:17 2010
@@ -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.authz.support;
@@ -25,6 +25,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import org.apache.directory.server.core.admin.AdministrativeInterceptor;
import org.apache.directory.server.core.authn.AuthenticationInterceptor;
import org.apache.directory.server.core.authz.AciAuthorizationInterceptor;
import org.apache.directory.server.core.authz.DefaultAuthorizationInterceptor;
@@ -65,7 +66,7 @@ import org.apache.directory.shared.ldap.
* <p>
* Operation is determined to be permitted if and only if there is at least one
* tuple left and all of them grants the access. (18.8.4. X.501)
- *
+ *
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class ACDFEngine
@@ -75,10 +76,10 @@ public class ACDFEngine
/**
* Creates a new instance.
- *
+ *
* @param oidRegistry an OID registry to be used by internal components
- * @param attrTypeRegistry an attribute type registry to be used by internal components
- *
+ * @param attrTypeRegistry an attribute type registry to be used by internal components
+ *
* @throws LdapException if failed to initialize internal components
*/
public ACDFEngine( SchemaManager schemaManager )
@@ -104,7 +105,7 @@ public class ACDFEngine
* Checks the user with the specified name can access the specified resource
* (entry, attribute type, or attribute value) and throws {@link LdapNoPermissionException}
* if the user doesn't have any permission to perform the specified grants.
- *
+ *
* @param proxy the proxy to the partition nexus
* @param userGroupNames the collection of the group DNs the user who is trying to access the resource belongs
* @param username the DN of the user who is trying to access the resource
@@ -135,6 +136,7 @@ public class ACDFEngine
// c.add( ReferralInterceptor.class.getName() );
c.add( AciAuthorizationInterceptor.class.getName() );
c.add( DefaultAuthorizationInterceptor.class.getName() );
+ c.add( AdministrativeInterceptor.class.getName() );
// c.add( ExceptionInterceptor.class.getName() );
c.add( OperationalAttributeInterceptor.class.getName() );
c.add( SchemaInterceptor.class.getName() );
@@ -150,7 +152,7 @@ public class ACDFEngine
* Returns <tt>true</tt> if the user with the specified name can access the specified resource
* (entry, attribute type, or attribute value) and throws {@link LdapNoPermissionException}
* if the user doesn't have any permission to perform the specified grants.
- *
+ *
* @param proxy the proxy to the partition nexus
* @param userGroupNames the collection of the group DNs the user who is trying to access the resource belongs
* @param userName the DN of the user who is trying to access the resource
@@ -174,7 +176,7 @@ public class ACDFEngine
// Determine the scope of the requested operation.
OperationScope scope;
-
+
if ( aciContext.getAttributeType() == null )
{
scope = OperationScope.ENTRY;
@@ -190,7 +192,7 @@ public class ACDFEngine
// Clone aciTuples in case it is unmodifiable.
aciContext.setAciTuples( new ArrayList<ACITuple>( aciContext.getAciTuples() ) );
-
+
// Filter unrelated and invalid tuples
for ( ACITupleFilter filter : filters )
{
@@ -199,7 +201,7 @@ public class ACDFEngine
// No need to continue filtering
return false;
}
-
+
aciContext.setAciTuples( filter.filter( aciContext, scope, userEntry ) );
}
Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authz/support/MaxImmSubFilter.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authz/support/MaxImmSubFilter.java?rev=980257&r1=980256&r2=980257&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authz/support/MaxImmSubFilter.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authz/support/MaxImmSubFilter.java Wed Jul 28 22:38:17 2010
@@ -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.authz.support;
@@ -27,6 +27,7 @@ import java.util.Iterator;
import javax.naming.directory.SearchControls;
+import org.apache.directory.server.core.admin.AdministrativeInterceptor;
import org.apache.directory.server.core.authn.AuthenticationInterceptor;
import org.apache.directory.server.core.authz.AciAuthorizationInterceptor;
import org.apache.directory.server.core.authz.DefaultAuthorizationInterceptor;
@@ -70,7 +71,7 @@ public class MaxImmSubFilter implements
public MaxImmSubFilter( SchemaManager schemaManager )
{
AttributeType objectClassAt = null;
-
+
try
{
objectClassAt = schemaManager.lookupAttributeTypeRegistry( SchemaConstants.OBJECT_CLASS_AT );
@@ -79,7 +80,7 @@ public class MaxImmSubFilter implements
{
// Do nothing
}
-
+
childrenFilter = new PresenceNode( objectClassAt );
childrenSearchControls = new SearchControls();
childrenSearchControls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
@@ -111,7 +112,7 @@ public class MaxImmSubFilter implements
for ( Iterator<ACITuple> i = aciContext.getAciTuples().iterator(); i.hasNext(); )
{
ACITuple tuple = i.next();
-
+
if ( !tuple.isGrant() )
{
continue;
@@ -127,7 +128,7 @@ public class MaxImmSubFilter implements
}
MaxImmSubItem mis = ( MaxImmSubItem ) item;
-
+
if ( immSubCount >= mis.getValue() )
{
i.remove();
@@ -148,6 +149,7 @@ public class MaxImmSubFilter implements
c.add( AuthenticationInterceptor.class.getName() );
c.add( AciAuthorizationInterceptor.class.getName() );
c.add( DefaultAuthorizationInterceptor.class.getName() );
+ c.add( AdministrativeInterceptor.class.getName() );
c.add( OperationalAttributeInterceptor.class.getName() );
c.add( SchemaInterceptor.class.getName() );
c.add( SubentryInterceptor.class.getName() );
@@ -160,14 +162,14 @@ public class MaxImmSubFilter implements
{
int cnt = 0;
EntryFilteringCursor results = null;
-
+
try
{
- SearchOperationContext searchContext = new SearchOperationContext( opContext.getSession(),
- ( DN ) entryName.getPrefix( 1 ), childrenFilter, childrenSearchControls );
+ SearchOperationContext searchContext = new SearchOperationContext( opContext.getSession(),
+ entryName.getPrefix( 1 ), childrenFilter, childrenSearchControls );
searchContext.setByPassed( SEARCH_BYPASS );
searchContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
-
+
results = opContext.getSession().getDirectoryService().getOperationManager().search( searchContext );
try