LDAP Naming Service Provider for JNDI
- Introduction
- Conformance
- Environment Properties
- Names
- Attributes
- URLs
- Java Objects
- Schema
- Exceptions
- API Mapping
- Federation
- Event Notification
- SASL Authentication
- SSL and Start TLS
- Connection Pooling
- Security Considerations
1. Introduction
The Lightweight Directory Access Protocol (LDAP) is an Internet standard for accessing directory services. The JNDI/LDAP service provider provides access to servers implementing the LDAP protocols.This document describes the features of the LDAP service provider. A major portion of the description is couched in terms of how the LDAP service provider behaves with respect to the descriptions in Guidelines for LDAP Service Providers. For examples and descriptions of how to use this provider, please see the JNDI Tutorial.
The LDAP service provider implements the basic features for LDAP access. Additional functionality, such as support for a number of popular LDAP controls, and for storing and reading RMI and CORBA objects, can be added to the basic provider by installing a booster pack, available for download at the JNDI Web site.
2. Conformance
The LDAP service provider conforms to the following standards:
Standard Supported LDAPv3 (RFC 2251) Yes LDAPv3 Attributes (RFC 2252) Yes LDAPv3 Distinguished Names (RFC 2253) Yes LDAP Search Filters (RFC 2254) Yes LDAP URL Format (RFC 2255) Yes LDAPv3 Schema (RFC 2256) Yes LDAPv2 (RFC 1777) Yes LDAP Authentication (RFC 2829) Yes Start TLS Extension (RFC 2830) Yes DIGEST-MD5 (RFC 2831) Yes
3. Environment Properties
Descriptions of JNDI, LDAP-specific, and SASL-specific properties are found in Guidelines for LDAP Service Providers.3.1 JNDI Properties
The LDAP service provider supports the following JNDI environment properties:
Property Supported Comments java.naming.batchsize Yes Default value is 1. java.naming.factory.control Yes
java.naming.factory.initial Yes
Specify com.sun.jndi.ldap.LdapCtxFactory to use the LDAP service provider as the initial context.java.naming.factory.object Yes java.naming.factory.state Yes java.naming.language No Ignored by the provider. java.naming.provider.url Yes
On systems earlier than the Java 2 SDK, v 1.4.1, can contain only a single URL.java.naming.referral Yes
java.naming.security.authentication Yes simple, none, list of SASL mechanisms java.naming.security.credentials Yes
java.naming.security.principal Yes
java.naming.security.protocol Yes ssl 3.2 LDAP-specific Properties
The provider supports the following LDAP-specific environment properties:
Property Supported Comments java.naming.ldap.attributes.binary Yes
java.naming.ldap.control.connect Yes
java.naming.ldap.deleteRDN Yes
java.naming.ldap.derefAliases Yes
java.naming.ldap.factory.socket Yes Default value is javax.net.ssl.SSLSocketFactory when the java.naming.security.protocol property is set to ssl. See the SSL Section for details. java.naming.ldap.ref.separator Yes
java.naming.ldap.referral.limit Yes
java.naming.ldap.typesOnly Yes
java.naming.ldap.version Yes
3.3 SASL-specific Properties
The provider supports the following SASL-specific environment properties:
Property Supported Comments java.naming.security.sasl.authorizationId Yes
java.naming.security.sasl.callback Yes
java.naming.security.sasl.realm Yes
javax.security.sasl.qop Yes
javax.security.sasl.strength Yes
Cipher selected depends on the ciphers available from the Java Cryptography Extension (JCE) service providers in the Java platform.javax.security.sasl.maxbuffer Yes
javax.security.sasl.server.authentication Yes
javax.security.sasl.policy.forward Yes
javax.security.sasl.policy.credentials Yes
javax.security.sasl.policy.noplaintext Yes
javax.security.sasl.policy.noactive Yes
javax.security.sasl.policy.nodictionary Yes
javax.security.sasl.policy.noanonymous Yes
3.4 Provider-specific Properties
The LDAP service provider defines the following provider-specific environment properties:
com.sun.jndi.ldap.connect.pool This property is used to specify that a pooled connection should be used when creating the initial context instance. If its value is "true", the provider will use a pooled connection if the parameters for creating a connection (referred to as the connection request) meet the criteria set forth by the connection pool configuration. If this property has not been set, or if it has been set to any other value, or if the connection request does not meet the criteria, the provider will not use a pooled connection. See the Connection Pooling section for more information on connection pooling.For example, the following code
env.put("com.sun.jndi.ldap.connect.pool", "true");directs the LDAP provider to use a pooled connection when creating an initial context.NOTE: On systems earlier than the Java 2 SDK, v 1.4.1, connection pooling is not supported and therefore, this property is ignored.
com.sun.jndi.ldap.connect.timeout The value of this property is the string representation of an integer representing the connection timeout in milliseconds. If the LDAP provider cannot establish a connection within that period, it aborts the connection attempt. The integer should be greater than zero. An integer less than or equal to zero means to use the network protocol's (i.e., TCP's) timeout value.If this property is not specified, the default is to wait for the connection to be established or until the underlying network times out.
For example,
env.put("com.sun.jndi.ldap.connect.timeout", "500");causes the LDAP service provider to abort the connection attempt if a connection cannot be established in half a second.When connection pooling has been requested for a connection, this property also determines the maximum wait time for a connection when all connections in the pool are in use and the maximum pool size has been reached. If the value of this property is less than or equal to zero under such circumstances, the provider will wait indefinitely for a connection to become available; otherwise, the provider will abort the wait when the maximum wait time has been exceeded. See the Connection Pooling section for details.
NOTE: On systems earlier than the Java 2 SDK, v 1.4, this property is ignored because there is no support in the SDK for connection timeouts.
com.sun.jndi.ldap.netscape.schemaBugs The Netscape Directory Server 4.0 and earlier releases do not support schema entries that comply with RFC 2252. Specifically, contrary to RFC 2252, the Netscape server requires OIDs (such as those for SUP and SYNTAX) be delimited by single quotes and MUST/MAY lists be enclosed by parentheses. When you update the schema of the Netscape Directory Server 4.0, you need to use this property to get around these problems.The following values are defined for this property:
true
activate the workaround.
false
do not activate the workaround.If this property is not set then its default value is false.
For example,
activates the workaround.env.put("com.sun.jndi.ldap.netscape.schemaBugs", "true");NOTE 1: This property may only be passed to the initial context and becomes fixed for the provider. It is unaffected by the addToEnvironment or removeFromEnvironment methods.
NOTE 2: If you are using Netscape Directory Server 4.1, do not use this property. The 4.1 server has problems parsing object class definitions that contain MUST/MAY clauses without parentheses. If you are creating or modifying an object class definition that contains a single MUST/MAY item, work around the bug by adding a superfluous value (such as 'objectClass') to the MUST/MAY list.
com.sun.jndi.ldap.trace.ber The value of this property is a java.io.OutputStream object into which a hexadecimal dump of the incoming and outgoing LDAP ASN.1 BER packets is written.No default is defined for this property.
For example,
env.put("com.sun.jndi.ldap.trace.ber", System.out);directs the LDAP protocol trace to the standard output stream.NOTE: This property may only be passed to the initial context and becomes fixed for the provider. It is unaffected by the addToEnvironment or removeFromEnvironment methods.
4. Names
The LDAP service provider supports names in accordance with the description in Guidelines for LDAP Service Providers. It supports LDAP distinguished names in the following formats:
Distinguished Name format Comments String Treat as composite name. Process the first component of the composite name as a distinguished name. Use rest of the components for federation. Name If instance of CompositeName, treat as composite name, which means process the first component of the composite name as a distinguished name and use the rest for federation. Otherwise, treat as parsed LDAP name, where each component of Name is a component of the LDAP name as defined in RFC 2253. LDAP URL String When passed to the initial context, the LDAP URL string is interpreted according to RFC 2255, and its distinguished name component interpreted according to RFC 2253. The name parser returned by an invocation of getNameParser() returns a parser that, when given a string name, parses it into components in accordance with RFC 2253.
5. Attributes
The LDAP service provider supports attributes in accordance with the description in Guidelines for LDAP Service Providers. It supports the following formats for specifying LDAP attribute values:
Attribute value format Supported Comments String values Yes
byte[] values Yes
Some LDAP servers support attribute subtyping, attribute name synonyms, and language codes for specifying language preferences for attribute values. In such cases, the attribute name returned by an LDAP server may be different from the one which was requested.
In LDAP, attribute names are case-insensitive. Therefore, when creating a collection of attributes to be passed as a parameter to JNDI operations, it is recommended to use a case-insensitive attributes class. For example,
Attributes attrs = new BasicAttributes(true); // ignoreCase=true
For all attribute values, regardless of whether they are String or byte[], you need to know the syntax and format of the attribute value. You can typically find this out by reading the schema document in which the attribute and its syntax is defined.
When attributes are supplied as arguments to JNDI calls then they must satisfy whatever schema is enforced at the LDAP directory. In particular, the objectClass attribute is normally required when creating a new LDAP entry (for example, when using Context.bind, Context.rebind or javax.naming.directory.Attributes)">DirContext.createSubcontext).
6. URLs
6.1 Uses
The LDAP service provider supports URLs in accordance with the description in Guidelines for LDAP Service Providers. It supports the following use of URLs:
URL usage Supported Comments LDAP URLs to configure the LDAP service provider. Yes
URLs passed as names to the InitialDirContext methods. Yes The attributes, scope, filter and extensions components of LDAP URLs are ignored by the search methods. URLs in LDAP referrals Yes The scope component of LDAP URLs is supported. The attributes, filter and extensions components are ignored. URLs returned as names in list, listBindings, and search enumerations. Yes
URLs linking federated namespaces. Yes 6.2 Automatic Discovery of LDAP Service
The LDAP service provider supports the use of DNS configuration for automatically discovering the LDAP service. When an LDAP URL in the above usage cases is missing the hostname and port but has a non-empty distinguished name, the LDAP service provider will attempt to locate the LDAP servers to use as described in the Guidelines for LDAP Service Providers.For example, given a URL of ldap:///dc=example,dc=com, the service provider will try to locate the DNS SRV records for _ldap._tcp.example.com. If the provider finds such records, it will then extract and use the hostnames and ports of the LDAP servers from the records. The order in which it uses these records follows the algorithm described in the Internet draft draft-ietf-ldapext-locate-08.txt.
For locating the DNS SRV records of the LDAP service, the LDAP service provider uses the DNS service configured for the underlying platform (on Solaris or Linux, for example, the DNS client configuration is read from the /etc/resolv.conf file). If DNS has not been configured for the underlying platform, the LDAP service provider will use localhost and 53 as the hostname and port of the DNS server. If no DNS service is available, or if the DNS service does not have the LDAP service's SRV records, the LDAP service provider will use localhost and 389 as the hostname and port of the LDAP server.
NOTE: On systems earlier than the Java 2 SDK, v 1.4.1, unspecified hostname and port always default to localhost and 389, respectively; no attempt is made to use DNS.
7. Java Objects
The LDAP service provider supports storing and reading the following types of objects, as specified in Guidelines for LDAP Service Providers.
Storable/Readable Objects Supported Comments Reference objects Yes
Referenceable objects Yes
Serializable objects Yes
DirContext objects Yes
See the JNDI Tutorial for examples.
8. Schema
The LDAP service provider supports the following schema bindings, as specified in Guidelines for LDAP Service Providers.
Schema Tree Supported Comments AttributeDefinition Yes ClassDefinition Yes SyntaxDefinition Yes MatchingRule Yes ExtensionDefinition No
ControlDefinition No
SASLMechanism No
9. Exceptions
The LDAP service provider maps LDAP error codes to JNDI exceptions according to Guidelines for LDAP Service Providers.
10. API Mapping
The LDAP service provider maps the following JNDI API methods to LDAP according to Guidelines for LDAP Service Providers:
Mapping for Context methods Supported Comments addToEnvironment Yes
bind Yes
close Yes
composeName Yes
destroySubcontext Yes
getEnvironment Yes
getNameInNamespace Yes
getNameParser Yes
list Yes
listBindings Yes
lookup Yes Does not process LinkRef specially. lookupLink Yes
rebind Yes
removeFromEnvironment Yes
rename Yes
unbind Yes
Mapping for DirContext methods Supported Comments bind Yes
createSubcontext Yes
destroySubcontext Yes
getAttributes Yes
getSchema Yes
getSchemaClassDefinition Yes
modifyAttributes Yes
rebind Yes
search Yes
Mapping for LdapContext methods Supported Comments extendedOperation Yes
getRequestControls Yes
getResponseControls Yes
newInstance Yes
reconnect Yes
setRequestControls Yes
Mapping for EventDirContext methods Supported Comments addNamingListener Yes
removeNamingListener Yes
targetMustExist Yes
11. Federation
The LDAP service provider supports federation in accordance with the description in Guidelines for LDAP Service Providers. It supports the following federation techniques:
Federation Technique Supported Comments Junction Yes Except when subordinate naming system is another LDAP system Implicit Next Naming System Pointer Yes
The LDAP service provider treats composite names as strongly separated. That is, it processes the first component of the composite name as a distinguished name and the rest of the components as names in the next naming system(s). For example, here are examples that lists the root of the next naming system federated beyond an LDAP context and looks up a name using a multicomponent composite name:
// List the root of the nns, // Note use of the trailing slash to indicate traversal into the nns NamingEnumeration enum = ctx.list("cn=objects,ou=Sales/"); // A composite name lookup Object obj = ctx.lookup("cn=objects,ou=Sales/some/x/y/z");
12. Event Notification
The LDAP service provider supports event notification in accordance with the description in Guidelines for LDAP Service Providers. It supports the following events:
Event Supported Comments Namespace change notification Yes Uses the persistent search control* Object change notification Yes Uses the persistent search control* Unsolicited notification Yes
* The persistent search control is defined in the IETF Internet-Draft draft-ietf-ldapext-psearch-03.txt.
13. SASL Authentication
The LDAP service provider supports SASL authentication in accordance with the description in Guidelines for LDAP Service Providers.The LDAP service provider supports the following SASL mechanisms.
In addition to these mechanisms, the provider supports additional SASL mechanisms made available via the framework defined in the Java SASL API (JSR 28 Public Review Draft), with the exception that the package is named com.sun.security.sasl.preview instead of javax.security.sasl.
- EXTERNAL (RFC 2222). This mechanism obtains authentication information from an external source (such as SSL/TLS or IPsec).
- DIGEST-MD5 (RFC 2831) is for Digest Authentication.
- GSSAPI (RFC 2222) is for Kerberos V5 authentication.
14. SSL and Start TLS
The LDAP service provider supports SSL in accordance with the description in Guidelines for LDAP Service Providers. It uses the default socket factory javax.net.ssl.SSLSocketFactory unless the java.naming.ldap.factory.socket property has been set to the class name of some other socket factory.The LDAP provider supports the the "Start TLS" extension ("1.3.6.1.4.1.1466.20037") by supplying a concrete implementation of the StartTlsResponse abstract class. Hostname verification is performed as per the Guidelines for LDAP Service Providers.
15. Connection Pooling
NOTE: Connection pooling is supported only on the Java 2 SDK, v 1.4.1 and later releases.
15.1 Overview
The LDAP service provider supports connection pooling by maintaining pools of previously used connections. Whenever the LDAP provider needs a connection (and the application has requested pooling), it gets a connection from the pool. If an existing connection is available, it will be used. If no existing connection is available, a new connection is created and used. When the provider is done with the connection, the connection is marked idle and can be reused.
An application requests connection pooling by adding the property, com.sun.jndi.ldap.connect.pool, to the environment properties passed to the initial context constructor. An application can decide whether to use pooling on a per-context basis by using environment properties with and without this property. This same mechanism is used to control whether pooled connections are used for referral handling and processing of LDAP URLs passed to the initial context. For example, when this property is present in the environment when the provider is processing a referral, the provider will use a pooled connection for the referral.
Here is sample code that requests that connection pooling be used for a new initial context and all contexts derived from it.
Hashtable env = new Hashtable(); env.put("com.sun.jndi.ldap.connect.pool", "true"); env.put(Context.PROVIDER_URL, url); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); DirContext ctx = new InitialDirContext(env); ...Only the addition of the single property, com.sun.jndi.ldap.connect.pool, is required; no other changes are required to the application.
The LDAP provider keeps track of whether a connection is being used through indications from the application. It assumes that an application that is maintaining an open context handle is using the connection. Therefore, in order for the LDAP provider to properly manage the pooled connections, the application must be diligent about invoking Context.close() on contexts that it no longer needs.
Bad connections are automatically detected and removed from the pool. The probability of a context ending up with a bad connection is the same regardless of whether connection pooling is used.
15.2 When Not to Use Pooling
Pooled connections are intended to be reused. Therefore, an application that plans on performing operations on a context that might alter the underlying connection's state should not use connection pooling for the context. Specifically, if an application is planning to use the Start TLS extended operation on a context, or is planning to change security-related properties (such as java.naming.security.principal or java.naming.security.protocol) after the initial context has been created, it should not use connection pooling for that context. Using connection pooling under such circumstances might compromise the security of the application and/or create unexpected behavior.15.3 Global Configuration
Connection pooling is configured and maintained per Java runtime. Connections are not shared across different runtimes. To use connection pooling, no configuration is required. Configuration is necessary only if you want to customize how pooling is done, such as controlling the size of the pools and which connections are pooled.Connection pooling is configured by a number of System properties at runtime startup time. Note that these are System properties, not environment properties and that they affect all connection pooling requests.
Here is a summary of the system properties. They are described in more detail in the rest of this section.
System Property Name Description Default com.sun.jndi.ldap.connect.pool.authentication A list of space-separated authentication types of connections that may be pooled. Valid types are "none", "simple", and "DIGEST-MD5". "none simple" com.sun.jndi.ldap.connect.pool.debug A string that indicates the level of debug output to produce. Valid values are "fine" (trace connection creation and removal) and "all" (all debugging information). com.sun.jndi.ldap.connect.pool.initsize The string representation of an integer that represents the number of connections per connection identity to create when initially creating a connection for the identity. 1 com.sun.jndi.ldap.connect.pool.maxsize The string representation of an integer that represents the maximum number of connections per connection identity that can be maintained concurrently. no maximum size com.sun.jndi.ldap.connect.pool.prefsize The string representation of an integer that represents the preferred number of connections per connection identity that should be maintained concurrently. no preferred size com.sun.jndi.ldap.connect.pool.protocol A list of space-separated protocol types of connections that may be pooled. Valid types are "plain" and "ssl". "plain" com.sun.jndi.ldap.connect.pool.timeout The string representation of an integer that represents the number of milliseconds that an idle connection may remain in the pool without being closed and removed from the pool. no timeout Here is an example that sets the maximum pool size to 20, the preferred pool size to 10, and the idle timeout to 5 minutes for pooled connections.
# java -Dcom.sun.jndi.ldap.connect.pool.maxsize=20 \ -Dcom.sun.jndi.ldap.connect.pool.prefsize=10 \ -Dcom.sun.jndi.ldap.connect.pool.timeout=300000 \ YourProgram15.3.1 What Gets Pooled
The LDAP provider will use a pooled connection only if the application has requested it and the request for the connection meets the pooling criteria. The application requests that a connection be pooled by using the com.sun.jndi.ldap.connect.pool environment property. The default pooling criteria is that plain (non-SSL) connections that use simple or no authentication are allowed to be pooled. The pooling criteria can be adjusted to include SSL connections and the DIGEST-MD5 authentication type by using System properties. No other type of customization of the pooling criteria is supported. In addition, a connection that requires the use of a custom socket factory or one that has enabled protocol tracing (via the com.sun.jndi.ldap.trace.ber environment property) cannot be pooled.To allow SSL connections to be pooled, include the string "ssl" in the com.sun.jndi.ldap.connect.pool.protocol System property. For example, to allow both plain and SSL connections to be pooled, set this System property to the string "plain ssl".
To allow DIGEST-MD5 connections to be pooled, include the string "DIGEST-MD5" in the com.sun.jndi.ldap.connect.pool.authentication System property. For example, to allow connections of anonymous, simple and DIGEST-MD5 authentication types to be pooled, set this System property to the string "none simple DIGEST-MD5".
15.3.2 How Connections are Pooled
The LDAP provider maintains pooled connections so that they can be reused. When an application requests to use a pooled connection, the LDAP provider needs to determine whether the request can be satisfied by an existing pooled connection. It does this by assigning a connection identity to each pooled connection and checking whether the incoming request has the same connection identity as that of one of its pooled connections.
A connection identity is the set of the parameters required to create a possibly authenticated LDAP connection. Its composition depends on the authentication type of the request, as shown in the following table.
Authentication type Connection identity contents none
- connection controls
- host name, port number as specified in the java.naming.provider.url property, referral, or URL supplied to the initial context
- the contents of the following properties:
java.naming.security.protocol java.naming.ldap.versionsimple
- all of the information listed for anonymous
- the contents of following properties:
java.naming.security.principal java.naming.security.credentialsDIGEST-MD5
- all of the information listed for simple
- the contents of following properties:
java.naming.security.sasl.authorizationId java.naming.security.sasl.realm javax.security.sasl.qop javax.security.sasl.strength javax.security.sasl.server.authentication javax.security.sasl.maxbuffer javax.security.sasl.policy.noplaintext javax.security.sasl.policy.noactive javax.security.sasl.policy.nodictionary javax.security.sasl.policy.noanonymous javax.security.sasl.policy.forward javax.security.sasl.policy.credentials
The initial pool size is the number of connections per connection identity that the LDAP service provider creates when first creating the pool (which corresponds to when the application first requests a pooled connection for that connection identity). Authentication of each connection in the pool is performed on demand, as the connection gets used. By default, the initial pool size is 1 and can be changed by using the System property com.sun.jndi.ldap.connect.pool.initsize. It is typically used at application start-up time to prime the pool with a certain number of connections to a server.
The maximum pool size is the maximum number of connections per connection identity that can be maintained concurrently by the LDAP service provider. Both in-use and idle connections contribute to this number. When the pool size reaches this number, no new connection for the corresponding connection identity may be created until a connection in the pool has been removed (i.e., the physical connection is closed). When the pool size reaches the maximum and all of the connections in the pool are in use, the application's request for a connection from that pool is blocked until a connection in the pool either becomes idle or is removed. A maximum pool size of 0 means that there is no maximum size: A request for a pooled connection will use an existing pooled idle connection or a newly created pooled connection.
The preferred pool size is the preferred number of connections per connection identity that the LDAP service provider should maintain. Both in-use and idle connections contribute to this number. When an application requests the use of a pooled connection and the pool size is less than the preferred size, the LDAP provider will create and use a new pooled connection regardless of whether an idle connection is availble. When an application is finished with a pooled connection (by invoking Context.close() on all contexts that share the connection) and the pool size is greater than the preferred size, the LDAP provider will close and remove the pooled connection from the pool. A preferred pool size of 0 means that there is no preferred size: A request for a pooled connection will result in a newly created connection only if no idle ones are available.
Note that the maximum pool size overrides both the initial and preferred pool sizes. For example, setting the preferred pool size greater than the maximum pool size is effectively setting it to the maximum pool size.
If this property is omitted, the context will not use connection pooling.
If this property has not been specified, the LDAP provider will wait indefinitely for a pooled connection to become available, and to wait for the default TCP timeout to take effect when creating a new connection.
Note that this property is different from the System property com.sun.jndi.ldap.connect.pool.timeout, which is related to the removal of idle pooled connections.
permission java.net.SocketPermission "host[:port]", "connect";
For each host/port identified in the java.naming.factory.initial property and in URL string names supplied to context methods.
permission java.net.SocketPermission "host[:port]", "connect,accept";
For each host/port named in the URL strings in References and javaCodebase attributes stored with Serializable objects.If you are using SASL authentication and will be setting the SASL client factory programmatically, grant your application the following permission.
permission java.lang.RuntimePermission "setFactory"If you use the "GSSAPI" SASL mechanism, you need the following additional permissions.
permission javax.security.auth.AuthPermission "createLoginContext.appClassName"; permission javax.security.auth.AuthPermission "doAsPrivileged";
For the application class that's going to be logging in and invoking the doAsPrivileged method.
permission java.net.SocketPermission "host[:port]", "connect";
For the host/port of the Kerberos Key Distribution Center (KDC).
permission javax.security.auth.kerberos.ServicePermission "krbtgt/realm@realm", "initiate"; permission javax.security.auth.kerberos.ServicePermission "ldap/fully-qualified-hostname@realm", "initiate";
For the realm and host of the LDAP service and KDC.