Server-Side JNDI Provider

The Apache Directory Server contains a JNDI provider for the LDAP namespace. Unlike the SUN JNDI LDAP Provider which is an LDAP client, the Server-Side JNDI Provider is not. JNDI operations on Contexts directly tap into the server's database partitions to add, lookup, alter, and search for entries. There is nothing done over the wire.

The server leverages its server side JNDI LDAP provider in several ways. First stored procedures written in Java will naturally use JNDI to alter entries using this provider. Thanks to JNDI the same procedure outside of the server can be tested using the SUN JNDI LDAP provider. This transparency is wicked cool since it makes testing easy. The server side JNDI provider is also used as the API of choice for integrating the server into other Java applications and servers. The first InitialContext request to the server side provider fires up the entire server. So you need not learn anything new to start using and embedding the Apache Directory Server!

This document describes the server side JNDI Provider in terms of the custom properties used to control its behavoir in the solid state and for configuring the server on start up.

Server Specific JNDI Properties

keyoptionaldescription
server.wkdirtrue The file system folder the server will use to store database files and other things. You can set server.wkdir to an absolute path or to a relative path like so:
server.wkdir=/opt/apacheds/work
server.wkdir=tmp/work
server.schemastrue The schema configuration settings. A space separated list of fully qualified class names. These classes must extend AbstractBootstrapSchema in the org.apache.ldap.server.schema.bootstrap package. Here's an example:
server.schemas = org.apache.ldap.server.schema.bootstrap.SystemSchema
 org.apache.ldap.server.schema.bootstrap.ApacheSchema
 org.apache.ldap.server.schema.bootstrap.CoreSchema
 org.apache.ldap.server.schema.bootstrap.CosineSchema
 org.apache.ldap.server.schema.bootstrap.InetorgpersonSchema
 org.apache.ldap.server.schema.bootstrap.Krb5kdcSchema
server.disable.anonymoustrue If present at all this key disables anonymous binds. The value of the property is disregarded. By default anonymous binds are allowed.
server.operation.synctrue If present when requesting an InitialContext this property forces all partitions to sync their buffers to disk if their implementation contains a cache. The value of the property is disregarded.
server.operation.shutdowntrue If present when requesting an InitialContext this property gracefully shuts down the server. The returned context is a useless DeadContext which throws exceptions when used. The value of the property is disregarded.
server.net.disable.protocoltrue Used when starting up the server to disable the networking frontend that handles LDAP protocol requests. The value of the property is disregarded. By default the LDAP protocol is enabled.
server.net.passthrutrue Used to pass an existing network frontend to the server rather than having the server create its own instance. The value of this property is a MINA ServiceRegistry instance.
server.net.ldap.porttrue The LDAP port to use for servicing LDAP protocol requests if not on the standard port: 389.
server.net.ldaps.porttrue WARNING: ONLY FOR JDK 1.5 AND HIGHER. Optionally specifies the LDAP port to use for servicing secure LDAP protocol requests. Secure LDAP port 636 is usually used.
server.db.partitionstrue The list of database partition identifiers. If this is not specified the only partition in the server is the system partition hanging off of the ou=system context. The value is a space separated list of partition names like 'apache example xyz123'.
server.db.partition.suffix.maybe A key base for listing the suffixes of database partitions. The identifier for the partition in the property above is appended to this base to form the key for the suffix of that partition. Here are some examples:
server.db.partition.suffix.apache=dc=apache,dc=org
server.db.partition.suffix.example=dc=example,dc=com
server.db.partition.suffix.xyz123=ou=xyz123
server.db.partition.indices.maybe A key base for listing the indices for database partitions. The identifier for the partition is appended to this base to form the key for the suffix of that partition. The value is a space separated list of attributeType names.
server.db.partition.indicies.apache=dc ou locale cn
server.db.partition.indicies.example=dc ou locale cn uid
server.db.partition.indicies.xyz123=ou cn
server.db.partition.attributes.maybe A key base for listing the attributes and values for the suffix entries of partitions. The identifier for the partition is appended to this base, then the name of attribute is appended to form the key for the attribuet in the suffix of that partition. More information on setting up partitions with this and other properties is here...
server.db.partition.attributes.apache.dc=apache
server.db.partition.attributes.apache.objectClass=domain top

Note that the optional columns of some rows were labeled as 'maybe'. If a partition is created then the respective property with the base would be required. It is only required when the respective partition is being defined.

Embedding the Apache Directory Server

Embedding the server is really easy. Just set the JNDI initial context factory and other security settings along with specific properties to fire her up. Here's a simple example of code that embeds the server using the minimum configuration information:

Hashtable env = new Hashtable();
env.put( Context.PROVIDER_URL, "ou=system" );
env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.ldap.server.jndi.ServerContextFactory" );
InitialDirContext ctx = new InitialDirContext( env );

This code snippet starts up the server on port 389 or the next available port if access to 389 is denied or another server is already bound to that port. There is only one partition in the system hanging off of the "ou=system" naming context. The server allows for anonymous binds and has two users preconfigured: a regular test user, uid=akarasulu,ou=users,ou=system with password test, and the super user uid=admin,ou=system, with password secret.

WARNING: REMOVE THE TEST USER AND RESET THE PASSWORD ON THE ADMIN USER ACCOUNT AFTER STARTING EVE.

Here's another more invovled configuration:

Hashtable env = new Hashtable();

// Standard JNDI properties
env.put( Context.PROVIDER_URL, "ou=system" );
env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.ldap.server.jndi.ServerContextFactory" );
env.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
env.put( Context.SECURITY_CREDENTIALS, "secret" );

// Eve specifice JNDI properties
env.put( EnvKeys.WKDIR, "/var/ldap" );
env.put( EnvKeys.DISABLE_ANONYMOUS, "true" );
env.put( EnvKeys.LDAP_PORT, "10389" );
env.put( EnvKeys.PARTITIONS, "apache" );

// Setup new partition for Apache
BasicAttributes attrs = new BasicAttributes( true );
BasicAttribute attr = new BasicAttribute( "objectClass" );
attr.add( "top" );
attr.add( "domain" );
attr.add( "extensibleObject" );
attrs.put( attr );
attr = new BasicAttribute( "dc" );
attr.add( "apache" );
attrs.put( attr );
env.put( EnvKeys.SUFFIX + "apache", "dc=apache,dc=org" );     // suffix
env.put( EnvKeys.INDICES + "apache", "ou uid objectClass" );  // user indices
env.put( EnvKeys.ATTRIBUTES + "apache", attrs );              // suffix entry

// Fire it up!
InitialDirContext ctx = new InitialDirContext( env );

This configuration starts up the server on port 10389 with anonymous binds disabled. The server stores its database files under /var/ldap and creates a new application partition for Apache entries off of the dc=apache,dc=org naming context in addition to the system partition. If you look closely at /var/ldap you'll see a directory named apache where you'll find even more database files. These files are the database files for the separate partition for apache.org entries.