directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akaras...@apache.org
Subject svn commit: rev 56471 - in incubator/directory/eve/trunk/jndi-provider/src: java/org/apache/eve java/org/apache/eve/jndi java/org/apache/eve/jndi/ibs test/org/apache/eve/jndi
Date Wed, 03 Nov 2004 04:19:54 GMT
Author: akarasulu
Date: Tue Nov  2 20:19:53 2004
New Revision: 56471

Added:
   incubator/directory/eve/trunk/jndi-provider/src/test/org/apache/eve/jndi/RootDSETest.java
Modified:
   incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/RootNexus.java
   incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/EveContext.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/ibs/AuthorizationService.java
   incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/ibs/OperationalAttributeService.java
Log:
Changes ...

 o added authorization code to reject alterations to root DSE in
   authorization service before calls even reach the target nexus
 o added root DSE attribute to the nexus 
 o implemented nexus' getRootDSE method and added some code to 
   add to the namingContexts attribute of the rootDSE as more 
   ContextPartitions are registered with the system
 o also added the vendorName attribute to rootDSE in constructor
   which is proudly fixed at "Apache Software Foundation"
 o added hooks to catch lookups and hasEntry calls for the rootDSE

Note:

 o note that lookup(Name) will return empty Attributes since all attributes 
   in the DSE are operational and these are filtered out by the op attr 
   service interceptor
 o the lookup(Name,String) method is the only one that returns attributes
   when they are explicitly asked for
 o other methods are protected by the authorization service: basically no
   alterations are allowed on the root DSE!



Modified: incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/RootNexus.java
==============================================================================
--- incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/RootNexus.java	(original)
+++ incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/RootNexus.java	Tue
Nov  2 20:19:53 2004
@@ -27,9 +27,13 @@
 import javax.naming.NameNotFoundException;
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.ModificationItem;
+import javax.naming.directory.Attribute;
 
 import org.apache.ldap.common.filter.ExprNode;
 import org.apache.ldap.common.NotImplementedException;
+import org.apache.ldap.common.message.LockableAttributeImpl;
+import org.apache.ldap.common.message.LockableAttributes;
+import org.apache.ldap.common.message.LockableAttributesImpl;
 
                                 
 /**
@@ -43,6 +47,12 @@
  */
 public class RootNexus implements PartitionNexus
 {
+    /** the vendorName string proudly set to: Apache Software Foundation*/
+    private static final String ASF = "Apache Software Foundation";
+    /** the vendorName DSE operational attribute */
+    private static final String VENDORNAME_ATTR = "vendorName";
+    /** the namingContexts DSE operational attribute */
+    private static final String NAMINGCTXS_ATTR = "namingContexts";
     /** Handle on the singleton instance of this class within the entire JVM. */
     private static RootNexus s_singleton = null;
     
@@ -50,13 +60,19 @@
     private SystemPartition system;
     /** the backends keyed by normalized suffix strings */
     private HashMap backends = new HashMap();
-    
-    
+    /** the read only rootDSE attributes */
+    private final Attributes rootDSE;
+
+
     /**
-     * Default constructor that checks to make sure that there is only one
-     * instance of this class within the entire JVM.
+     * Creates the root nexus singleton of the entire system.  The root DSE has
+     * several attributes that are injected into it besides those that may
+     * already exist.  As partitions are added to the system more namingContexts
+     * attributes are added to the rootDSE.
+     *
+     * @see <a href="http://www.faqs.org/rfcs/rfc3045.html">Vendor Information</a>
      */
-    public RootNexus( SystemPartition system )
+    public RootNexus( SystemPartition system, Attributes rootDSE )
     {
         if ( null != s_singleton )
         {
@@ -65,6 +81,18 @@
         
         s_singleton = this;
         this.system = system;
+
+        // setup that root DSE
+        this.rootDSE = rootDSE;
+        Attribute attr = new LockableAttributeImpl( NAMINGCTXS_ATTR );
+        attr.add( "" );
+        rootDSE.put( attr );
+
+        attr = new LockableAttributeImpl( VENDORNAME_ATTR );
+        attr.add( ASF );
+        rootDSE.put( attr );
+
+        // register will add to the list of namingContexts as well
         register( this.system );
     }
     
@@ -107,8 +135,7 @@
     /**
      * @see PartitionNexus#listSuffixes(boolean)
      */
-    public Iterator listSuffixes( boolean normalized )
-        throws NamingException 
+    public Iterator listSuffixes( boolean normalized ) throws NamingException
     {
         return Collections.unmodifiableSet( backends.keySet() ).iterator();
     }
@@ -121,7 +148,7 @@
      */
     public Attributes getRootDSE() 
     {
-        throw new NotImplementedException();
+        return rootDSE;
     }
 
 
@@ -131,6 +158,8 @@
      */
     public void register( ContextPartition backend )
     {
+        Attribute namingContexts = rootDSE.get( NAMINGCTXS_ATTR );
+        namingContexts.add( backend.getSuffix( false ).toString() );
         backends.put( backend.getSuffix( true ).toString(), backend );
     }
 
@@ -141,6 +170,8 @@
      */
     public void unregister( ContextPartition backend )
     {
+        Attribute namingContexts = rootDSE.get( NAMINGCTXS_ATTR );
+        namingContexts.remove( backend.getSuffix( false ).toString() );
         backends.remove( backend.getSuffix( true ).toString() );
     }
 
@@ -224,6 +255,13 @@
      */
     public Attributes lookup( Name dn )  throws NamingException
     {
+        if ( dn.size() == 0 )
+        {
+            LockableAttributes retval = ( LockableAttributes ) rootDSE.clone();
+            retval.setLocked( true );
+            return retval;
+        }
+
         ContextPartition backend = getBackend( dn );
         return backend.lookup( dn );
     }
@@ -234,6 +272,21 @@
      */
     public Attributes lookup( Name dn, String[] attrIds )  throws NamingException
     {
+        if ( dn.size() == 0 )
+        {
+            LockableAttributes retval = new LockableAttributesImpl();
+            NamingEnumeration list = rootDSE.getIDs();
+            while ( list.hasMore() )
+            {
+                String id = ( String ) list.next();
+                Attribute attr = rootDSE.get( id );
+                retval.put( ( Attribute ) attr.clone() );
+            }
+
+            retval.setLocked( true );
+            return retval;
+        }
+
         ContextPartition backend = getBackend( dn );
         return backend.lookup( dn, attrIds );
     }
@@ -244,6 +297,11 @@
      */
     public boolean hasEntry( Name dn ) throws NamingException
     {
+        if ( dn.size() == 0 )
+        {
+            return true;
+        }
+
         ContextPartition backend = getBackend( dn );
         return backend.hasEntry( dn );
     }

Modified: incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/EveContext.java
==============================================================================
--- incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/EveContext.java
(original)
+++ incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/EveContext.java
Tue Nov  2 20:19:53 2004
@@ -28,6 +28,7 @@
 import org.apache.ldap.common.filter.PresenceNode;
 import org.apache.ldap.common.util.NamespaceTools;
 import org.apache.ldap.common.message.LockableAttributesImpl;
+import org.apache.ldap.common.exception.LdapNoPermissionException;
 
 import org.apache.eve.PartitionNexus;
 import org.apache.eve.auth.LdapPrincipal;
@@ -305,6 +306,12 @@
     public void destroySubcontext( Name name ) throws NamingException
     {
         Name target = buildTarget( name );
+
+        if ( target.size() == 0 )
+        {
+            throw new LdapNoPermissionException( "can't delete the rootDSE" );
+        }
+
         nexusProxy.delete( target );
     }
 
@@ -364,6 +371,12 @@
     {
         Name oldDn = buildTarget( oldName );
         Name newDn = buildTarget( newName );
+
+        if ( oldDn.size() == 0 )
+        {
+            throw new LdapNoPermissionException( "can't rename the rootDSE" );
+        }
+
         Name oldBase = oldName.getSuffix( 1 );
         Name newBase = newName.getSuffix( 1 );
 

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
Tue Nov  2 20:19:53 2004
@@ -42,7 +42,6 @@
 import org.apache.eve.RootNexus;
 import org.apache.eve.SystemPartition;
 import org.apache.eve.ApplicationPartition;
-import org.apache.ldap.common.exception.LdapConfigurationException;
 import org.apache.eve.jndi.ibs.*;
 import org.apache.eve.db.*;
 import org.apache.eve.db.jdbm.JdbmDatabase;
@@ -361,7 +360,7 @@
 
         system = new SystemPartition( db, eng, attributes );
         globalRegistries = new GlobalRegistries( system, bootstrapRegistries );
-        nexus = new RootNexus( system );
+        nexus = new RootNexus( system, new LockableAttributesImpl() );
         provider = new EveJndiProvider( nexus );
 
 

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
Tue Nov  2 20:19:53 2004
@@ -32,7 +32,6 @@
 import org.apache.eve.jndi.*;
 import org.apache.ldap.common.name.NameComponentNormalizer;
 import org.apache.ldap.common.name.DnParser;
-import org.apache.ldap.common.exception.LdapNoPermissionException;
 
 
 /**
@@ -94,6 +93,12 @@
         {
             Name principalDn = getPrincipal( invocation ).getDn();
 
+            if ( name.toString().equals( "" ) )
+            {
+                String msg = "The rootDSE cannot be deleted!";
+                throw new LdapNoPermissionException( msg );
+            }
+
             if ( name == ADMIN_DN || name.equals( ADMIN_DN ) )
             {
                 String msg = "User " + principalDn;
@@ -177,6 +182,12 @@
         {
             Name principalDn = getPrincipal( invocation ).getDn();
 
+            if ( dn.toString().equals( "" ) )
+            {
+                String msg = "The rootDSE cannot be modified!";
+                throw new LdapNoPermissionException( msg );
+            }
+
             if ( ! principalDn.equals( ADMIN_DN ) )
             {
                 if ( dn == ADMIN_DN || dn.equals( ADMIN_DN ) )
@@ -244,6 +255,12 @@
         if ( invocation.getState() == InvocationStateEnum.PREINVOCATION )
         {
             Name principalDn = getPrincipal( invocation ).getDn();
+
+            if ( dn.toString().equals( "" ) )
+            {
+                String msg = "The rootDSE cannot be moved or renamed!";
+                throw new LdapNoPermissionException( msg );
+            }
 
             if ( dn == ADMIN_DN || dn.equals( ADMIN_DN ) )
             {

Modified: incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/ibs/OperationalAttributeService.java
==============================================================================
--- incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/ibs/OperationalAttributeService.java
(original)
+++ incubator/directory/eve/trunk/jndi-provider/src/java/org/apache/eve/jndi/ibs/OperationalAttributeService.java
Tue Nov  2 20:19:53 2004
@@ -275,6 +275,4 @@
         }
         return true;
     }
-
-
 }

Added: incubator/directory/eve/trunk/jndi-provider/src/test/org/apache/eve/jndi/RootDSETest.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/jndi-provider/src/test/org/apache/eve/jndi/RootDSETest.java
Tue Nov  2 20:19:53 2004
@@ -0,0 +1,286 @@
+/*
+ *   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;
+
+
+import java.util.Hashtable;
+import java.io.File;
+import java.io.IOException;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+
+import junit.framework.TestCase;
+import org.apache.commons.io.FileUtils;
+import org.apache.ldap.common.exception.LdapNoPermissionException;
+
+
+/**
+ * Testing RootDSE lookups and context creation using the empty string.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class RootDSETest extends TestCase
+{
+    /** flag whether to delete database files for each test or not */
+    protected boolean doDelete = true;
+
+
+    /**
+     * Get's the initial context factory for the provider's ou=system context
+     * root.
+     *
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        doDelete( new File( "target" + File.separator + "eve" ) );
+    }
+
+
+    /**
+     * Deletes the Eve working directory.
+     *
+     * @throws java.io.IOException if there are failures while deleting.
+     */
+    protected void doDelete( File wkdir ) throws IOException
+    {
+        if ( doDelete )
+        {
+            if ( wkdir.exists() )
+            {
+                FileUtils.deleteDirectory( wkdir );
+            }
+        }
+    }
+
+
+    /**
+     * Sets the system context root to null.
+     *
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception
+    {
+        super.tearDown();
+        Hashtable env = new Hashtable();
+        env.put( Context.PROVIDER_URL, "ou=system" );
+        env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.eve.jndi.EveContextFactory"
);
+        env.put( EveContextFactory.SHUTDOWN_OP_ENV, "" );
+        env.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
+        env.put( Context.SECURITY_CREDENTIALS, "testing" );
+        try { new InitialContext( env ); } catch( Exception e ) {}
+    }
+
+
+    /**
+     * Creates an initial context using the empty string for the provider URL.
+     * This should work.
+     *
+     * @throws NamingException if there are any problems
+     */
+    public void testGetInitialContext() throws NamingException
+    {
+        Hashtable env = new Hashtable();
+        env.put( EveContextFactory.WKDIR_ENV, "target/eve" );
+        env.put( Context.PROVIDER_URL, "" );
+        env.put( Context.INITIAL_CONTEXT_FACTORY, EveContextFactory.class.getName() );
+        InitialContext initCtx = new InitialContext( env );
+        assertNotNull( initCtx );
+    }
+
+
+    /**
+     * Gets a DirContext from the InitialContext for the empty string or RootDSE
+     * and checks that none of the operational attributes are returned.
+     *
+     * @throws NamingException if there are any problems
+     */
+    public void testGetInitialContextLookupAttributes() throws NamingException
+    {
+        Hashtable env = new Hashtable();
+        env.put( EveContextFactory.WKDIR_ENV, "target/eve" );
+        env.put( Context.PROVIDER_URL, "" );
+        env.put( Context.INITIAL_CONTEXT_FACTORY, EveContextFactory.class.getName() );
+        InitialContext initCtx = new InitialContext( env );
+        assertNotNull( initCtx );
+
+        DirContext ctx = ( DirContext ) initCtx.lookup( "" );
+        Attributes attributes = ctx.getAttributes( "" );
+        assertEquals( 0, attributes.size() );
+    }
+
+
+    /**
+     * Checks for namingContexts and vendorName attributes.
+     *
+     * @throws NamingException if there are any problems
+     */
+    public void testGetInitialContextLookupAttributesByName() throws NamingException
+    {
+        Hashtable env = new Hashtable();
+        env.put( EveContextFactory.WKDIR_ENV, "target/eve" );
+        env.put( Context.PROVIDER_URL, "" );
+        env.put( Context.INITIAL_CONTEXT_FACTORY, EveContextFactory.class.getName() );
+        InitialContext initCtx = new InitialContext( env );
+        assertNotNull( initCtx );
+
+        DirContext ctx = ( DirContext ) initCtx.lookup( "" );
+        Attributes attributes = ctx.getAttributes( "",
+                new String[]{ "namingContexts", "vendorName" });
+        assertEquals( 2, attributes.size() );
+        assertEquals( "Apache Software Foundation", attributes.get( "vendorName" ).get()
);
+        assertTrue( attributes.get( "namingContexts" ).contains( "" ) );
+        assertTrue( attributes.get( "namingContexts" ).contains( "ou=system" ) );
+    }
+
+
+    /**
+     * Checks for lack of permissions to delete this entry.
+     *
+     * @throws NamingException if there are any problems
+     */
+    public void testDelete() throws NamingException
+    {
+        Hashtable env = new Hashtable();
+        env.put( EveContextFactory.WKDIR_ENV, "target/eve" );
+        env.put( Context.PROVIDER_URL, "" );
+        env.put( Context.INITIAL_CONTEXT_FACTORY, EveContextFactory.class.getName() );
+        InitialContext initCtx = new InitialContext( env );
+        assertNotNull( initCtx );
+
+        DirContext ctx = ( DirContext ) initCtx.lookup( "" );
+
+        LdapNoPermissionException notNull = null;
+
+        try
+        {
+            ctx.destroySubcontext( "" );
+            fail( "we should never get here" );
+        }
+        catch ( LdapNoPermissionException e )
+        {
+            notNull = e;
+        }
+
+        assertNotNull( notNull );
+    }
+
+
+    /**
+     * Checks for lack of permissions to rename or move this entry.
+     *
+     * @throws NamingException if there are any problems
+     */
+    public void testRename() throws NamingException
+    {
+        Hashtable env = new Hashtable();
+        env.put( EveContextFactory.WKDIR_ENV, "target/eve" );
+        env.put( Context.PROVIDER_URL, "" );
+        env.put( Context.INITIAL_CONTEXT_FACTORY, EveContextFactory.class.getName() );
+        InitialContext initCtx = new InitialContext( env );
+        assertNotNull( initCtx );
+
+        DirContext ctx = ( DirContext ) initCtx.lookup( "" );
+
+        LdapNoPermissionException notNull = null;
+
+        try
+        {
+            ctx.rename( "", "ou=system" );
+            fail( "we should never get here" );
+        }
+        catch ( LdapNoPermissionException e )
+        {
+            notNull = e;
+        }
+
+        assertNotNull( notNull );
+    }
+
+
+    /**
+     * Checks for lack of permissions to modify this entry.
+     *
+     * @throws NamingException if there are any problems
+     */
+    public void testModify() throws NamingException
+    {
+        Hashtable env = new Hashtable();
+        env.put( EveContextFactory.WKDIR_ENV, "target/eve" );
+        env.put( Context.PROVIDER_URL, "" );
+        env.put( Context.INITIAL_CONTEXT_FACTORY, EveContextFactory.class.getName() );
+        InitialContext initCtx = new InitialContext( env );
+        assertNotNull( initCtx );
+
+        DirContext ctx = ( DirContext ) initCtx.lookup( "" );
+
+        LdapNoPermissionException notNull = null;
+
+        try
+        {
+            ctx.modifyAttributes( "", 0, null );
+            fail( "we should never get here" );
+        }
+        catch ( LdapNoPermissionException e )
+        {
+            notNull = e;
+        }
+
+        assertNotNull( notNull );
+    }
+
+
+
+
+    /**
+     * Checks for lack of permissions to modify this entry.
+     *
+     * @throws NamingException if there are any problems
+     */
+    public void testModify2() throws NamingException
+    {
+        Hashtable env = new Hashtable();
+        env.put( EveContextFactory.WKDIR_ENV, "target/eve" );
+        env.put( Context.PROVIDER_URL, "" );
+        env.put( Context.INITIAL_CONTEXT_FACTORY, EveContextFactory.class.getName() );
+        InitialContext initCtx = new InitialContext( env );
+        assertNotNull( initCtx );
+
+        DirContext ctx = ( DirContext ) initCtx.lookup( "" );
+
+        LdapNoPermissionException notNull = null;
+
+        try
+        {
+            ctx.modifyAttributes( "", new ModificationItem[]{} );
+            fail( "we should never get here" );
+        }
+        catch ( LdapNoPermissionException e )
+        {
+            notNull = e;
+        }
+
+        assertNotNull( notNull );
+    }
+}

Mime
View raw message