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 2005/10/15 19:54:49 UTC
svn commit: r321394 - in /directory/apacheds/trunk/core/src:
main/java/org/apache/ldap/server/authz/
main/java/org/apache/ldap/server/authz/support/
test/org/apache/ldap/server/authz/ test/org/apache/ldap/server/authz/support/
Author: akarasulu
Date: Sat Oct 15 10:54:41 2005
New Revision: 321394
URL: http://svn.apache.org/viewcvs?rev=321394&view=rev
Log:
changes ...
o added rename, move and combined test cases
o added modify test cases
o added more utility functions to the AbstractAuthorizationTest
o commented out code for requiring grantRemove/grantAdd perms on old RDN
deletes in modifyRdn operations that change the RDN - this does not
comply with X.501 although it makes a lot of sense
o OldAuthenticationService now disables itself for its static rules when
the basic authorization service is enabled.
o fixed bug in move operation handling to make sure import/export/rename
permissions are correctly mandated for respective overloads
o fixed bug in AbstractAuthorizationTest: was not looking up operational
attribute administrativeRole properly to create subentries under ou=system
o fixed bug in MicroOperationFilter: filter accepted ACI without testing
the presence of all required micro operation permissions.
o fixed bug in GroupCache: group cache was not properly updating the cache on
modify operations on groups that are a groupOfNames and groupOfUniqueNames
o fixed NPE in GroupCache
o fixed bug in AuthorizationService in lookup(Name, String[]) where the
attribute ids where not being used for nexus lookups.
TODO:
o more testing with different kinds of ACI constructs should add to the total
number of tests per operation
o doco badly needed
o need to make the code not use the nexus for search list and lookups - the
next interceptor should be used
Added:
directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/ModifyAuthorizationTest.java (with props)
directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/MoveRenameAuthorizationTest.java (with props)
Modified:
directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/AuthorizationService.java
directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/GroupCache.java
directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/OldAuthorizationService.java
directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/support/MicroOperationFilter.java
directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/AbstractAuthorizationTest.java
directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/support/MicroOperationFilterTest.java
Modified: directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/AuthorizationService.java
URL: http://svn.apache.org/viewcvs/directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/AuthorizationService.java?rev=321394&r1=321393&r2=321394&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/AuthorizationService.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/AuthorizationService.java Sat Oct 15 10:54:41 2005
@@ -35,7 +35,6 @@
import org.apache.ldap.common.aci.ACIItem;
import org.apache.ldap.common.exception.LdapNamingException;
import org.apache.ldap.common.message.ResultCodeEnum;
-import org.apache.ldap.common.util.NamespaceTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -524,7 +523,7 @@
public Attributes lookup( NextInterceptor next, Name dn, String[] attrIds ) throws NamingException
{
- Attributes entry = nexus.lookup( dn, attrIds );
+ Attributes entry = nexus.lookup( dn );
LdapPrincipal user = ( ( ServerContext ) InvocationStack.getInstance().peek().getCaller() ).getPrincipal();
if ( user.getName().equalsIgnoreCase( DirectoryPartitionNexus.ADMIN_PRINCIPAL ) || ! enabled )
@@ -579,32 +578,32 @@
engine.checkPermission( next, userGroups, user.getJndiName(), user.getAuthenticationLevel(), name, null,
null, Collections.singleton( MicroOperation.RENAME ), tuples, entry );
- if ( deleteOldRn )
- {
- String oldRn = name.get( name.size() - 1 );
- if ( NamespaceTools.hasCompositeComponents( oldRn ) )
- {
- String[] comps = NamespaceTools.getCompositeComponents( oldRn );
- for ( int ii = 0; ii < comps.length; ii++ )
- {
- String id = NamespaceTools.getRdnAttribute( comps[ii] );
- String value = NamespaceTools.getRdnValue( comps[ii] );
- engine.checkPermission( next, userGroups, user.getJndiName(),
- user.getAuthenticationLevel(), name, id,
- value, Collections.singleton( MicroOperation.REMOVE ),
- tuples, entry );
- }
- }
- else
- {
- String id = NamespaceTools.getRdnAttribute( oldRn );
- String value = NamespaceTools.getRdnValue( oldRn );
- engine.checkPermission( next, userGroups, user.getJndiName(),
- user.getAuthenticationLevel(), name, id,
- value, Collections.singleton( MicroOperation.REMOVE ),
- tuples, entry );
- }
- }
+// if ( deleteOldRn )
+// {
+// String oldRn = name.get( name.size() - 1 );
+// if ( NamespaceTools.hasCompositeComponents( oldRn ) )
+// {
+// String[] comps = NamespaceTools.getCompositeComponents( oldRn );
+// for ( int ii = 0; ii < comps.length; ii++ )
+// {
+// String id = NamespaceTools.getRdnAttribute( comps[ii] );
+// String value = NamespaceTools.getRdnValue( comps[ii] );
+// engine.checkPermission( next, userGroups, user.getJndiName(),
+// user.getAuthenticationLevel(), name, id,
+// value, Collections.singleton( MicroOperation.REMOVE ),
+// tuples, entry );
+// }
+// }
+// else
+// {
+// String id = NamespaceTools.getRdnAttribute( oldRn );
+// String value = NamespaceTools.getRdnValue( oldRn );
+// engine.checkPermission( next, userGroups, user.getJndiName(),
+// user.getAuthenticationLevel(), name, id,
+// value, Collections.singleton( MicroOperation.REMOVE ),
+// tuples, entry );
+// }
+// }
next.modifyRn( name, newRn, deleteOldRn );
tupleCache.subentryRenamed( name, newName );
@@ -635,8 +634,9 @@
addSubentryAciTuples( tuples, oriChildName, entry );
Collection perms = new HashSet();
- perms.add( MicroOperation.RENAME );
+ perms.add( MicroOperation.IMPORT );
perms.add( MicroOperation.EXPORT );
+ perms.add( MicroOperation.RENAME );
engine.checkPermission( next, userGroups, user.getJndiName(), user.getAuthenticationLevel(),
oriChildName, null, null, perms, tuples, entry );
@@ -647,32 +647,32 @@
engine.checkPermission( next, userGroups, user.getJndiName(), user.getAuthenticationLevel(),
oriChildName, null, null, Collections.singleton( MicroOperation.IMPORT ), tuples, entry );
- if ( deleteOldRn )
- {
- String oldRn = oriChildName.get( oriChildName.size() - 1 );
- if ( NamespaceTools.hasCompositeComponents( oldRn ) )
- {
- String[] comps = NamespaceTools.getCompositeComponents( oldRn );
- for ( int ii = 0; ii < comps.length; ii++ )
- {
- String id = NamespaceTools.getRdnAttribute( comps[ii] );
- String value = NamespaceTools.getRdnValue( comps[ii] );
- engine.checkPermission( next, userGroups, user.getJndiName(),
- user.getAuthenticationLevel(), oriChildName, id,
- value, Collections.singleton( MicroOperation.REMOVE ),
- tuples, entry );
- }
- }
- else
- {
- String id = NamespaceTools.getRdnAttribute( oldRn );
- String value = NamespaceTools.getRdnValue( oldRn );
- engine.checkPermission( next, userGroups, user.getJndiName(),
- user.getAuthenticationLevel(), oriChildName, id,
- value, Collections.singleton( MicroOperation.REMOVE ),
- tuples, entry );
- }
- }
+// if ( deleteOldRn )
+// {
+// String oldRn = oriChildName.get( oriChildName.size() - 1 );
+// if ( NamespaceTools.hasCompositeComponents( oldRn ) )
+// {
+// String[] comps = NamespaceTools.getCompositeComponents( oldRn );
+// for ( int ii = 0; ii < comps.length; ii++ )
+// {
+// String id = NamespaceTools.getRdnAttribute( comps[ii] );
+// String value = NamespaceTools.getRdnValue( comps[ii] );
+// engine.checkPermission( next, userGroups, user.getJndiName(),
+// user.getAuthenticationLevel(), oriChildName, id,
+// value, Collections.singleton( MicroOperation.REMOVE ),
+// tuples, entry );
+// }
+// }
+// else
+// {
+// String id = NamespaceTools.getRdnAttribute( oldRn );
+// String value = NamespaceTools.getRdnValue( oldRn );
+// engine.checkPermission( next, userGroups, user.getJndiName(),
+// user.getAuthenticationLevel(), oriChildName, id,
+// value, Collections.singleton( MicroOperation.REMOVE ),
+// tuples, entry );
+// }
+// }
next.move( oriChildName, newParentName, newRn, deleteOldRn );
tupleCache.subentryRenamed( oriChildName, newName );
Modified: directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/GroupCache.java
URL: http://svn.apache.org/viewcvs/directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/GroupCache.java?rev=321394&r1=321393&r2=321394&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/GroupCache.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/GroupCache.java Sat Oct 15 10:54:41 2005
@@ -132,6 +132,21 @@
{
Attribute oc = entry.get( OC_ATTR );
+ if ( oc == null )
+ {
+ if ( entry.get( MEMBER_ATTR ) != null )
+ {
+ return entry.get( MEMBER_ATTR );
+ }
+
+ if ( entry.get( UNIQUEMEMBER_ATTR ) != null )
+ {
+ return entry.get( UNIQUEMEMBER_ATTR );
+ }
+
+ return null;
+ }
+
if ( oc.contains( GROUPOFNAMES_OC ) )
{
return entry.get( MEMBER_ATTR );
@@ -320,7 +335,7 @@
*/
public void groupModified( Name name, int modOp, Attributes mods, Attributes entry ) throws NamingException
{
- Attribute members = getMemberAttribute( entry );
+ Attribute members = getMemberAttribute( mods );
if ( members == null )
{
@@ -353,6 +368,12 @@
{
String group = ( String ) list.next();
Set members = ( Set ) groups.get( group );
+
+ if ( members == null )
+ {
+ continue;
+ }
+
if ( members.contains( member ) )
{
if ( memberGroups == null )
Modified: directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/OldAuthorizationService.java
URL: http://svn.apache.org/viewcvs/directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/OldAuthorizationService.java?rev=321394&r1=321393&r2=321394&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/OldAuthorizationService.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/OldAuthorizationService.java Sat Oct 15 10:54:41 2005
@@ -76,6 +76,8 @@
* the name parser used by this service
*/
private DnParser dnParser;
+ private boolean enabled = true;
+
/**
@@ -90,6 +92,9 @@
{
AttributeTypeRegistry atr = factoryCfg.getGlobalRegistries().getAttributeTypeRegistry();
dnParser = new DnParser( new ConcreteNameComponentNormalizer( atr ) );
+
+ // disable this static module if basic access control mechanisms are enabled
+ enabled = ! factoryCfg.getStartupConfiguration().isAccessControlEnabled();
}
@@ -99,6 +104,12 @@
public void delete( NextInterceptor nextInterceptor, Name name ) throws NamingException
{
+ if ( !enabled )
+ {
+ nextInterceptor.delete( name );
+ return;
+ }
+
Name principalDn = getPrincipal().getJndiName();
if ( name.toString().equals( "" ) )
@@ -162,7 +173,11 @@
*/
public void modify( NextInterceptor nextInterceptor, Name name, int modOp, Attributes attrs ) throws NamingException
{
- protectModifyAlterations( name );
+ if ( enabled )
+ {
+ protectModifyAlterations( name );
+ }
+
nextInterceptor.modify( name, modOp, attrs );
}
@@ -175,7 +190,10 @@
*/
public void modify( NextInterceptor nextInterceptor, Name name, ModificationItem[] items ) throws NamingException
{
- protectModifyAlterations( name );
+ if ( enabled )
+ {
+ protectModifyAlterations( name );
+ }
nextInterceptor.modify( name, items );
}
@@ -192,13 +210,6 @@
if ( !principalDn.equals( ADMIN_DN ) )
{
- if ( dn == ADMIN_DN || dn.equals( ADMIN_DN ) )
- {
- String msg = "User " + principalDn;
- msg += " does not have permission to modify the admin account.";
- throw new LdapNoPermissionException( msg );
- }
-
if ( dn.size() > 2 && dn.startsWith( USER_BASE_DN ) )
{
String msg = "User " + principalDn;
@@ -232,14 +243,20 @@
public void modifyRn( NextInterceptor nextInterceptor, Name name, String newRn, boolean deleteOldRn ) throws NamingException
{
- protectDnAlterations( name );
+ if ( enabled )
+ {
+ protectDnAlterations( name );
+ }
nextInterceptor.modifyRn( name, newRn, deleteOldRn );
}
public void move( NextInterceptor nextInterceptor, Name oriChildName, Name newParentName ) throws NamingException
{
- protectDnAlterations( oriChildName );
+ if ( enabled )
+ {
+ protectDnAlterations( oriChildName );
+ }
nextInterceptor.move( oriChildName, newParentName );
}
@@ -248,7 +265,10 @@
Name oriChildName, Name newParentName, String newRn,
boolean deleteOldRn ) throws NamingException
{
- protectDnAlterations( oriChildName );
+ if ( enabled )
+ {
+ protectDnAlterations( oriChildName );
+ }
nextInterceptor.move( oriChildName, newParentName, newRn, deleteOldRn );
}
@@ -294,9 +314,9 @@
public Attributes lookup( NextInterceptor nextInterceptor, Name name ) throws NamingException
{
Attributes attributes = nextInterceptor.lookup( name );
- if ( attributes == null )
+ if ( ! enabled || attributes == null )
{
- return null;
+ return attributes;
}
protectLookUp( name );
@@ -307,9 +327,9 @@
public Attributes lookup( NextInterceptor nextInterceptor, Name name, String[] attrIds ) throws NamingException
{
Attributes attributes = nextInterceptor.lookup( name, attrIds );
- if ( attributes == null )
+ if ( ! enabled || attributes == null )
{
- return null;
+ return attributes;
}
protectLookUp( name );
@@ -375,31 +395,36 @@
SearchControls searchCtls ) throws NamingException
{
NamingEnumeration e = nextInterceptor.search( base, env, filter, searchCtls );
+ if ( !enabled )
+ {
+ return e;
+ }
//if ( searchCtls.getReturningAttributes() != null )
//{
// return null;
//}
- LdapContext ctx =
- ( LdapContext ) InvocationStack.getInstance().peek().getCaller();
+ LdapContext ctx = ( LdapContext ) InvocationStack.getInstance().peek().getCaller();
return new SearchResultFilteringEnumeration( e, searchCtls, ctx,
- new SearchResultFilter()
+ new SearchResultFilter()
+ {
+ public boolean accept( LdapContext ctx, SearchResult result, SearchControls controls )
+ throws NamingException
{
- public boolean accept( LdapContext ctx, SearchResult result,
- SearchControls controls )
- throws NamingException
- {
- return OldAuthorizationService.this.isSearchable( ctx, result );
- }
- } );
+ return OldAuthorizationService.this.isSearchable( ctx, result );
+ }
+ });
}
public NamingEnumeration list( NextInterceptor nextInterceptor, Name base ) throws NamingException
{
NamingEnumeration e = nextInterceptor.list( base );
- LdapContext ctx =
- ( LdapContext ) InvocationStack.getInstance().peek().getCaller();
+ if ( !enabled )
+ {
+ return e;
+ }
+ LdapContext ctx = ( LdapContext ) InvocationStack.getInstance().peek().getCaller();
return new SearchResultFilteringEnumeration( e, null, ctx,
new SearchResultFilter()
Modified: directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/support/MicroOperationFilter.java
URL: http://svn.apache.org/viewcvs/directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/support/MicroOperationFilter.java?rev=321394&r1=321393&r2=321394&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/support/MicroOperationFilter.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/support/MicroOperationFilter.java Sat Oct 15 10:54:41 2005
@@ -40,7 +40,11 @@
*/
public class MicroOperationFilter implements ACITupleFilter
{
- public Collection filter( Collection tuples, OperationScope scope, NextInterceptor next, Collection userGroupNames, Name userName, Attributes userEntry, AuthenticationLevel authenticationLevel, Name entryName, String attrId, Object attrValue, Attributes entry, Collection microOperations ) throws NamingException
+ public Collection filter( Collection tuples, OperationScope scope, NextInterceptor next,
+ Collection userGroupNames, Name userName, Attributes userEntry,
+ AuthenticationLevel authenticationLevel, Name entryName, String attrId,
+ Object attrValue, Attributes entry, Collection microOperations )
+ throws NamingException
{
if( tuples.size() == 0 )
{
@@ -50,13 +54,20 @@
for( Iterator i = tuples.iterator(); i.hasNext(); )
{
ACITuple tuple = ( ACITuple ) i.next();
- boolean retain = false;
+
+ /*
+ * The ACITuple must contain all the MicroOperations specified within the
+ * microOperations argument. Just matching a single microOperation is not
+ * enough. All must be matched to retain the ACITuple.
+ */
+
+ boolean retain = true;
for( Iterator j = microOperations.iterator(); j.hasNext(); )
{
MicroOperation microOp = ( MicroOperation ) j.next();
- if( tuple.getMicroOperations().contains( microOp ) )
+ if( ! tuple.getMicroOperations().contains( microOp ) )
{
- retain = true;
+ retain = false;
break;
}
}
Modified: directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/AbstractAuthorizationTest.java
URL: http://svn.apache.org/viewcvs/directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/AbstractAuthorizationTest.java?rev=321394&r1=321393&r2=321394&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/AbstractAuthorizationTest.java (original)
+++ directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/AbstractAuthorizationTest.java Sat Oct 15 10:54:41 2005
@@ -114,6 +114,20 @@
/**
+ * Deletes a user with a specific UID under ou=users,ou=system.
+ *
+ * @param uid the RDN value for the user to delete
+ * @throws NamingException if there are problems removing the user
+ * i.e. user does not exist
+ */
+ public void deleteUser( String uid ) throws NamingException
+ {
+ DirContext adminCtx = getContextAsAdmin();
+ adminCtx.destroySubcontext( "uid="+uid+",ou=users" );
+ }
+
+
+ /**
* Creates a simple user as an inetOrgPerson under the ou=users,ou=system
* container. The user's RDN attribute is the uid argument. This argument
* is also used as the value of the two MUST attributes: sn and cn.
@@ -160,6 +174,23 @@
/**
+ * Removes a user from a group.
+ *
+ * @param userUid the RDN attribute value of the user to remove from the group
+ * @param groupCn the RDN attribute value of the group to have user removed from
+ * @throws NamingException if there are problems accessing the group
+ */
+ public void removeUserFromGroup( String userUid, String groupCn ) throws NamingException
+ {
+ DirContext adminCtx = getContextAsAdmin();
+ Attributes changes = new BasicAttributes( "uniqueMember",
+ "uid="+userUid+",ou=users,ou=system", true );
+ adminCtx.modifyAttributes( "cn="+groupCn+",ou=groups",
+ DirContext.REMOVE_ATTRIBUTE, changes );
+ }
+
+
+ /**
* Gets the context at ou=system as a specific user.
*
* @param user the DN of the user to get the context as
@@ -193,6 +224,13 @@
}
+ public void deleteAccessControlSubentry( String cn ) throws NamingException
+ {
+ DirContext adminCtx = getContextAsAdmin();
+ adminCtx.destroySubcontext( "cn=" + cn );
+ }
+
+
/**
* Creates an access control subentry under ou=system whose subtree covers
* the entire naming context.
@@ -206,7 +244,7 @@
DirContext adminCtx = getContextAsAdmin();
// modify ou=system to be an AP for an A/C AA if it is not already
- Attributes ap = adminCtx.getAttributes( "" );
+ Attributes ap = adminCtx.getAttributes( "", new String[] { "administrativeRole" } );
Attribute administrativeRole = ap.get( "administrativeRole" );
if ( administrativeRole == null || ! administrativeRole.contains( SubentryService.AC_AREA ) )
{
Added: directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/ModifyAuthorizationTest.java
URL: http://svn.apache.org/viewcvs/directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/ModifyAuthorizationTest.java?rev=321394&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/ModifyAuthorizationTest.java (added)
+++ directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/ModifyAuthorizationTest.java Sat Oct 15 10:54:41 2005
@@ -0,0 +1,544 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.ldap.server.authz;
+
+
+import org.apache.ldap.common.exception.LdapNoPermissionException;
+import org.apache.ldap.common.name.LdapName;
+
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+import javax.naming.Name;
+import javax.naming.directory.*;
+import java.util.List;
+import java.util.ArrayList;
+
+
+/**
+ * Tests whether or not authorization around entry modify operations work properly.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class ModifyAuthorizationTest extends AbstractAuthorizationTest
+{
+ /**
+ * Checks if an attribute of a simple entry (an organizationalUnit) with an RDN
+ * relative to ou=system can be modified by a specific non-admin user. If a
+ * permission exception is encountered it is caught and false is returned,
+ * otherwise true is returned. The entry is deleted after being created just in case
+ * subsequent calls to this method are made in the same test case: the admin account
+ * is used to add and delete this test entry so permissions to add and delete are not
+ * required to test the modify operation by the user.
+ *
+ * @param uid the unique identifier for the user (presumed to exist under ou=users,ou=system)
+ * @param password the password of this user
+ * @param entryRdn the relative DN, relative to ou=system where entry is created
+ * for modification test
+ * @param mods the modifications to make to the entry
+ * @return true if the modifications can be made by the user at the specified location,
+ * false otherwise.
+ * @throws javax.naming.NamingException if there are problems conducting the test
+ */
+ public boolean checkCanModifyAs( String uid, String password, String entryRdn, ModificationItem[] mods )
+ throws NamingException
+ {
+ // create the entry with the telephoneNumber attribute to modify
+ Attributes testEntry = new BasicAttributes( "ou", "testou", true );
+ Attribute objectClass = new BasicAttribute( "objectClass" );
+ testEntry.put( objectClass );
+ objectClass.add( "top" );
+ objectClass.add( "organizationalUnit" );
+ testEntry.put( "telephoneNumber", "867-5309" ); // jenny don't change your number
+
+ DirContext adminContext = getContextAsAdmin();
+
+ try
+ {
+ // create the entry as admin
+ LdapName userName = new LdapName( "uid="+uid+",ou=users,ou=system" );
+ adminContext.createSubcontext( entryRdn, testEntry );
+
+ // modify the entry as the user
+ DirContext userContext = getContextAs( userName, password );
+ userContext.modifyAttributes( entryRdn, mods );
+
+ return true;
+ }
+ catch ( LdapNoPermissionException e )
+ {
+ return false;
+ }
+ finally
+ {
+ // let's clean up
+ adminContext.destroySubcontext( entryRdn );
+ }
+ }
+
+
+ /**
+ * Checks if an attribute of a simple entry (an organizationalUnit) with an RDN
+ * relative to ou=system can be modified by a specific non-admin user. If a
+ * permission exception is encountered it is caught and false is returned,
+ * otherwise true is returned. The entry is deleted after being created just in case
+ * subsequent calls to this method are made in the same test case: the admin account
+ * is used to add and delete this test entry so permissions to add and delete are not
+ * required to test the modify operation by the user.
+ *
+ * @param uid the unique identifier for the user (presumed to exist under ou=users,ou=system)
+ * @param password the password of this user
+ * @param entryRdn the relative DN, relative to ou=system where entry is created
+ * for modification test
+ * @param mods the attributes to modify in the entry
+ * @param modOp the modification operation to use for all attributes
+ * @return true if the modifications can be made by the user at the specified location,
+ * false otherwise.
+ * @throws javax.naming.NamingException if there are problems conducting the test
+ */
+ public boolean checkCanModifyAs( String uid, String password, String entryRdn, int modOp, Attributes mods )
+ throws NamingException
+ {
+ // create the entry with the telephoneNumber attribute to modify
+ Attributes testEntry = new BasicAttributes( "ou", "testou", true );
+ Attribute objectClass = new BasicAttribute( "objectClass" );
+ testEntry.put( objectClass );
+ objectClass.add( "top" );
+ objectClass.add( "organizationalUnit" );
+ testEntry.put( "telephoneNumber", "867-5309" ); // jenny don't change your number
+
+ DirContext adminContext = getContextAsAdmin();
+
+ try
+ {
+ // create the entry as admin
+ LdapName userName = new LdapName( "uid="+uid+",ou=users,ou=system" );
+ adminContext.createSubcontext( entryRdn, testEntry );
+
+ // modify the entry as the user
+ DirContext userContext = getContextAs( userName, password );
+ userContext.modifyAttributes( entryRdn, modOp, mods );
+
+ return true;
+ }
+ catch ( LdapNoPermissionException e )
+ {
+ return false;
+ }
+ finally
+ {
+ // let's clean up
+ adminContext.destroySubcontext( entryRdn );
+ }
+ }
+
+
+ /**
+ * Checks if a user can modify an attribute of their own entry. Users are
+ * presumed to reside under ou=users,ou=system. If a permission exception is
+ * encountered it is caught and false is returned, otherwise true is returned.
+ *
+ * @param uid the unique identifier for the user (presumed to exist under ou=users,ou=system)
+ * @param password the password of this user
+ * @param mods the attributes to modify in the entry
+ * @param modOp the modification operation to use for all attributes
+ * @return true if the modifications can be made by the user his/her own entry,
+ * false otherwise.
+ * @throws javax.naming.NamingException if there are problems conducting the test
+ */
+ public boolean checkCanSelfModify( String uid, String password, int modOp, Attributes mods )
+ throws NamingException
+ {
+ try
+ {
+ // modify the entry as the user
+ Name userEntry = new LdapName( "uid="+uid+",ou=users,ou=system" );
+ DirContext userContext = getContextAs( userEntry, password, userEntry.toString() );
+ userContext.modifyAttributes( "", modOp, mods );
+ return true;
+ }
+ catch ( LdapNoPermissionException e )
+ {
+ return false;
+ }
+ }
+
+
+ /**
+ * Checks if a user can modify an attribute of their own entry. Users are
+ * presumed to reside under ou=users,ou=system. If a permission exception is
+ * encountered it is caught and false is returned, otherwise true is returned.
+ *
+ * @param uid the unique identifier for the user (presumed to exist under ou=users,ou=system)
+ * @param password the password of this user
+ * @param mods the attributes to modify in the entry
+ * @return true if the modifications can be made by the user his/her own entry,
+ * false otherwise.
+ * @throws javax.naming.NamingException if there are problems conducting the test
+ */
+ public boolean checkCanSelfModify( String uid, String password, ModificationItem[] mods )
+ throws NamingException
+ {
+ try
+ {
+ // modify the entry as the user
+ Name userEntry = new LdapName( "uid="+uid+",ou=users,ou=system" );
+ DirContext userContext = getContextAs( userEntry, password, userEntry.toString() );
+ userContext.modifyAttributes( "", mods );
+ return true;
+ }
+ catch ( LdapNoPermissionException e )
+ {
+ return false;
+ }
+ }
+
+
+ /**
+ * Converts a set of attributes and a modification operation type into a MoficationItem array.
+ *
+ * @param modOp the modification operation to perform
+ * @param changes the modifications to the attribute
+ * @return the array of modification items represting the changes
+ * @throws NamingException if there are problems accessing attributes
+ */
+ private ModificationItem[] toItems( int modOp, Attributes changes ) throws NamingException
+ {
+ List mods = new ArrayList();
+ NamingEnumeration list = changes.getAll();
+ while ( list.hasMore() )
+ {
+ Attribute attr = ( Attribute ) list.next();
+ mods.add( new ModificationItem( modOp, attr ) );
+ }
+ ModificationItem[] modArray = new ModificationItem[mods.size()];
+ return ( ModificationItem[] ) mods.toArray( modArray );
+ }
+
+
+ public void testSelfModification() throws NamingException
+ {
+ // ----------------------------------------------------------------------------------
+ // Modify with Attribute Addition
+ // ----------------------------------------------------------------------------------
+
+ // create the non-admin user
+ createUser( "billyd", "billyd" );
+
+ // create the password modification
+ ModificationItem[] mods = toItems( DirContext.REPLACE_ATTRIBUTE,
+ new BasicAttributes( "userPassword", "williams", true ) );
+
+ // try a modify operation which should fail without any ACI
+ assertFalse( checkCanSelfModify( "billyd", "billyd", mods ) );
+
+ // Gives grantModify, and grantRead perm to all users in the Administrators group for
+ // entries and all attribute types and values
+ createAccessControlSubentry( "selfModifyUserPassword",
+ "{ " +
+ "identificationTag \"addAci\", " +
+ "precedence 14, " +
+ "authenticationLevel none, " +
+ "itemOrUserFirst userFirst: { " +
+ "userClasses { thisEntry }, " +
+ "userPermissions { " +
+ "{ protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse, grantRead } }, " +
+ "{ protectedItems {allAttributeValues {userPassword}}, grantsAndDenials { grantAdd, grantRemove } } " +
+ "} } }" );
+
+ // try a modify operation which should succeed with ACI
+ assertTrue( checkCanSelfModify( "billyd", "billyd", mods ) );
+ deleteAccessControlSubentry( "selfModifyUserPassword" );
+ }
+
+
+ /**
+ * Checks to make sure group membership based userClass works for modify operations.
+ *
+ * @throws javax.naming.NamingException if the test encounters an error
+ */
+ public void testGrantModifyByAdministrators() throws NamingException
+ {
+ // ----------------------------------------------------------------------------------
+ // Modify with Attribute Addition
+ // ----------------------------------------------------------------------------------
+
+ // create the add modifications
+ ModificationItem[] mods = toItems( DirContext.ADD_ATTRIBUTE,
+ new BasicAttributes( "registeredAddress", "100 Park Ave.", true ) );
+
+ // create the non-admin user
+ createUser( "billyd", "billyd" );
+
+ // 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
+ // 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 { " +
+ "{ protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse } }, " +
+ "{ protectedItems {allAttributeValues {registeredAddress}}, grantsAndDenials { grantAdd } } " +
+ "} } }" );
+
+ // see if we can now add that test entry which we could not before
+ // 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" );
+
+ // try a modify operation which should succeed with ACI and group membership change
+ assertTrue( checkCanModifyAs( "billyd", "billyd", "ou=testou", mods ) );
+ deleteAccessControlSubentry( "administratorModifyAdd" );
+
+ // ----------------------------------------------------------------------------------
+ // Modify with Attribute Removal
+ // ----------------------------------------------------------------------------------
+
+ // now let's test to see if we can perform a modify with a delete op
+ mods = toItems( DirContext.REMOVE_ATTRIBUTE,
+ new BasicAttributes( "telephoneNumber", "867-5309", true ) );
+
+ // 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
+ // 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 { " +
+ "{ protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse } }, " +
+ "{ protectedItems {allAttributeValues {telephoneNumber}}, grantsAndDenials { grantRemove } } " +
+ "} } }" );
+
+ // try a modify operation which should succeed with ACI and group membership change
+ assertTrue( checkCanModifyAs( "billyd", "billyd", "ou=testou", mods ) );
+ deleteAccessControlSubentry( "administratorModifyRemove" );
+
+ // ----------------------------------------------------------------------------------
+ // Modify with Attribute Replace (requires both grantRemove and grantAdd on attrs)
+ // ----------------------------------------------------------------------------------
+
+ // now let's test to see if we can perform a modify with a delete op
+ mods = toItems( DirContext.REPLACE_ATTRIBUTE,
+ new BasicAttributes( "telephoneNumber", "867-5309", true ) );
+
+ // 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
+ // 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 { " +
+ "{ protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse } }, " +
+ "{ protectedItems {allAttributeValues {telephoneNumber}}, grantsAndDenials { grantAdd, grantRemove } } " +
+ "} } }" );
+
+ // try a modify operation which should succeed with ACI and group membership change
+ assertTrue( checkCanModifyAs( "billyd", "billyd", "ou=testou", mods ) );
+ deleteAccessControlSubentry( "administratorModifyReplace" );
+
+ /* =================================================================================
+ * DO IT ALL OVER AGAIN BUT USE THE OTHER MODIFY METHOD
+ * ================================================================================= */
+
+ // ----------------------------------------------------------------------------------
+ // Modify with Attribute Addition
+ // ----------------------------------------------------------------------------------
+
+ // create the add modifications
+ Attributes changes = new BasicAttributes( "registeredAddress", "100 Park Ave.", true );
+
+ // 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
+ // 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 { " +
+ "{ protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse } }, " +
+ "{ protectedItems {allAttributeValues {registeredAddress}}, grantsAndDenials { grantAdd } } " +
+ "} } }" );
+
+ // try a modify operation which should succeed with ACI and group membership change
+ assertTrue( checkCanModifyAs( "billyd", "billyd", "ou=testou", DirContext.ADD_ATTRIBUTE, changes ) );
+ deleteAccessControlSubentry( "administratorModifyAdd" );
+
+ // ----------------------------------------------------------------------------------
+ // Modify with Attribute Removal
+ // ----------------------------------------------------------------------------------
+
+ // now let's test to see if we can perform a modify with a delete op
+ changes = new BasicAttributes( "telephoneNumber", "867-5309", true );
+
+ // 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
+ // 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 { " +
+ "{ protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse } }, " +
+ "{ protectedItems {allAttributeValues {telephoneNumber}}, grantsAndDenials { grantRemove } } " +
+ "} } }" );
+
+ // try a modify operation which should succeed with ACI and group membership change
+ assertTrue( checkCanModifyAs( "billyd", "billyd", "ou=testou", DirContext.REMOVE_ATTRIBUTE, changes ) );
+ deleteAccessControlSubentry( "administratorModifyRemove" );
+
+ // ----------------------------------------------------------------------------------
+ // Modify with Attribute Replace (requires both grantRemove and grantAdd on attrs)
+ // ----------------------------------------------------------------------------------
+
+ // now let's test to see if we can perform a modify with a delete op
+ changes = new BasicAttributes( "telephoneNumber", "867-5309", true );
+
+ // 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
+ // 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 { " +
+ "{ protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse } }, " +
+ "{ protectedItems {allAttributeValues {telephoneNumber}}, grantsAndDenials { grantAdd, grantRemove } } " +
+ "} } }" );
+
+ // try a modify operation which should succeed with ACI and group membership change
+ assertTrue( checkCanModifyAs( "billyd", "billyd", "ou=testou", DirContext.REPLACE_ATTRIBUTE, changes ) );
+ deleteAccessControlSubentry( "administratorModifyReplace" );
+ }
+
+
+// /**
+// * Checks to make sure name based userClass works for modify operations.
+// *
+// * @throws javax.naming.NamingException if the test encounters an error
+// */
+// public void testGrantModifyByName() throws NamingException
+// {
+// // create the non-admin user
+// createUser( "billyd", "billyd" );
+//
+// // try an modify operation which should fail without any ACI
+// assertFalse( checkCanModifyAs( "billyd", "billyd", "ou=testou", "867-5309" ) );
+//
+// // now add a subentry that enables user billyd to modify an entry below ou=system
+// createAccessControlSubentry( "billydAdd", "{ " +
+// "identificationTag \"addAci\", " +
+// "precedence 14, " +
+// "authenticationLevel none, " +
+// "itemOrUserFirst userFirst: { " +
+// "userClasses { name { \"uid=billyd,ou=users,ou=system\" } }, " +
+// "userPermissions { { " +
+// "protectedItems {entry, allUserAttributeTypesAndValues}, " +
+// "grantsAndDenials { grantModify, grantRead, grantBrowse } } } } }" );
+//
+// // should work now that billyd is authorized by name
+// assertTrue( checkCanModifyAs( "billyd", "billyd", "ou=testou", "867-5309" ) );
+// }
+//
+//
+// /**
+// * Checks to make sure subtree based userClass works for modify operations.
+// *
+// * @throws javax.naming.NamingException if the test encounters an error
+// */
+// public void testGrantModifyBySubtree() throws NamingException
+// {
+// // create the non-admin user
+// createUser( "billyd", "billyd" );
+//
+// // try a modify operation which should fail without any ACI
+// assertFalse( checkCanModifyAs( "billyd", "billyd", "ou=testou", "867-5309" ) );
+//
+// // now add a subentry that enables user billyd to modify an entry below ou=system
+// createAccessControlSubentry( "billyAddBySubtree", "{ " +
+// "identificationTag \"addAci\", " +
+// "precedence 14, " +
+// "authenticationLevel none, " +
+// "itemOrUserFirst userFirst: { " +
+// "userClasses { subtree { { base \"ou=users,ou=system\" } } }, " +
+// "userPermissions { { " +
+// "protectedItems {entry, allUserAttributeTypesAndValues}, " +
+// "grantsAndDenials { grantModify, grantRead, grantBrowse } } } } }" );
+//
+// // should work now that billyd is authorized by the subtree userClass
+// assertTrue( checkCanModifyAs( "billyd", "billyd", "ou=testou", "867-5309" ) );
+// }
+//
+//
+// /**
+// * Checks to make sure <b>allUsers</b> userClass works for modify operations.
+// *
+// * @throws javax.naming.NamingException if the test encounters an error
+// */
+// public void testGrantModifyAllUsers() throws NamingException
+// {
+// // create the non-admin user
+// createUser( "billyd", "billyd" );
+//
+// // try an add operation which should fail without any ACI
+// assertFalse( checkCanModifyAs( "billyd", "billyd", "ou=testou", "867-5309" ) );
+//
+// // now add a subentry that enables anyone to add an entry below ou=system
+// createAccessControlSubentry( "anybodyAdd", "{ " +
+// "identificationTag \"addAci\", " +
+// "precedence 14, " +
+// "authenticationLevel none, " +
+// "itemOrUserFirst userFirst: { " +
+// "userClasses { allUsers }, " +
+// "userPermissions { { " +
+// "protectedItems {entry, allUserAttributeTypesAndValues}, " +
+// "grantsAndDenials { grantModify, grantRead, grantBrowse } } } } }" );
+//
+// // see if we can now modify that test entry's number which we could not before
+// // should work with billyd now that all users are authorized
+// assertTrue( checkCanModifyAs( "billyd", "billyd", "ou=testou", "867-5309" ) );
+// }
+}
Propchange: directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/ModifyAuthorizationTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/MoveRenameAuthorizationTest.java
URL: http://svn.apache.org/viewcvs/directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/MoveRenameAuthorizationTest.java?rev=321394&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/MoveRenameAuthorizationTest.java (added)
+++ directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/MoveRenameAuthorizationTest.java Sat Oct 15 10:54:41 2005
@@ -0,0 +1,482 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.ldap.server.authz;
+
+
+import org.apache.ldap.common.exception.LdapNoPermissionException;
+import org.apache.ldap.common.name.LdapName;
+
+import javax.naming.NamingException;
+import javax.naming.directory.*;
+
+
+/**
+ * Tests whether or not authorization around entry renames and moves work properly.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class MoveRenameAuthorizationTest extends AbstractAuthorizationTest
+{
+ /**
+ * Checks if a simple entry (organizationalUnit) can be renamed at an RDN relative
+ * to ou=system by a specific non-admin user. If a permission exception
+ * is encountered it is caught and false is returned, otherwise true is returned
+ * when the entry is created. The entry is deleted after being created just in case
+ * subsequent calls to this method do not fail: the admin account is used to delete
+ * this test entry so permissions to delete are not required to delete it by the user.
+ *
+ * @param uid the unique identifier for the user (presumed to exist under ou=users,ou=system)
+ * @param password the password of this user
+ * @param entryRdn the relative DN, relative to ou=system where entry renames are tested
+ * @param newRdn the new RDN for the entry under ou=system
+ * @return true if the entry can be renamed by the user at the specified location, false otherwise
+ * @throws javax.naming.NamingException if there are problems conducting the test
+ */
+ public boolean checkCanRenameAs( String uid, String password, String entryRdn, String newRdn )
+ throws NamingException
+ {
+ Attributes testEntry = new BasicAttributes( "ou", "testou", true );
+ Attribute objectClass = new BasicAttribute( "objectClass" );
+ testEntry.put( objectClass );
+ objectClass.add( "top" );
+ objectClass.add( "organizationalUnit" );
+
+ DirContext adminContext = getContextAsAdmin();
+ try
+ {
+ // create the new entry as the admin user
+ adminContext.createSubcontext( entryRdn, testEntry );
+
+ LdapName userName = new LdapName( "uid="+uid+",ou=users,ou=system" );
+ DirContext userContext = getContextAs( userName, password );
+ userContext.rename( entryRdn, newRdn );
+
+ // delete the renamed context as the admin user
+ adminContext.destroySubcontext( newRdn );
+ return true;
+ }
+ catch ( LdapNoPermissionException e )
+ {
+ // delete the original context as the admin user since rename
+ // of newly created test entry did not succeed
+ adminContext.destroySubcontext( entryRdn );
+ return false;
+ }
+ }
+
+
+ /**
+ * Checks to make sure group membership based userClass works for renames,
+ * moves and moves with renames.
+ *
+ * @throws javax.naming.NamingException if the test encounters an error
+ */
+ public void testGrantByAdministrators() throws NamingException
+ {
+ // ----------------------------------------------------------------------------
+ // Test simple RDN change: NO SUBTREE MOVEMENT!
+ // ----------------------------------------------------------------------------
+
+ // create the non-admin user
+ createUser( "billyd", "billyd" );
+
+ // try the rename operation which should fail without any ACI
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou", "ou=newname" ) );
+
+ // Gives grantRename perm to all users in the Administrators group for entries
+ createAccessControlSubentry( "grantRenameByAdmin", "{ " +
+ "identificationTag \"addAci\", " +
+ "precedence 14, " +
+ "authenticationLevel none, " +
+ "itemOrUserFirst userFirst: { " +
+ "userClasses { userGroup { \"cn=Administrators,ou=groups,ou=system\" } }, " +
+ "userPermissions { { " +
+ "protectedItems {entry}, " +
+ "grantsAndDenials { grantRename, grantBrowse } } } } }" );
+
+ // see if we can now rename that test entry which we could not before
+ // rename op should still fail since billyd is not in the admin group
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou", "ou=newname" ) );
+
+ // now add billyd to the Administrator group and try again
+ addUserToGroup( "billyd", "Administrators" );
+
+ // try a rename operation which should succeed with ACI and group membership change
+ assertTrue( checkCanRenameAs( "billyd", "billyd", "ou=testou", "ou=newname" ) );
+
+ // now let's cleanup
+ removeUserFromGroup( "billyd", "Administrators" );
+ deleteAccessControlSubentry( "grantRenameByAdmin" );
+ deleteUser( "billyd" );
+
+ // ----------------------------------------------------------------------------
+ // Test move and RDN change at the same time.
+ // ----------------------------------------------------------------------------
+
+ // create the non-admin user
+ createUser( "billyd", "billyd" );
+
+ // try an move w/ rdn change which should fail without any ACI
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=newname,ou=groups" ) );
+
+ // Gives grantRename, grantImport, grantExport perm to all users in the Administrators
+ // group for entries - browse is needed just to read navigate the tree at root
+ createAccessControlSubentry( "grantRenameMoveByAdmin", "{ " +
+ "identificationTag \"addAci\", " +
+ "precedence 14, " +
+ "authenticationLevel none, " +
+ "itemOrUserFirst userFirst: { " +
+ "userClasses { userGroup { \"cn=Administrators,ou=groups,ou=system\" } }, " +
+ "userPermissions { { " +
+ "protectedItems {entry}, " +
+ "grantsAndDenials { grantExport, grantImport, grantRename, grantBrowse } } } } }" );
+
+ // see if we can move and rename the test entry which we could not before
+ // op should still fail since billyd is not in the admin group
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=newname,ou=groups" ) );
+
+ // now add billyd to the Administrator group and try again
+ addUserToGroup( "billyd", "Administrators" );
+
+ // try move w/ rdn change which should succeed with ACI and group membership change
+ assertTrue( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=newname,ou=groups" ) );
+
+ // now let's cleanup
+ removeUserFromGroup( "billyd", "Administrators" );
+ deleteAccessControlSubentry( "grantRenameMoveByAdmin" );
+ deleteUser( "billyd" );
+
+ // ----------------------------------------------------------------------------
+ // Test move ONLY without any RDN changes.
+ // ----------------------------------------------------------------------------
+
+ // create the non-admin user
+ createUser( "billyd", "billyd" );
+
+ // try move operation which should fail without any ACI
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=testou,ou=groups" ) );
+
+ // Gives grantImport, and grantExport perm to all users in the Administrators group for entries
+ createAccessControlSubentry( "grantMoveByAdmin", "{ " +
+ "identificationTag \"addAci\", " +
+ "precedence 14, " +
+ "authenticationLevel none, " +
+ "itemOrUserFirst userFirst: { " +
+ "userClasses { userGroup { \"cn=Administrators,ou=groups,ou=system\" } }, " +
+ "userPermissions { { " +
+ "protectedItems {entry}, " +
+ "grantsAndDenials { grantExport, grantImport, grantBrowse } } } } }" );
+
+ // see if we can now move that test entry which we could not before
+ // op should still fail since billyd is not in the admin group
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=testou,ou=groups" ) );
+
+ // now add billyd to the Administrator group and try again
+ addUserToGroup( "billyd", "Administrators" );
+
+ // try move operation which should succeed with ACI and group membership change
+ assertTrue( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=testou,ou=groups" ) );
+
+ // now let's cleanup
+ removeUserFromGroup( "billyd", "Administrators" );
+ deleteAccessControlSubentry( "grantMoveByAdmin" );
+ deleteUser( "billyd" );
+ }
+
+
+ /**
+ * Checks to make sure name based userClass works for rename, move, and
+ * rename with move operation access controls.
+ *
+ * @throws javax.naming.NamingException if the test encounters an error
+ */
+ public void testGrantByName() throws NamingException
+ {
+ // ----------------------------------------------------------------------------
+ // Test simple RDN change: NO SUBTREE MOVEMENT!
+ // ----------------------------------------------------------------------------
+
+ // create the non-admin user
+ createUser( "billyd", "billyd" );
+
+ // try the rename operation which should fail without any ACI
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou", "ou=newname" ) );
+
+ // Gives grantRename perm specifically to the billyd user
+ createAccessControlSubentry( "grantRenameByName", "{ " +
+ "identificationTag \"addAci\", " +
+ "precedence 14, " +
+ "authenticationLevel none, " +
+ "itemOrUserFirst userFirst: { " +
+ "userClasses { name { \"uid=billyd,ou=users,ou=system\" } }, " +
+ "userPermissions { { " +
+ "protectedItems {entry}, " +
+ "grantsAndDenials { grantRename, grantBrowse } } } } }" );
+
+ // try a rename operation which should succeed with ACI
+ assertTrue( checkCanRenameAs( "billyd", "billyd", "ou=testou", "ou=newname" ) );
+
+ // now let's cleanup
+ deleteAccessControlSubentry( "grantRenameByName" );
+ deleteUser( "billyd" );
+
+ // ----------------------------------------------------------------------------
+ // Test move and RDN change at the same time.
+ // ----------------------------------------------------------------------------
+
+ // create the non-admin user
+ createUser( "billyd", "billyd" );
+
+ // try an move w/ rdn change which should fail without any ACI
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=newname,ou=groups" ) );
+
+ // Gives grantRename, grantImport, grantExport perm to billyd user on entries
+ createAccessControlSubentry( "grantRenameMoveByName", "{ " +
+ "identificationTag \"addAci\", " +
+ "precedence 14, " +
+ "authenticationLevel none, " +
+ "itemOrUserFirst userFirst: { " +
+ "userClasses { name { \"uid=billyd,ou=users,ou=system\" } }, " +
+ "userPermissions { { " +
+ "protectedItems {entry}, " +
+ "grantsAndDenials { grantExport, grantImport, grantRename, grantBrowse } } } } }" );
+
+ // try move w/ rdn change which should succeed with ACI
+ assertTrue( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=newname,ou=groups" ) );
+
+ // now let's cleanup
+ deleteAccessControlSubentry( "grantRenameMoveByName" );
+ deleteUser( "billyd" );
+
+ // ----------------------------------------------------------------------------
+ // Test move ONLY without any RDN changes.
+ // ----------------------------------------------------------------------------
+
+ // create the non-admin user
+ createUser( "billyd", "billyd" );
+
+ // try move operation which should fail without any ACI
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=testou,ou=groups" ) );
+
+ // Gives grantImport, and grantExport perm to billyd user for entries
+ createAccessControlSubentry( "grantMoveByName", "{ " +
+ "identificationTag \"addAci\", " +
+ "precedence 14, " +
+ "authenticationLevel none, " +
+ "itemOrUserFirst userFirst: { " +
+ "userClasses { name { \"uid=billyd,ou=users,ou=system\" } }, " +
+ "userPermissions { { " +
+ "protectedItems {entry}, " +
+ "grantsAndDenials { grantExport, grantImport, grantBrowse } } } } }" );
+
+ // try move operation which should succeed with ACI
+ assertTrue( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=testou,ou=groups" ) );
+
+ // now let's cleanup
+ deleteAccessControlSubentry( "grantMoveByName" );
+ deleteUser( "billyd" );
+ }
+
+
+ /**
+ * Checks to make sure subtree based userClass works for rename, move, and
+ * rename with move operation access controls.
+ *
+ * @throws javax.naming.NamingException if the test encounters an error
+ */
+ public void testGrantBySubtree() throws NamingException
+ {
+ // ----------------------------------------------------------------------------
+ // Test simple RDN change: NO SUBTREE MOVEMENT!
+ // ----------------------------------------------------------------------------
+
+ // create the non-admin user
+ createUser( "billyd", "billyd" );
+
+ // try the rename operation which should fail without any ACI
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou", "ou=newname" ) );
+
+ // Gives grantRename perm for entries to those users selected by the subtree
+ createAccessControlSubentry( "grantRenameByTree", "{ " +
+ "identificationTag \"addAci\", " +
+ "precedence 14, " +
+ "authenticationLevel none, " +
+ "itemOrUserFirst userFirst: { " +
+ "userClasses { subtree { { base \"ou=users,ou=system\" } } }, " +
+ "userPermissions { { " +
+ "protectedItems {entry}, " +
+ "grantsAndDenials { grantRename, grantBrowse } } } } }" );
+
+ // try a rename operation which should succeed with ACI
+ assertTrue( checkCanRenameAs( "billyd", "billyd", "ou=testou", "ou=newname" ) );
+
+ // now let's cleanup
+ deleteAccessControlSubentry( "grantRenameByTree" );
+ deleteUser( "billyd" );
+
+ // ----------------------------------------------------------------------------
+ // Test move and RDN change at the same time.
+ // ----------------------------------------------------------------------------
+
+ // create the non-admin user
+ createUser( "billyd", "billyd" );
+
+ // try an move w/ rdn change which should fail without any ACI
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=newname,ou=groups" ) );
+
+ // Gives grantRename, grantImport, grantExport for entries to users selected by subtree
+ createAccessControlSubentry( "grantRenameMoveByTree", "{ " +
+ "identificationTag \"addAci\", " +
+ "precedence 14, " +
+ "authenticationLevel none, " +
+ "itemOrUserFirst userFirst: { " +
+ "userClasses { subtree { { base \"ou=users,ou=system\" } } }, " +
+ "userPermissions { { " +
+ "protectedItems {entry}, " +
+ "grantsAndDenials { grantExport, grantImport, grantRename, grantBrowse } } } } }" );
+
+ // try move w/ rdn change which should succeed with ACI
+ assertTrue( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=newname,ou=groups" ) );
+
+ // now let's cleanup
+ deleteAccessControlSubentry( "grantRenameMoveByTree" );
+ deleteUser( "billyd" );
+
+ // ----------------------------------------------------------------------------
+ // Test move ONLY without any RDN changes.
+ // ----------------------------------------------------------------------------
+
+ // create the non-admin user
+ createUser( "billyd", "billyd" );
+
+ // try move operation which should fail without any ACI
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=testou,ou=groups" ) );
+
+ // Gives grantImport, and grantExport perm for entries to subtree selected users
+ createAccessControlSubentry( "grantMoveByTree", "{ " +
+ "identificationTag \"addAci\", " +
+ "precedence 14, " +
+ "authenticationLevel none, " +
+ "itemOrUserFirst userFirst: { " +
+ "userClasses { subtree { { base \"ou=users,ou=system\" } } }, " +
+ "userPermissions { { " +
+ "protectedItems {entry}, " +
+ "grantsAndDenials { grantExport, grantImport, grantBrowse } } } } }" );
+
+ // try move operation which should succeed with ACI
+ assertTrue( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=testou,ou=groups" ) );
+
+ // now let's cleanup
+ deleteAccessControlSubentry( "grantMoveByTree" );
+ deleteUser( "billyd" );
+ }
+
+
+ /**
+ * Checks to make sure the <b>anyUser</b> userClass works for rename, move, and
+ * rename with move operation access controls.
+ *
+ * @throws javax.naming.NamingException if the test encounters an error
+ */
+ public void testGrantByAnyuser() throws NamingException
+ {
+ // ----------------------------------------------------------------------------
+ // Test simple RDN change: NO SUBTREE MOVEMENT!
+ // ----------------------------------------------------------------------------
+
+ // create the non-admin user
+ createUser( "billyd", "billyd" );
+
+ // try the rename operation which should fail without any ACI
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou", "ou=newname" ) );
+
+ // Gives grantRename perm for entries to any user
+ createAccessControlSubentry( "grantRenameByAny", "{ " +
+ "identificationTag \"addAci\", " +
+ "precedence 14, " +
+ "authenticationLevel none, " +
+ "itemOrUserFirst userFirst: { " +
+ "userClasses { allUsers }, " +
+ "userPermissions { { " +
+ "protectedItems {entry}, " +
+ "grantsAndDenials { grantRename, grantBrowse } } } } }" );
+
+ // try a rename operation which should succeed with ACI
+ assertTrue( checkCanRenameAs( "billyd", "billyd", "ou=testou", "ou=newname" ) );
+
+ // now let's cleanup
+ deleteAccessControlSubentry( "grantRenameByAny" );
+ deleteUser( "billyd" );
+
+ // ----------------------------------------------------------------------------
+ // Test move and RDN change at the same time.
+ // ----------------------------------------------------------------------------
+
+ // create the non-admin user
+ createUser( "billyd", "billyd" );
+
+ // try an move w/ rdn change which should fail without any ACI
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=newname,ou=groups" ) );
+
+ // Gives grantRename, grantImport, grantExport for entries to any user
+ createAccessControlSubentry( "grantRenameMoveByAny", "{ " +
+ "identificationTag \"addAci\", " +
+ "precedence 14, " +
+ "authenticationLevel none, " +
+ "itemOrUserFirst userFirst: { " +
+ "userClasses { allUsers }, " +
+ "userPermissions { { " +
+ "protectedItems {entry}, " +
+ "grantsAndDenials { grantExport, grantImport, grantRename, grantBrowse } } } } }" );
+
+ // try move w/ rdn change which should succeed with ACI
+ assertTrue( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=newname,ou=groups" ) );
+
+ // now let's cleanup
+ deleteAccessControlSubentry( "grantRenameMoveByAny" );
+ deleteUser( "billyd" );
+
+ // ----------------------------------------------------------------------------
+ // Test move ONLY without any RDN changes.
+ // ----------------------------------------------------------------------------
+
+ // create the non-admin user
+ createUser( "billyd", "billyd" );
+
+ // try move operation which should fail without any ACI
+ assertFalse( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=testou,ou=groups" ) );
+
+ // Gives grantImport, and grantExport perm for entries to any user
+ createAccessControlSubentry( "grantMoveByAny", "{ " +
+ "identificationTag \"addAci\", " +
+ "precedence 14, " +
+ "authenticationLevel none, " +
+ "itemOrUserFirst userFirst: { " +
+ "userClasses { allUsers }, " +
+ "userPermissions { { " +
+ "protectedItems {entry}, " +
+ "grantsAndDenials { grantExport, grantImport, grantBrowse } } } } }" );
+
+ // try move operation which should succeed with ACI
+ assertTrue( checkCanRenameAs( "billyd", "billyd", "ou=testou,ou=users", "ou=testou,ou=groups" ) );
+
+ // now let's cleanup
+ deleteAccessControlSubentry( "grantMoveByAny" );
+ deleteUser( "billyd" );
+ }
+}
Propchange: directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/MoveRenameAuthorizationTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/support/MicroOperationFilterTest.java
URL: http://svn.apache.org/viewcvs/directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/support/MicroOperationFilterTest.java?rev=321394&r1=321393&r2=321394&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/support/MicroOperationFilterTest.java (original)
+++ directory/apacheds/trunk/core/src/test/org/apache/ldap/server/authz/support/MicroOperationFilterTest.java Sat Oct 15 10:54:41 2005
@@ -54,6 +54,7 @@
USER_OPERATIONS_A.add( MicroOperation.BROWSE );
USER_OPERATIONS_B.add( MicroOperation.COMPARE );
USER_OPERATIONS_B.add( MicroOperation.DISCLOSE_ON_ERROR );
+ TUPLE_OPERATIONS.add( MicroOperation.ADD );
TUPLE_OPERATIONS.add( MicroOperation.BROWSE );
TUPLE_OPERATIONS.add( MicroOperation.EXPORT );
}