You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2006/09/01 02:38:33 UTC

svn commit: r439119 - in /directory/trunks/apacheds: core-unit/src/test/java/org/apache/directory/server/core/authz/ core/src/main/java/org/apache/directory/server/core/ core/src/main/java/org/apache/directory/server/core/authz/

Author: akarasulu
Date: Thu Aug 31 17:38:32 2006
New Revision: 439119

URL: http://svn.apache.org/viewvc?rev=439119&view=rev
Log:
Fix for DIRSERVER-617: Add ACI for Administrators group if not already present

Added:
    directory/trunks/apacheds/core-unit/src/test/java/org/apache/directory/server/core/authz/AdministratorsGroupTest.java
      - copied unchanged from r439118, directory/branches/apacheds/1.0/core-unit/src/test/java/org/apache/directory/server/core/authz/AdministratorsGroupTest.java
Modified:
    directory/trunks/apacheds/core-unit/src/test/java/org/apache/directory/server/core/authz/AbstractAuthorizationITest.java
    directory/trunks/apacheds/core-unit/src/test/java/org/apache/directory/server/core/authz/ModifyAuthorizationITest.java
    directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
    directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/AuthorizationService.java
    directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/DefaultAuthorizationService.java
    directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/GroupCache.java

Modified: directory/trunks/apacheds/core-unit/src/test/java/org/apache/directory/server/core/authz/AbstractAuthorizationITest.java
URL: http://svn.apache.org/viewvc/directory/trunks/apacheds/core-unit/src/test/java/org/apache/directory/server/core/authz/AbstractAuthorizationITest.java?rev=439119&r1=439118&r2=439119&view=diff
==============================================================================
--- directory/trunks/apacheds/core-unit/src/test/java/org/apache/directory/server/core/authz/AbstractAuthorizationITest.java (original)
+++ directory/trunks/apacheds/core-unit/src/test/java/org/apache/directory/server/core/authz/AbstractAuthorizationITest.java Thu Aug 31 17:38:32 2006
@@ -158,6 +158,25 @@
 
 
     /**
+     * Creates a simple groupOfUniqueNames under the ou=groups,ou=system
+     * container.  The admin user is always a member of this newly created 
+     * group.
+     */
+    public Name createGroup( String groupName ) throws NamingException
+    {
+        DirContext adminCtx = getContextAsAdmin();
+        Attributes group = new BasicAttributes( true );
+        Attribute objectClass = new BasicAttribute( "objectClass" );
+        group.put( objectClass );
+        objectClass.add( "top" );
+        objectClass.add( "groupOfUniqueNames" );
+        group.put( "uniqueMember", PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED );
+        adminCtx.createSubcontext( "cn=" + groupName + ",ou=groups", group );
+        return new LdapDN( "cn=" + groupName + ",ou=groups,ou=system" );
+    }
+
+
+    /**
      * Adds an existing user under ou=users,ou=system to an existing group under the
      * ou=groups,ou=system container.
      *

Modified: directory/trunks/apacheds/core-unit/src/test/java/org/apache/directory/server/core/authz/ModifyAuthorizationITest.java
URL: http://svn.apache.org/viewvc/directory/trunks/apacheds/core-unit/src/test/java/org/apache/directory/server/core/authz/ModifyAuthorizationITest.java?rev=439119&r1=439118&r2=439119&view=diff
==============================================================================
--- directory/trunks/apacheds/core-unit/src/test/java/org/apache/directory/server/core/authz/ModifyAuthorizationITest.java (original)
+++ directory/trunks/apacheds/core-unit/src/test/java/org/apache/directory/server/core/authz/ModifyAuthorizationITest.java Thu Aug 31 17:38:32 2006
@@ -267,7 +267,7 @@
      *
      * @throws javax.naming.NamingException if the test encounters an error
      */
-    public void testGrantModifyByAdministrators() throws NamingException
+    public void testGrantModifyByTestGroup() throws NamingException
     {
         // ----------------------------------------------------------------------------------
         // Modify with Attribute Addition
@@ -279,15 +279,17 @@
 
         // create the non-admin user
         createUser( "billyd", "billyd" );
+        
+        createGroup( "TestGroup" );
 
         // try a modify operation which should fail without any ACI
         assertFalse( checkCanModifyAs( "billyd", "billyd", "ou=testou", mods ) );
 
-        // Gives grantModify, and grantRead perm to all users in the Administrators group for
+        // Gives grantModify, and grantRead perm to all users in the TestGroup group for
         // entries and all attribute types and values
         createAccessControlSubentry( "administratorModifyAdd", "{ " + "identificationTag \"addAci\", "
             + "precedence 14, " + "authenticationLevel none, " + "itemOrUserFirst userFirst: { "
-            + "userClasses { userGroup { \"cn=Administrators,ou=groups,ou=system\" } }, " + "userPermissions { "
+            + "userClasses { userGroup { \"cn=TestGroup,ou=groups,ou=system\" } }, " + "userPermissions { "
             + "{ protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse } }, "
             + "{ protectedItems {allAttributeValues {registeredAddress}}, grantsAndDenials { grantAdd } } " + "} } }" );
 
@@ -295,8 +297,8 @@
         // add op should still fail since billd is not in the admin group
         assertFalse( checkCanModifyAs( "billyd", "billyd", "ou=testou", mods ) );
 
-        // now add billyd to the Administrator group and try again
-        addUserToGroup( "billyd", "Administrators" );
+        // now add billyd to the TestGroup group and try again
+        addUserToGroup( "billyd", "TestGroup" );
 
         // try a modify operation which should succeed with ACI and group membership change
         assertTrue( checkCanModifyAs( "billyd", "billyd", "ou=testou", mods ) );
@@ -312,11 +314,11 @@
         // make sure we cannot remove the telephone number from the test entry
         assertFalse( checkCanModifyAs( "billyd", "billyd", "ou=testou", mods ) );
 
-        // Gives grantModify, and grantRead perm to all users in the Administrators group for
+        // Gives grantModify, and grantRead perm to all users in the TestGroup group for
         // entries and all attribute types and values
         createAccessControlSubentry( "administratorModifyRemove", "{ " + "identificationTag \"addAci\", "
             + "precedence 14, " + "authenticationLevel none, " + "itemOrUserFirst userFirst: { "
-            + "userClasses { userGroup { \"cn=Administrators,ou=groups,ou=system\" } }, " + "userPermissions { "
+            + "userClasses { userGroup { \"cn=TestGroup,ou=groups,ou=system\" } }, " + "userPermissions { "
             + "{ protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse } }, "
             + "{ protectedItems {allAttributeValues {telephoneNumber}}, grantsAndDenials { grantRemove } } " + "} } }" );
 
@@ -334,11 +336,11 @@
         // make sure we cannot remove the telephone number from the test entry
         assertFalse( checkCanModifyAs( "billyd", "billyd", "ou=testou", mods ) );
 
-        // Gives grantModify, and grantRead perm to all users in the Administrators group for
+        // Gives grantModify, and grantRead perm to all users in the TestGroup group for
         // entries and all attribute types and values
         createAccessControlSubentry( "administratorModifyReplace", "{ " + "identificationTag \"addAci\", "
             + "precedence 14, " + "authenticationLevel none, " + "itemOrUserFirst userFirst: { "
-            + "userClasses { userGroup { \"cn=Administrators,ou=groups,ou=system\" } }, " + "userPermissions { "
+            + "userClasses { userGroup { \"cn=TestGroup,ou=groups,ou=system\" } }, " + "userPermissions { "
             + "{ protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse } }, "
             + "{ protectedItems {allAttributeValues {telephoneNumber}}, grantsAndDenials { grantAdd, grantRemove } } "
             + "} } }" );
@@ -360,11 +362,11 @@
         // try a modify operation which should fail without any ACI
         assertFalse( checkCanModifyAs( "billyd", "billyd", "ou=testou", DirContext.ADD_ATTRIBUTE, changes ) );
 
-        // Gives grantModify, and grantRead perm to all users in the Administrators group for
+        // Gives grantModify, and grantRead perm to all users in the TestGroup group for
         // entries and all attribute types and values
         createAccessControlSubentry( "administratorModifyAdd", "{ " + "identificationTag \"addAci\", "
             + "precedence 14, " + "authenticationLevel none, " + "itemOrUserFirst userFirst: { "
-            + "userClasses { userGroup { \"cn=Administrators,ou=groups,ou=system\" } }, " + "userPermissions { "
+            + "userClasses { userGroup { \"cn=TestGroup,ou=groups,ou=system\" } }, " + "userPermissions { "
             + "{ protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse } }, "
             + "{ protectedItems {allAttributeValues {registeredAddress}}, grantsAndDenials { grantAdd } } " + "} } }" );
 
@@ -382,11 +384,11 @@
         // make sure we cannot remove the telephone number from the test entry
         assertFalse( checkCanModifyAs( "billyd", "billyd", "ou=testou", DirContext.REMOVE_ATTRIBUTE, changes ) );
 
-        // Gives grantModify, and grantRead perm to all users in the Administrators group for
+        // Gives grantModify, and grantRead perm to all users in the TestGroup group for
         // entries and all attribute types and values
         createAccessControlSubentry( "administratorModifyRemove", "{ " + "identificationTag \"addAci\", "
             + "precedence 14, " + "authenticationLevel none, " + "itemOrUserFirst userFirst: { "
-            + "userClasses { userGroup { \"cn=Administrators,ou=groups,ou=system\" } }, " + "userPermissions { "
+            + "userClasses { userGroup { \"cn=TestGroup,ou=groups,ou=system\" } }, " + "userPermissions { "
             + "{ protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse } }, "
             + "{ protectedItems {allAttributeValues {telephoneNumber}}, grantsAndDenials { grantRemove } } " + "} } }" );
 
@@ -404,11 +406,11 @@
         // make sure we cannot remove the telephone number from the test entry
         assertFalse( checkCanModifyAs( "billyd", "billyd", "ou=testou", DirContext.REPLACE_ATTRIBUTE, changes ) );
 
-        // Gives grantModify, and grantRead perm to all users in the Administrators group for
+        // Gives grantModify, and grantRead perm to all users in the TestGroup group for
         // entries and all attribute types and values
         createAccessControlSubentry( "administratorModifyReplace", "{ " + "identificationTag \"addAci\", "
             + "precedence 14, " + "authenticationLevel none, " + "itemOrUserFirst userFirst: { "
-            + "userClasses { userGroup { \"cn=Administrators,ou=groups,ou=system\" } }, " + "userPermissions { "
+            + "userClasses { userGroup { \"cn=TestGroup,ou=groups,ou=system\" } }, " + "userPermissions { "
             + "{ protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse } }, "
             + "{ protectedItems {allAttributeValues {telephoneNumber}}, grantsAndDenials { grantAdd, grantRemove } } "
             + "} } }" );
@@ -417,6 +419,7 @@
         assertTrue( checkCanModifyAs( "billyd", "billyd", "ou=testou", DirContext.REPLACE_ATTRIBUTE, changes ) );
         deleteAccessControlSubentry( "administratorModifyReplace" );
     }
+
 
     //    /**
     //     * Checks to make sure name based userClass works for modify operations.

Modified: directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
URL: http://svn.apache.org/viewvc/directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java?rev=439119&r1=439118&r2=439119&view=diff
==============================================================================
--- directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java (original)
+++ directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java Thu Aug 31 17:38:32 2006
@@ -445,7 +445,7 @@
             attributes.put( "displayName", "Directory Superuser" );
             attributes.put( "cn", "system administrator" );
             attributes.put( "sn", "administrator" );
-            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL );
+            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED );
             attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() );
             attributes.put( "displayName", "Directory Superuser" );
 
@@ -472,7 +472,7 @@
             attributes.put( objectClass );
 
             attributes.put( "ou", "users" );
-            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL );
+            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED );
             attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() );
 
             partitionNexus.add( userDn, attributes );
@@ -496,7 +496,7 @@
             attributes.put( objectClass );
 
             attributes.put( "ou", "groups" );
-            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL );
+            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED );
             attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() );
 
             partitionNexus.add( groupDn, attributes );
@@ -520,8 +520,8 @@
             objectClass.add( "groupOfUniqueNames" );
             attributes.put( objectClass );
             attributes.put( "cn", "Administrators" );
-            attributes.put( "uniqueMember", PartitionNexus.ADMIN_PRINCIPAL );
-            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL );
+            attributes.put( "uniqueMember", PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED );
+            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED );
             attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() );
 
             partitionNexus.add(normName, attributes );
@@ -547,7 +547,7 @@
             attributes.put( objectClass );
 
             attributes.put( "ou", "configuration" );
-            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL );
+            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED );
             attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() );
 
             partitionNexus.add( configurationDn, attributes );
@@ -571,7 +571,7 @@
             attributes.put( objectClass );
 
             attributes.put( "ou", "partitions" );
-            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL );
+            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED );
             attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() );
 
             partitionNexus.add( partitionsDn, attributes );
@@ -595,7 +595,7 @@
             attributes.put( objectClass );
 
             attributes.put( "ou", "services" );
-            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL );
+            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED );
             attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() );
 
             partitionNexus.add( servicesDn, attributes );
@@ -619,7 +619,7 @@
             attributes.put( objectClass );
 
             attributes.put( "ou", "interceptors" );
-            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL );
+            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED );
             attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() );
 
             partitionNexus.add( interceptorsDn, attributes );
@@ -644,7 +644,7 @@
 
             attributes.put( "objectClass", "extensibleObject" );
             attributes.put( "prefNodeName", "sysPrefRoot" );
-            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL );
+            attributes.put( "creatorsName", PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED );
             attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() );
 
             partitionNexus.add( sysPrefRootDn, attributes );

Modified: directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/AuthorizationService.java
URL: http://svn.apache.org/viewvc/directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/AuthorizationService.java?rev=439119&r1=439118&r2=439119&view=diff
==============================================================================
--- directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/AuthorizationService.java (original)
+++ directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/AuthorizationService.java Thu Aug 31 17:38:32 2006
@@ -34,7 +34,6 @@
 import org.apache.directory.server.core.invocation.InvocationStack;
 import org.apache.directory.server.core.jndi.ServerContext;
 import org.apache.directory.server.core.jndi.ServerLdapContext;
-import org.apache.directory.server.core.partition.PartitionNexus;
 import org.apache.directory.server.core.partition.PartitionNexusProxy;
 import org.apache.directory.server.core.schema.AttributeTypeRegistry;
 import org.apache.directory.server.core.schema.ConcreteNameComponentNormalizer;
@@ -361,7 +360,7 @@
         // Access the principal requesting the operation, and bypass checks if it is the admin
         Invocation invocation = InvocationStack.getInstance().peek();
         LdapPrincipal principal = ( ( ServerContext ) invocation.getCaller() ).getPrincipal();
-        LdapDN userName = principal.getJndiName();
+        LdapDN principalDn = principal.getJndiName();
 
         // bypass authz code if we are disabled
         if ( !enabled )
@@ -371,7 +370,7 @@
         }
 
         // bypass authz code but manage caches if operation is performed by the admin
-        if ( userName.toNormName().equalsIgnoreCase( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) )
+        if ( isPrincipalAnAdministrator( principalDn ) )
         {
             next.add( normName, entry );
             tupleCache.subentryAdded( normName.toNormName(), normName, entry );
@@ -389,7 +388,7 @@
         }
 
         // Assemble all the information required to make an access control decision
-        Set userGroups = groupCache.getGroups( userName.toNormName() );
+        Set userGroups = groupCache.getGroups( principalDn.toNormName() );
         Collection tuples = new HashSet();
 
         // Build the total collection of tuples to be considered for add rights
@@ -399,7 +398,7 @@
 
         // check if entry scope permission is granted
         PartitionNexusProxy proxy = invocation.getProxy();
-        engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), normName, null, null,
+        engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), normName, null, null,
             ADD_PERMS, tuples, subentryAttrs );
 
         // now we must check if attribute type and value scope permission is granted
@@ -409,7 +408,7 @@
             Attribute attr = ( Attribute ) attributeList.next();
             for ( int ii = 0; ii < attr.size(); ii++ )
             {
-                engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), normName, attr
+                engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), normName, attr
                     .getID(), attr.get( ii ), ADD_PERMS, tuples, entry );
             }
         }
@@ -431,7 +430,7 @@
         PartitionNexusProxy proxy = invocation.getProxy();
         Attributes entry = proxy.lookup( name, PartitionNexusProxy.LOOKUP_BYPASS );
         LdapPrincipal principal = ( ( ServerContext ) invocation.getCaller() ).getPrincipal();
-        LdapDN userName = principal.getJndiName();
+        LdapDN principalDn = principal.getJndiName();
 
         // bypass authz code if we are disabled
         if ( !enabled )
@@ -441,7 +440,7 @@
         }
 
         // bypass authz code but manage caches if operation is performed by the admin
-        if ( userName.toString().equalsIgnoreCase( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) )
+        if ( isPrincipalAnAdministrator( principalDn ) )
         {
             next.delete( name );
             tupleCache.subentryDeleted( name, entry );
@@ -449,13 +448,13 @@
             return;
         }
 
-        Set userGroups = groupCache.getGroups( userName.toString() );
+        Set userGroups = groupCache.getGroups( principalDn.toString() );
         Collection tuples = new HashSet();
         addPerscriptiveAciTuples( proxy, tuples, name, entry );
         addEntryAciTuples( tuples, entry );
         addSubentryAciTuples( proxy, tuples, name, entry );
 
-        engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), name, null, null,
+        engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), name, null, null,
             REMOVE_PERMS, tuples, entry );
 
         next.delete( name );
@@ -471,7 +470,7 @@
         PartitionNexusProxy proxy = invocation.getProxy();
         Attributes entry = proxy.lookup( name, PartitionNexusProxy.LOOKUP_BYPASS );
         LdapPrincipal principal = ( ( ServerContext ) invocation.getCaller() ).getPrincipal();
-        LdapDN userName = principal.getJndiName();
+        LdapDN principalDn = principal.getJndiName();
 
         // bypass authz code if we are disabled
         if ( !enabled )
@@ -481,7 +480,7 @@
         }
 
         // bypass authz code but manage caches if operation is performed by the admin
-        if ( userName.toString().equalsIgnoreCase( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) )
+        if ( isPrincipalAnAdministrator( principalDn ) )
         {
             next.modify( name, modOp, mods );
             tupleCache.subentryModified( name, modOp, mods, entry );
@@ -489,13 +488,13 @@
             return;
         }
 
-        Set userGroups = groupCache.getGroups( userName.toString() );
+        Set userGroups = groupCache.getGroups( principalDn.toString() );
         Collection tuples = new HashSet();
         addPerscriptiveAciTuples( proxy, tuples, name, entry );
         addEntryAciTuples( tuples, entry );
         addSubentryAciTuples( proxy, tuples, name, entry );
 
-        engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), name, null, null,
+        engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), name, null, null,
             Collections.singleton( MicroOperation.MODIFY ), tuples, entry );
 
         NamingEnumeration attrList = mods.getAll();
@@ -518,7 +517,7 @@
             Attribute attr = ( Attribute ) attrList.next();
             for ( int ii = 0; ii < attr.size(); ii++ )
             {
-                engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), name, attr
+                engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), name, attr
                     .getID(), attr.get( ii ), perms, tuples, entry );
             }
         }
@@ -536,7 +535,7 @@
         PartitionNexusProxy proxy = invocation.getProxy();
         Attributes entry = proxy.lookup( name, PartitionNexusProxy.LOOKUP_BYPASS );
         LdapPrincipal principal = ( ( ServerContext ) invocation.getCaller() ).getPrincipal();
-        LdapDN userName = principal.getJndiName();
+        LdapDN principalDn = principal.getJndiName();
 
         // bypass authz code if we are disabled
         if ( !enabled )
@@ -546,7 +545,7 @@
         }
 
         // bypass authz code but manage caches if operation is performed by the admin
-        if ( userName.toString().equalsIgnoreCase( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) )
+        if ( isPrincipalAnAdministrator( principalDn ) )
         {
             next.modify( name, mods );
             tupleCache.subentryModified( name, mods, entry );
@@ -554,13 +553,13 @@
             return;
         }
 
-        Set userGroups = groupCache.getGroups( userName.toString() );
+        Set userGroups = groupCache.getGroups( principalDn.toString() );
         Collection tuples = new HashSet();
         addPerscriptiveAciTuples( proxy, tuples, name, entry );
         addEntryAciTuples( tuples, entry );
         addSubentryAciTuples( proxy, tuples, name, entry );
 
-        engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), name, null, null,
+        engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), name, null, null,
             Collections.singleton( MicroOperation.MODIFY ), tuples, entry );
 
         Collection perms = null;
@@ -582,7 +581,7 @@
             Attribute attr = mods[ii].getAttribute();
             for ( int jj = 0; jj < attr.size(); jj++ )
             {
-                engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), name, attr
+                engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), name, attr
                     .getID(), attr.get( jj ), perms, tuples, entry );
             }
         }
@@ -599,22 +598,21 @@
         PartitionNexusProxy proxy = invocation.getProxy();
         Attributes entry = proxy.lookup( name, PartitionNexusProxy.LOOKUP_BYPASS );
         LdapPrincipal principal = ( ( ServerContext ) invocation.getCaller() ).getPrincipal();
-        LdapDN userName = principal.getJndiName();
+        LdapDN principalDn = principal.getJndiName();
 
-        if ( userName.toNormName().equalsIgnoreCase( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) || !enabled
-            || name.toString().trim().equals( "" ) ) // no checks on the rootdse
+        if ( isPrincipalAnAdministrator( principalDn ) || !enabled || name.toString().trim().equals( "" ) ) // no checks on the rootdse
         {
             return next.hasEntry( name );
         }
 
-        Set userGroups = groupCache.getGroups( userName.toNormName() );
+        Set userGroups = groupCache.getGroups( principalDn.toNormName() );
         Collection tuples = new HashSet();
         addPerscriptiveAciTuples( proxy, tuples, name, entry );
         addEntryAciTuples( tuples, entry );
         addSubentryAciTuples( proxy, tuples, name, entry );
 
         // check that we have browse access to the entry
-        engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), name, null, null,
+        engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), name, null, null,
             BROWSE_PERMS, tuples, entry );
 
         return next.hasEntry( name );
@@ -679,7 +677,7 @@
         LdapDN principalDn = new LdapDN( principal.getName() );
         principalDn.normalize( attrRegistry.getNormalizerMapping() );
         
-        if ( principalDn.toNormName().equalsIgnoreCase( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) || !enabled )
+        if ( isPrincipalAnAdministrator( principalDn ) || !enabled )
         {
             return next.lookup( dn, attrIds );
         }
@@ -698,7 +696,7 @@
         LdapDN principalDn = (LdapDN)user.getJndiName();
         principalDn.normalize( attrRegistry.getNormalizerMapping() );
         
-        if ( principalDn.toString().equals( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) || !enabled )
+        if ( isPrincipalAnAdministrator( principalDn ) || !enabled )
         {
             return next.lookup( name );
         }
@@ -715,7 +713,7 @@
         PartitionNexusProxy proxy = invocation.getProxy();
         Attributes entry = proxy.lookup( name, PartitionNexusProxy.LOOKUP_BYPASS );
         LdapPrincipal principal = ( ( ServerContext ) invocation.getCaller() ).getPrincipal();
-        LdapDN userName = principal.getJndiName();
+        LdapDN principalDn = principal.getJndiName();
         LdapDN newName = ( LdapDN ) name.clone();
         newName.remove( name.size() - 1 );
         newName.add( parseNormalized( newRn ).get( 0 ) );
@@ -728,7 +726,7 @@
         }
 
         // bypass authz code but manage caches if operation is performed by the admin
-        if ( userName.toString().equalsIgnoreCase( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) )
+        if ( isPrincipalAnAdministrator( principalDn ) )
         {
             next.modifyRn( name, newRn, deleteOldRn );
             tupleCache.subentryRenamed( name, newName );
@@ -738,13 +736,13 @@
             return;
         }
 
-        Set userGroups = groupCache.getGroups( userName.toString() );
+        Set userGroups = groupCache.getGroups( principalDn.toString() );
         Collection tuples = new HashSet();
         addPerscriptiveAciTuples( proxy, tuples, name, entry );
         addEntryAciTuples( tuples, entry );
         addSubentryAciTuples( proxy, tuples, name, entry );
 
-        engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), name, null, null,
+        engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), name, null, null,
             RENAME_PERMS, tuples, entry );
 
         //        if ( deleteOldRn )
@@ -788,7 +786,7 @@
         PartitionNexusProxy proxy = invocation.getProxy();
         Attributes entry = proxy.lookup( oriChildName, PartitionNexusProxy.LOOKUP_BYPASS );
         LdapPrincipal principal = ( ( ServerContext ) invocation.getCaller() ).getPrincipal();
-        LdapDN userName = principal.getJndiName();
+        LdapDN principalDn = principal.getJndiName();
         LdapDN newName = ( LdapDN ) newParentName.clone();
         newName.add( newRn );
 
@@ -800,7 +798,7 @@
         }
 
         // bypass authz code but manage caches if operation is performed by the admin
-        if ( userName.toString().equalsIgnoreCase( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) )
+        if ( isPrincipalAnAdministrator( principalDn ) )
         {
             next.move( oriChildName, newParentName, newRn, deleteOldRn );
             tupleCache.subentryRenamed( oriChildName, newName );
@@ -808,13 +806,13 @@
             return;
         }
 
-        Set userGroups = groupCache.getGroups( userName.toString() );
+        Set userGroups = groupCache.getGroups( principalDn.toString() );
         Collection tuples = new HashSet();
         addPerscriptiveAciTuples( proxy, tuples, oriChildName, entry );
         addEntryAciTuples( tuples, entry );
         addSubentryAciTuples( proxy, tuples, oriChildName, entry );
 
-        engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), oriChildName, null,
+        engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), oriChildName, null,
             null, MOVERENAME_PERMS, tuples, entry );
 
         // Get the entry again without operational attributes
@@ -841,7 +839,7 @@
         addPerscriptiveAciTuples( proxy, destTuples, newName, subentryAttrs );
         // Evaluate the target context to see whether it
         // allows an entry named newName to be imported as a subordinate.
-        engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), newName, null,
+        engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), newName, null,
             null, IMPORT_PERMS, destTuples, subentryAttrs );
 
         //        if ( deleteOldRn )
@@ -886,7 +884,7 @@
         LdapDN newName = ( LdapDN ) newParentName.clone();
         newName.add( oriChildName.get( oriChildName.size() - 1 ) );
         LdapPrincipal principal = ( ( ServerContext ) invocation.getCaller() ).getPrincipal();
-        LdapDN userName = principal.getJndiName();
+        LdapDN principalDn = principal.getJndiName();
 
         // bypass authz code if we are disabled
         if ( !enabled )
@@ -896,7 +894,7 @@
         }
 
         // bypass authz code but manage caches if operation is performed by the admin
-        if ( userName.toString().equalsIgnoreCase( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) )
+        if ( isPrincipalAnAdministrator( principalDn ) )
         {
             next.move( oriChildName, newParentName );
             tupleCache.subentryRenamed( oriChildName, newName );
@@ -904,13 +902,13 @@
             return;
         }
 
-        Set userGroups = groupCache.getGroups( userName.toString() );
+        Set userGroups = groupCache.getGroups( principalDn.toString() );
         Collection tuples = new HashSet();
         addPerscriptiveAciTuples( proxy, tuples, oriChildName, entry );
         addEntryAciTuples( tuples, entry );
         addSubentryAciTuples( proxy, tuples, oriChildName, entry );
 
-        engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), oriChildName, null,
+        engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), oriChildName, null,
             null, EXPORT_PERMS, tuples, entry );
         
         // Get the entry again without operational attributes
@@ -937,7 +935,7 @@
         addPerscriptiveAciTuples( proxy, destTuples, newName, subentryAttrs );
         // Evaluate the target context to see whether it
         // allows an entry named newName to be imported as a subordinate.
-        engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), newName, null,
+        engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), newName, null,
             null, IMPORT_PERMS, destTuples, subentryAttrs );
 
         next.move( oriChildName, newParentName );
@@ -954,7 +952,7 @@
         ServerLdapContext ctx = ( ServerLdapContext ) invocation.getCaller();
         LdapPrincipal user = ctx.getPrincipal();
         NamingEnumeration e = next.list( base );
-        if ( user.getName().equalsIgnoreCase( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) || !enabled )
+        if ( isPrincipalAnAdministrator( user.getJndiName() ) || !enabled )
         {
             return e;
         }
@@ -974,8 +972,7 @@
 
         boolean isSubschemaSubentryLookup = subschemaSubentryDn.equals( base.toNormName() );
         boolean isRootDSELookup = base.size() == 0 && searchCtls.getSearchScope() == SearchControls.OBJECT_SCOPE;
-        if ( principalDn.toNormName().equals( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) || !enabled || 
-            isRootDSELookup || isSubschemaSubentryLookup )
+        if ( isPrincipalAnAdministrator( principalDn ) || !enabled || isRootDSELookup || isSubschemaSubentryLookup )
         {
             return e;
         }
@@ -983,6 +980,12 @@
         return new SearchResultFilteringEnumeration( e, searchCtls, invocation, authzFilter );
     }
 
+    
+    public final boolean isPrincipalAnAdministrator( LdapDN principalDn ) throws NamingException
+    {
+        return groupCache.isPrincipalAnAdministrator( principalDn );
+    }
+    
 
     public boolean compare( NextInterceptor next, LdapDN name, String oid, Object value ) throws NamingException
     {
@@ -991,22 +994,22 @@
         PartitionNexusProxy proxy = invocation.getProxy();
         Attributes entry = proxy.lookup( name, PartitionNexusProxy.LOOKUP_BYPASS );
         LdapPrincipal principal = ( ( ServerContext ) invocation.getCaller() ).getPrincipal();
-        LdapDN userName = principal.getJndiName();
+        LdapDN principalDn = principal.getJndiName();
 
-        if ( userName.toNormName().equals( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) || !enabled )
+        if ( isPrincipalAnAdministrator( principalDn ) || !enabled )
         {
             return next.compare( name, oid, value );
         }
 
-        Set userGroups = groupCache.getGroups( userName.toNormName() );
+        Set userGroups = groupCache.getGroups( principalDn.toNormName() );
         Collection tuples = new HashSet();
         addPerscriptiveAciTuples( proxy, tuples, name, entry );
         addEntryAciTuples( tuples, entry );
         addSubentryAciTuples( proxy, tuples, name, entry );
 
-        engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), name, null, null,
+        engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), name, null, null,
             READ_PERMS, tuples, entry );
-        engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), name, oid, value,
+        engine.checkPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), name, oid, value,
             COMPARE_PERMS, tuples, entry );
 
         return next.compare( name, oid, value );
@@ -1019,8 +1022,9 @@
         Invocation invocation = InvocationStack.getInstance().peek();
         PartitionNexusProxy proxy = invocation.getProxy();
         LdapPrincipal principal = ( ( ServerContext ) invocation.getCaller() ).getPrincipal();
-        LdapDN userName = principal.getJndiName();
-        if ( userName.toString().equalsIgnoreCase( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) || !enabled )
+        LdapDN principalDn = principal.getJndiName();
+        
+        if ( isPrincipalAnAdministrator( principalDn ) || !enabled )
         {
             return next.getMatchedName( dn );
         }
@@ -1035,13 +1039,13 @@
         while ( matched.size() > 0 )
         {
             entry = proxy.lookup( matched, PartitionNexusProxy.GETMATCHEDDN_BYPASS );
-            Set userGroups = groupCache.getGroups( userName.toString() );
+            Set userGroups = groupCache.getGroups( principalDn.toString() );
             Collection tuples = new HashSet();
             addPerscriptiveAciTuples( proxy, tuples, matched, entry );
             addEntryAciTuples( tuples, entry );
             addSubentryAciTuples( proxy, tuples, matched, entry );
 
-            if ( engine.hasPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), matched, null,
+            if ( engine.hasPermission( proxy, userGroups, principalDn, principal.getAuthenticationLevel(), matched, null,
                 null, MATCHEDNAME_PERMS, tuples, entry ) )
             {
                 return matched;

Modified: directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/DefaultAuthorizationService.java
URL: http://svn.apache.org/viewvc/directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/DefaultAuthorizationService.java?rev=439119&r1=439118&r2=439119&view=diff
==============================================================================
--- directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/DefaultAuthorizationService.java (original)
+++ directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/DefaultAuthorizationService.java Thu Aug 31 17:38:32 2006
@@ -20,12 +20,15 @@
 package org.apache.directory.server.core.authz;
 
 
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 import javax.naming.Name;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 import javax.naming.NoPermissionException;
+import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
 import javax.naming.directory.ModificationItem;
 import javax.naming.directory.SearchControls;
@@ -60,11 +63,6 @@
 public class DefaultAuthorizationService extends BaseInterceptor
 {
     /**
-     * the administrator's distinguished {@link Name}
-     */
-    private static LdapDN ADMIN_DN;
-
-    /**
      * the base distinguished {@link Name} for all users
      */
     private static LdapDN USER_BASE_DN;
@@ -77,13 +75,21 @@
     private static LdapDN GROUP_BASE_DN_NORMALIZED;
 
     /**
+     * the distinguished {@link Name} for the administrator group
+     */
+    private static LdapDN ADMIN_GROUP_DN;
+    private static LdapDN ADMIN_GROUP_DN_NORMALIZED;
+
+    /**
      * the name parser used by this service
      */
     private boolean enabled = true;
     
-    private Map oidsMap;
+    private Set administrators = new HashSet(2);
     
-
+    private Map normalizerMapping;
+    
+    private PartitionNexus nexus;
 
     /**
      * Creates a new instance.
@@ -95,21 +101,47 @@
 
     public void init( DirectoryServiceConfiguration factoryCfg, InterceptorConfiguration cfg ) throws NamingException
     {
-        oidsMap = factoryCfg.getGlobalRegistries().getAttributeTypeRegistry().getNormalizerMapping();
-        //dnParser = new DnParser( new ConcreteNameComponentNormalizer( atr ) );
+        nexus = factoryCfg.getPartitionNexus();
+        normalizerMapping = factoryCfg.getGlobalRegistries().getAttributeTypeRegistry().getNormalizerMapping();
 
         // disable this static module if basic access control mechanisms are enabled
         enabled = !factoryCfg.getStartupConfiguration().isAccessControlEnabled();
-        ADMIN_DN = PartitionNexus.getAdminName(); 
         
         USER_BASE_DN = PartitionNexus.getUsersBaseName();
-        USER_BASE_DN_NORMALIZED = LdapDN.normalize( USER_BASE_DN, oidsMap );
+        USER_BASE_DN_NORMALIZED = LdapDN.normalize( USER_BASE_DN, normalizerMapping );
         
         GROUP_BASE_DN = PartitionNexus.getGroupsBaseName();
-        GROUP_BASE_DN_NORMALIZED = LdapDN.normalize( GROUP_BASE_DN, oidsMap );
+        GROUP_BASE_DN_NORMALIZED = LdapDN.normalize( GROUP_BASE_DN, normalizerMapping );
+     
+        ADMIN_GROUP_DN = new LdapDN( "cn=Administrators,ou=groups,ou=system" );
+        ADMIN_GROUP_DN_NORMALIZED = ( LdapDN ) ADMIN_GROUP_DN.clone();
+        ADMIN_GROUP_DN_NORMALIZED.normalize( normalizerMapping );
+        loadAdministrators();
+    }
+    
+    
+    private void loadAdministrators() throws NamingException
+    {
+        // read in the administrators and cache their normalized names
+        Set newAdministrators = new HashSet( 2 );
+        Attributes adminGroup = nexus.lookup( ADMIN_GROUP_DN_NORMALIZED );
+        
+        if ( adminGroup == null )
+        {
+            return;
+        }
+        
+        Attribute uniqueMember = adminGroup.get( "uniqueMember" );
+        for ( int ii = 0; ii < uniqueMember.size(); ii++ )
+        {
+            LdapDN memberDn = new LdapDN( ( String ) uniqueMember.get( ii ) );
+            memberDn.normalize( normalizerMapping );
+            newAdministrators.add( memberDn.toNormName() );
+        }
+        administrators = newAdministrators;
     }
 
-
+    
     // Note:
     //    Lookup, search and list operations need to be handled using a filter
     // and so we need access to the filter service.
@@ -122,7 +154,7 @@
             return;
         }
 
-        Name principalDn = getPrincipal().getJndiName();
+        LdapDN principalDn = getPrincipal().getJndiName();
 
         if ( name.toString().equals( "" ) )
         {
@@ -130,7 +162,13 @@
             throw new LdapNoPermissionException( msg );
         }
 
-        if ( name == ADMIN_DN || name.equals( ADMIN_DN ) )
+        if ( name.toNormName().equals( ADMIN_GROUP_DN_NORMALIZED.toNormName() ) )
+        {
+            String msg = "The Administrators group cannot be deleted!";
+            throw new LdapNoPermissionException( msg );
+        }
+
+        if ( isTheAdministrator( name ) )
         {
             String msg = "User " + principalDn;
             msg += " does not have permission to delete the admin account.";
@@ -138,7 +176,7 @@
             throw new LdapNoPermissionException( msg );
         }
 
-        if ( name.size() > 2 && name.startsWith( USER_BASE_DN ) && !principalDn.equals( ADMIN_DN ) )
+        if ( name.size() > 2 && name.startsWith( USER_BASE_DN ) && !isAnAdministrator( principalDn ) )
         {
             String msg = "User " + principalDn;
             msg += " does not have permission to delete the user account: ";
@@ -146,7 +184,7 @@
             throw new LdapNoPermissionException( msg );
         }
 
-        if ( name.size() > 2 && name.startsWith( GROUP_BASE_DN ) && !principalDn.equals( ADMIN_DN ) )
+        if ( name.size() > 2 && name.startsWith( GROUP_BASE_DN ) && !isAnAdministrator( principalDn ) )
         {
             String msg = "User " + principalDn;
             msg += " does not have permission to delete the group entry: ";
@@ -157,6 +195,24 @@
         nextInterceptor.delete( name );
     }
 
+    
+    private final boolean isTheAdministrator( LdapDN normalizedDn )
+    {
+        return normalizedDn.toNormName() == PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED || 
+             normalizedDn.toNormName().equals( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED );
+    }
+    
+    
+    private final boolean isAnAdministrator( LdapDN normalizedDn ) throws NamingException
+    {
+        if ( isTheAdministrator( normalizedDn ) )
+        {
+            return true;
+        }
+        
+        return administrators.contains( normalizedDn.toNormName() );
+    }
+    
 
     /**
      * Note that we do nothing here. First because this is not an externally
@@ -186,6 +242,14 @@
         if ( enabled )
         {
             protectModifyAlterations( name );
+            nextInterceptor.modify( name, modOp, attrs );
+
+            // update administrators if we change administrators group
+            if ( name.toNormName().equals( ADMIN_GROUP_DN_NORMALIZED.toNormName() ) )
+            {
+                loadAdministrators();
+            }
+            return;
         }
 
         nextInterceptor.modify( name, modOp, attrs );
@@ -203,7 +267,16 @@
         if ( enabled )
         {
             protectModifyAlterations( name );
+            nextInterceptor.modify( name, items );
+
+            // update administrators if we change administrators group
+            if ( name.toNormName().equals( ADMIN_GROUP_DN_NORMALIZED.toNormName() ) )
+            {
+                loadAdministrators();
+            }
+            return;
         }
+        
         nextInterceptor.modify( name, items );
     }
 
@@ -218,8 +291,14 @@
             throw new LdapNoPermissionException( msg );
         }
 
-        if ( !principalDn.toNormName().equals( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) )
+        if ( ! isAnAdministrator( principalDn ) )
         {
+            // allow self modifications 
+            if ( dn.toNormName().equals( getPrincipal().getJndiName().toNormName() ) )
+            {
+                return;
+            }
+            
             if ( dn.toNormName().equals( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) )
             {
                 String msg = "User " + principalDn;
@@ -228,7 +307,7 @@
                 throw new LdapNoPermissionException( msg );
             }
 
-            if ( dn.size() > 2 && dn.startsWith( USER_BASE_DN ) )
+            if ( dn.size() > 2 && dn.startsWith( USER_BASE_DN_NORMALIZED ) )
             {
                 String msg = "User " + principalDn;
                 msg += " does not have permission to modify the account of the";
@@ -238,7 +317,7 @@
                 throw new LdapNoPermissionException( msg );
             }
 
-            if ( dn.size() > 2 && dn.startsWith( GROUP_BASE_DN ) )
+            if ( dn.size() > 2 && dn.startsWith( GROUP_BASE_DN_NORMALIZED ) )
             {
                 String msg = "User " + principalDn;
                 msg += " does not have permission to modify the group entry ";
@@ -247,8 +326,8 @@
             }
         }
     }
-
-
+    
+    
     // ------------------------------------------------------------------------
     // DN altering operations are a no no for any user entry.  Basically here
     // are the rules of conduct to follow:
@@ -290,7 +369,7 @@
     }
 
 
-    private void protectDnAlterations( Name dn ) throws LdapNoPermissionException
+    private void protectDnAlterations( LdapDN dn ) throws NamingException
     {
         LdapDN principalDn = getPrincipal().getJndiName();
 
@@ -300,7 +379,12 @@
             throw new LdapNoPermissionException( msg );
         }
 
-        if ( dn == ADMIN_DN || dn.equals( ADMIN_DN ) )
+        if ( dn.toNormName().equals( ADMIN_GROUP_DN_NORMALIZED.toNormName() ) )
+        {
+            throw new LdapNoPermissionException( "The Administrators group cannot be moved or renamed!" );
+        }
+        
+        if ( isTheAdministrator( dn ) )
         {
             String msg = "User '" + principalDn.getUpName();
             msg += "' does not have permission to move or rename the admin";
@@ -309,7 +393,7 @@
             throw new LdapNoPermissionException( msg );
         }
 
-        if ( dn.size() > 2 && dn.startsWith( USER_BASE_DN ) && !principalDn.equals( ADMIN_DN ) )
+        if ( dn.size() > 2 && dn.startsWith( USER_BASE_DN_NORMALIZED ) && !isAnAdministrator( principalDn ) )
         {
             String msg = "User '" + principalDn;
             msg += "' does not have permission to move or rename the user";
@@ -318,7 +402,7 @@
             throw new LdapNoPermissionException( msg );
         }
 
-        if ( dn.size() > 2 && dn.startsWith( GROUP_BASE_DN ) && !principalDn.equals( ADMIN_DN ) )
+        if ( dn.size() > 2 && dn.startsWith( GROUP_BASE_DN_NORMALIZED ) && !isAnAdministrator( principalDn ) )
         {
             String msg = "User " + principalDn;
             msg += " does not have permission to move or rename the group entry ";
@@ -358,9 +442,9 @@
     {
         LdapContext ctx = ( LdapContext ) InvocationStack.getInstance().peek().getCaller();
         LdapDN principalDn = ( ( ServerContext ) ctx ).getPrincipal().getJndiName();
-        if ( !principalDn.equals( ADMIN_DN ) )
+        if ( !isAnAdministrator( principalDn ) )
         {
-            if ( normalizedDn.size() > 2 && normalizedDn.startsWith( USER_BASE_DN ) )
+            if ( normalizedDn.size() > 2 && normalizedDn.startsWith( USER_BASE_DN_NORMALIZED ) )
             {
                 // allow for self reads
                 if ( normalizedDn.getNormName().equals( principalDn.getNormName() ) )
@@ -374,7 +458,7 @@
                 throw new LdapNoPermissionException( msg );
             }
 
-            if ( normalizedDn.size() > 2 && normalizedDn.startsWith( GROUP_BASE_DN ) )
+            if ( normalizedDn.size() > 2 && normalizedDn.startsWith( GROUP_BASE_DN_NORMALIZED ) )
             {
                 // allow for self reads
                 if ( normalizedDn.getNormName().equals( principalDn.getNormName() ) )
@@ -388,7 +472,7 @@
                 throw new LdapNoPermissionException( msg );
             }
 
-            if ( normalizedDn.equals( ADMIN_DN ) )
+            if ( isTheAdministrator( normalizedDn ) )
             {
                 // allow for self reads
                 if ( normalizedDn.getNormName().equals( principalDn.getNormName() ) )
@@ -455,12 +539,10 @@
         LdapDN principalDn = ( ( ServerContext ) invocation.getCaller() ).getPrincipal().getJndiName();
         LdapDN dn;
         dn = new LdapDN( result.getName() );
-        dn.normalize( oidsMap );
+        dn.normalize( normalizerMapping );
 
-        boolean isAdmin = principalDn.toNormName().equals( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED );
-        
-        // Admin user gets full access to all entries
-        if ( isAdmin )
+        // Admin users gets full access to all entries
+        if ( isAnAdministrator( principalDn ) )
         {
             return true;
         }
@@ -486,7 +568,7 @@
         }
         
         // Non-admin users cannot read the admin entry
-        if ( dn.toNormName().equals( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) )
+        if ( isTheAdministrator( dn ) )
         {
             return false;
         }

Modified: directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/GroupCache.java
URL: http://svn.apache.org/viewvc/directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/GroupCache.java?rev=439119&r1=439118&r2=439119&view=diff
==============================================================================
--- directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/GroupCache.java (original)
+++ directory/trunks/apacheds/core/src/main/java/org/apache/directory/server/core/authz/GroupCache.java Thu Aug 31 17:38:32 2006
@@ -71,16 +71,24 @@
      */
     private Map normalizerMap;
     
+    /** the normalized dn of the administrators group */
+    LdapDN administratorsGroupDn;
+    
     /**
      * Creates a static group cache.
      *
      * @param factoryCfg the context factory configuration for the server
      */
-    public GroupCache(DirectoryServiceConfiguration factoryCfg) throws NamingException
+    public GroupCache( DirectoryServiceConfiguration factoryCfg ) throws NamingException
     {
     	normalizerMap = factoryCfg.getGlobalRegistries().getAttributeTypeRegistry().getNormalizerMapping();
         this.nexus = factoryCfg.getPartitionNexus();
         this.env = ( Hashtable ) factoryCfg.getEnvironment().clone();
+        
+        // stuff for dealing with the admin group
+        administratorsGroupDn = new LdapDN( "cn=Administrators,ou=groups,ou=system" );
+        administratorsGroupDn.normalize( normalizerMap );
+
         initialize();
     }
 
@@ -405,6 +413,31 @@
         }
     }
 
+    
+    /**
+     * An optimization.  By having this method here we can directly access the group
+     * membership information and lookup to see if the principalDn is contained within.
+     * 
+     * @param principalDn the normalized DN of the user to check if they are an admin
+     * @return true if the principal is an admin or the admin
+     */
+    public final boolean isPrincipalAnAdministrator( LdapDN principalDn )
+    {
+        if ( principalDn.toNormName().equals( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) )
+        {
+            return true;
+        }
+        
+        Set members = ( Set ) groups.get( administratorsGroupDn.toNormName() );
+        if ( members == null )
+        {
+            log.warn( "What do you mean there is no administrators group? This is bad news." );
+            return false;
+        }
+        
+        return members.contains( principalDn.toNormName() );
+    }
+    
 
     /**
      * Gets the set of groups a user is a member of.  The groups are returned