You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tr...@apache.org on 2005/09/23 08:19:36 UTC

svn commit: r291080 - in /directory: apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/ apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/acdf/ network/branches/0.7/ network/branches/0.7/xdocs/ network/trunk/ network/trunk/xdo...

Author: trustin
Date: Thu Sep 22 23:19:20 2005
New Revision: 291080

URL: http://svn.apache.org/viewcvs?rev=291080&view=rev
Log:
Changes in MINA:
* Removed forum from the navigation menu
* Added developer and major contributor list.

Changes in ldap-common and ApacheDS-core:
* Moved ACDFEngine to ApacheDC-core authz package because ACDFEngine requires the access to the DIT.


Added:
    directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/ACDFEngine.java   (with props)
Removed:
    directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/acdf/
    directory/shared/ldap/trunk/common/src/java/org/apache/ldap/common/acl/ACDFEngine.java
Modified:
    directory/network/branches/0.7/project.xml
    directory/network/branches/0.7/xdocs/navigation.xml
    directory/network/trunk/project.xml
    directory/network/trunk/xdocs/navigation.xml

Added: directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/ACDFEngine.java
URL: http://svn.apache.org/viewcvs/directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/ACDFEngine.java?rev=291080&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/ACDFEngine.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/ACDFEngine.java Thu Sep 22 23:19:20 2005
@@ -0,0 +1,615 @@
+/*
+ * Copyright (c) 2004 Solarsis Group LLC.
+ *
+ * Licensed under the Open Software License, Version 2.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://opensource.org/licenses/osl-2.1.php
+ *
+ * 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 java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import javax.naming.Name;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+
+import org.apache.ldap.common.acl.ACITuple;
+import org.apache.ldap.common.acl.AuthenticationLevel;
+import org.apache.ldap.common.acl.MicroOperation;
+import org.apache.ldap.common.acl.ProtectedItem;
+import org.apache.ldap.common.acl.UserClass;
+import org.apache.ldap.common.acl.ProtectedItem.MaxValueCountItem;
+import org.apache.ldap.common.acl.ProtectedItem.RestrictedByItem;
+import org.apache.ldap.common.exception.LdapNoPermissionException;
+
+public class ACDFEngine
+{
+    public ACDFEngine()
+    {
+    }
+    
+    /**
+     * Checks the user with the specified name can access the specified resource
+     * (entry, attribute type, or attribute value) and throws {@link LdapNoPermissionException}
+     * if the user doesn't have any permission to perform the specified grants.
+     *  
+     * @param userGroupName the DN of the group of the user who is trying to access the resource
+     * @param username the DN of the user who is trying to access the resource
+     * @param entryName the DN of the entry the user is trying to access 
+     * @param attrId the attribute type of the attribute the user is trying to access.
+     *               <tt>null</tt> if the user is not accessing a specific attribute type.
+     * @param attrValue the attribute value of the attribute the user is trying to access.
+     *                  <tt>null</tt> if the user is not accessing a specific attribute value.
+     * @param entry the attributes of the entry
+     * @param microOperations the {@link MicroOperation}s to perform
+     * @param aciTuples {@link ACITuple}s translated from {@link ACIItem}s in the subtree entries
+     * @throws LdapNoPermissionException if user don't have enough permission to perform the operation
+     */
+    public void checkPermission(
+            Name userGroupName, Name username, AuthenticationLevel authenticationLevel,
+            Name entryName, String attrId, Object attrValue, Attributes entry,
+            Collection microOperations, Collection aciTuples ) throws LdapNoPermissionException 
+    {
+        if( !hasPermission(
+                userGroupName, username, authenticationLevel,
+                entryName, attrId, attrValue, entry,
+                microOperations, aciTuples ) )
+        {
+            throw new LdapNoPermissionException();
+        }
+    }
+    
+    /**
+     * Returns <tt>true</tt> if the user with the specified name can access the specified resource
+     * (entry, attribute type, or attribute value) and throws {@link LdapNoPermissionException}
+     * if the user doesn't have any permission to perform the specified grants.
+     *  
+     * @param userGroupName the DN of the group of the user who is trying to access the resource
+     * @param userName the DN of the user who is trying to access the resource
+     * @param entryName the DN of the entry the user is trying to access 
+     * @param attrId the attribute type of the attribute the user is trying to access.
+     *               <tt>null</tt> if the user is not accessing a specific attribute type.
+     * @param attrValue the attribute value of the attribute the user is trying to access.
+     *                  <tt>null</tt> if the user is not accessing a specific attribute value.
+     * @param entry the attributes of the entry
+     * @param microOperations the {@link MicroOperation}s to perform
+     * @param aciTuples {@link ACITuple}s translated from {@link ACIItem}s in the subtree entries
+     */
+    public boolean hasPermission(
+            Name userGroupName, Name userName, AuthenticationLevel authenticationLevel,
+            Name entryName, String attrId, Object attrValue, Attributes entry,
+            Collection microOperations, Collection aciTuples ) 
+    {
+        aciTuples = removeTuplesWithoutRelatedUserClasses(
+                userGroupName, userName, authenticationLevel, entryName, aciTuples );
+        aciTuples = removeTuplesWithoutRelatedProtectedItems( userName, entryName, attrId, attrValue, entry, aciTuples );
+        
+        // TODO Discard all tuples that include the maxValueCount, maxImmSub, restrictedBy which
+        // grant access and which don't satisfy any of these constraints
+        // We have to access the DIT here, but no way so far.  We need discussion here.
+        
+        aciTuples = removeTuplesWithoutRelatedMicroOperation( microOperations, aciTuples );
+        aciTuples = getTuplesWithHighestPrecedence( aciTuples );
+        
+        aciTuples = getTuplesWithMostSpecificUserClasses( aciTuples );
+        aciTuples = getTuplesWithMostSpecificProtectedItems( attrId, attrValue, aciTuples );
+        
+        // Grant access if and only if one or more tuples remain and
+        // all grant access. Otherwise deny access.
+        for( Iterator i = aciTuples.iterator(); i.hasNext(); )
+        {
+            ACITuple tuple = ( ACITuple ) i.next();
+            if( !tuple.isGrant() )
+            {
+                return false;
+            }
+            
+        }
+        return true;
+    }
+    
+    private Collection removeTuplesWithoutRelatedUserClasses(
+            Name userGroupName, Name userName, AuthenticationLevel authenticationLevel,
+            Name entryName, Collection aciTuples )
+    {
+        Collection filteredTuples = new ArrayList( aciTuples );
+        for( Iterator i = aciTuples.iterator(); i.hasNext(); )
+        {
+            ACITuple tuple = ( ACITuple ) i.next();
+            if( tuple.isGrant() )
+            {
+                if( !matchUserClass( userGroupName, userName, entryName, tuple.getUserClasses() ) ||
+                        authenticationLevel.compareTo( tuple.getAuthenticationLevel() ) < 0 )
+                {
+                    i.remove();
+                }
+            }
+            else // Denials
+            {
+                if( !matchUserClass( userGroupName, userName, entryName, tuple.getUserClasses() ) &&
+                        authenticationLevel.compareTo( tuple.getAuthenticationLevel() ) >= 0 )
+                {
+                    i.remove();
+                }
+            }
+        }
+        
+        return filteredTuples;
+    }
+    
+    private Collection removeTuplesWithoutRelatedProtectedItems(
+            Name userName,
+            Name entryName, String attrId, Object attrValue, Attributes entry,
+            Collection aciTuples )
+    {
+        Collection filteredTuples = new ArrayList();
+        for( Iterator i = aciTuples.iterator(); i.hasNext(); )
+        {
+            ACITuple tuple = ( ACITuple ) i.next();
+            if( matchProtectedItem( userName, entryName, attrId, attrValue, entry, tuple.getProtectedItems() ) )
+            {
+                filteredTuples.add( tuple );
+            }
+        }
+        
+        return filteredTuples;
+    }
+    
+    protected Collection removeTuplesWithoutRelatedMicroOperation(
+            Collection microOperations, Collection aciTuples )
+    {
+        Collection filteredTuples = new ArrayList();
+
+        for( Iterator i = aciTuples.iterator(); i.hasNext(); )
+        {
+            ACITuple tuple = ( ACITuple ) i.next();
+            boolean retain = false;
+            for( Iterator j = microOperations.iterator(); j.hasNext(); )
+            {
+                MicroOperation microOp = ( MicroOperation ) j.next();
+                if( tuple.getMicroOperations().contains( microOp ) )
+                {
+                    retain = true;
+                    break;
+                }
+            }
+            
+            if( retain )
+            {
+                filteredTuples.add( tuple );
+            }
+        }
+        
+        return filteredTuples;
+    }
+    
+    private Collection getTuplesWithHighestPrecedence( Collection aciTuple )
+    {
+        Collection filteredTuples = new ArrayList();
+        
+        int maxPrecedence = -1;
+        for( Iterator i = aciTuple.iterator(); i.hasNext(); )
+        {
+            ACITuple tuple = ( ACITuple ) i.next();
+            if( tuple.getPrecedence() > maxPrecedence ) 
+            {
+                maxPrecedence = tuple.getPrecedence();
+            }
+        }
+        
+        for( Iterator i = aciTuple.iterator(); i.hasNext(); )
+        {
+            ACITuple tuple = ( ACITuple ) i.next();
+            if( tuple.getPrecedence() == maxPrecedence ) 
+            {
+                filteredTuples.add( tuple );
+            }            
+        }
+        
+        return filteredTuples;
+    }
+    
+    private Collection getTuplesWithMostSpecificUserClasses( Collection aciTuples )
+    {
+        if( aciTuples.size() <= 1 )
+        {
+            return aciTuples;
+        }
+
+        Collection filteredTuples = new ArrayList();
+        
+        // If there are any tuples matching the requestor with UserClasses
+        // element name or thisEntry, discard all other tuples.
+        for( Iterator i = aciTuples.iterator(); i.hasNext(); )
+        {
+            ACITuple tuple = ( ACITuple ) i.next();
+            for( Iterator j = tuple.getUserClasses().iterator(); j.hasNext(); )
+            {
+                UserClass userClass = ( UserClass ) j.next();
+                if( userClass instanceof UserClass.Name ||
+                        userClass instanceof UserClass.ThisEntry )
+                {
+                    filteredTuples.add( tuple );
+                    break;
+                }
+            }
+        }
+        
+        if( filteredTuples.size() > 0 )
+        {
+            return filteredTuples;
+        }
+        
+        // Otherwise if there are any tuples matching UserGroup,
+        // discard all other tuples.
+        for( Iterator i = aciTuples.iterator(); i.hasNext(); )
+        {
+            ACITuple tuple = ( ACITuple ) i.next();
+            for( Iterator j = tuple.getUserClasses().iterator(); j.hasNext(); )
+            {
+                UserClass userClass = ( UserClass ) j.next();
+                if( userClass instanceof UserClass.UserGroup )
+                {
+                    filteredTuples.add( tuple );
+                    break;
+                }
+            }
+        }
+        
+        if( filteredTuples.size() > 0 )
+        {
+            return filteredTuples;
+        }
+
+        // Otherwise if there are any tuples matching subtree,
+        // discard all other tuples.
+        for( Iterator i = aciTuples.iterator(); i.hasNext(); )
+        {
+            ACITuple tuple = ( ACITuple ) i.next();
+            for( Iterator j = tuple.getUserClasses().iterator(); j.hasNext(); )
+            {
+                UserClass userClass = ( UserClass ) j.next();
+                if( userClass instanceof UserClass.Subtree )
+                {
+                    // FIXME I don't know what to do with this.
+                    break;
+                }
+            }
+        }
+        
+        if( filteredTuples.size() > 0 )
+        {
+            return filteredTuples;
+        }
+        
+        return aciTuples;
+    }
+    
+    private Collection getTuplesWithMostSpecificProtectedItems( String attrId, Object attrValue, Collection aciTuples )
+    {
+        if( aciTuples.size() <= 1 )
+        {
+            return aciTuples;
+        }
+
+        Collection filteredTuples = new ArrayList();
+        
+        // If the protected item is an attribute and there are tuples that
+        // specify the attribute type explicitly, discard all other tuples.
+        for( Iterator i = aciTuples.iterator(); i.hasNext(); )
+        {
+            ACITuple tuple = ( ACITuple ) i.next();
+            itemLoop: for( Iterator j = tuple.getProtectedItems().iterator(); j.hasNext(); )
+            {
+                ProtectedItem item = ( ProtectedItem ) j.next();
+                if( item instanceof ProtectedItem.AttributeType )
+                {
+                    if( contains( attrId, ( ( ProtectedItem.AttributeType ) item ).iterator() ) )
+                    {
+                        filteredTuples.add( tuple );
+                        break;
+                    }
+                }
+                else if( item instanceof ProtectedItem.AllAttributeValues )
+                {
+                    if( contains( attrId, ( ( ProtectedItem.AllAttributeValues ) item ).iterator() ) )
+                    {
+                        filteredTuples.add( tuple );
+                        break;
+                    }
+                }
+                else if( item instanceof ProtectedItem.SelfValue )
+                {
+                    if( contains( attrId, ( ( ProtectedItem.SelfValue ) item ).iterator() ) )
+                    {
+                        filteredTuples.add( tuple );
+                        break;
+                    }
+                }
+                else if( item instanceof ProtectedItem.SelfValue )
+                {
+                    if( contains( attrId, ( ( ProtectedItem.SelfValue ) item ).iterator() ) )
+                    {
+                        filteredTuples.add( tuple );
+                        break;
+                    }
+                }
+                else if( item instanceof ProtectedItem.AttributeValue )
+                {
+                    ProtectedItem.AttributeValue av = ( ProtectedItem.AttributeValue ) item;
+                    for( Iterator k = av.iterator(); k.hasNext(); )
+                    {
+                        Attribute attr = ( Attribute ) k.next();
+                        if( attr.getID().equalsIgnoreCase( attrId ) )
+                        {
+                            filteredTuples.add( tuple );
+                            break itemLoop;
+                        }
+                    }
+                }
+            }
+        }
+        
+        if( filteredTuples.size() > 0 )
+        {
+            return filteredTuples;
+        }
+
+        // If the protected item is an attribute value, and there are tuples
+        // that specify the attribute value explicitly, discard all other tuples.
+        // A protected item which is a rangeOfValues is to be treated as
+        // specifying an attribute value explicitly. 
+        for( Iterator i = aciTuples.iterator(); i.hasNext(); )
+        {
+            ACITuple tuple = ( ACITuple ) i.next();
+            itemLoop: for( Iterator j = tuple.getProtectedItems().iterator(); j.hasNext(); )
+            {
+                ProtectedItem item = ( ProtectedItem ) j.next();
+                if( item instanceof ProtectedItem.RangeOfValues )
+                {
+                    ProtectedItem.RangeOfValues rov = ( ProtectedItem.RangeOfValues ) item;
+                    // FIXME I don't know what to do with this ExprNode.
+                    break;
+                }
+            }
+        }
+
+        if( filteredTuples.size() > 0 )
+        {
+            return filteredTuples;
+        }
+
+        return aciTuples;
+    }
+    
+
+    private boolean matchUserClass( Name userGroupName, Name username, Name entryName, Collection userClasses )
+    {
+        for( Iterator i = userClasses.iterator(); i.hasNext(); )
+        {
+            UserClass userClass = ( UserClass ) i.next();
+            if( userClass == UserClass.ALL_USERS )
+            {
+                return true;
+            }
+            else if( userClass == UserClass.THIS_ENTRY )
+            {
+                if( username.equals( entryName ) )
+                {
+                    return true;
+                }
+            }
+            else if( userClass instanceof UserClass.Name )
+            {
+                UserClass.Name nameUserClass = ( UserClass.Name ) userClass;
+                if( nameUserClass.getNames().contains( username ) )
+                {
+                    return true;
+                }
+            }
+            else if( userClass instanceof UserClass.UserGroup )
+            {
+                UserClass.UserGroup userGroupUserClass = ( UserClass.UserGroup ) userClass;
+                if( userGroupName != null && userGroupUserClass.getNames().contains( userGroupName ) )
+                {
+                    return true;
+                }
+            }
+            else if( userClass instanceof UserClass.Subtree )
+            {
+                // FIXME I don't know what to do in case of subtree userClass.
+            }
+            else
+            {
+                throw new InternalError( "Unexpected userClass: " + userClass.getClass().getName() );
+            }
+        }
+
+        return false;
+    }
+    
+    private boolean matchProtectedItem(
+            Name userName,
+            Name entryName, String attrId, Object attrValue, Attributes entry,
+            Collection protectedItems )
+    {
+        for( Iterator i = protectedItems.iterator(); i.hasNext(); )
+        {
+            ProtectedItem item = ( ProtectedItem ) i.next();
+            if( item == ProtectedItem.ENTRY )
+            {
+                if( attrId == null )
+                {
+                    return true;
+                }
+            }
+            else if( item == ProtectedItem.ALL_USER_ATTRIBUTE_TYPES )
+            {
+                if( attrId != null )
+                {
+                    return true;
+                }
+            }
+            else if( item == ProtectedItem.ALL_USER_ATTRIBUTE_TYPES_AND_VALUES )
+            {
+                if( attrId != null && attrValue != null )
+                {
+                    return true;
+                }
+            }
+            else if( item instanceof ProtectedItem.AllAttributeValues )
+            {
+                if( attrId == null )
+                {
+                    continue;
+                }
+
+                ProtectedItem.AllAttributeValues aav = ( ProtectedItem.AllAttributeValues ) item;
+                for( Iterator j = aav.iterator(); j.hasNext(); )
+                {
+                    if( attrId.equalsIgnoreCase( ( String ) j.next() ) )
+                    {
+                        return true;
+                    }
+                }
+            }
+            else if( item instanceof ProtectedItem.AttributeType )
+            {
+                if( attrId == null )
+                {
+                    continue;
+                }
+                
+                ProtectedItem.AttributeType at = ( ProtectedItem.AttributeType ) item;
+                for( Iterator j = at.iterator(); j.hasNext(); )
+                {
+                    if( attrId.equalsIgnoreCase( ( String ) j.next() ) )
+                    {
+                        return true;
+                    }
+                }
+            }
+            else if( item instanceof ProtectedItem.AttributeValue )
+            {
+                if( attrId == null || attrValue == null )
+                {
+                    continue;
+                }
+                
+                ProtectedItem.AttributeValue av = ( ProtectedItem.AttributeValue ) item;
+                for( Iterator j = av.iterator(); j.hasNext(); )
+                {
+                    Attribute attr = ( Attribute ) j.next();
+                    if( attrId.equalsIgnoreCase( attr.getID() ) &&
+                            attr.contains( attrValue ) )
+                    {
+                        return true;
+                    }
+                }
+            }
+            else if( item instanceof ProtectedItem.Classes )
+            {
+                ProtectedItem.Classes c = ( ProtectedItem.Classes ) item;
+                // FIXME I don't know what to do yet
+            }
+            else if( item instanceof ProtectedItem.MaxImmSub )
+            {
+                ProtectedItem.MaxImmSub mis = ( ProtectedItem.MaxImmSub ) item;
+                if( attrId == null )
+                {
+                    return true;
+                }
+            }
+            else if( item instanceof ProtectedItem.MaxValueCount )
+            {
+                if( attrId == null )
+                {
+                    continue;
+                }
+
+                ProtectedItem.MaxValueCount mvc = ( ProtectedItem.MaxValueCount ) item;
+                for( Iterator j = mvc.iterator(); j.hasNext(); )
+                {
+                    MaxValueCountItem mvcItem = ( MaxValueCountItem ) j.next();
+                    if( attrId.equalsIgnoreCase( mvcItem.getAttributeType() ) )
+                    {
+                        return true;
+                    }
+                }
+            }
+            else if( item instanceof ProtectedItem.RangeOfValues )
+            {
+                ProtectedItem.RangeOfValues rov = ( ProtectedItem.RangeOfValues ) item;
+                // FIXME I don't know what to do yet.
+            }
+            else if( item instanceof ProtectedItem.RestrictedBy )
+            {
+                if( attrId == null )
+                {
+                    continue;
+                }
+
+                ProtectedItem.RestrictedBy rb = ( ProtectedItem.RestrictedBy ) item;
+                for( Iterator j = rb.iterator(); j.hasNext(); )
+                {
+                    RestrictedByItem rbItem = ( RestrictedByItem ) j.next();
+                    if( attrId.equalsIgnoreCase( rbItem.getAttributeType() ) )
+                    {
+                        return true;
+                    }
+                }
+            }
+            else if( item instanceof ProtectedItem.SelfValue )
+            {
+                if( attrId == null || attrValue == null )
+                {
+                    continue;
+                }
+                
+                ProtectedItem.SelfValue sv = ( ProtectedItem.SelfValue ) item;
+                for( Iterator j = sv.iterator(); j.hasNext(); )
+                {
+                    Attribute attr = entry.get( String.valueOf( j.next() ) );
+                    if( attr.contains( userName ) || attr.contains( userName.toString() ) )
+                    {
+                        return true;
+                    }
+                }
+            }
+            else
+            {
+                throw new InternalError( "Unexpected protectedItem: " + item.getClass().getName() );
+            }
+        }
+        
+        return false;
+    }
+    
+    private static boolean contains( Object needle, Iterator haystack )
+    {
+        if( needle == null )
+        {
+            return false;
+        }
+
+        while( haystack.hasNext() )
+        {
+            if( haystack.next().equals( needle ) )
+            {
+                return true;
+            }
+        }
+        
+        return false;
+    }
+}

Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/ACDFEngine.java
------------------------------------------------------------------------------
    svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision

Modified: directory/network/branches/0.7/project.xml
URL: http://svn.apache.org/viewcvs/directory/network/branches/0.7/project.xml?rev=291080&r1=291079&r2=291080&view=diff
==============================================================================
--- directory/network/branches/0.7/project.xml (original)
+++ directory/network/branches/0.7/project.xml Thu Sep 22 23:19:20 2005
@@ -22,6 +22,25 @@
     /www/cvs.apache.org/dist/directory
   </distributionDirectory>
 
+  <developers>
+    <developer>
+      <name>Trustin Lee</name>
+      <id>trustin</id>
+      <email>trustin@gmail.com</email>
+      <organization>Solarsis LLC</organization>
+      <url>http://gleamynode.net/</url>
+      <timezone>+9</timezone>
+    </developer>
+  </developers>
+  <contributors>
+    <contributor>
+      <name>Jan Andersson</name>
+    </contributor>
+    <contributor>
+      <name>Vinod Panicker</name>
+    </contributor>
+  </contributors>
+
   <repository>
     <connection>
       scm:svn:http://svn.apache.org/repos/asf/directory:network/branches/0.7

Modified: directory/network/branches/0.7/xdocs/navigation.xml
URL: http://svn.apache.org/viewcvs/directory/network/branches/0.7/xdocs/navigation.xml?rev=291080&r1=291079&r2=291080&view=diff
==============================================================================
--- directory/network/branches/0.7/xdocs/navigation.xml (original)
+++ directory/network/branches/0.7/xdocs/navigation.xml Thu Sep 22 23:19:20 2005
@@ -29,7 +29,6 @@
 		
    <menu name="MINA Community">
      <item name="Mailing List" href="mail-lists.html"/>
-     <item name="Support Forum" href="http://gleamynode.net/dev/forum/list.php?1"/>
      <item name="Issue Tracker" href="http://issues.apache.org/jira/browse/DIRMINA"/>
      <item name="Wiki Pages" href="http://wiki.apache.org/directory/MinaHome"/>
    </menu>

Modified: directory/network/trunk/project.xml
URL: http://svn.apache.org/viewcvs/directory/network/trunk/project.xml?rev=291080&r1=291079&r2=291080&view=diff
==============================================================================
--- directory/network/trunk/project.xml (original)
+++ directory/network/trunk/project.xml Thu Sep 22 23:19:20 2005
@@ -22,6 +22,25 @@
     /www/cvs.apache.org/dist/directory
   </distributionDirectory>
 
+  <developers>
+    <developer>
+      <name>Trustin Lee</name>
+      <id>trustin</id>
+      <email>trustin@gmail.com</email>
+      <organization>Solarsis LLC</organization>
+      <url>http://gleamynode.net/</url>
+      <timezone>+9</timezone>
+    </developer>
+  </developers>
+  <contributors>
+    <contributor>
+      <name>Jan Andersson</name>
+    </contributor>
+    <contributor>
+      <name>Vinod Panicker</name>
+    </contributor>
+  </contributors>
+
   <repository>
     <connection>
       scm:svn:http://svn.apache.org/repos/asf/directory/network/trunk

Modified: directory/network/trunk/xdocs/navigation.xml
URL: http://svn.apache.org/viewcvs/directory/network/trunk/xdocs/navigation.xml?rev=291080&r1=291079&r2=291080&view=diff
==============================================================================
--- directory/network/trunk/xdocs/navigation.xml (original)
+++ directory/network/trunk/xdocs/navigation.xml Thu Sep 22 23:19:20 2005
@@ -29,7 +29,6 @@
 		
    <menu name="MINA Community">
      <item name="Mailing List" href="mail-lists.html"/>
-     <item name="Support Forum" href="http://gleamynode.net/dev/forum/list.php?1"/>
      <item name="Issue Tracker" href="http://issues.apache.org/jira/browse/DIRMINA"/>
      <item name="Wiki Pages" href="http://wiki.apache.org/directory/MinaHome"/>
    </menu>