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 2004/10/31 06:10:29 UTC
svn commit: rev 56121 - in incubator/directory/eve/trunk/backend/core: . src/java/org/apache/eve src/java/org/apache/eve/auth src/java/org/apache/eve/exception src/java/org/apache/eve/jndi src/java/org/apache/eve/jndi/exception src/java/org/apache/eve/jndi/ibs src/java/org/apache/eve/schema src/java/org/apache/eve/schema/bootstrap src/test/org/apache/eve/jndi
Author: akarasulu
Date: Sat Oct 30 22:10:29 2004
New Revision: 56121
Added:
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/auth/
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/auth/LdapPrincipal.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveNoPermissionException.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/AuthenticationService.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/exception/EveAuthenticationException.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/exception/EveAuthenticationNotSupportedException.java
incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/SimpleAuthenticationTest.java
Modified:
incubator/directory/eve/trunk/backend/core/project.properties
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/SystemPartition.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveContext.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveContextFactory.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveDirContext.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveJndiProvider.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveLdapContext.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/OperationalAttributeService.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/SchemaService.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/GlobalRegistries.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/BootstrapRegistries.java
incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/AbstractJndiTest.java
incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/EveContextFactoryTest.java
Log:
Changes ...
o introduced authentication service interceptor
o added new field for the authenticated Principal to EveContext
o authentication service removes creds from env after successful auth
o implemented several test cases for authentication handling policies
o added new bootstrap property for enabling anonymous use
o enabled automatic creation of the admin account on db building
first time bootstrap attempts
o heavily cleaned up context implementations
o context constructors now just take a Name instead of LdapName arg
o a special context constructor also takes the principal for propagating
the principal across JNDI contexts created by the same user
o new LdapPrincipal - was using X500Principal but this had some serious
issues: basically it capitalized all attribute names but we need a
fully normalized name
o corrected misspelling of isHumanReadible()
o added some extra aspectj properties to play
o added authentication service to the before pipeline
Notes ...
o phew lots of major changes here
o test cases working but we need more to confirm correct operation
o we really need to document all this once done - it's a must
Modified: incubator/directory/eve/trunk/backend/core/project.properties
==============================================================================
--- incubator/directory/eve/trunk/backend/core/project.properties (original)
+++ incubator/directory/eve/trunk/backend/core/project.properties Sat Oct 30 22:10:29 2004
@@ -1,18 +1,15 @@
maven.junit.fork=yes
-maven.javadoc.private=true
+#maven.javadoc.private=true
maven.javadoc.overview=src/java/org/apache/eve/schema/overview.html
-maven.javadoc.customtags=tag1 tag2
-tag1.name=todo
-tag1.description=To Do:
-tag1.enabled=true
-tag1.scope=all
+# AspectJ Properties
+# =======================
+
+#maven.aspectj.verbose=true
+#maven.aspectj.incremental=true
+maven.aspectj.time=true
-tag2.name=task
-tag2.description=Task:
-tag2.enabled=false
-tag2.scope=all
# schema class generation
# =======================
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/SystemPartition.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/SystemPartition.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/SystemPartition.java Sat Oct 30 22:10:29 2004
@@ -42,7 +42,8 @@
public final class SystemPartition extends AbstractContextPartition
{
/** the default user principal or DN */
- public final static String DEFAULT_PRINCIPAL = "uid=admin,ou=system";
+ public final static String ADMIN_PRINCIPAL = "uid=admin,ou=system";
+ public final static String ADMIN_UID = "admin";
/**
* System backend suffix constant. Should be kept down to a single Dn name
@@ -98,7 +99,7 @@
attributes = new LockableAttributesImpl() ;
attributes.put( "objectClass", "top" ) ;
attributes.put( "objectClass", "organizationalUnit" ) ;
- attributes.put( "creatorsName", DEFAULT_PRINCIPAL ) ;
+ attributes.put( "creatorsName", ADMIN_PRINCIPAL ) ;
attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() ) ;
attributes.put( NamespaceTools.getRdnAttribute( SUFFIX ),
NamespaceTools.getRdnValue( SUFFIX ) ) ;
Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/auth/LdapPrincipal.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/auth/LdapPrincipal.java Sat Oct 30 22:10:29 2004
@@ -0,0 +1,86 @@
+/*
+ * 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.auth;
+
+
+import javax.naming.Name;
+import java.security.Principal;
+
+import org.apache.ldap.common.name.LdapName;
+
+
+/**
+ * An alternative X500 user implementation that has access to the distinguished
+ * name of the principal as well as the String representation.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class LdapPrincipal implements Principal
+{
+ /** the normalized distinguished name of the principal */
+ private final Name name;
+ /** the no name anonymous user whose DN is the empty String */
+ public static final Principal ANONYMOUS = new LdapPrincipal();
+
+
+ /**
+ * Creates a new LDAP/X500 principal.
+ *
+ * @param name the normalized distinguished name of the principal
+ */
+ public LdapPrincipal( Name name )
+ {
+ this.name = name;
+ }
+
+
+ /**
+ * Creates a principal for the no name anonymous user whose DN is the empty
+ * String.
+ */
+ private LdapPrincipal()
+ {
+ this.name = new LdapName();
+ }
+
+
+
+ /**
+ * Gets a cloned copy of the normalized distinguished name of this
+ * principal as a JNDI Name. It must be cloned to protect this Principal
+ * from alteration.
+ *
+ * @return the normalized distinguished name of the principal as a JNDI Name
+ */
+ public Name getDn()
+ {
+ return ( Name ) name.clone();
+ }
+
+
+ /**
+ * Gets the normalized distinguished name of the principal as a String.
+ *
+ * @see Principal#getName()
+ * @return
+ */
+ public String getName()
+ {
+ return name.toString();
+ }
+}
Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveNoPermissionException.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveNoPermissionException.java Sat Oct 30 22:10:29 2004
@@ -0,0 +1,64 @@
+/*
+ * 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.exception;
+
+
+import javax.naming.NoPermissionException;
+
+import org.apache.ldap.common.message.ResultCodeEnum;
+
+
+/**
+ * A NoPermissionException which associates a resultCode namely the
+ * {@link ResultCodeEnum#INSUFFICIENTACCESSRIGHTS} resultCode with the exception.
+ *
+ * @see EveException
+ * @see NoPermissionException
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class EveNoPermissionException extends NoPermissionException
+ implements EveException
+{
+ /**
+ * @see NoPermissionException#NoPermissionException()
+ */
+ public EveNoPermissionException()
+ {
+ super();
+ }
+
+
+ /**
+ * @see NoPermissionException#NoPermissionException(String)
+ */
+ public EveNoPermissionException( String explanation )
+ {
+ super( explanation );
+ }
+
+
+ /**
+ * Always returns {@link ResultCodeEnum#INSUFFICIENTACCESSRIGHTS}
+ *
+ * @see EveException#getResultCode()
+ */
+ public ResultCodeEnum getResultCode()
+ {
+ return ResultCodeEnum.INSUFFICIENTACCESSRIGHTS;
+ }
+}
Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/AuthenticationService.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/AuthenticationService.java Sat Oct 30 22:10:29 2004
@@ -0,0 +1,242 @@
+/*
+ * 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.IOException;
+import javax.naming.NamingException;
+import javax.naming.Context;
+import javax.naming.ConfigurationException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.Attribute;
+
+import org.apache.eve.RootNexus;
+import org.apache.eve.SystemPartition;
+import org.apache.eve.auth.LdapPrincipal;
+import org.apache.eve.exception.EveNoPermissionException;
+import org.apache.eve.exception.EveNamingException;
+import org.apache.eve.jndi.exception.EveAuthenticationNotSupportedException;
+import org.apache.eve.jndi.exception.EveNameNotFoundException;
+import org.apache.eve.jndi.exception.EveAuthenticationException;
+import org.apache.ldap.common.message.ResultCodeEnum;
+import org.apache.ldap.common.util.ArrayUtils;
+import org.apache.ldap.common.name.LdapName;
+import org.apache.ldap.common.name.NameComponentNormalizer;
+import org.apache.ldap.common.name.DnParser;
+
+
+/**
+ * A service used to for authenticating users.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class AuthenticationService implements Interceptor
+{
+
+ private static final String TYPE = Context.SECURITY_AUTHENTICATION;
+ private static final String PRINCIPAL = Context.SECURITY_PRINCIPAL;
+ private static final String ADMIN = SystemPartition.ADMIN_PRINCIPAL;
+
+ /** the root nexus to all database partitions */
+ private final RootNexus nexus;
+ /** whether or not to allow anonymous users */
+ private boolean allowAnonymous = false;
+ /** the normalizing DnParser to use while parsing names */
+ private final DnParser parser;
+
+
+ /**
+ * Creates an authentication service interceptor.
+ *
+ * @param nexus the root nexus to access all database partitions
+ */
+ public AuthenticationService( RootNexus nexus, NameComponentNormalizer normalizer,
+ boolean allowAnonymous ) throws EveNamingException
+ {
+ this.nexus = nexus;
+ this.allowAnonymous = allowAnonymous;
+ try
+ {
+ this.parser = new DnParser( normalizer );
+ }
+ catch ( IOException e )
+ {
+ EveNamingException ene = new EveNamingException( ResultCodeEnum.OTHER );
+ ene.setRootCause( e );
+ throw ene;
+ }
+ }
+
+
+ public void invoke( Invocation invocation ) throws NamingException
+ {
+ if ( invocation.getState() != InvocationStateEnum.PREINVOCATION )
+ {
+ return;
+ }
+
+ EveContext ctx = ( EveLdapContext ) invocation.getContextStack().peek();
+ if ( ctx.getPrincipal() != null )
+ {
+ if ( ctx.getEnvironment().containsKey( Context.SECURITY_CREDENTIALS ) )
+ {
+ ctx.removeFromEnvironment( Context.SECURITY_CREDENTIALS );
+ }
+
+ return;
+ }
+
+ String principal = getPrincipal( ctx.getEnvironment() );
+
+ if ( principal.length() == 0 )
+ {
+ if ( allowAnonymous )
+ {
+ ctx.setPrincipal( LdapPrincipal.ANONYMOUS );
+ return;
+ }
+ else
+ {
+ throw new EveNoPermissionException( "" );
+ }
+ }
+
+ Object creds = ctx.getEnvironment().get( Context.SECURITY_CREDENTIALS );
+ if ( creds == null )
+ {
+ creds = ArrayUtils.EMPTY_BYTE_ARRAY;
+ }
+ else if ( creds instanceof String )
+ {
+ creds = ( ( String ) creds ).getBytes();
+ }
+
+ LdapName principalDn = new LdapName( principal );
+ Attributes userEntry = nexus.lookup( principalDn );
+ if ( userEntry == null )
+ {
+ throw new EveNameNotFoundException();
+ }
+
+ Object userPassword;
+ Attribute userPasswordAttr = userEntry.get( "userPassword" );
+ if ( userPasswordAttr == null )
+ {
+ userPassword = ArrayUtils.EMPTY_BYTE_ARRAY;
+ }
+ else
+ {
+ userPassword = userPasswordAttr.get();
+ if ( userPassword instanceof String )
+ {
+ userPassword = ( ( String ) userPassword ).getBytes();
+ }
+ }
+
+ if ( ! ArrayUtils.isEquals( creds, userPassword ) )
+ {
+ throw new EveAuthenticationException();
+ }
+
+ synchronized( parser )
+ {
+ ctx.setPrincipal( new LdapPrincipal( parser.parse( principal ) ) );
+ }
+
+ // remove creds so there is no security risk
+ ctx.removeFromEnvironment( Context.SECURITY_CREDENTIALS );
+ }
+
+
+ /**
+ * Gets the effective principal associated with a JNDI context's environment.
+ *
+ * @param env the JNDI Context environment
+ * @return the effective principal
+ * @throws NamingException if certain properties are not present or present
+ * in wrong values or present in the wrong combinations
+ */
+ private String getPrincipal( Hashtable env ) throws NamingException
+ {
+ if ( "strong".equalsIgnoreCase( ( String ) env.get( TYPE ) ) )
+ {
+ throw new EveAuthenticationNotSupportedException( ResultCodeEnum.AUTHMETHODNOTSUPPORTED );
+ }
+
+ // --------------------------------------------------------------------
+ // if both the authtype and principal keys not defined then the
+ // princial is set to the admin user for the system
+ // --------------------------------------------------------------------
+ if ( ! env.containsKey( TYPE ) && ! env.containsKey( PRINCIPAL ) )
+ {
+ return SystemPartition.ADMIN_PRINCIPAL;
+ }
+
+ // the authtype is set but the principal is not
+ if ( env.containsKey( TYPE ) && ! env.containsKey( PRINCIPAL ) )
+ {
+ Object val = env.get( TYPE );
+
+ // princial is set to the anonymous user if authType is "none"
+ if ( "none".equalsIgnoreCase( ( String ) val ) )
+ {
+ return "";
+ }
+ // princial is set to the admin user if authType is "simple"
+ else if ( "simple".equalsIgnoreCase( ( String ) val ) )
+ {
+ return ADMIN;
+ }
+
+ // blow chuncks if we see any other authtype values
+ throw new ConfigurationException( "Unknown value for property " + TYPE + ": " + val );
+ }
+
+ // both are set
+ if ( env.containsKey( TYPE ) && env.containsKey( PRINCIPAL ) )
+ {
+ Object val = env.get( TYPE );
+
+ // princial is set to the anonymous user if authType is "none"
+ if ( "none".equalsIgnoreCase( ( String ) val ) )
+ {
+ String msg = "Ambiguous configuration: " + TYPE;
+ msg += " is set to none and the security principal";
+ msg += " is set using " + PRINCIPAL + " as well";
+ throw new ConfigurationException( msg );
+ }
+ // princial is set to the admin user if authType is "simple"
+ else if ( "simple".equalsIgnoreCase( ( String ) val ) )
+ {
+ return ( String ) env.get( PRINCIPAL );
+ }
+
+ // blow chuncks if we see any other authtype values
+ throw new ConfigurationException( "Unknown value for property " + TYPE + ": " + val );
+ }
+
+ // we have the principal key so we set that as the value
+ if ( env.containsKey( PRINCIPAL ) )
+ {
+ return ( String ) env.get( PRINCIPAL );
+ }
+
+ return ADMIN;
+ }
+}
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveContext.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveContext.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveContext.java Sat Oct 30 22:10:29 2004
@@ -17,22 +17,18 @@
package org.apache.eve.jndi;
-import java.util.Hashtable ;
+import java.util.Hashtable;
+import java.security.Principal;
-import javax.naming.Name ;
-import javax.naming.Context ;
-import javax.naming.NameParser ;
-import javax.naming.ldap.Control ;
-import javax.naming.NamingException ;
-import javax.naming.NamingEnumeration ;
-import javax.naming.directory.Attributes ;
-import javax.naming.InvalidNameException ;
-import javax.naming.directory.SearchControls ;
-
-import org.apache.ldap.common.name.LdapName ;
-import org.apache.ldap.common.filter.PresenceNode ;
-import org.apache.ldap.common.util.NamespaceTools ;
-import org.apache.ldap.common.message.LockableAttributesImpl ;
+import javax.naming.*;
+import javax.naming.ldap.Control;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.SearchControls;
+
+import org.apache.ldap.common.name.LdapName;
+import org.apache.ldap.common.filter.PresenceNode;
+import org.apache.ldap.common.util.NamespaceTools;
+import org.apache.ldap.common.message.LockableAttributesImpl;
import org.apache.eve.PartitionNexus;
@@ -46,15 +42,17 @@
public abstract class EveContext implements Context
{
/** */
- public static final String DELETE_OLD_RDN_PROP = "java.naming.ldap.deleteRDN" ;
+ public static final String DELETE_OLD_RDN_PROP = "java.naming.ldap.deleteRDN";
/** The interceptor proxy to the backend nexus */
- private final PartitionNexus nexusProxy ;
+ private final PartitionNexus nexusProxy;
/** The cloned environment used by this Context */
- private final Hashtable env ;
+ private final Hashtable env;
/** The distinguished name of this Context */
- private final LdapName dn ;
-
+ private final LdapName dn;
+ /** The Principal associated with this context */
+ private Principal principal;
+
// ------------------------------------------------------------------------
// Constructors
@@ -63,7 +61,12 @@
/**
* Must be called by all subclasses to initialize the nexus proxy and the
- * environment settings to be used by this Context implementation.
+ * environment settings to be used by this Context implementation. This
+ * specific contstructor relies on the presence of the {@link
+ * Context#PROVIDER_URL} key and value to determine the distinguished name
+ * of the newly created context. It also checks to make sure the
+ * referenced name actually exists within the system. This constructor
+ * is used for all InitialContext requests.
*
* @param nexusProxy the intercepting proxy to the nexus.
* @param env the environment properties used by this context.
@@ -72,40 +75,82 @@
*/
protected EveContext( PartitionNexus nexusProxy, Hashtable env ) throws NamingException
{
- this.nexusProxy = nexusProxy ;
- this.env = ( Hashtable ) env.clone() ;
-
- if ( null == env.get( PROVIDER_URL ) )
+ String url;
+
+ // set references to cloned env and the proxy
+ this.nexusProxy = nexusProxy;
+ this.env = ( Hashtable ) env.clone();
+
+ /* --------------------------------------------------------------------
+ * check for the provider URL property and make sure it exists
+ * as a valid value or else we need to throw a configuration error
+ * ------------------------------------------------------------------ */
+ if ( ! env.containsKey( Context.PROVIDER_URL ) )
{
- throw new NamingException( PROVIDER_URL + " property not found in environment." ) ;
+ throw new ConfigurationException( "Expected property "
+ + Context.PROVIDER_URL + " but could not find it in env!" );
}
-
- /*
- * TODO Make sure we can handle URLs here as well as simple DNs
- * The PROVIDER_URL is interpreted as just a entry Dn since we are
- * within the server. However this may change in the future if we
- * want to convey the listener from which the protocol originating
- * requests are comming from.
- */
- dn = new LdapName( ( String ) env.get( PROVIDER_URL ) ) ;
+ url = ( String ) env.get( Context.PROVIDER_URL );
+ if ( url == null )
+ {
+ throw new ConfigurationException( "Expected value for property "
+ + Context.PROVIDER_URL + " but it was set to null in env!" );
+ }
+
+ dn = new LdapName( url );
+ if ( ! nexusProxy.hasEntry( dn ) )
+ {
+ throw new NameNotFoundException( dn + " does not exist" );
+ }
}
/**
* Must be called by all subclasses to initialize the nexus proxy and the
- * environment settings to be used by this Context implementation.
- *
+ * environment settings to be used by this Context implementation. This
+ * constructor is used to propagate new contexts from existing contexts.
+ *
+ * @param principal the directory user principal that is propagated
* @param nexusProxy the intercepting proxy to the nexus
* @param env the environment properties used by this context
* @param dn the distinguished name of this context
*/
- protected EveContext( PartitionNexus nexusProxy, Hashtable env, LdapName dn )
+ protected EveContext( Principal principal, PartitionNexus nexusProxy,
+ Hashtable env, Name dn )
+ {
+ this.dn = ( LdapName ) dn.clone();
+ this.env = ( Hashtable ) env.clone();
+ this.env.put( PROVIDER_URL, dn.toString() );
+ this.nexusProxy = nexusProxy;
+ this.principal = principal;
+ }
+
+
+ // ------------------------------------------------------------------------
+ // New Impl Specific Public Methods
+ // ------------------------------------------------------------------------
+
+
+ /**
+ * Gets the principal of the authenticated user which also happens to own
+ * @return
+ */
+ public Principal getPrincipal()
+ {
+ return principal;
+ }
+
+
+ /**
+ * Package friendly setter to alter the principal. It is very important
+ * for security's sake to keep this package friendly and not public.
+ *
+ * @param principal the directory user principal
+ */
+ void setPrincipal( Principal principal )
{
- this.dn = ( LdapName ) dn.clone() ;
- this.env = ( Hashtable ) env.clone() ;
- this.env.put( PROVIDER_URL, dn.toString() ) ;
- this.nexusProxy = nexusProxy ;
+ this.principal = principal;
}
@@ -121,7 +166,7 @@
*/
protected PartitionNexus getNexusProxy()
{
- return nexusProxy ;
+ return nexusProxy ;
}
@@ -132,7 +177,7 @@
*/
protected Name getDn()
{
- return dn ;
+ return dn;
}
@@ -155,16 +200,16 @@
*/
public String getNameInNamespace() throws NamingException
{
- return dn.toString() ;
+ return dn.toString();
}
/**
* @see javax.naming.Context#getEnvironment()
*/
- public Hashtable getEnvironment() throws NamingException
+ public Hashtable getEnvironment()
{
- return env ;
+ return env;
}
@@ -174,7 +219,7 @@
*/
public Object addToEnvironment( String propName, Object propVal ) throws NamingException
{
- return env.put( propName, propVal ) ;
+ return env.put( propName, propVal );
}
@@ -183,7 +228,7 @@
*/
public Object removeFromEnvironment( String propName ) throws NamingException
{
- return env.remove( propName ) ;
+ return env.remove( propName );
}
@@ -192,7 +237,7 @@
*/
public Context createSubcontext( String name ) throws NamingException
{
- return createSubcontext( new LdapName( name ) ) ;
+ return createSubcontext( new LdapName( name ) );
}
@@ -211,11 +256,11 @@
*
* TODO Add multivalued RDN handling code
*/
- Attributes attributes = new LockableAttributesImpl() ;
- LdapName target = buildTarget( name ) ;
- String rdn = name.get( name.size() - 1 ) ;
- String rdnAttribute = NamespaceTools.getRdnAttribute( rdn ) ;
- String rdnValue = NamespaceTools.getRdnValue( rdn ) ;
+ Attributes attributes = new LockableAttributesImpl();
+ LdapName target = buildTarget( name );
+ String rdn = name.get( name.size() - 1 );
+ String rdnAttribute = NamespaceTools.getRdnAttribute( rdn );
+ String rdnValue = NamespaceTools.getRdnValue( rdn );
/*
* TODO Add code within the interceptor service managing operational
@@ -223,11 +268,11 @@
* attributes before normalization. The result should have ths same
* affect as the following line within the interceptor.
*
- * attributes.put( BootstrapSchema.DN_ATTR, target.toString() ) ;
+ * attributes.put( BootstrapSchema.DN_ATTR, target.toString() );
*/
- attributes.put( rdnAttribute, rdnValue ) ;
- attributes.put( JavaLdapSupport.OBJECTCLASS_ATTR, JavaLdapSupport.JCONTAINER_ATTR ) ;
- attributes.put( JavaLdapSupport.OBJECTCLASS_ATTR, JavaLdapSupport.TOP_ATTR ) ;
+ attributes.put( rdnAttribute, rdnValue );
+ attributes.put( JavaLdapSupport.OBJECTCLASS_ATTR, JavaLdapSupport.JCONTAINER_ATTR );
+ attributes.put( JavaLdapSupport.OBJECTCLASS_ATTR, JavaLdapSupport.TOP_ATTR );
/*
* Add the new context to the server which as a side effect adds
@@ -236,12 +281,12 @@
* we need to copy over the controls as well to propagate the complete
* environment besides whats in the hashtable for env.
*/
- nexusProxy.add( target.toString(), target, attributes ) ;
+ nexusProxy.add( target.toString(), target, attributes );
- EveLdapContext ctx = new EveLdapContext( nexusProxy, env, target ) ;
- Control [] controls = ( Control [] ) ( ( EveLdapContext ) this ).getRequestControls().clone() ;
- ctx.setRequestControls( controls ) ;
- return ctx ;
+ EveLdapContext ctx = new EveLdapContext( principal, nexusProxy, env, target );
+ Control [] controls = ( Control [] ) ( ( EveLdapContext ) this ).getRequestControls().clone();
+ ctx.setRequestControls( controls );
+ return ctx;
}
@@ -250,7 +295,7 @@
*/
public void destroySubcontext( String name ) throws NamingException
{
- destroySubcontext( new LdapName( name ) ) ;
+ destroySubcontext( new LdapName( name ) );
}
@@ -259,8 +304,8 @@
*/
public void destroySubcontext( Name name ) throws NamingException
{
- Name target = buildTarget( name ) ;
- nexusProxy.delete( target ) ;
+ Name target = buildTarget( name );
+ nexusProxy.delete( target );
}
@@ -269,7 +314,7 @@
*/
public void bind( String name, Object obj ) throws NamingException
{
- bind( new LdapName( name ), obj ) ;
+ bind( new LdapName( name ), obj );
}
@@ -280,7 +325,7 @@
{
if ( obj instanceof EveLdapContext )
{
- throw new IllegalArgumentException( "Cannot bind a directory context object!" ) ;
+ throw new IllegalArgumentException( "Cannot bind a directory context object!" );
}
/*
@@ -293,12 +338,12 @@
*
* TODO Add multivalued RDN handling code
*/
- Attributes attributes = new LockableAttributesImpl() ;
- Name target = buildTarget( name ) ;
+ Attributes attributes = new LockableAttributesImpl();
+ Name target = buildTarget( name );
// Serialize object into entry attributes and add it.
- JavaLdapSupport.serialize( attributes, obj ) ;
- nexusProxy.add( target.toString(), target, attributes ) ;
+ JavaLdapSupport.serialize( attributes, obj );
+ nexusProxy.add( target.toString(), target, attributes );
}
@@ -308,7 +353,7 @@
public void rename( String oldName, String newName )
throws NamingException
{
- rename( new LdapName( oldName ), new LdapName( newName ) ) ;
+ rename( new LdapName( oldName ), new LdapName( newName ) );
}
@@ -317,15 +362,15 @@
*/
public void rename( Name oldName, Name newName ) throws NamingException
{
- Name oldDn = buildTarget( oldName ) ;
- Name newDn = buildTarget( newName ) ;
- Name oldBase = oldName.getSuffix( 1 ) ;
- Name newBase = newName.getSuffix( 1 ) ;
+ Name oldDn = buildTarget( oldName );
+ Name newDn = buildTarget( newName );
+ Name oldBase = oldName.getSuffix( 1 );
+ Name newBase = newName.getSuffix( 1 );
- String newRdn = newName.get( newName.size() - 1 ) ;
- String oldRdn = oldName.get( oldName.size() - 1 ) ;
+ String newRdn = newName.get( newName.size() - 1 );
+ String oldRdn = oldName.get( oldName.size() - 1 );
- boolean delOldRdn = true ;
+ boolean delOldRdn = true;
/*
* Attempt to use the java.naming.ldap.deleteRDN environment property
@@ -333,10 +378,10 @@
*/
if ( null != env.get( DELETE_OLD_RDN_PROP ) )
{
- String delOldRdnStr = ( String ) env.get( DELETE_OLD_RDN_PROP ) ;
+ String delOldRdnStr = ( String ) env.get( DELETE_OLD_RDN_PROP );
delOldRdn = ! ( delOldRdnStr.equals( "false" ) ||
delOldRdnStr.equals( "no" ) ||
- delOldRdnStr.equals( "0" ) ) ;
+ delOldRdnStr.equals( "0" ) );
}
/*
@@ -349,19 +394,19 @@
*/
if ( oldName.size() == newName.size() && oldBase.equals( newBase ) )
{
- nexusProxy.modifyRn( oldDn, newRdn, delOldRdn ) ;
+ nexusProxy.modifyRn( oldDn, newRdn, delOldRdn );
}
else
{
- Name parent = newDn.getSuffix( 1 ) ;
+ Name parent = newDn.getSuffix( 1 );
if ( newRdn.equalsIgnoreCase( oldRdn ) )
{
- nexusProxy.move( oldDn, parent ) ;
+ nexusProxy.move( oldDn, parent );
}
else
{
- nexusProxy.move( oldDn, parent, newRdn, delOldRdn ) ;
+ nexusProxy.move( oldDn, parent, newRdn, delOldRdn );
}
}
}
@@ -372,7 +417,7 @@
*/
public void rebind( String name, Object obj ) throws NamingException
{
- rebind( new LdapName( name ), obj ) ;
+ rebind( new LdapName( name ), obj );
}
@@ -381,14 +426,14 @@
*/
public void rebind( Name name, Object obj ) throws NamingException
{
- Name target = buildTarget( name ) ;
+ Name target = buildTarget( name );
if ( nexusProxy.hasEntry( target ) )
{
- nexusProxy.delete( target ) ;
+ nexusProxy.delete( target );
}
- bind( name, obj ) ;
+ bind( name, obj );
}
@@ -397,7 +442,7 @@
*/
public void unbind( String name ) throws NamingException
{
- unbind( new LdapName( name ) ) ;
+ unbind( new LdapName( name ) );
}
@@ -406,7 +451,7 @@
*/
public void unbind( Name name ) throws NamingException
{
- nexusProxy.delete( buildTarget( name ) ) ;
+ nexusProxy.delete( buildTarget( name ) );
}
@@ -415,7 +460,7 @@
*/
public Object lookup( String name ) throws NamingException
{
- return lookup( new LdapName( name ) ) ;
+ return lookup( new LdapName( name ) );
}
@@ -424,27 +469,27 @@
*/
public Object lookup( Name name ) throws NamingException
{
- LdapName target = buildTarget( name ) ;
- Attributes attributes = nexusProxy.lookup( target ) ;
+ LdapName target = buildTarget( name );
+ Attributes attributes = nexusProxy.lookup( target );
// First lets test and see if the entry is a serialized java object
if ( attributes.get( JavaLdapSupport.JCLASSNAME_ATTR ) != null )
{
// Give back serialized object and not a context
- return JavaLdapSupport.deserialize( attributes ) ;
+ return JavaLdapSupport.deserialize( attributes );
}
// Initialize and return a context since the entry is not a java object
- EveLdapContext ctx = new EveLdapContext( nexusProxy, env, target ) ;
+ EveLdapContext ctx = new EveLdapContext( principal, nexusProxy, env, target );
// Need to add controls to propagate extended ldap operational env
- Control [] controls = ( ( EveLdapContext ) this ).getRequestControls() ;
+ Control [] controls = ( ( EveLdapContext ) this ).getRequestControls();
if ( null != controls )
{
- ctx.setRequestControls( ( Control [] ) controls.clone() ) ;
+ ctx.setRequestControls( ( Control [] ) controls.clone() );
}
- return ctx ;
+ return ctx;
}
@@ -453,7 +498,7 @@
*/
public Object lookupLink( String name ) throws NamingException
{
- throw new UnsupportedOperationException() ;
+ throw new UnsupportedOperationException();
}
@@ -462,7 +507,7 @@
*/
public Object lookupLink( Name name ) throws NamingException
{
- throw new UnsupportedOperationException() ;
+ throw new UnsupportedOperationException();
}
@@ -476,7 +521,7 @@
*/
public NameParser getNameParser( String name ) throws NamingException
{
- return LdapName.getNameParser() ;
+ return LdapName.getNameParser();
}
@@ -490,7 +535,7 @@
*/
public NameParser getNameParser( Name name ) throws NamingException
{
- return LdapName.getNameParser() ;
+ return LdapName.getNameParser();
}
@@ -499,7 +544,7 @@
*/
public NamingEnumeration list( String name ) throws NamingException
{
- return list( new LdapName( name ) ) ;
+ return list( new LdapName( name ) );
}
@@ -508,7 +553,7 @@
*/
public NamingEnumeration list( Name name ) throws NamingException
{
- return nexusProxy.list( buildTarget( name ) ) ;
+ return nexusProxy.list( buildTarget( name ) );
}
@@ -517,7 +562,7 @@
*/
public NamingEnumeration listBindings( String name ) throws NamingException
{
- return listBindings( new LdapName( name ) ) ;
+ return listBindings( new LdapName( name ) );
}
@@ -527,12 +572,12 @@
public NamingEnumeration listBindings( Name name ) throws NamingException
{
// Conduct a special one level search at base for all objects
- Name base = buildTarget( name ) ;
- PresenceNode filter = new PresenceNode( "objectClass" ) ;
- SearchControls ctls = new SearchControls() ;
- ctls.setSearchScope( SearchControls.ONELEVEL_SCOPE ) ;
+ Name base = buildTarget( name );
+ PresenceNode filter = new PresenceNode( "objectClass" );
+ SearchControls ctls = new SearchControls();
+ ctls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
- return nexusProxy.search( base , getEnvironment(), filter, ctls ) ;
+ return nexusProxy.search( base , getEnvironment(), filter, ctls );
}
@@ -541,7 +586,7 @@
*/
public String composeName( String name, String prefix ) throws NamingException
{
- return composeName( new LdapName( name ), new LdapName( prefix ) ).toString() ;
+ return composeName( new LdapName( name ), new LdapName( prefix ) ).toString();
}
@@ -555,7 +600,7 @@
// No prefix reduces to name, or the name relative to this context
if ( prefix == null || prefix.size() == 0 )
{
- return name ;
+ return name;
}
/*
@@ -574,8 +619,8 @@
*/
// 1). Find the Dn for name and walk it from the head to tail
- Name fqn = buildTarget( name ) ;
- String head = prefix.get( 0 ) ;
+ Name fqn = buildTarget( name );
+ String head = prefix.get( 0 );
// 2). Walk the fqn trying to match for the head of the prefix
while ( fqn.size() > 0 )
@@ -583,16 +628,16 @@
// match found end loop
if ( fqn.get( 0 ).equalsIgnoreCase( head ) )
{
- return fqn ;
+ return fqn;
}
else // 2). Remove name components from the Dn until a match
{
- fqn.remove( 0 ) ;
+ fqn.remove( 0 );
}
}
throw new NamingException( "The prefix '" + prefix
- + "' is not an ancestor of this " + "entry '" + dn + "'" ) ;
+ + "' is not an ancestor of this " + "entry '" + dn + "'" );
}
@@ -613,10 +658,10 @@
LdapName buildTarget( Name relativeName ) throws InvalidNameException
{
// Clone our DN or absolute path
- LdapName target = ( LdapName ) dn.clone() ;
+ LdapName target = ( LdapName ) dn.clone();
// Add to left hand side of cloned DN the relative name arg
- target.addAll( target.size(), relativeName ) ;
- return target ;
+ target.addAll( target.size(), relativeName );
+ return target;
}
}
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveContextFactory.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveContextFactory.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveContextFactory.java Sat Oct 30 22:10:29 2004
@@ -6,15 +6,19 @@
import java.util.ArrayList;
import java.io.File;
+import javax.naming.Name;
import javax.naming.Context;
import javax.naming.NamingException;
-import javax.naming.Name;
+import javax.naming.ConfigurationException;
import javax.naming.directory.Attributes;
import javax.naming.spi.InitialContextFactory;
import org.apache.ldap.common.name.LdapName;
import org.apache.ldap.common.schema.AttributeType;
import org.apache.ldap.common.schema.Normalizer;
+import org.apache.ldap.common.message.LockableAttributesImpl;
+import org.apache.ldap.common.util.ArrayUtils;
+import org.apache.ldap.common.util.DateUtils;
import org.apache.eve.RootNexus;
import org.apache.eve.SystemPartition;
@@ -45,16 +49,25 @@
*/
public class EveContextFactory implements InitialContextFactory
{
+ // for convenience
+ private static final String TYPE = Context.SECURITY_AUTHENTICATION;
+ private static final String PRINCIPAL = Context.SECURITY_PRINCIPAL;
+ //private static final String ADMIN = SystemPartition.ADMIN_PRINCIPAL;
+
+ /** property used to shutdown the system */
public static final String SHUTDOWN_OP_ENV = "eve.operation.shutdown";
+ /** property used to sync the system with disk */
public static final String SYNC_OP_ENV = "eve.operation.sync";
/** key base for a set of user indices provided as comma sep list of attribute names or oids */
public static final String USER_INDICES_ENV_BASE = "eve.user.db.indices";
- /** the path to eve's working directory - relative or absolute */
+ /** bootstrap prop: path to eve's working directory - relative or absolute */
public static final String WKDIR_ENV = "eve.wkdir";
/** default path to working directory if WKDIR_ENV property is not set */
public static final String DEFAULT_WKDIR = "eve";
/** a comma separated list of schema class files to load */
public static final String SCHEMAS_ENV = "eve.schemas";
+ /** bootstrap prop: if key is present it enables anonymous users */
+ public static final String ANONYMOUS_ENV = "eve.enable.anonymous";
// ------------------------------------------------------------------------
//
@@ -85,7 +98,7 @@
public static final String SUFFIX_BASE_ENV = "eve.db.partition.suffix.";
/** the envprop key base to the space separated list of indices for a partition */
public static final String INDICES_BASE_ENV = "eve.db.partition.indices.";
- /** the envprop key base to the Attributes for the context root entry */
+ /** the envprop key base to the Attributes for the context nexus entry */
public static final String ATTRIBUTES_BASE_ENV = "eve.db.partition.attributes.";
// ------------------------------------------------------------------------
@@ -100,7 +113,7 @@
private SystemPartition system;
private GlobalRegistries globalRegistries;
- private RootNexus root;
+ private RootNexus nexus;
/**
@@ -148,10 +161,88 @@
if ( null == provider )
{
this.initialEnv = env;
+
+ // check if we are trying to boostrap as another user
+ if ( initialEnv.containsKey( PRINCIPAL ) &&
+ initialEnv.containsKey( TYPE ) &&
+ initialEnv.get( TYPE ).equals( "none" ) )
+ {
+ String msg = "Ambiguous configuration: " + TYPE;
+ msg += " is set to none and the security principal";
+ msg += " is set using " + PRINCIPAL + " as well";
+ throw new ConfigurationException( msg );
+ }
+ else if ( ! initialEnv.containsKey( Context.SECURITY_PRINCIPAL ) &&
+ initialEnv.containsKey( Context.SECURITY_AUTHENTICATION ) &&
+ initialEnv.get( Context.SECURITY_AUTHENTICATION ).equals( "none" ) )
+ {
+ throw new ConfigurationException( "using authentication type none "
+ + "for anonymous binds while trying to bootstrap Eve "
+ + "- this is not allowed ONLY the admin can bootstrap" );
+ }
+ else if ( initialEnv.containsKey( Context.SECURITY_PRINCIPAL ) &&
+ ! initialEnv.get( Context.SECURITY_PRINCIPAL ).equals( SystemPartition.ADMIN_PRINCIPAL ) )
+ {
+ throw new ConfigurationException( "user "
+ + initialEnv.get( Context.SECURITY_PRINCIPAL )
+ + " is not allowed to bootstrap the system. ONLY the "
+ + "admin can bootstrap" );
+ }
+
initialize();
+ createAdminAccount();
+ }
+
+ EveContext ctx = ( EveContext ) provider.getLdapContext( env );
+ return ctx;
+ }
+
+
+ /**
+ * Returns true if we had to create the admin account since this is the
+ * first time we started the server. Otherwise if the account exists then
+ * we are not starting for the first time.
+ *
+ * @return
+ * @throws NamingException
+ */
+ private boolean createAdminAccount() throws NamingException
+ {
+ Name admin = new LdapName( SystemPartition.ADMIN_PRINCIPAL );
+
+ /*
+ * If the admin entry is there, then the database was already created
+ * before so we just need to lookup the userPassword field to see if
+ * the password matches.
+ */
+ if ( nexus.hasEntry( admin ) )
+ {
+ return false;
+ }
+
+ Attributes attributes = new LockableAttributesImpl();
+ attributes.put( "objectClass", "top" );
+ attributes.put( "objectClass", "person" );
+ attributes.put( "objectClass", "organizationalPerson" );
+ attributes.put( "objectClass", "inetOrgPerson" );
+ attributes.put( "uid", SystemPartition.ADMIN_UID );
+ attributes.put( "displayName", "Directory Superuser" );
+ attributes.put( "creatorsName", SystemPartition.ADMIN_PRINCIPAL );
+ attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() );
+ attributes.put( "displayName", "Directory Superuser" );
+
+ if ( initialEnv.containsKey( Context.SECURITY_CREDENTIALS ) )
+ {
+ attributes.put( "userPassword", initialEnv.get(
+ Context.SECURITY_CREDENTIALS ) );
}
-
- return provider.getLdapContext( env );
+ else
+ {
+ attributes.put( "userPassword", ArrayUtils.EMPTY_BYTE_ARRAY );
+ }
+
+ nexus.add( SystemPartition.ADMIN_PRINCIPAL, admin, attributes );
+ return true;
}
@@ -195,8 +286,7 @@
{
if ( ! wkdirFile.exists() )
{
- throw new NamingException( "working directory " + wkdir
- + " does not exist" );
+ throw new NamingException( "working directory " + wkdir + " does not exist" );
}
}
else
@@ -234,8 +324,8 @@
system = new SystemPartition( db, eng, attributes );
globalRegistries = new GlobalRegistries( system, bootstrapRegistries );
- root = new RootNexus( system );
- provider = new EveJndiProvider( root );
+ nexus = new RootNexus( system );
+ provider = new EveJndiProvider( nexus );
// --------------------------------------------------------------------
@@ -248,11 +338,18 @@
* before and onError interceptor chains.
*/
InvocationStateEnum[] state = new InvocationStateEnum[]{
- InvocationStateEnum.POSTINVOCATION
+ InvocationStateEnum.PREINVOCATION
};
- Interceptor interceptor;
- FilterService filterService =
- new FilterServiceImpl();
+ boolean allowAnonymous = initialEnv.containsKey( ANONYMOUS_ENV );
+ Interceptor interceptor = new AuthenticationService( nexus, allowAnonymous );
+ provider.addInterceptor( interceptor, state );
+
+ /*
+ * Create and add the Eve Exception service interceptor to both the
+ * before and onError interceptor chains.
+ */
+ state = new InvocationStateEnum[]{ InvocationStateEnum.POSTINVOCATION };
+ FilterService filterService = new FilterServiceImpl();
interceptor = ( Interceptor ) filterService;
provider.addInterceptor( interceptor, state );
@@ -264,16 +361,14 @@
InvocationStateEnum.PREINVOCATION,
InvocationStateEnum.FAILUREHANDLING
};
- interceptor = new EveExceptionService( root );
+ interceptor = new EveExceptionService( nexus );
provider.addInterceptor( interceptor, state );
/*
* Create and add the Eve schema service interceptor to before chain.
*/
- state = new InvocationStateEnum[]{
- InvocationStateEnum.PREINVOCATION
- };
- interceptor = new SchemaService( root, globalRegistries, filterService );
+ state = new InvocationStateEnum[]{ InvocationStateEnum.PREINVOCATION };
+ interceptor = new SchemaService( nexus, globalRegistries, filterService );
provider.addInterceptor( interceptor, state );
/*
@@ -284,10 +379,11 @@
InvocationStateEnum.PREINVOCATION,
InvocationStateEnum.POSTINVOCATION
};
- interceptor = new OperationalAttributeService( root, globalRegistries,
- filterService );
+ interceptor = new OperationalAttributeService( nexus, globalRegistries, filterService );
provider.addInterceptor( interceptor, state );
+
+ // fire up the app partitions now!
if ( initialEnv.get( PARTITIONS_ENV ) != null )
{
initAppPartitions( wkdir );
@@ -315,7 +411,6 @@
String wkdir = eveWkdir + File.separator + names[ii];
mkdirs( eveWkdir, names[ii] );
-
// ----------------------------------------------------------------
// create the database/store
// ----------------------------------------------------------------
@@ -371,10 +466,10 @@
.toArray( new AttributeType[attributeTypeList.size()] );
ApplicationPartition partition = new ApplicationPartition( upSuffix,
normSuffix, db, eng, indexTypes );
- root.register( partition );
+ nexus.register( partition );
// ----------------------------------------------------------------
- // add the root context entry
+ // add the nexus context entry
// ----------------------------------------------------------------
Attributes rootEntry = ( Attributes ) initialEnv.get(
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveDirContext.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveDirContext.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveDirContext.java Sat Oct 30 22:10:29 2004
@@ -20,6 +20,7 @@
import java.io.IOException;
import java.util.Hashtable;
import java.text.ParseException;
+import java.security.Principal;
import javax.naming.Name;
import javax.naming.ldap.Control;
@@ -75,14 +76,16 @@
/**
* Creates a new EveDirContext with a distinguished name which is used to
* set the PROVIDER_URL to the distinguished name for this context.
- *
+ *
+ * @param principal the principal which is propagated
* @param nexusProxy the intercepting proxy to the nexus
* @param env the environment properties used by this context
* @param dn the distinguished name of this context
*/
- protected EveDirContext( PartitionNexus nexusProxy, Hashtable env, LdapName dn )
+ protected EveDirContext( Principal principal, PartitionNexus nexusProxy,
+ Hashtable env, Name dn )
{
- super( nexusProxy, env, dn );
+ super( principal, nexusProxy, env, dn );
}
@@ -291,7 +294,8 @@
getNexusProxy().add( target.toString(), target, attributes );
// Initialize the new context
- EveLdapContext ctx = new EveLdapContext( getNexusProxy(), getEnvironment(), target );
+ EveLdapContext ctx = new EveLdapContext( getPrincipal(), getNexusProxy(),
+ getEnvironment(), target );
Control [] controls = ( ( EveLdapContext ) this ).getRequestControls();
if ( controls != null )
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveJndiProvider.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveJndiProvider.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveJndiProvider.java Sat Oct 30 22:10:29 2004
@@ -113,14 +113,14 @@
/**
* @see org.apache.eve.EveBackendSubsystem#getLdapContext(Hashtable)
*/
- public LdapContext getLdapContext( Hashtable aenv ) throws NamingException
+ public LdapContext getLdapContext( Hashtable env ) throws NamingException
{
if ( this.isShutdown )
{
throw new IllegalStateException( "Eve has been shutdown!" );
}
- return new EveLdapContext( proxy, aenv );
+ return new EveLdapContext( proxy, env );
}
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveLdapContext.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveLdapContext.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveLdapContext.java Sat Oct 30 22:10:29 2004
@@ -18,31 +18,40 @@
import java.util.Hashtable;
+import java.security.Principal;
import javax.naming.NamingException;
+import javax.naming.Name;
import javax.naming.ldap.Control;
import javax.naming.ldap.ExtendedRequest;
import javax.naming.ldap.ExtendedResponse;
import javax.naming.ldap.LdapContext;
-import org.apache.ldap.common.name.LdapName;
+import org.apache.ldap.common.NotImplementedException;
import org.apache.eve.PartitionNexus;
/**
+ * An Eve implementation of a JNDI LdapContext.
*
* @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
public class EveLdapContext extends EveDirContext implements LdapContext
{
+ private static final Control[] EMPTY_CONTROLS = new Control[0];
+ private Control[] requestControls = EMPTY_CONTROLS;
+ private Control[] responseControls = EMPTY_CONTROLS;
+ private Control[] connectControls = EMPTY_CONTROLS;
+
/**
- * TODO Document me!
+ * Creates an instance of an EveLdapContext.
*
- * @param nexusProxy TODO
- * @param env TODO
+ * @param nexusProxy the proxy to a partition nexus
+ * @param env the JNDI environment parameters
+ * @throws NamingException the context cannot be created
*/
public EveLdapContext( PartitionNexus nexusProxy, Hashtable env ) throws NamingException
{
@@ -53,14 +62,15 @@
/**
* Creates a new EveDirContext with a distinguished name which is used to
* set the PROVIDER_URL to the distinguished name for this context.
- *
+ *
+ * @param principal the directory user principal that is propagated
* @param nexusProxy the intercepting proxy to the nexus
* @param env the environment properties used by this context
* @param dn the distinguished name of this context
*/
- EveLdapContext( PartitionNexus nexusProxy, Hashtable env, LdapName dn )
+ EveLdapContext( Principal principal, PartitionNexus nexusProxy, Hashtable env, Name dn )
{
- super( nexusProxy, env, dn );
+ super( principal, nexusProxy, env, dn );
}
@@ -70,8 +80,7 @@
*/
public ExtendedResponse extendedOperation( ExtendedRequest request )
{
- // TODO Auto-generated method stub
- return null;
+ throw new NotImplementedException();
}
@@ -82,8 +91,10 @@
public LdapContext newInstance( Control[] requestControls )
throws NamingException
{
- // TODO Auto-generated method stub
- return null;
+ EveLdapContext ctx = new EveLdapContext( getPrincipal(), getNexusProxy(),
+ getEnvironment(), getDn() );
+ ctx.setRequestControls( requestControls );
+ return ctx;
}
@@ -92,56 +103,44 @@
*/
public void reconnect( Control[] connCtls ) throws NamingException
{
- // TODO Auto-generated method stub
+ this.connectControls = connCtls;
}
/**
- * TODO Document me!
- *
* @see javax.naming.ldap.LdapContext#getConnectControls()
*/
public Control[] getConnectControls() throws NamingException
{
- // TODO Auto-generated method stub
- return null;
+ return this.connectControls;
}
/**
- * TODO Document me!
- *
* @see javax.naming.ldap.LdapContext#setRequestControls(
* javax.naming.ldap.Control[])
*/
public void setRequestControls( Control[] requestControls )
throws NamingException
{
- // TODO Auto-generated method stub
+ this.requestControls = requestControls;
}
/**
- * TODO Document me!
- *
* @see javax.naming.ldap.LdapContext#getRequestControls()
*/
public Control[] getRequestControls() throws NamingException
{
- // TODO Auto-generated method stub
- return null;
+ return requestControls;
}
/**
- * TODO Document me!
- *
* @see javax.naming.ldap.LdapContext#getResponseControls()
*/
public Control[] getResponseControls() throws NamingException
{
- // TODO Auto-generated method stub
- return null;
+ return responseControls;
}
-
}
Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/exception/EveAuthenticationException.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/exception/EveAuthenticationException.java Sat Oct 30 22:10:29 2004
@@ -0,0 +1,45 @@
+/*
+ * 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.exception;
+
+
+import javax.naming.AuthenticationException;
+
+import org.apache.eve.exception.EveException;
+import org.apache.ldap.common.message.ResultCodeEnum;
+
+
+/**
+ * The Eve version of an {@link AuthenticationException} which associates the
+ * {@link ResultCodeEnum.INVALIDCREDENTIALS} value with it.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class EveAuthenticationException extends AuthenticationException
+ implements EveException
+{
+ /**
+ * Gets ResultCodeEnum.INVALIDCREDENTIALS every time.
+ *
+ * @return ResultCodeEnum.INVALIDCREDENTIALS
+ */
+ public ResultCodeEnum getResultCode()
+ {
+ return ResultCodeEnum.INVALIDCREDENTIALS;
+ }
+}
Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/exception/EveAuthenticationNotSupportedException.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/exception/EveAuthenticationNotSupportedException.java Sat Oct 30 22:10:29 2004
@@ -0,0 +1,121 @@
+/*
+ * 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.exception;
+
+
+import javax.naming.AuthenticationNotSupportedException;
+
+import org.apache.eve.exception.EveException;
+import org.apache.ldap.common.message.ResultCodeEnum;
+
+
+/**
+ * An Eve subclass of the {@link AuthenticationNotSupportedException} carrying
+ * along an unequivocal ResultCodeEnum value.
+ *
+ * @see <a href="http://java.sun.com/products/jndi/tutorial/ldap/models/exceptions.html">Exceptions</a>
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class EveAuthenticationNotSupportedException
+ extends AuthenticationNotSupportedException implements EveException
+{
+ /** the result code type safe enumeration */
+ private final ResultCodeEnum resultCode;
+
+
+ // ------------------------------------------------------------------------
+ // C O N S T R U C T O R S
+ // ------------------------------------------------------------------------
+
+
+ /**
+ * Creates an EveException with the resultCode.
+ *
+ * @see AuthenticationNotSupportedException#AuthenticationNotSupportedException()
+ * @param resultCode the resultCode enumeration
+ * @throws IllegalArgumentException if the resultCode is not one of the
+ * codes corresponding to an AuthenticationNotSupportedException
+ */
+ public EveAuthenticationNotSupportedException( ResultCodeEnum resultCode )
+ {
+ super();
+ this.resultCode = resultCode;
+ checkResultCode();
+ }
+
+
+ /**
+ * Sets the resultCode associated with this EveException.
+ *
+ * @see AuthenticationNotSupportedException#AuthenticationNotSupportedException(String)
+ * @param resultCode the resultCode enumeration
+ * @throws IllegalArgumentException if the resultCode is not one of the
+ * codes corresponding to an AuthenticationNotSupportedException
+ */
+ public EveAuthenticationNotSupportedException( String explanation, ResultCodeEnum resultCode )
+ {
+ super( explanation );
+ this.resultCode = resultCode;
+ checkResultCode();
+ }
+
+
+ // ------------------------------------------------------------------------
+ // EveException methods
+ // ------------------------------------------------------------------------
+
+
+ /**
+ * @see org.apache.eve.exception.EveException#getResultCode()
+ */
+ public ResultCodeEnum getResultCode()
+ {
+ return resultCode;
+ }
+
+
+ // ------------------------------------------------------------------------
+ // P R I V A T E M E T H O D S
+ // ------------------------------------------------------------------------
+
+
+ /**
+ * Checks to make sure the resultCode value is right for this exception
+ * type.
+ *
+ * @throws IllegalArgumentException if the result code is not one of
+ * {@link ResultCodeEnum#INAPPROPRIATEAUTHENTICATION},
+ * {@link ResultCodeEnum#AUTHMETHODNOTSUPPORTED},
+ * {@link ResultCodeEnum#CONFIDENTIALITYREQUIRED}.
+ */
+ private void checkResultCode()
+ {
+ switch( resultCode.getValue() )
+ {
+ case( ResultCodeEnum.INAPPROPRIATEAUTHENTICATION_VAL ):
+ break;
+ case( ResultCodeEnum.CONFIDENTIALITYREQUIRED_VAL ):
+ break;
+ case( ResultCodeEnum.AUTHMETHODNOTSUPPORTED_VAL ):
+ break;
+ default:
+ throw new IllegalArgumentException( "Unexceptable result code "
+ + "for this exception type: " + resultCode.getName() );
+ }
+ }
+}
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/OperationalAttributeService.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/OperationalAttributeService.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/OperationalAttributeService.java Sat Oct 30 22:10:29 2004
@@ -289,6 +289,6 @@
String principal;
Context ctx = ( ( Context ) invocation.getContextStack().peek() );
principal = ( String ) ctx.getEnvironment().get( Context.SECURITY_PRINCIPAL );
- return principal == null ? SystemPartition.DEFAULT_PRINCIPAL : principal;
+ return principal == null ? SystemPartition.ADMIN_PRINCIPAL : principal;
}
}
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/SchemaService.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/SchemaService.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/SchemaService.java Sat Oct 30 22:10:29 2004
@@ -147,7 +147,7 @@
{
String id = ( String ) list.next();
AttributeType type = registry.lookup( id );
- boolean isBinary = ! type.getSyntax().isHumanReadable();
+ boolean isBinary = ! type.getSyntax().isHumanReadible();
if ( isBinary || binaries.contains( type ) )
{
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/GlobalRegistries.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/GlobalRegistries.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/GlobalRegistries.java Sat Oct 30 22:10:29 2004
@@ -384,7 +384,7 @@
// try
// {
// String schema = attributeTypeRegistry.getSchemaName( at.getOid() );
-// if ( ! hasMatchingRule && at.getSyntax().isHumanReadable() )
+// if ( ! hasMatchingRule && at.getSyntax().isHumanReadible() )
// {
// errors.add( new NullPointerException( "attributeType "
// + at.getName() + " in schema " + schema + " with OID "
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/BootstrapRegistries.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/BootstrapRegistries.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/BootstrapRegistries.java Sat Oct 30 22:10:29 2004
@@ -359,7 +359,7 @@
// try
// {
// String schema = attributeTypeRegistry.getSchemaName( at.getOid() );
-// if ( ! hasMatchingRule && at.getSyntax().isHumanReadable() )
+// if ( ! hasMatchingRule && at.getSyntax().isHumanReadible() )
// {
// errors.add( new NullPointerException( "attributeType "
// + at.getName() + " in schema " + schema + " with OID "
Modified: incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/AbstractJndiTest.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/AbstractJndiTest.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/AbstractJndiTest.java Sat Oct 30 22:10:29 2004
@@ -19,9 +19,11 @@
import java.util.Hashtable;
import java.io.File;
+import java.io.IOException;
import javax.naming.ldap.LdapContext;
import javax.naming.Context;
import javax.naming.InitialContext;
+import javax.naming.NamingException;
import junit.framework.TestCase;
import org.apache.commons.io.FileUtils;
@@ -44,6 +46,9 @@
/** extra environment parameters that can be added before setUp */
protected Hashtable extras = new Hashtable();
+ /** extra environment parameters that can be added before setUp to override values */
+ protected Hashtable overrides = new Hashtable();
+
/**
* Get's the initial context factory for the provider's ou=system context
@@ -54,24 +59,67 @@
protected void setUp() throws Exception
{
super.setUp();
+ doDelete( new File( "target" + File.separator + "eve" ) );
+ setSysRoot( "uid=admin,ou=system", "testing" );
+ }
- if ( doDelete == true )
- {
- File file = new File( "target/eve" );
- if ( file.exists() )
+ /**
+ * Deletes the Eve working directory.
+ *
+ * @throws IOException if there are failures while deleting.
+ */
+ protected void doDelete( File wkdir ) throws IOException
+ {
+ if ( doDelete )
+ {
+ if ( wkdir.exists() )
{
- FileUtils.deleteDirectory( file );
+ FileUtils.deleteDirectory( wkdir );
}
}
+ }
+
+ /**
+ * Sets and returns the system root. Values of user and password used to
+ * set the respective JNDI properties. These values can be overriden by the
+ * overrides properties.
+ *
+ * @param user the username for authenticating as this user
+ * @param passwd the password of the user
+ * @return the sysRoot context which is also set
+ * @throws NamingException if there is a failure of any kind
+ */
+ protected LdapContext setSysRoot( String user, String passwd ) throws NamingException
+ {
Hashtable env = new Hashtable();
- env.putAll( extras );
- env.put( Context.PROVIDER_URL, "ou=system" );
- env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.eve.jndi.EveContextFactory" );
- env.put( EveContextFactory.WKDIR_ENV, "target/eve" );
- InitialContext initialContext = new InitialContext( env );
- sysRoot = ( LdapContext ) initialContext.lookup( "" );
+ env.put( Context.SECURITY_PRINCIPAL, user );
+ env.put( Context.SECURITY_CREDENTIALS, passwd );
+ return setSysRoot( env );
+ }
+
+
+ /**
+ * Sets the system root taking into account the extras and overrides
+ * properties. In between these it sets the properties for the working
+ * directory, the provider URL and the JNDI InitialContexFactory to use.
+ *
+ * @param env an environment to use while setting up the system root.
+ * @return the sysRoot context which is also set
+ * @throws NamingException if there is a failure of any kind
+ */
+ protected LdapContext setSysRoot( Hashtable env ) throws NamingException
+ {
+ Hashtable envFinal = new Hashtable();
+ envFinal.putAll( extras );
+ envFinal.putAll( env );
+ envFinal.put( Context.PROVIDER_URL, "ou=system" );
+ envFinal.put( EveContextFactory.WKDIR_ENV, "target" + File.separator + "eve" );
+ envFinal.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.eve.jndi.EveContextFactory" );
+ envFinal.putAll( overrides );
+ InitialContext initialContext = new InitialContext( envFinal );
+ return sysRoot = ( LdapContext ) initialContext.lookup( "" );
}
@@ -87,6 +135,8 @@
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
{
@@ -94,7 +144,6 @@
}
catch( Exception e )
{
-
}
sysRoot = null;
Modified: incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/EveContextFactoryTest.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/EveContextFactoryTest.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/EveContextFactoryTest.java Sat Oct 30 22:10:29 2004
@@ -108,6 +108,7 @@
{
Hashtable env = new Hashtable();
env.put( Context.PROVIDER_URL, "dc=example" );
+ env.put( Context.SECURITY_CREDENTIALS, "testing" );
env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.eve.jndi.EveContextFactory" );
InitialContext initialContext = new InitialContext( env );
DirContext appRoot = ( DirContext ) initialContext.lookup( "" );
@@ -127,6 +128,7 @@
{
Hashtable env = new Hashtable();
env.put( Context.PROVIDER_URL, "ou=testing" );
+ env.put( Context.SECURITY_CREDENTIALS, "testing" );
env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.eve.jndi.EveContextFactory" );
InitialContext initialContext = new InitialContext( env );
DirContext appRoot = ( DirContext ) initialContext.lookup( "" );
Added: incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/SimpleAuthenticationTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/SimpleAuthenticationTest.java Sat Oct 30 22:10:29 2004
@@ -0,0 +1,260 @@
+/*
+ * 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.io.File;
+import java.io.IOException;
+import java.util.Hashtable;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.Attributes;
+import javax.naming.NamingException;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.ConfigurationException;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.ldap.common.util.ArrayUtils;
+
+
+/**
+ * A set of simple tests to make sure simple authentication is working as it
+ * should.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class SimpleAuthenticationTest extends AbstractJndiTest
+{
+ /**
+ * Cleans up old database files on creation.
+ *
+ * @throws IOException if we can't clean the files
+ */
+ public SimpleAuthenticationTest() throws IOException
+ {
+ doDelete( new File( "target" + File.separator + "eve" ) );
+ }
+
+
+ /**
+ * Customizes setup for each test case.
+ *
+ * <ul>
+ * <li>sets doDelete to false for test1AdminAccountCreation</li>
+ * <li>sets doDelete to false for test2AccountExistsOnRestart</li>
+ * <li>sets doDelete to true for all other cases</li>
+ * <li>bypasses normal setup for test3BuildDbNoNothing</li>
+ * <li>bypasses normal setup for test5BuildDbNoPassWithPrincAuthNone</li>
+ * <li>bypasses normal setup for test4BuildDbNoPassNoPrincAuthNone</li>
+ * <li>bypasses normal setup for </li>
+ * <li></li>
+ * </ul>
+ *
+ * @throws Exception
+ */
+ protected void setUp() throws Exception
+ {
+ if ( getName().equals( "test1AdminAccountCreation" ) ||
+ getName().equals( "test2AccountExistsOnRestart" ) )
+ {
+ super.doDelete = false;
+ }
+ else
+ {
+ super.doDelete = true;
+ }
+
+ if ( getName().equals( "test3BuildDbNoNothing" ) ||
+ getName().equals( "test5BuildDbNoPassWithPrincAuthNone" ) ||
+ getName().equals( "test4BuildDbNoPassNoPrincAuthNone" ) )
+ {
+ return;
+ }
+
+ super.setUp();
+ }
+
+
+ /**
+ * Checks all attributes of the admin account entry minus the userPassword
+ * attribute.
+ *
+ * @param attrs the entries attributes
+ */
+ protected void performAdminAccountChecks( Attributes attrs )
+ {
+ assertTrue( attrs.get( "objectClass" ).contains( "top" ) );
+ assertTrue( attrs.get( "objectClass" ).contains( "person" ) );
+ assertTrue( attrs.get( "objectClass" ).contains( "organizationalPerson" ) );
+ assertTrue( attrs.get( "objectClass" ).contains( "inetOrgPerson" ) );
+ assertTrue( attrs.get( "displayName" ).contains( "Directory Superuser" ) );
+ }
+
+
+ /**
+ * Check the creation of the admin account.
+ *
+ * @throws NamingException if there are failures
+ */
+ public void test1AdminAccountCreation() throws NamingException
+ {
+ DirContext ctx = ( DirContext ) sysRoot.lookup( "uid=admin" );
+ Attributes attrs = ctx.getAttributes( "" );
+ performAdminAccountChecks( attrs );
+ assertTrue( attrs.get( "userPassword" ).contains( "testing" ) );
+ }
+
+
+ /**
+ * Check the creation of the admin account even after a restart.
+ *
+ * @throws NamingException if there are failures
+ */
+ public void test2AccountExistsOnRestart() throws NamingException
+ {
+ DirContext ctx = ( DirContext ) sysRoot.lookup( "uid=admin" );
+ Attributes attrs = ctx.getAttributes( "" );
+
+ performAdminAccountChecks( attrs );
+ assertTrue( attrs.get( "userPassword" ).contains( "testing" ) );
+ }
+
+
+ /**
+ * Checks that we can give basically the minimal set of properties without
+ * any security information to build and bootstrap a new system. The admin
+ * user is presumed and no password is used.
+ *
+ * @throws Exception if there are problems
+ */
+ public void test3BuildDbNoNothing() throws Exception
+ {
+ // clean out the database
+ doDelete( new File( "target" + File.separator + "eve" ) );
+ LdapContext ctx = setSysRoot( new Hashtable() );
+ Attributes attributes = ctx.getAttributes( "uid=admin" );
+ assertNotNull( attributes );
+
+ // Eve has started now so we access another context w/o the wkdir
+ Hashtable env = new Hashtable();
+ env.put( Context.PROVIDER_URL, "ou=system" );
+ env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.eve.jndi.EveContextFactory" );
+ InitialContext initial = new InitialContext( env );
+ ctx = ( LdapContext ) initial.lookup( "uid=admin" );
+ assertNotNull( ctx );
+ attributes = ctx.getAttributes( "" );
+ assertNotNull( attributes );
+
+ performAdminAccountChecks( attributes );
+ assertTrue( attributes.get( "userPassword" ).contains( ArrayUtils.EMPTY_BYTE_ARRAY ) );
+ }
+
+
+ /**
+ * Tests to make sure we throw an error when Context.SECURITY_AUTHENTICATION
+ * is set to "none" when trying to bootstrap the system. Only the admin
+ * user is allowed to bootstrap. Subsequent calls can 'bind' (authenticate
+ * in our case since there is no network connection) anonymously though.
+ *
+ * @throws Exception if anything goes wrong
+ */
+ public void test4BuildDbNoPassNoPrincAuthNone() throws Exception
+ {
+ // clean out the database
+ tearDown();
+ doDelete( new File( "target" + File.separator + "eve" ) );
+ Hashtable env = new Hashtable();
+ env.put( Context.SECURITY_AUTHENTICATION, "none" );
+
+ try
+ {
+ setSysRoot( env );
+ fail( "should not get here due to exception" );
+ }
+ catch( ConfigurationException e )
+ {
+ }
+
+ // ok this should start up the system now as admin
+ Hashtable anonymous = new Hashtable();
+ anonymous.put( EveContextFactory.ANONYMOUS_ENV, "true" );
+ EveLdapContext ctx = ( EveLdapContext ) setSysRoot( anonymous );
+ assertNotNull( ctx );
+
+ // now go in as anonymous user and we should be wh
+ env.put( Context.PROVIDER_URL, "ou=system" );
+ env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.eve.jndi.EveContextFactory" );
+
+ InitialContext initial = new InitialContext( env );
+ ctx = ( EveLdapContext ) initial.lookup( "uid=admin" );
+ assertNotNull( ctx );
+ Attributes attributes = ctx.getAttributes( "" );
+ assertNotNull( attributes );
+
+ performAdminAccountChecks( attributes );
+ assertTrue( attributes.get( "userPassword" ).contains( ArrayUtils.EMPTY_BYTE_ARRAY ) );
+ }
+
+
+ public void test5BuildDbNoPassWithPrincAuthNone() throws Exception
+ {
+ // clean out the database
+ tearDown();
+ doDelete( new File( "target" + File.separator + "eve" ) );
+ Hashtable env = new Hashtable();
+ env.put( Context.SECURITY_AUTHENTICATION, "none" );
+ env.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
+
+ try
+ {
+ setSysRoot( env );
+ fail( "should not get here due to exception" );
+ }
+ catch( ConfigurationException e )
+ {
+ }
+
+// // clean out the database
+// doDelete( new File( "target" + File.separator + "eve" ) );
+// Hashtable env = new Hashtable();
+// env.put( Context.SECURITY_AUTHENTICATION, "none" );
+// env.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
+// EveLdapContext ctx = ( EveLdapContext ) setSysRoot( env );
+// X500Principal principal = ctx.getPrincipal();
+// assertTrue( principal.getName().equalsIgnoreCase( SystemPartition.ADMIN_PRINCIPAL ) );
+// Attributes attributes = ctx.getAttributes( "uid=admin" );
+// assertNotNull( attributes );
+//
+// // Eve has started now so we access another context w/o the wkdir
+// env = new Hashtable();
+// env.put( Context.PROVIDER_URL, "ou=system" );
+// env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.eve.jndi.EveContextFactory" );
+// InitialContext initial = new InitialContext( env );
+// ctx = ( EveLdapContext ) initial.lookup( "uid=admin" );
+// assertNotNull( ctx );
+// attributes = ctx.getAttributes( "" );
+// assertNotNull( attributes );
+//
+// assertTrue( attributes.get( "objectClass" ).contains( "top" ) );
+// assertTrue( attributes.get( "objectClass" ).contains( "person" ) );
+// assertTrue( attributes.get( "objectClass" ).contains( "organizationalPerson" ) );
+// assertTrue( attributes.get( "objectClass" ).contains( "inetOrgPerson" ) );
+// assertTrue( attributes.get( "userPassword" ).contains( ArrayUtils.EMPTY_BYTE_ARRAY ) );
+// assertTrue( attributes.get( "displayName" ).contains( "Directory Superuser" ) );
+ }
+}