Complete Contents
Preface
Chapter 1 Understanding LDAP
Chapter 2 Using the Netscape Directory SDK for Java
Chapter 3 Quick Start
Chapter 4 Writing an LDAP Client
Chapter 5 Using the LDAP Java Classes
Chapter 6 Searching the Directory
Chapter 7 Using Filter Configuration Files
Chapter 8 Adding, Updating, and Deleting Entries
Chapter 9 Comparing Values in Entries
Chapter 10 Working with LDAP URLs
Chapter 11 Getting Server Information
Chapter 12 Connecting Over SSL
Chapter 13 Working with LDAP Controls
Chapter 14 Using SASL Authentication
Chapter 15 Using Netscape's JNDI Service Provider
Chapter 16 Working with Extended Operations
Chapter 17 Using the Asynchronous Interface
Glossary
Directory SDK for Java 4.0 Programmer's Guide: Using the JNDI Service Provider
Previous Next Contents Index


Chapter 15 Using the JNDI Service Provider

This chapter explains JNDI and shows you how to use Netscape's LDAP Service Provider for JNDI.

The Java Naming and Directory Interface (JNDI) allows Java applications to use a single set of methods to access multiple naming and directory services such as LDAP and NIS. JNDI was developed by the JavaSoft division of Sun Microsystems along with several industry partners, including Netscape.

The chapter contains the following sections:


How JNDI Works
JNDI is a Java API that provides a common way for programmers to access a variety of naming and directory services. The API consists of several packages:

JNDI operates through a layer of software called a Service Provider. The Service Provider implements the JNDI operations in terms of a particular underlying protocol.

JNDI's Service Provider Interface (SPI) allows you to select Service Providers at runtime. In many cases you can use the same JNDI methods regardless of whether the Service Provider is talking to an LDAP server or using another protocol such as NIS. In order to access all of the functionality of the LDAP protocol, however, you will have to use methods outside of this abstraction.

For more information about JNDI and Service Providers as well as software, examples, and sample code visit http://java.sun.com/products/jndi.

Netscape's LDAP Service Provider
Netscape's LDAP Service Provider is based on version 1.2 of JNDI. In order to have JNDI use Netscape's LDAP Service Provider, you must prepare your environment and select the Service Provider in your code. The following section will help you do this.


Installing the Service Provider
Installing the Netscape LDAP Service Provider involves

The rest of this section will show you how to perform these tasks.

Add the Provider to the Classpath
Before using the Netscape LDAP Service Provider for JNDI in an application launched from the command line, you must add the provider and its associated JAR files to your Java CLASSPATH.

To do this, include the following files in your CLASSPATH:

Specify the Service Provider when Creating the Initial Context
In order to communicate with an LDAP server, JNDI needs to know where to find the LDAP Service Provider.

To have it use the Netscape Service Provider, add the following code to your Java application:

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.netscape.jndi.ldap.LdapContextFactory");
/* Insert any additional "env.put(... ...)" statements
DirContext ctx = new InitialDirContext(env);
Add the JNDI object schema to the Directory (Optional)
Before you can store Java objects in an LDAP directory, you must make sure that the JNDI object schema is available to the directory. If you are using Netscape Directory Server, this requires a modification to your directory schema.

Depending on which version of Netscape Directory Server you are using, there are two ways to do this.

Updating Netscape Directory Server 4.1
If you are using Netscape Directory Server 4.1 you must update the existing JNDI schema file. This is done as follows:

  1. Stop the server
  2. In the <server-root>/slapd-<id>/config/ directory, replace the java-object-schema.conf file with the one provided in the Netscape Directory SDK for Java.
  3. Restart the server
Updating Pre-4.1 Netscape Directory Servers
If you are using Netscape Directory Server 4.0 or earlier, you must add the JNDI schema file. This is done as follows:

  1. Stop the server.
  2. Copy the java-object-schema.conf file that is included with the Netscape Directory SDK for Java to the <server-root>/slapd-<id>/config directory.
  3. Edit <server-root>/slapd-<id>/config/ns-schema.conf to include the following line:
    include <server-root>/slapd-<id>/config/java-object-schema.conf
  4. Restart the server.

JNDI Environment Properties
JNDI has a number of environment properties that you can set at the system level or pass directly to the initial context via a Hashtable. Netscape's LDAP Service Provider accepts all properties that are defined globally for JNDI. For those settings that are relevant to LDAP, but not included in the JNDI specification, Netscape's LDAP Service Provider uses the same property names and semantics as the Sun Microsystems LDAP Service Provider.

If a change or addition to the JNDI context environment occurs after an initial context is created, it will be immediately visible unless the changed property pertains to the connection. To force these changes to take effect, invoke the LdapContext.reconnect() method. LdapContext is an extended Context that supports LDAP-specific methods (see "Working with Controls").

The following table contains all JNDI environment properties that are relevant for the Netscape LDAP Service Provider. (Any additional properties that are used by the JNDI Naming Manager are not listed here.) The provider will silently ignore any properties that are not in the table.

Table 15.1 Descriptions of JNDI Environment Properties
Environment Property
Description
java.naming.factory.initial
Used to select the LDAP provider. To select the Netscape LDAP provider, specify com.netscape.jndi.ldap.LdapContextFactory
java.naming.provider.url
Specifies LDAP server information. For example:

env.put(Context.PROVIDER_URL,
"ldap://dilly.mcom.com:389");


If this property is not set, the Service Provider will attempt to access an LDAP server at port 389 of the local host.
java.naming.ldap.version
Specifies the protocol version for the Service Provider. Two values are possible:
2 - selects LDAP Version 2 (LDAPv2)
3 - selects LDAP Version 3 (LDAPv3)
For example:
env.put("java.naming.ldap.version", "3");

sets the protocol version to 3.

If this property is not set, the Service Provider will attempt to use LDAPv3. If this fails, LDAPv2 is used.
java.naming.security.authentication
Specifies the authentication mechanism that the Service Provider will use. The following values are permitted:
none - use no authentication (anonymous)
simple - use weak authentication (clear text password)

If this environment property is not set but the java.naming.security.principal property has been set, the Service Provider will use simple authentication. If neither property is set, the Service Provider will bind anonymously.
java.naming.security.principal
Specifies the DN of the authenticating principal. For example:

env.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");

If this property is not set, the Service Provider will bind anonymously.
java.naming.security.credentials
Specifies the password of the authenticating principal. For example:

env.put(Context.SECURITY_CREDENTIALS, "secret");
java.naming.security.protocol
Specifies the security protocol that the Service Provider will use. One possible value is defined:

ssl - use Secure Socket Layer

This is implemented as follows:

env.put(Context.SECURITY_PROTOCOL, "ssl");

When this property is set and the java.naming.ldap.factory.socket property has not been set, the default socket factory netscape.net.SSLSocket is used.

This class is provided with Netscape Communicator 4.05 and higher.If java.naming.ldap.factory.socket
has been set, the socket factory specified therein is used.
java.naming.security.sasl.authorizationId
Specifies which user DN to use for SASL authentication.
java.naming.security.sasl.callback
Specifies a callback handler for SASL mechanisms. This value of this property must be an instance of javax.security.auth.callback.
CallbackHandler
.

java.naming.security.sasl.client.pkgs
Specifies a "|"-separated list of packages. These packages are used to located factories that produce SASL mechanism drivers.
java.naming.ldap.factory.socket
Specifies the class name of a socket factory. This environment property is used to override the default socket factory.
For example:

env.put("Java.naming.ldap.factory.
socket", "crysec.SSL.SSLSocket");


If the java.naming.security.protocol property has been set, but this property is not set, then the default value of netscape.net.SSLSocket is used.

See Chapter 12, "Connecting Over SSL" for more information.
java.naming.ldap.ssl.ciphers
Specifies the suite of ciphers used for SSL connections. These connections are made through sockets created by the factory specified with java.naming.ldap.factory.
socket. The value of this property is of the type java.lang.Object. For example:

env.put("java.naming.ldap.ssl.ciphers",
crysec.SSL.SSLParams.getcipherSuite());

java.naming.batchsize
Specifies if searches are to block until all results are available or to return results in batches. A setting of 0 (zero) indicates that the Service Provider should block until all results are received.

If this property is not set or is "0" then search results are returned in batches of one.
java.naming.ldap.maxresults
Specifies the default maximum number of results returned for a search request. 0 (zero) means that there is no limit. If not specified, the default value is 1000.

A request using the parameter SearchConstraints in the DirContext.search() method can override this value.
java.naming.referral
Specifies the maximum number of referrals to follow in a chain of referrals. A setting of 0 (zero) indicates that there is no limit. The default limit is 10.
java.naming.ldap.deleteRDN
Specifies whether the old RDN is removed during rename(). If the value is set to true, the old RDN is removed. Otherwise, the RDN is not removed. The default value is true.
java.naming.ldap.derefAliases
Specifies how aliases are dereferenced during search operations.

The possible values are:
always - always dereference aliases
never - never dereference aliases
finding - dereference aliases only during name resolution
searching - dereference aliases only after name resolution.

NOTE: Netscape Directory Server 3.x and 4.x do not support aliases.
java.naming.ldap.typesOnly
Specifies whether to only return attribute types during searches and calls to getAttributes(). Possible values are true or false. The default is false.
java.naming.ldap.control.connect
An array of controls to set for an LDAPConnection when executing LDAP operations.
java.naming.ldap.attributes.binary
Specifies attributes that have binary syntax. It extends the Service Provider's list of known binary attributes. The value of this property is a list of comma-separated attribute names. For example:

env.put("java.naming.ldap.attributes.
binary", "mpegVideo, mpegAudio");


In contrast to the Netscape Directory SDK for Java, JNDI does not allow you a choice of whether to read attributes as Strings or byte arrays. All attributes are returned as Strings unless they are considered to have binary syntax. The values of attributes that have binary syntax are returned as byte arrays instead of Strings.
java.naming.ldap.attributes.binary
(continued)
If this property is not set then, by default, only the following attributes and OIDs are recognized as having binary syntax:
attribute names containing ;binary
photo (0.9.2342.19200300.100.1.7)
personalSignature (0.9.2342.19200300.100.1.53)
audio (0.9.2342.19200300.100.1.55)
jpegPhoto (0.9.2342.19200300.100.1.60)
jpegSerialzedData (1.3.6.1.4.1.42.2.27.4.1.7)
thumbnailPhoto (1.3.6.1.4.1.1466.101.120.35)
thumbnailLogo (1.3.6.1.4.1.1466.101.120.36)
userPassword (2.5.4.35)
userCertificate (2.5.4.36)
cACertificate (2.5.4.37)
authorityRevocationList (2.5.4.38)
certificateRevocationList (2.5.4.39)
crossCertificatePair (2.5.4.40)
x500UniqueIdentifier (2.5.4.45)
java.naming.ldap.ref.separator
Specifies the character to use when encoding a RefAddr object in the javaReferenceAddress attribute. This property is used to avoid a conflict should the default separator character appear in the components of a RefAddr object.
If no value is specified, then the default separator is the hash character (#).


Working with Controls
JNDI 1.2 and the Netscape LDAP Service Provider support LDAP controls. Since JNDI only defines a generic interface for controls, the task of defining particular controls and their interfaces is left to the Service Provider. All controls supported by the Netscape Directory Server are implemented in the com.netscape.jndi.ldap.controls package. If you plan to use controls, you will need to import this package in your source code.

Note. This is in addition to the JNDI packages that are already specified in your CLASSPATH.

Netscape's LDAP Service Provider is implemented on top of the Directory SDK which means that any controls that are available in the SDK are also available through JNDI. These controls use the same API as the Directory SDK, except that they begin with "Ldap" instead of "LDAP." For instance, the SDK control LDAPSortControl is available as LdapSortControl in the Netscape LDAP Service Provider for JNDI.

For more information about controls, see Chapter 13, "Working with LDAP Controls."

The following example shows you how to use LdapSortControl. Since controls are not part of the generalized directory context (DirContext), you must call getInitialLdapContext() instead of getInitialDirContext(). This creates an LdapContext object as the initial context.

import java.util.Hashtable;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
import com.netscape.jndi.ldap.controls.*;
public class SortReverseOrder {
   public static void main (String[] args) {
      Hashtable env = new Hashtable(5, 0.75f);
      /** Specify the initial context implementation to use.*/
      env.put(Context.INITIAL_CONTEXT_FACTORY,
      "com.netscape.jndi.ldap.LdapContextFactory");
      /* Specify host and port to use for directory service */
      env.put(Context.PROVIDER_URL, "ldap://localhost:389");
      LdapContext ctx = null;
      try {
         /* get a handle to an Initial DirContext */
         ctx = new InitialLdapContext(env, null);
         /* specify search constraints to search subtree */
         SearchControls cons = new SearchControls();
         cons.setSearchScope(SearchControls.SUBTREE_SCOPE);
         cons.setReturningAttributes(new String[] { "sn" });
         // specify sort control
         ctx.setRequestControls(
         new Control[] {new LdapSortControl(
            new LdapSortKey[]{
               new LdapSortKey("sn", true, null)},Control.CRITICAL)});
         /* search for all entries of type "person" */
         NamingEnumeration results = ctx.search("o=mcom.com",
                                    "(objectclass=person)", cons);
         /* for each entry print out name + all attrs and values */
         while (results != null && results.hasMore()) {
            SearchResult si = (SearchResult)results.next();
            Attributes attrs = si.getAttributes();
         /* print each attribute */
         for (NamingEnumeration ae = attrs.getAll();
               ae.hasMoreElements();) {
            Attribute attr = (Attribute)ae.next();
            String attrId = attr.getID();
            /* print each value */
            for (NamingEnumeration vals = attr.getAll();
               vals.hasMore();
               System.out.println(attrId + ": " + vals.next()));}
               System.out.println();
            }
         }
         catch (NamingException e) {
            System.err.println("Search example failed.");
            e.printStackTrace();
         }
      finally {
         // cleanup
         if (ctx != null) {
            try { ctx.close(); } catch (Exception e) {}
         }
      }
   }
}

 

© Copyright 1999 Netscape Communications Corporation. All rights reserved.