Author: akarasulu
Date: Mon Nov 1 01:54:17 2004
New Revision: 56220
Added:
incubator/directory/eve/trunk/jndi-provider/src/test/org/apache/eve/jndi/ibs/AuthorizationServiceTest.java
Modified:
incubator/directory/eve/trunk/jndi-provider/src/aspects/org/apache/eve/jndi/ProviderNexusAspect.java
incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/EveContextFactory.java
incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/InvocationMethodEnum.java
incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/ibs/AuthorizationService.java
Log:
got the authorization service workign with some test cases - got much more to
do though
Modified:
incubator/directory/eve/trunk/jndi-provider/src/aspects/org/apache/eve/jndi/ProviderNexusAspect.java
==============================================================================
---
incubator/directory/eve/trunk/jndi-provider/src/aspects/org/apache/eve/jndi/ProviderNexusAspect.java
(original)
+++
incubator/directory/eve/trunk/jndi-provider/src/aspects/org/apache/eve/jndi/ProviderNexusAspect.java
Mon Nov 1 01:54:17 2004
@@ -166,7 +166,7 @@
call( public Attributes lookup( Name ) ) ||
call( public void modify( Name, int, Attributes ) ) ||
call( public void modify( Name, ModificationItem [] ) ) ||
- call( public void modifyRdn( Name, String, boolean ) ) ||
+ call( public void modifyRn( Name, String, boolean ) ) ||
call( public void move( Name, Name ) ) ||
call( public void move( Name, Name, String, boolean ) ) ||
call( public NamingEnumeration
Modified:
incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/EveContextFactory.java
==============================================================================
---
incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/EveContextFactory.java
(original)
+++
incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/EveContextFactory.java
Mon Nov 1 01:54:17 2004
@@ -359,8 +359,8 @@
/*
- * Create and add the Eve Exception service interceptor to both the
- * before and onError interceptor chains.
+ * Create and add the Authentication service interceptor to before
+ * interceptor chain.
*/
InvocationStateEnum[] state = new InvocationStateEnum[]{
InvocationStateEnum.PREINVOCATION
@@ -378,6 +378,14 @@
state = new InvocationStateEnum[]{ InvocationStateEnum.POSTINVOCATION
};
FilterService filterService = new FilterServiceImpl();
interceptor = ( Interceptor ) filterService;
+ provider.addInterceptor( interceptor, state );
+
+ /*
+ * Create and add the Authorization service interceptor to before
+ * interceptor chain.
+ */
+ state = new InvocationStateEnum[]{ InvocationStateEnum.PREINVOCATION };
+ interceptor = new AuthorizationService( normalizer, filterService );
provider.addInterceptor( interceptor, state );
/*
Modified:
incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/InvocationMethodEnum.java
==============================================================================
---
incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/InvocationMethodEnum.java
(original)
+++
incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/InvocationMethodEnum.java
Mon Nov 1 01:54:17 2004
@@ -44,7 +44,7 @@
public static final String LOOKUP_NAME_STRINGARR_STR =
"lookup(Name, String[])";
/** name/signature for the add() method */
- public static final String ADD_STR = "add()";
+ public static final String ADD_STR = "add()";
/** name/signature for the delete() method */
public static final String DELETE_STR = "delete()";
/** name/signature for the hasEntry() method */
@@ -62,7 +62,7 @@
public static final String MODIFY_NAME_MODIFICATIONITEMARR_STR =
"modify(Name, ModificationItem[])";
/** name/signature for the modifyRdn() method */
- public static final String MODIFYRDN_STR = "modifyRdn()";
+ public static final String MODIFYRN_STR = "modifyRn()";
/** name/signature for the move(Name, Name) method */
public static final String MOVE_NAME_NAME_STR = "move(Name, Name)";
/** name/signature for the move(Name, Name, String, boolean) method */
@@ -77,7 +77,7 @@
LOOKUP_NAME_STRINGARR_STR,
ADD_STR, DELETE_STR, HASENTRY_STR, ISSUFFIX_STR, LIST_STR,
LOOKUP_NAME_STR, MODIFY_NAME_INT_ATTRIBUTES_STR,
- MODIFY_NAME_MODIFICATIONITEMARR_STR, MODIFYRDN_STR,
+ MODIFY_NAME_MODIFICATIONITEMARR_STR, MODIFYRN_STR,
MOVE_NAME_NAME_STR, MOVE_NAME_NAME_STRING_BOOL_STR, SEARCH_STR
};
@@ -186,7 +186,7 @@
map.put( "hasEntry", new InvocationMethodEnum[]{ HASENTRY } );
map.put( "isSuffix", new InvocationMethodEnum[]{ ISSUFFIX } );
map.put( "listSuffixes", new InvocationMethodEnum[]{ LISTSUFFIXES } );
- map.put( "modifyRdn", new InvocationMethodEnum[]{ MODIFYRDN } );
+ map.put( "modifyRn", new InvocationMethodEnum[]{ MODIFYRDN } );
map.put( "getSuffix", new InvocationMethodEnum[]{ GETSUFFIX } );
map.put( "getMatchedDn", new InvocationMethodEnum[]{ GETMATCHEDDN } );
Modified:
incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/ibs/AuthorizationService.java
==============================================================================
---
incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/ibs/AuthorizationService.java
(original)
+++
incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/ibs/AuthorizationService.java
Mon Nov 1 01:54:17 2004
@@ -17,17 +17,24 @@
package org.apache.eve.jndi.ibs;
+import java.io.IOException;
import javax.naming.Name;
import javax.naming.NamingException;
+import javax.naming.ldap.LdapContext;
import javax.naming.directory.Attributes;
import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
-import org.apache.eve.RootNexus;
import org.apache.eve.SystemPartition;
+import org.apache.eve.db.SearchResultFilter;
+import org.apache.eve.db.DbSearchResult;
import org.apache.eve.exception.EveNoPermissionException;
import org.apache.eve.jndi.BaseInterceptor;
import org.apache.eve.jndi.Invocation;
import org.apache.eve.jndi.InvocationStateEnum;
+import org.apache.eve.jndi.EveContext;
+import org.apache.ldap.common.name.NameComponentNormalizer;
+import org.apache.ldap.common.name.DnParser;
/**
@@ -43,18 +50,34 @@
/** the base distinguished [EMAIL PROTECTED] Name} for all users */
private static final Name USER_BASE_DN = SystemPartition.getUsersBaseDn();
- /** the root nexus to all database partitions */
- private final RootNexus nexus;
+ /** the name parser used by this service */
+ private final DnParser dnParser;
/**
* Creates an authorization service interceptor.
*
- * @param nexus the root nexus to access all database partitions
+ * @param normalizer a schema enabled name component normalizer
+ * @param filterService a [EMAIL PROTECTED] FilterService} to register
filters with
*/
- public AuthorizationService( RootNexus nexus )
+ public AuthorizationService( NameComponentNormalizer normalizer,
+ FilterService filterService )
+ throws NamingException
{
- this.nexus = nexus;
+ try
+ {
+ this.dnParser = new DnParser( normalizer );
+ }
+ catch ( IOException e )
+ {
+ NamingException ne = new NamingException();
+ ne.setRootCause( e );
+ throw ne;
+ }
+
+ AuthorizationFilter filter = new AuthorizationFilter();
+ filterService.addLookupFilter( filter );
+ filterService.addSearchResultFilter( filter );
}
@@ -79,7 +102,8 @@
throw new EveNoPermissionException( msg );
}
- if ( name.startsWith( USER_BASE_DN ) && ! principalDn.equals(
ADMIN_DN ) )
+ if ( name.size() > 2 && name.startsWith( USER_BASE_DN )
+ && ! principalDn.equals( ADMIN_DN ) )
{
String msg = "User " + principalDn;
msg += " does not have permission to delete the user account:
";
@@ -144,7 +168,14 @@
{
Name principalDn = getPrincipal( invocation ).getDn();
- if ( dn.startsWith( USER_BASE_DN ) && ! principalDn.equals(
ADMIN_DN ) )
+ if ( dn == ADMIN_DN || dn.equals( ADMIN_DN ) && !
principalDn.equals( ADMIN_DN ) )
+ {
+ String msg = "User " + principalDn;
+ msg += " does not have permission to modify the admin
account.";
+ throw new EveNoPermissionException( msg );
+ }
+
+ if ( dn.size() > 2 && dn.startsWith( USER_BASE_DN ) && !
principalDn.equals( ADMIN_DN ) )
{
String msg = "User " + principalDn;
msg += " does not have permission to modify the account of
the";
@@ -203,12 +234,60 @@
throw new EveNoPermissionException( msg );
}
- if ( dn.startsWith( USER_BASE_DN ) && ! principalDn.equals(
ADMIN_DN ) )
+ if ( dn.size() > 2 && dn.startsWith( USER_BASE_DN ) && !
principalDn.equals( ADMIN_DN ) )
{
String msg = "User " + principalDn;
msg += " does not have permission to move or rename the user";
msg += " account: " + dn + ". Only the admin can move or";
msg += " rename user accounts.";
+ throw new EveNoPermissionException( msg );
+ }
+ }
+ }
+
+
+ private class AuthorizationFilter implements SearchResultFilter,
LookupFilter
+ {
+ public boolean accept( LdapContext ctx, DbSearchResult result,
SearchControls controls )
+ throws NamingException
+ {
+ Name dn;
+ synchronized( dnParser )
+ {
+ dn = dnParser.parse( result.getName() );
+ }
+
+ Name principalDn = ( ( EveContext ) ctx ).getPrincipal().getDn();
+ if ( dn.size() > 2 && dn.startsWith( USER_BASE_DN ) && !
principalDn.equals( ADMIN_DN ) )
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+
+ public void filter( LdapContext ctx, Name dn, Attributes entry )
throws NamingException
+ {
+ filter( ctx, dn );
+ }
+
+
+ public void filter( LdapContext ctx, Name dn, Attributes entry,
String[] ids )
+ throws NamingException
+ {
+ filter( ctx, dn );
+ }
+
+
+ private void filter( LdapContext ctx, Name dn ) throws NamingException
+ {
+ Name principalDn = ( ( EveContext ) ctx ).getPrincipal().getDn();
+ if ( dn.size() > 2 && dn.startsWith( USER_BASE_DN ) && !
principalDn.equals( ADMIN_DN ) )
+ {
+ String msg = "Access to user account " + dn + " not permitted";
+ msg += " for user " + principalDn + ". Only the admin can";
+ msg += " access user account information";
throw new EveNoPermissionException( msg );
}
}
Added:
incubator/directory/eve/trunk/jndi-provider/src/test/org/apache/eve/jndi/ibs/AuthorizationServiceTest.java
==============================================================================
--- (empty file)
+++
incubator/directory/eve/trunk/jndi-provider/src/test/org/apache/eve/jndi/ibs/AuthorizationServiceTest.java
Mon Nov 1 01:54:17 2004
@@ -0,0 +1,174 @@
+/*
+ * 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.eve.jndi.ibs;
+
+
+import java.util.Hashtable;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.Attributes;
+
+import org.apache.eve.jndi.EveLdapContext;
+import org.apache.eve.jndi.AbstractJndiTest;
+import org.apache.eve.exception.EveNoPermissionException;
+import org.apache.ldap.common.message.LockableAttributesImpl;
+
+
+/**
+ * Tests the Authorization service to make sure it is enforcing policies
+ * correctly.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class AuthorizationServiceTest extends AbstractJndiTest
+{
+ EveLdapContext sysRootAsNonRootUser;
+
+
+ /**
+ * Set's up a context for an authenticated non-root user.
+ *
+ * @see AbstractJndiTest#setUp()
+ */
+ protected void setUp() throws Exception
+ {
+ // bring the system up
+ super.setUp();
+
+ // authenticate as akarasulu
+ Hashtable env = new Hashtable( );
+ env.put( Context.PROVIDER_URL, "ou=system" );
+ env.put( Context.INITIAL_CONTEXT_FACTORY,
"org.apache.eve.jndi.EveContextFactory" );
+ env.put( Context.SECURITY_PRINCIPAL,
"uid=akarasulu,ou=users,ou=system" );
+ env.put( Context.SECURITY_CREDENTIALS, "test" );
+ InitialContext ictx = new InitialContext( env );
+ sysRootAsNonRootUser = ( EveLdapContext ) ictx.lookup( "" );
+ }
+
+
+ /**
+ * Makes sure the admin cannot delete the admin account.
+ *
+ * @throws NamingException if there are problems
+ */
+ public void testNoDeleteOnAdminByAdmin() throws NamingException
+ {
+ try
+ {
+ sysRoot.destroySubcontext( "uid=admin" );
+ fail( "admin should not be able to delete his account" );
+ }
+ catch ( EveNoPermissionException e )
+ {
+ assertNotNull( e );
+ }
+ }
+
+
+ /**
+ * Makes sure a non-admin user cannot delete the admin account.
+ *
+ * @throws NamingException if there are problems
+ */
+ public void testNoDeleteOnAdminByNonAdmin() throws NamingException
+ {
+ try
+ {
+ sysRootAsNonRootUser.destroySubcontext( "uid=admin" );
+ fail( sysRootAsNonRootUser.getPrincipal().getDn()
+ + " should not be able to delete his account" );
+ }
+ catch ( EveNoPermissionException e )
+ {
+ assertNotNull( e );
+ }
+ }
+
+
+ /**
+ * Makes sure the admin cannot rename the admin account.
+ *
+ * @throws NamingException if there are problems
+ */
+ public void testNoRdnChangesOnAdminByAdmin() throws NamingException
+ {
+ try
+ {
+ sysRoot.rename( "uid=admin", "uid=alex" );
+ fail( "admin should not be able to rename his account" );
+ }
+ catch ( EveNoPermissionException e )
+ {
+ assertNotNull( e );
+ }
+ }
+
+
+ /**
+ * Makes sure a non-admin user cannot rename the admin account.
+ *
+ * @throws NamingException if there are problems
+ */
+ public void testNoRdnChangesOnAdminByNonAdmin() throws NamingException
+ {
+ try
+ {
+ sysRootAsNonRootUser.rename( "uid=admin", "uid=alex" );
+ fail( "admin should not be able to rename his account" );
+ }
+ catch ( EveNoPermissionException e )
+ {
+ assertNotNull( e );
+ }
+ }
+
+
+ /**
+ * Makes sure the admin cannot rename the admin account.
+ *
+ * @throws NamingException if there are problems
+ */
+ public void testModifyOnAdminByAdmin() throws NamingException
+ {
+ Attributes attributes = new LockableAttributesImpl();
+ attributes.put( "userPassword", "replaced" );
+ sysRoot.modifyAttributes( "uid=admin", DirContext.REPLACE_ATTRIBUTE,
attributes );
+ Attributes newAttrs = sysRoot.getAttributes( "uid=admin" );
+ assertEquals( "replaced", newAttrs.get( "userPassword" ).get() );
+ }
+
+
+// /**
+// * Makes sure the a non-admin user cannot rename the admin account.
+// */
+// public void testModifyOnAdminByNonAdmin()
+// {
+// Attributes attributes = new LockableAttributesImpl();
+// attributes.put( "userPassword", "replaced" );
+//
+// try
+// {
+// sysRootAsNonRootUser.modifyAttributes( "uid=admin",
+// DirContext.REPLACE_ATTRIBUTE, attributes );
+// fail( sysRootAsNonRootUser.getPrincipal().getDn() +
+// " should not be able to modify attributes on admin" );
+// } catch( Exception e ) { }
+// }
+}