JNDI Implementor Guidelines for LDAP Service Providers

Draft 0.4.2

Please send feedback to jndi@java.sun.com

Table of Contents
 
1. Introduction
2. Conformance
3. Environment Properties
4. Names
5. Attributes
6. URLs
7. Java Objects
8. Schema
9. Exceptions
10. API Mapping
11. Federation
12. SASL
13. Extensions and Controls
14. Event Notification
15. SSL
 

1. Introduction

This document specifies guidelines that developers creating LDAP service providers and service providers that support LDAP-like features should follow. By following these guidelines, developers can produce implementations that JNDI API users can configure and use with minimal differences.

Not all of the features described in this document must be supported by an LDAP service provider. However, if a feature is supported, it should be supported in the way described by this document.



2. Conformance

An LDAP service provider that supports LDAP version 3 (LDAPv3) conforms to: An LDAP service provider that supports LDAP version 2 (LDAPv2) conforms to:

3. Environment Properties

Environment properties are the means by which JNDI application users configure and affect the behavior of JNDI service providers. Consequently, service providers must interpret and handle environment properties in the same way.

There are four types of environment properties that affect LDAP service providers:

3.1 Overview

3.1.1 Initialization

When creating an initial context, environment properties can be passed as an argument to the constructor or may be initialized as specified in the JNDI documentation.

In particular, if any of the following properties is not supplied in the environment properties then it is sought from the system properties, applet parameters, and both provider and application resource files (in that order):

In the case of the control, object and state factory properties, if more than one occurrence of the property is located, then its values are concatenated into a single list. In the case of the url property and all other properties, only the first occurrence is used.

A context's environment properties can be examined using the Context.getEnvironment method.

3.1.2 Modification

A context's environment properties may be changed using the Context.addToEnvironment and Context.removeFromEnvironment methods.

3.1.3 Scope

With the exception of the java.naming.provider.url and java.naming.factory.initial properties, changing a property using the Context.addToEnvironment or Context.removeFromEnvironment methods affects the context instance on which the method is invoked. For example, if you specify new credentials for a context to use, subsequent methods invoked on that context that require communication with the server will use those new credentials (perhaps internally by first creating a new connection to the server). These updated environment properties are inherited by context instances that are subsequently derived from the affected context instance, but do not otherwise affect other context instances that were in existence prior to the update.

3.1.4 Timeliness

When a change is made to the environment properties, there is no requirement that the change be verified and acted upon at the time the  Context.addToEnvironment or Context.removeFromEnvironment method is invoked. The only requirement is that the change (or changes) be effective the next time an operation that uses that property is invoked.

3.1.5 Defaults

This specification defines defaults for the environment properties. In a few cases, the default is determined by the service provider. If a context does not have a particular environment property, it behaves as if it has that environment property with its default value.

When a property is removed from the environment properties of a context, the context assumes the default behavior specified for that property. This does not necessarily mean that the default value must be recorded as the property's value. The removal may also be indicated by the absence of the property from the context's environment properties.

3.1.6 Acceptable Values

This specification defines acceptable values for the environment properties. Some environment properties have a fixed set of acceptable values while others have values that must follow a particular syntax. If an unacceptable value is presented, a property-specific exception will be thrown (for example, ConfigurationException, IllegalArgumentException, or AuthenticationNotSupportedException). In some cases, it might be reasonable for the service provider to accept additional values than those specified, in which case, those values should be documented.

3.2 JNDI Properties

LDAP service providers should process the JNDI environment properties according to the following specifications. In the examples given, env is an instance of Hashtable that holds the environment properties used to create an initial context.

java.naming.batchsize
The value of this property is a string of decimal digits that specifies the batch size of search results returned by the server.

This property affects the blocking behaviour of the Context.list, Context.listBindings, and DirContext.search methods and the NamingEnumeration objects that they return. It does not affect how many items are returned in the enumeration; it only affects how the items are batched or read at the LDAP protocol level.

A setting of zero means that the provider should block until all results have been received. A setting of an integer n greater than zero means that the provider should block until n results have been received from the server or until the enumeration terminates, whichever produces the fewer number of results. After the application has read n results (using NamingEnumeration.next or NamingEnumeration.nextElement), the provider should read n more results from the server or until the enumeration terminates, whichever produces the fewer number of results.

If this property is not set then its default value is implementation-specific.

For example,

env.put(Context.BATCHSIZE, "24");
specifies that the provider should block until 24 entries have been read from the server or until the enumeration terminates, whichever produces the fewer number of results.
java.naming.factory.control
The value of this property is a colon-separated list of fully qualified class names of control factory classes.

The factories are responsible for narrowing the class of response controls. They create specific response controls from the generic response controls generated by the provider.

No default value is defined for this property.

For example,

env.put(LdapContext.CONTROL_FACTORIES,
        "com.sun.jndi.ldap.ctl.ResponseControlFactory");
sets the ResponseControlFactory class as the control factory to try.
java.naming.factory.initial
The value of this property is the fully qualified class name of the factory class which creates the initial context for the LDAP service provider.

It is used to select a particular LDAP service provider; it's not actually used by the provider itself. This property need not be set when the name argument to initial context methods is a URL.

No default value is defined for this property.

For example,

env.put(Context.INITIAL_CONTEXT_FACTORY,
        "com.sun.jndi.ldap.LdapCtxFactory");
selects Sun's LDAP provider.
java.naming.factory.object
The value of this property is a colon-separated list of fully qualified class names of object factory classes.

The factories are responsible for creating specific objects from the LDAP entries returned by the provider. For example, a Person object factory might generate a Person object from an LDAP entry of object class person. Object factories behave in the opposite way to state factories in that they generate objects from LDAP attributes.

No default value is defined for this property.

For example,

env.put(Context.OBJECT_FACTORIES,
        "com.sun.jndi.ldap.obj.PersonFromLDAP");
sets the PersonFromLDAP class as the object factory to try.
java.naming.factory.state
The value of this property is a colon-separated list of fully qualified class names of state factory classes.

The factories are responsible for creating an object's state (for storing) from the object itself. For example, a Person state factory might generate an LDAP entry of object class person from a Person object. State factories behave in the opposite way to object factories in that they generate LDAP attributes from objects.

No default value is defined for this property.

For example,

env.put(Context.STATE_FACTORIES,
        "com.sun.jndi.ldap.obj.PersonToLDAP");
sets the PersonToLDAP class as the state factory to try.
java.naming.language
The value of this property is a string language tag according to RFC 1766.
This property indicates a preference for a particular natural language. A provider may adjust its LDAP requests and responses according to the value of this property.
The affect of this property is implementation-specific. No default value is defined.
For example:
env.put(Context.LANGUAGE, "ja-JP");
indicates a preference for Japanese.
java.naming.provider.url
The value of this property is a list of space-separated LDAP or LDAPS URL strings, each of which specifies the hostname and port number of the LDAP server, and the root distinguished name of the naming context to use. An LDAP URL specifies the use of a plain (i.e., unprotected) connection; an LDAPS URL specifies the use of an SSL connection. If the list contains more than one URL, the provider should attempt to use each URL in turn until it is able to create a successful connection, and after creation, set the property to the successful URL.

The default hostname is localhost; the default port is 389 for plain connections and 636 for SSL connections. The default root distinguished name is the empty string. If this property is not set, or if either the hostname or port number is omitted, then the default values are used in place of the missing information. If both the hostname and port are missing but a non-empty distinguished name is present in the URL, then the provider should use the distinguished name to determine the hostname and port of the LDAP server(s) as described in the URLs section and when a connection has been established successfully, set the java.naming.provider.url property to a URL constructed using the successful hostname, port and distinguished name. See also the URLs section for information on how the provider should treat other information found in the URL.

For example:

env.put(Context.PROVIDER_URL, "ldap://secserver:636");
specifies that the LDAP server is running on a host named secserver at port 636.

NOTE: Changing this property using the Context.addToEnvironment or Context.removeFromEnvironment methods does not affect the context. It is only used by the initial context constructors.

java.naming.referral
The value of this property is a string that specifies how referrals shall be handled by the provider. The following values are defined for this property:
follow
automatically follow any referrals.
throw
throw a ReferralException for each referral.
ignore
ignore referrals if they appear in results. A PartialResultException is thrown to indicate an incomplete result. In addition, for LDAPv3 servers, the provider shall request that referrals be treated as ordinary attributes when they appear in entries. This is achieved by sending a non-critical ManageDsaIT (RFC 3296) LDAP control with each LDAP request. LDAP servers which do not support this LDAP control will simply ignore it and process the request as normal.

See the URLs section for information on how to treat multiple URLs found in a single referral entry.

If this property is not set then its default value is ignore.

For example:

env.put(Context.REFERRAL, "throw");
specifies that referrals encountered during an LDAP operation should throw a ReferralException to the application.
java.naming.security.authentication
The value of this property is a string that specifies the authentication mechanism(s) for the provider to use. The following values are defined for this property:
none
use no authentication (anonymous bind).
simple
use simple authentication (a cleartext password).
A space-separated list of one or more SASL mechanism names:
use the first available SASL mechanism in the list that conforms to the specified policy requirements

See the SASL section for information on how this property is used for SASL authentication. See  RFC 2829  for information on LDAP authentication mechanisms.

If this property is not set then its default value is none, unless the java.naming.security.credentials property is set, in which case the default value is simple. If this property is set to a value that the provider does not recognize or support, it should throw AuthenticationNotSupportedException.

For example:

env.put(Context.SECURITY_AUTHENTICATION, "simple");
specifies that simple authentication be used to authenticate to the LDAP server. Or,
env.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5 CRAM-MD5");
specifies that DIGEST-MD5 authentication be used and, if that SASL mechanism is unavailable, that CRAM-MD5 authentication be used. If neither is available then throw AuthenticationNotSupportedException.
java.naming.security.credentials
The value of this property is an object that specifies the credentials of the principal to be authenticated. Its format and handling depends on the value of the  java.naming.security.authentication property.
For anonymous binds, this property is ignored - an empty string is always used for the credentials. For simple authentication and SASL authentication that requires a password, the value of this property may be supplied as a java.lang.String, a char[] or a byte[]. If it is a String or a char[] then it is encoded into a byte array using UTF-8 in the case of LDAPv3 and encoded using ISO-Latin-1 in the case of LDAPv2. If it is a byte[] then it is used as is.
See the SASL section for information on how this property is used for SASL authentication.
No default value is defined for this property.
For example:
env.put(Context.SECURITY_CREDENTIALS, "secret");
sets the credentials to be the string "secret".
java.naming.security.principal
The value of this property is a string that specifies the identity of the principal to be authenticated. Its format depends on the authentication type; see RFC 2829  for more information. The value is used as the name component in an LDAP ASN.1 BindRequest for non-SASL authentication. For SASL authentication, the value of this property is used as the authentication ID for SASL mechanisms that need an authentication ID.

The provider is not required to verify the validity of the principal name. It may, for example, just pass the string to be verified by the server. If the principal identified is not a valid principal then the provider shall throw an AuthenticationException.

No default value is defined for this property.

For example:

env.put(Context.SECURITY_PRINCIPAL, "cn=admin,o=sun,c=us");
sets the principal name to be the distinguished name "cn=admin, o=sun, c=us".
java.naming.security.protocol
The value of this property is a string that specifies the security protocol for the provider to use. The following value is defined for this property:
 
ssl
use Secure Sockets Layer version 3.0.

If this property is set to ssl, the provider must use SSL sockets, or throw ConfigurationException if it is unable to do so. In addition to the value listed above, a provider may support other security protocols. However, such provider-specific protocols might not be supported by all providers. If this property is set to a security protocol that the provider does not recognize or support, it should throw ConfigurationException.

If the  java.naming.ldap.factory.socket  property is set, then the socket factory identified by that property must create sockets that are appropriate for this protocol setting. For example, if the security protocol is set to ssl, then the socket factory must create SSL-compliant sockets.

If this property is not set then the default is to use no security protocol.

As a developer of the LDAP provider, you should be aware that using SSL to connect to a server on a port that is not listening for SSL connections causes the socket to hang. Similarly, using a plain socket to connect to a server that is listening for SSL connections also leads to hanging. This is a characteristic of the protocol that some implementations may choose to correct but is not otherwise required to do so. The provider's documentation, however, should describe this behavior to its users. See SSL for information on how to use SSL.

For example:

env.put(Context.SECURITY_PROTOCOL, "ssl");
specifies that SSL-compliant sockets be used to communicate with the server.

3.3 LDAP-specific Properties

LDAP-specific properties are environment properties that apply to LDAP service providers in general. These properties' names have the prefix "java.naming.ldap.". The following table lists LDAP-specific properties that have been defined so far. If there is a property that you feel belongs on this list, please send a description of it to jndi@java.sun.com.

java.naming.ldap.attributes.binary
The value of this property is a string of space-separated attribute names. It specifies attributes which have non-string syntax. It extends the provider's built-in list of non-string attributes (below). The value of an attribute that has non-string syntax is returned as a byte array (byte[]) instead of a String.
No default is defined. If this property is not set then only the following attributes are considered to have non-string syntax:
Attribute ID OID Reference
Any attribute ID with the ";binary" option.    
photo 0.9.2342.19200300.100.1.7 RFC 1274
personalSignature 0.9.2342.19200300.100.1.53 RFC 1274
audio 0.9.2342.19200300.100.1.55 RFC 1274
jpegPhoto 0.9.2342.19200300.100.1.60 RFC 2798
javaSerializedData 1.3.6.1.4.1.42.2.27.4.1.7 RFC 2713
thumbnailPhoto 2.16.128.113533.1.1400.1 NAC LIP Schema
thumbnailLogo 2.16.128.113533.1.1400.2 NAC LIP Schema
userPassword 2.5.4.35 RFC 2256
userCertificate 2.5.4.36 RFC 2256
cACertificate 2.5.4.37 RFC 2256
authorityRevocationList 2.5.4.38 RFC 2256
certificateRevocationList 2.5.4.39 RFC 2256
crossCertificatePair 2.5.4.40 RFC 2256
x500UniqueIdentifier 2.5.4.45 RFC 2256
For example:
env.put("java.naming.ldap.attributes.binary",
        "mpegVideo myspecialkey");
informs the provider to return values of the mpegVideo and myspecialkey attributes as byte[].
java.naming.ldap.control.connect
The value of this property is a Control[] object.  It sets the connection request controls that are active on a connection. See LdapContext.
No default value is defined for this property.
For example:
env.put("java.naming.ldap.control.connect",
        new Control[]{ new ManageReferralControl(true) });
sets a critical ManageDsaIT LDAP control as the connection request control.

java.naming.ldap.deleteRDN
The value of this property is a string that specifies whether the old RDN is removed by the Context.rename method. The following values are defined for this property:
 
true
delete the old RDN from the entry during the rename operation.
false
retain the old RDN as an attribute value of the entry.

 
If this property is not set then its default value is true.

For example:

env.put("java.naming.ldap.deleteRDN", "false");
causes the old RDN to be retained as an attribute of the renamed entry.

java.naming.ldap.derefAliases
The value of this property is a string that specifies how aliases are dereferenced during search operations. The following values are defined for this property:
always
always dereference aliases.
never
never dereference aliases.
finding
dereference aliases only during name resolution (that is, while locating the target entry).
searching
dereference aliases once name resolution has completed (that is, after locating the target entry).
If this property is not set then its default value is always.
For example:
env.put("java.naming.ldap.derefAliases", "searching");
causes the provider to dereference aliases only once the target entry has been located.

NOTE: this property is unrelated to the dereference-links flag in the SearchControls object.

java.naming.ldap.factory.socket
The value of this property is a string identifying the class name of a socket factory.
This property is used to override the default socket factory. The class specified in this property must implement the javax.net.SocketFactory interface. See http://java.sun.com/j2se/1.4/docs/guide/security/jsse/JSSERefGuide.html for more information. See SSL for information on how to use SSL.
In addition, if the  java.naming.security.protocol  property is set, then the socket factory identified by this property must create sockets which are appropriate for that protocol setting. For example, if the security protocol is set to ssl then the socket factory must create SSL-compliant sockets.
No default is defined for this property.
For example:
env.put("java.naming.ldap.factory.socket",
        "javax.net.ssl.SSLSocketFactory");
sets the socket factory of the provider to be javax.net.ssl.SSLSocketFactory.

java.naming.ldap.ref.separator
The value of this property is a string containing the character to use when encoding a RefAddr object in the javaReferenceAddress attribute (see Java Objects).
This property is used to avoid a conflict in the case where the default separator character appears in the components of a RefAddr object.
If this property is not set then its default value is '#' (the hash character).
For example:
env.put("java.naming.ldap.ref.separator", ":");
specifies that the separator ':' (the colon character) be used when storing RefAddr instances.

java.naming.ldap.referral.limit
The value of this property is a string of decimal digits specifying the maximum number of referrals to follow in a chain of referrals. A setting of zero indicates that there is no limit.
If this property is not set then the default value is 10.
For example:
env.put("java.naming.ldap.referral.limit", "5");
specifies that the referral limit is 5.

java.naming.ldap.typesOnly
The value of this property is a string that specifies whether only attribute IDs are returned in results - attribute values are omitted. Affects the SearchResult.getAttributes and DirContext.getAttributes methods. The following values are defined for this property:
 
true
return only attribute IDs.
false
return both attribute IDs and attribute values.

If this property is not set then its default value is false.

For example:

env.put("java.naming.ldap.typesOnly", "true");
causes the server to return attribute IDs but not attribute values.
java.naming.ldap.version
The value of this property is a string that specifies the protocol version for the provider. The following values are defined for this property:
 
2
selects LDAP version 2 (LDAPv2).
3
selects LDAP version 3 (LDAPv3).

If this property is not set then the provider first attempts to bind using LDAP v3 and fails over to using LDAP v2 if a protocol error is received from the server. This failover mechanism is only used when the java.naming.security.authentication property indicates anonymous bind or simple authentication.

For example:

env.put("java.naming.ldap.version", "2");
requests the LDAP provider to communicate with the server using LDAPv2.

3.4 Feature-specific Properties

Feature-specific properties are environment properties which apply to a particular feature which is supported by a provider.

3.4.1 SASL Properties

There are two groups of SASL properties. The first group comprises those that relate to how the JNDI service provider interacts with the Java SASL API (JSR 28). These properties have the prefix "java.naming.security.sasl." The second group comprises those that affect the SASL mechanisms. These properties are specified in the Java SASL API and have the prefix "javax.security.sasl." See the SASL section and the Java SASL API for details about this second group of properties.

java.naming.security.sasl.authorizationId

The value of this property is a string that specifies the authorization ID for the SASL mechanisms.

If this property is not set, then the authorization ID passed to the SASL mechanisms is the empty string. According to SASL (RFC 2222), using an authorization ID of the empty string directs the server to derive an authorization ID from the client's authentication credentials.

For example:

env.put("java.naming.security.sasl.authorizationId",
        "dn:cn=administrators,ou=groups,o=sun,c=us");
specifies the identity to use for authorization (access control) upon successful authentication.

java.naming.security.sasl.realm

The value of this property is a string that specifies the realm information required by some SASL mechanisms such as DIGEST-MD5.

If this property is not set, then a mechanism-specific default such as that negotiated between the client and server during the authentication exchange is used.

For example:

env.put("java.naming.security.sasl.realm", "webusers");
specifies that the client wants to use the "webusers" realm for authentication.


java.naming.security.sasl.callback

The value of this property is an instance of javax.security.auth.callback.CallbackHandler. When the provider uses a SASL mechanism that requires callbacks, the SASL mechanism uses the object supplied in the property. The callback handler should satisfy a NameCallback by supplying the authentication ID.

If this property is not set, then the provider should use a default callback handler that satisfies the NameCallback using the value of the java.naming.security.principal property, satisfies the PasswordCallback using the value of the java.naming.security.credentials property, and satisfies the RealmCallback and RealmChoiceCallback (described in the Java SASL API) using the value of the java.naming.security.sasl.realm property.

For example:

env.put("java.naming.security.sasl.callback",
        new MyCallbackHandler());
supplies an instance of the callback handler for SASL mechanisms to use.

javax.security.sasl.qop
The value of this property is a ','-separated list of quality-of-protection (qop) values used to specify the client's qop preference. A qop value is one of The order of the list specifies the preference order. If this property is absent, the default qop is "auth".

javax.security.sasl.strength
The value of this property is a ','-separated list of cipher strength values used to specify the client's preference. A strength value is one of The order of the list specifies the preference order. If this property is absent, the default strength is "high,medium,low".

For privacy in DIGEST-MD5, "high" maps to "3des", "medium" to "rc4" or "des", and "low" to "rc4-56" or "rc4-40".


javax.security.sasl.maxbuffer
The value of this property is the string representation of an integer that specifies the maximum size of the receive buffer in bytes that the client is willing to receive. If this property is absent, the default size is defined by the SASL mechanism.

javax.security.sasl.server.authentication
The value of this property is either "true" or "false", specifying whether the server must authenticate to the client or not, respectively. If this property is absent, the default is "false".

javax.security.sasl.policy.forward
The value of this property is either "true" or "false", specifying whether the selected SASL mechanism must support forward secrecy between sessions or not, respectively. If this property is absent, the default is "false".

javax.security.sasl.policy.credentials
The value of this property is either "true" or "false", specifying whether the selected SASL mechanism must require client credentials or not, respectively. If this property is absent, the default is "false".

javax.security.sasl.policy.noplaintext
The value of this property is either "true" or "false", specifying whether the selected SASL mechanism must not be susceptible to simple plain passive attacks or not, respectively. If this property is absent, the default is "false".

javax.security.sasl.policy.noactive
The value of this property is either "true" or "false", specifying whether the selected SASL mechanism must not be susceptible to active (non-dictionary) attacks or not, respectively. If this property is absent, the default is "false".

javax.security.sasl.policy.nodictionary
The value of this property is either "true" or "false", specifying whether the selected SASL mechanism must not be susceptible to dictionary attacks or not, respectively. If this property is absent, the default is "false".

javax.security.sasl.policy.noanonymous
The value of this property is either "true" or "false", specifying whether the selected SASL mechanism must not accept anonymous logins or not, respectively. If this property is absent, the default is "false".

3.5 Provider-specific Properties

Provider-specific properties are environment properties which apply only to particular provider implementations. The names of these properties are chosen by the provider's implementor. The recommended policy for naming these properties is to use the implementor's reversed DNS domain name to prefix the provider's package name and to use that package name to prefix the property name. For example, Sun prefixes its provider-specific LDAP properties with "com.sun.jndi.ldap".

4. Names

Names are handled by the provider's context methods according to the following rules:
  1. String names supplied as parameters to the context methods are in the composite name syntax.The first component of the composite name is an LDAP distinguished name while the rest of the components are used for federation.
  2. If a Name argument is a CompositeName object then its first component is assumed to be an LDAP distinguished name and the remaining components (if any) are used for federation.
  3. If a Name argument is not a CompositeName object then all of its components are assumed to be the parsed form of an LDAP distinguished name. That is, each Name component is an LDAP relative distinguished name (RDN).
  4. Names are parsed using the name parser returned by the Context.getNameParser method. The parser accepts LDAP distinguished names as String objects and produces LDAP distinguished names as Name objects.
  5. Names returned by context operations are string composite names or string URLs.
The syntax of string LDAP distinguished names follows RFC 2253. For example:
The name supplied to an LDAP context is always relative to that context. For example, given an LDAP context (lctx) for "dc=widget,dc=com", in order to name LDAP entries in that subtree, a name relative to "dc=widget,dc=com" must be supplied. For example, the following call obtains the attributes for the
"cn=John Smith,dc=widget,dc=com" entry,

        Attributes attrs = lctx.getAttributes("cn=John Smith");

Similarly, when a context is enumerated using any of the enumeration methods (Context.list, Context.listBindings, DirContext.search), the names returned are relative to the target context--the context being enumerated.  When referrals are invoked, instead of a relative name, an LDAP or LDAPS URL string containing the fully qualified name is returned. (If the enumeration was performed using a plain connection, an LDAP URL string is returned; if it was done using an SSL connection, an LDAPS URL string is returned.) The format of LDAP URLs is defined in RFC 2255.

LDAP URLs that follow RFC 2255 and LDAPS URLs may be supplied to any of the context methods. The hostname and port number are extracted from the URL and used to contact the LDAP server; the URL's scheme ("ldap" or "ldaps") is used to determine whether a plain or SSL connection is used. The java.naming.factory.initial and java.naming.provider.url properties are ignored. For example,

    DirContext ictx = new InitialDirContext();
    Attributes attrs = ictx.getAttributes(
        "ldap://wserver:389/cn=John Smith,dc=widget,dc=com");

This code fragment contacts the LDAP server at machine wserver at port 389 using a plain connection.


5. Attributes

The LDAP provider expects as input and returns as output all attribute values as either String or byte[] objects.  See the java.naming.ldap.attributes.binary environment property for which ones are treated as byte[] and how to extend the list.


6. URLs

RFC 2255 describes the syntactic format of LDAP URLs. The format contains all the elements necessary to specify an LDAP search operation, with provisions for supporting extensions:
ldap://host:port/dn?attributes?scope?filter?extensions
Authentication information may be specified in the extensions portion of the URL. See the RFC for a complete description of the format.

In addition to LDAP URLs, the provider may also support the non-standard but widely used LDAPS URLs. LDAPS URLs use SSL connections instead of plain (i.e., unprotected) connections. They have a syntax similar to LDAP URLs except the schemes are different and the default port for LDAPS URLs is 636 instead of 389.

ldaps://host:port/dn?attributes?scope?filter?extensions

URLs play a role in several places in JNDI:

  1. Configuration of service providers.
    To configure an LDAP service provider, you typically supply one or more space-separated LDAP or LDAPS URLs in the java.naming.provider.url property. This is used by the LDAP service provider to configure its connection to the directory server. Only the host, port, and dn parts of the URL are relevant in this setting. Supplying other parts of the URL results in a ConfigurationException.
     
  2. Argument to initial context methods.
    If a URL string (with syntax scheme_id:rest_of_name) is passed to the methods in InitialContext, either as a String argument or as the first component of Name, the URL's scheme id is used to locate the context factory for handling that scheme. If none is found, the URL string is treated as an ordinary name and passed to the initial context specified by the java.naming.factory.initial property is used. See the java.naming.spi.NamingManager.getURLContext method for details on how URL context factories are located. Note that this support for URLs as names is only available in the initial context.

    With the exception of the search methods, when an LDAP or LDAPS URL is passed as a name to the initial context, the URL should not contain any query ('?') components. Otherwise, an InvalidNameException is thrown by the service provider. For the search methods, the query components of the URL override any corresponding components supplied as arguments. For example, if an LDAP URL containing a scope component is supplied, then that scope overrides any scope setting that may be passed in a SearchControls argument.
     

  3. Referrals.
    An LDAP referral contains a list of one or more URLs. To process an LDAP referral (either explicitly or implicitly by setting the java.naming.referral property), the service provider needs to use the information in the these URLs to create connections to LDAP servers to which they refer. When multiple URLs are present in a single referral they are treated as alternatives and each is followed until one succeeds. The complete URL (that is, including any query components) is used.
     
  4. Returned as a name in list and search enumerations.
    When the name of the entry being returned has a name that is not relative to the target context (i.e., the starting context for the list or search), the name is returned as a URL. See the NameClassPair.isRelative method for details.
     
  5. Argument to the getObjectInstance method of NamingManager or DirectoryManager.
    When an LDAP namespace is federated underneath another namespace (for example, such as DNS), the information that is stored in the superior namespace might be an LDAP or LDAPS URL. In such a scenario, a lookup/list/search operation in the superior namespace would return a Reference containing an LDAP or LDAPS URL for the LDAP namespace. The service provider for the superior namespace would pass the Reference to the getObjectInstance method to create an instance of an LDAP context.
For items (1), (2), (3), and (5), if the URL is missing the hostname and port but has a non-empty distinguished name, the provider should use the algorithm for discovering LDAP services with DNS as described in the Internet draft draft-ietf-ldapext-locate-08.txt. If the provider does not use this algorithm, or if the DNS configuration is not available, then the provider should use localhost as the hostname, and 389 as the port for plain connections, 636 as the port for SSL connections.

7. Java Objects

7.1 Storing

The LDAP provider should support the storing of Java objects into the directory. This is implemented in the following methods: The provider should support at a minimum the storage of the following types of Java objects:
  1. Instances of Reference
  2. Objects that implement the Referenceable interface
  3. Objects that implement the Serializable interface
  4. Objects that implement the DirContext interface
It should check whether an object is in these four categories in the order listed because that is most likely to capture the intent of the client. For example, a Reference is Serializable, so if you performed the Serializable check first, no References would ever be stored in the reference format (that is, they would all be serialized).

References, referenceable and serializable objects should be stored according to RFC 2713. DirContext objects should be stored by storing their attributes.

When storing a reference's list of RefAddr into the javaReferenceAddress attribute, the separator to use for delimiting the address's position, type and content are controlled using the environment property java.naming.ldap.ref.separator. If this environment property is not specified, the hash character '#' should be used as the separator.

The provider uses the DirectoryManager.getStateToBind method when storing objects in the directory. This allows objects of any type to be transformed into one of the four categories listed above so that they can be stored into the directory.

7.2 Reading

Objects are read from the directory using the following operations: When the provider reads an entry from the directory, it will get LDAP attributes, and attributes defined in RFC 2713 if the entry has an associated Java object. If the entry contains Java object-related attributes, the provider should recreate the object using those attributes. Otherwise, the provider should return an instance of DirContext containing the attributes of the entry. For both DirContext and Java objects, the provider should then invoke DirectoryManager.getObjectInstance() on it and return the result to the caller.

8.0 Schema

JNDI does not specify schema-related details such as structure and contents of the schema tree, permission to modify to the contents of the schema tree, and the effect of such modifications on the directory are dependent on the underlying directory. JNDI specifies only that the root schema context--that returned by DirContext.getSchema()--contain the following bindings: This document specifies the structure and content of schema trees that are derived from LDAP-based schemas. It describes how the schema tree is laid out, and the mandatory and optional attributes that you can expect to find associated with entries in different parts of this schema tree.

Permission to modify the contents of the schema tree is determined by the directory administrator. When the schema tree is modified, the changes are made to schema stored on the directory server.

8.1 Schema Tree Structure

In addition to the three bindings in the root schema context listed previously, the root schema context may also contain the following four bindings:
Name of Binding Description of Binding
AttributeDefinition Root of the attribute definition tree: a flat namespace with attributes identified by their name or OID.
ClassDefinition Root of the "objectclass" definition tree: a flat namespace with object classes identified by their name or OID.
SyntaxDefinition Root of the syntax definition tree: a flat namespace with syntaxes identified by their OID.
MatchingRule Root of matching rule tree: a flat namespace with matching rules identified by their name or OID.
ExtensionDefinition Root of the extensions tree: a flat namespace with extensions identified by their OID.
ControlDefinition Root of the controls tree: a flat namespace with controls identified by their OID.
SASLMechanism Root of the SASL tree: a flat namespace with SASL authentication mechanisms identified by their string name.

Any or all of these bindings may be absent if the underlying directory does not publish such schema information, or the service provider does not support retrieving them. If these names are present in the root schema context, however, they must have the binding specified in the above table.

The attribute names and values of these entries' attributes are case-insensitive.

8.2 Attribute Definitions

The name "AttributeDefinition" is bound to a context containing DirContext objects representing attribute definitions in the schema. For example, if a directory supports a "commonName" attribute, the "AttributeDefinition" context would have a binding with name "commonName" that is bound to a DirContext object.

Each object in the "AttributeDefinition" context has the following mandatory and optional attributes:
 

Attribute Identifier Attribute Value Description
NUMERICOID (mandatory) unique identifier (OID)
NAME attribute's name
DESC attribute's description
OBSOLETE "true" if obsolete, "false" or absent otherwise
SUP name of superior attribute type from which this attribute's type is derived
EQUALITY name or OID of matching rule if equality matching allowed, absent otherwise
ORDERING name or OID of matching rule if ordering matching allowed, absent otherwise
SUBSTRING name or OID of matching rule if substring matching allowed, absent otherwise
SYNTAX numeric OID of syntax of values of this type
SINGLE-VALUE "true" if attribute not multi-valued, "false" or absent otherwise.
COLLECTIVE "true" if attribute is collective, "false" or absent otherwise.
NO-USER-MODIFICATION "true" if not user-modifiable, "false" or absent otherwise.
USAGE description of attribute usage

These attributes have a 1-to-1 correspondence with the names defined in RFC 2252 for "AttributeTypeDescription." All the attribute values are represented by the java.lang.String class.

You can, for example, obtain the object representing the "cn" attribute using the following code:

DirContext schema = ctx.getSchema(""); // get schema tree
DirContext cnSchema = schema.lookup("AttributeDefinition/cn");
If you then get the attributes of the "cnSchema" DirContext object, you would see:
NUMERICOID      2.5.4.3
NAME            cn
SYNTAX          1.3.6.1.4.1.1466.115.121.1.15
DESC            Standard Attribute, alias for commonName
An equivalent way of getting "cnSchema" is if you already have a "cn" attribute. The following code illustrates this alternative:
Attributes attrs = ctx.getAttributes("cn=John", new String[]{"cn"});
Attribute cnAttr = attrs.get("cn");
DirContext cnSchema = cnAttr.getAttributeDefinition();

8.3 Object Class Definitions

The name "ClassDefinition" is bound to a context containing DirContext objects representing object class definitions in the schema. For example, if a directory supports a "country" object class, the "ClassDefinition" context would have a binding with name "country" that is bound to a DirContext object.

Each object in the "ClassDefinition" context has the following mandatory and optional attributes:
 

 
Attribute Identifier Attribute Value Description
NUMERICOID (mandatory) unique identifier (OID)
NAME object class's name
DESC object class's description
OBSOLETE "true" if obsolete, "false" or absent otherwise
SUP name of superior object class from which this object class is derived
ABSTRACT "true" if object class is abstract, "false" or absent otherwise
STRUCTURAL "true" if object class is structural, "false" or absent otherwise
AUXILIARY "true" if object class is auxiliary, "false" or absent otherwise
MUST a list of type names of attributes that must be present
MAY a list of type names of attributes that may be present

These attributes have a 1-to-1 correspondence with the names defined in RFC 2252 for "ObjectClassDescription." All the attribute values are represented by the java.lang.String class.

You can, for example, obtain the object representing the "country" object class using the following code:

DirContext schema = ctx.getSchema(""); // get schema tree
DirContext countrySchema = schema.lookup("ClassDefinition/country");
If you then get the attributes of the "countrySchema" DirContext object, you would see:
NUMERICOID      2.5.6.2
NAME            country
MAY             aci, searchguide, description
MUST            objectclass, c
DESC            Standard ObjectClass
SUP             top
An equivalent way of getting "countrySchema" is if you already have a "country" object. The following code illustrates this alternative:
// Read object from directory
DirContext countryObj = (DirContext)ctx.lookup("c=us", new String[]{"country"});

// Get all of object's object class definitions
DirContext objClasses = countryAttr.getSchemaClassDefinition();

// Pick out "country" object class in particular
DirContext countryClass = (DirContext)objClasses.lookup("country");

NOTE: JNDI 1.1's specification of getSchemaClassDefinition() implies that the service provider should return any one of an object's object class definitions. This specification is inadequate because an object usually has multiple object classes and the application might require knowledge about any of those object classes depending on what it is doing. The proposal as illustrated by the example above is to return a context containing all of the object class definitions.

8.4 Syntax Definitions

The name "SyntaxDefinition" is bound to a context containing DirContext objects representing syntax definitions in the schema. For example, if a directory supports the "1.3.6.1.4.1.1466.115.121.1.15" syntax (Directory String) syntax, the "SyntaxDefinition" context would have a binding with name "1.3.6.1.4.1.1466.115.121.1.15" that is bound to a DirContext object.

Each object in "SyntaxDefinition" context has the following mandatory and optional attributes:
 

Attribute Identifier Attribute Value Description
NUMERICOID (mandatory) unique identifier (OID)
DESC syntax's description

These attributes have a 1-to-1 correspondence with the names defined in RFC 2252 for "SyntaxDescription." All the attribute values are represented by the java.lang.String class.

You can, for example, obtain the object representing the "1.3.6.1.4.1.1466.115.121.1.15" syntax using the following code:

DirContext schema = ctx.getSchema(""); // get schema tree
DirContext dirStringSchema = 
    schema.lookup("SyntaxDefinition/1.3.6.1.4.1.1466.115.121.1.15");
If you then get the attributes of the "dirStringSchema" DirContext object, you would see:
NUMERICOID      1.3.6.1.4.1.1466.115.121.1.15
DESC            Directory String
An equivalent way of getting "dirStringSchema" is if you already have an attribute that has that syntax (such as, the "country" attribute). The following code illustrates this alternative:
Attributes attrs = ctx.getAttributes("c=us", new String[]{"country"});
Attribute countryAttr = attrs.get("country");
DirContext dirStringSchema = countryAttr.getSyntaxAttributeDefinition();

8.5 Matching Rules

The name "MatchingRule" is bound to a context containing DirContext objects representing matching rules in the schema. A "matching rule" uniquely identifies the algorithm to use when comparing attribute values. For example, a directory might support a matching rule that is based on how a string sounds and define it as the "soundAlikeMatch" matching rule. Then, the "MatchingRule" context would have a binding with name "soundAlikeMatch" that is bound to a DirContext object.

When a matching rule is an extensible matching rule, it must also contain an "APPLIES" attribute listing the attributes to which this extensible matching rule can be applied.

Each object in "MatchingRule" context has the following mandatory and optional attributes:
 

Attribute Identifier Attribute Value Description
NUMERICOID (mandatory) unique identifier (OID)
NAME name of matching rule
DESC matching rule's description
OBSOLETE "true" if obsolete, "false" or absent otherwise
SYNTAX numeric oid of syntax to which this rule applies
APPLIES a list type names of attributes to which this extensible matching rule applies

These attributes have a 1-to-1 correspondence with the names defined in RFC 2252 for "MatchingRuleDescription" and "MatchingRuleUseDescription." All the attribute values are represented by the java.lang.String class.

You can, for example, obtain the object representing the "soundAlikeMatch" syntax using the following code:

DirContext schema = ctx.getSchema(""); // get schema tree
DirContext soundMatchSchema = 
    schema.lookup("MatchingRule/soundAlikeMatch");
If you then get the attributes of the "soundMatchSchema" DirContext object, you would see:
NUMERICOID      1.2.3.4.5
NAME            soundAlikeMatch
SYNTAX          1.3.6.1.4.1.1466.115.121.1.15 (for directory string)
APPLIES         2.5.4.41, 2.5.4.15
DESC            Home-grown Phonetic match

8.6 Extension Definitions

The name "ExtensionDefinition" is bound to a context containing DirContext objects representing extensions supported by the server. For example, a directory might support the "Start TLS" extension ("1.3.6.1.4.1.1466.20037"). Then, the "ExtensionDefinition" context would have a binding with name "1.3.6.1.4.1.1466.20037" that is bound to a DirContext object.

Each object in "ExtensionDefinition" context has the following mandatory and optional attributes:
 

Attribute Identifier Attribute Value Description
NUMERICOID (mandatory) unique identifier (OID)
DESC extension's description

All the attribute values are represented by the java.lang.String class.

You can, for example, obtain the object representing the Start TLS extension ("1.3.6.1.4.1.1466.20037") using the following code:

DirContext schema = ctx.getSchema(""); // get schema tree
DirContext startTLSSchema = 
    schema.lookup("ExtensionDefinition/1.3.6.1.4.1.1466.20037");
If you then get the attributes of the "startTLSSchema" DirContext object, you would see:
NUMERICOID      1.3.6.1.4.1.1466.20037
DESC            Start TLS (see RFC 2830)

8.7 Control Definitions

The name "ControlDefinition" is bound to a context containing DirContext objects representing controls supported by the server. For example, a directory might support the control for asking the server to sort the search results it returns.

Each object in "ControlDefinition" context has the following mandatory and optional attributes:
 

Attribute Identifier Attribute Value Description
NUMERICOID (mandatory) unique identifier (string)
DESC control's description

All the attribute values are represented by the java.lang.String class.

You can, for example, obtain the object representing the server-side sorting control ("1.2.840.113556.1.4.473") using the following code:

DirContext schema = ctx.getSchema(""); // get schema tree
DirContext svrSortSchema = 
    schema.lookup("ControlDefinition/1.2.840.113556.1.4.473");
If you then get the attributes of the "svrSortSchema" DirContext object, you would see:
NUMERICOID      1.2.840.113556.1.4.473
DESC            server-side sorting of search results

8.8 SASL Mechanisms

The name "SASLMechanism" is bound to a context containing DirContext objects representing SASL authentication mechanisms supported by the server. For example, a directory might support the EXTERNAL SASL mechanism (RFC 2222) which requests that the server make use of security credentials exchanged by a lower layer.

Each object in "SASLMechanism" context has the following mandatory and optional attributes:
 

Attribute Identifier Attribute Value Description
NAME (mandatory) SASL mechanism's name
DESC SASL mechanism's description

All the attribute values are represented by the java.lang.String class.

You can, for example, obtain the object representing the EXTERNAL SASL mechanism using the following code:

DirContext schema = ctx.getSchema(""); // get schema tree
DirContext saslExternalSchema = 
    schema.lookup("SASLMechanism/EXTERNAL");
If you then get the attributes of the "saslExternalSchema" DirContext object, you would see:
NAME      EXTERNAL
DESC      EXTERNAL SASL mechanism (RFC 2222)

9. Exceptions

When building an LDAP provider, you need to translate LDAP error codes (see RFC 2251) into JNDI exceptions. You should use the following table when performing the translation. Furthermore, you should encode as much information as possible about the error into the exception's detailed message, "root cause" exception, resolved and remaining names. Note that resolved name and resolved object should correspond to each other's setting.
 
LDAP error code Exception or Action
success (0) Report success.
operationsError (1) NamingException
protocolError (2) CommunicationException
timeLimitExceeded (3) TimeLimitExceededException
sizeLimitExceeded (4) SizeLimitExceededException
compareFalse (5) Used by DirContext.search() and does not generate an exception.
compareTrue (6) Used by DirContext.search() and does not generate an exception.
authMethodNotSupported (7) AuthenticationNotSupportedException
strongAuthRequired (8) AuthenticationNotSupportedException
partialResults (9) If java.naming.referral is set to ignore, or contents of error does not contain a referral, throw PartialResultException. Otherwise, use the contents to build a referral.
referral (10) If java.naming.referral is set to ignore then throw PartialResultException. If it is set to throw then throw ReferralException. If it is set to follow then the provider shall follow the referral. If the value for java.naming.ldap.referral.limit is exceeded while following the referral then throw LimitExceededException.
adminLimitExceeded (11) LimitExceededException
unavailableCriticalExtension (12) OperationNotSupportedException
confidentialityRequired (13) AuthenticationNotSupportedException
saslBindInProgress (14) Used internally by LDAP provider during multi-stage SASL authentication.
noSuchAttribute (16) NoSuchAttributeException
undefinedAttributeType (17) InvalidAttributeIdentifierException
inappropriateMatching (18) InvalidSearchFilterException
constraintViolation (19) InvalidAttributeValueException
attributeOrValueExists (20) AttributeInUseException
invalidAttributeSyntax (21) InvalidAttributeValueException
noSuchObject (32) NameNotFoundException
aliasProblem (33) NamingException
invalidDNSyntax (34) InvalidNameException
isLeaf (35) Used by provider; usually doesn't generate exception.
aliasDereferencingProblem (36) NamingException
inappropriateAuthentication (48) AuthenticationNotSupportedException
invalidCredentials (49) AuthenticationException
insufficientAccessRights (50) NoPermissionException
busy (51) ServiceUnavailableException
unavailable (52) ServiceUnavailableException
unwillingToPerform (53) OperationNotSupportedException
loopDetect (54) NamingException
namingViolation (64) InvalidNameException
objectClassViolation (65) SchemaViolationException
notAllowedOnNonLeaf (66) ContextNotEmptyException
notAllowedOnRDN (67) SchemaViolationException
entryAlreadyExists (68) NameAlreadyBoundException
objectClassModsProhibited (69) SchemaViolationException
affectsMultipleDSAs (71) NamingException
other (80) NamingException

10. API Mapping

The methods of the JNDI API context interfaces are mapped onto LDAP operations as follows.
 
EventContext.addNamingListener
EventDirContext.addNamingListener
Register a listener for receiving naming events that take place in the specified subtree of LDAP entries. LDAP servers notify clients of events by means of LDAP controls attached to LDAP operation responses or by means of an LDAP unsolicited notifications. Such responses are then processed by the LDAP provider and indicated to the application in the form of NamingEvent or UnsolicitedNotificationEvent.
Context.addToEnvironment
Update context's environment properties. If multiple contexts share the same set of environment properties, the provider should take care to only modify the intended context's environment. Changing an environment property might require changes to the existing connection the context is using.
Supplying null for the property value has the same effect as removing the property.
For all environment properties, the new property is recorded even if it does not affect the context. See the Environment Properties section.
Context.bind

DirContext.bind
Perform an LDAP add operation to create a new entry in the directory. The DirContext.bind method can accept null as the object to bind if it is also supplied a non-null set of attributes. Otherwise, if the method is given insufficient information (i.e., no object or attributes), no entry can be added. If an object is provided in the arguments, then it is converted into attributes and stored in the entry along with any supplied attributes, as described in the Java Objects section. The provider should use the DirectoryManager.getStateToBind method to transform the input object into a form that it can store.
If the provider does not support binding any objects in the directory then it should throw OperationNotSupportedException. Otherwise, if it does support binding objects but does not support the supplied object then it should throw IllegalArgumentException.
Context.close
Release resources associated with context. For example, if the connection being used by this context is not shared with another context, the provider may abandon any outstanding requests and close the network connection to the server. Precisely which resources are released is implementation-dependent.
Context.composeName
If the parent context is from the same LDAP namespace, then concatenate the names according to the LDAP name syntax described in Context.getNameParser(). Otherwise, concatenate the names as composite names.
Context.createSubcontext

DirContext.createSubcontext
Perform an LDAP add operation to create the named entry and its associated attributes. If no attributes are supplied then the objectClass attribute is generated with the values top and javaContainer (javaContainer is a structural class that is necessary to avoid a schema violation error).
Context.destroySubcontext
Perform an LDAP delete operation to remove the named entry and its associated attributes. The named entry must be a leaf entry; subtrees are not removed. If the leaf entry does not exist (but its parent exists), the operation still succeeds.
LdapContext.extendedOperation
Perform an LDAP extended operation.
DirContext.getAttributes
Perform an LDAP base-object search operation to retrieve the LDAP entry's attributes. Use "(objectclass=*)" as the filter.
If the list of requested attributes is null or contains the special attribute identifier '*' then all the user attributes at the LDAP entry are returned. If operational attributes are required then those attribute identifiers must be present in the list of requested attributes.
LdapContext.getConnectControls
Retrieve the connection request controls in effect for LDAP bind operations invoked on this context.
Context.getEnvironment
Return the environment properties recorded at the context.
Context.getNameInNamespace
Return the LDAP distinguished name of the context.
Context.getNameParser
Return a name parser that parses LDAP names according to RFC 2253.
LdapContext.getRequestControls
Retrieve the request controls in effect for LDAP operations subsequently invoked on this context.
LdapContext.getResponseControls
Retrieve the response controls returned by the last LDAP operation invoked on this context.
DirContext.getSchema
See the Schema Section.
DirContext.getSchemaClassDefinition
See the Schema Section.
Context.list
Perform an LDAP one-level search operation of the named entry using the filter "(objectclass=*)" to retrieve the names of the entries immediately below the named entry.
Ask for, at a minimum, the javaClassName attributes so that the class name of each entry can be determined. If the class name cannot be determined, return javax.naming.directory.DirContext as the class name.
The names which are returned are either relative to the named context or they are LDAP or LDAPS URLs.
Context.listBindings
Perform an LDAP one-level search operation of the named entry using the filter "(objectclass=*)" to retrieve the attributes representing objects (or object references). Request the attributes for reconstructing the Java object and possibly other attributes as well. See Java Objects on how to reconstruct the object. If the object cannot be reconstructed according to RFC 2713 then return a DirContext object representing the LDAP entry. The provider should use the DirectoryManager.getObjectInstance method to satisfy calls to the Binding.getObject method.
The names which are returned are either relative to the named context or they are LDAP or LDAPS URLs.
Context.lookup

Context.lookupLink
Perform an LDAP base-object search operation of the named entry using the filter "(objectclass=*)". Request (possibly all) the attributes for reconstructing the Java object. See Java Objects on how to reconstruct the object. The provider should use the DirectoryManager.getObjectInstance method to satisfy calls to the Binding.getObject method.
DirContext.modifyAttributes
Perform an LDAP modify operation at the named entry using the supplied modifications. For the overloaded method that accepts an Attributes, first convert the Attributes argument into an ordered list of modifications by enumerating its contents using Attributes.getAll() and reusing the modification operation argument (mod_op).
LdapContext.newInstance
Initialize an new instance of this context with the specified request controls.
Context.rebind

DirContext.rebind
This method may involve several different LDAP operations. First get the existing entry's attributes. If the existing entry does not exist, this method behaves the same as bind(). Otherwise, if no attributes have been supplied and the object being bound is DirContext, invoke DirContext.getAttributes() and use the result as the attributes argument (attrs). If there are still no attributes, use the original entry's attributes as attrs. Remove the existing entry using the LDAP delete operation. Convert the object provided in the arguments into attributes (as described in the Java Objects section) and store in the entry along with attrs using the LDAP add operation. The provider should use the DirectoryManager.getStateToBind method to transform the input object into a form that it can store.
LdapContext.reconnect
Reconnect to the LDAP server using the supplied connection request controls and the current environment properties.
Context.removeFromEnvironment
Remove context's environment properties. If multiple contexts share the same set of environment properties, the provider should take care to only modify the intended context's environment. Changing an environment property might require changes to the existing connection the context is using.
For all environment properties, the new property is recorded even if it does not affect the context. Removing a property should cause the context to assume the property's default.
EventContext.removeNamingListener
Deregister a naming event listener so that subsequent events destined for that listener are not delivered.
Context.rename
Perform an LDAP modify DN operation to rename the entry. If LDAPv2 is being used then the new name and the old name must share the same immediate parent name. If the parents are not equal then throw InvalidNameException.
Note the effect of the  java.naming.ldap.deleteRDN  property on the behavior of this method.
DirContext.search
Perform an LDAP search operation according to the specified search controls.
If the list of requested attributes is null or contains the special attribute identifier '*' then all the user attributes at the LDAP entry are returned. If operational attributes are required then those attribute identifiers must be present in the list of requested attributes.
If objects are requested to be returned, then the Java object-related attributes (RFC 2713) are requested in addition to any requested by the API user. If these attributes are present then they are used to assemble the original objects (see Java Objects). If the object cannot be reconstructed according to RFC 2713 then return a DirContext object representing the LDAP entry. The provider should use the DirectoryManager.getObjectInstance method to satisfy calls to the Binding.getObject method.
The names which are returned are either relative to the named context or they are LDAP or LDAPS URLs.
The provider may use an LDAP compare operation instead of an LDAP search when the search filter supplied is suitably constrained:
 
  • The filter must be of the form "(<attributeID>=<value>)"
  • The scope must be object scope
  • Zero attributes must be requested (empty returning-attributes list)

In the forms of search that accept a string filter as argument, the syntax of the filter follows RFC 2254 with the exception that Unicode characters are also allowed. The use of Unicode characters is preferable to the use of encoded UTF-8 octets. The service provider is responsible for translating the Unicode characters into their corresponding UTF-8 representation for transmission to the server. For example, the Greek letter alpha can be specified in the string filter either as "\u03B1" or as "\\CE\\B1".

In the form search(Name, Attributes) and related methods, the Attributes argument is converted into a string filter by creating a conjunctive expression out of its elements. Each attribute value is treated as a literal; therefore '*' and other special characters defined in RFC 2254 that appear in the values of an attribute should be escaped according to the rules in RFC 2254. For example, an attribute value of '*' should be encoded as the string "\\2a".

In the form search(Name, String filterExpr, Object[] filterArgs) and its String overloaded method, "{num}" expansion is done in the filter by putting in values from filterArgs. Each "{num}" component may appear in the place of "attr" or "value" in Section 4 from RFC 2254.

The objects in filterArgs should be encoded in the following way:
 

  • byte arrays (byte[]) are encoded by encoding each byte as a string according to RFC 2254. For example, the array {0, 1, 10, 100} is encoded as the string "\\00\\01\\0a\\64".
  • Strings are treated as literals. In other words, '*' and other special characters defined in RFC 2254 that appear in the string are escaped according to the rules in RFC 2254. For example, a string of "*" is encoded as the string "\\2a".
  • Objects that are neither String nor byte[] are converted to their string form using Object.toString() and then the rules for String applied.
LdapContext.setRequestControls
Set the request controls for LDAP operations subsequently invoked on this context.
EventContext.targetMustExist
Determine whether a listener can register interest in an LDAP entry that doesn't exist.
Context.unbind
Perform an LDAP delete operation to remove the named entry. The named entry must be a leaf entry; subtrees are not removed. If the leaf entry does not exist (but its parents exist), the operation still succeeds.

11. Federation

The LDAP service provider should support federation using strong separation and either or both of junctions or implicit next naming system pointer.

12. SASL

The provider supports SASL mechanisms by means of the Java SASL API (JSR 28). This allows SASL mechanism drivers from different vendors to be used with the LDAP provider, and also allows a SASL mechanism driver to be used with different LDAP providers and even non-LDAP protocol libraries.

The Java SASL API depends on the Java Authentication and Authorization Service (JAAS), which provides callback support for SASL mechanisms that need to obtain or supply user/application information directly.

12.1 SASL Configuration

To specify that SASL authentication be used, you specify the official IANA-registered names of the SASL mechanisms in the java.naming.security.authentication property. The first SASL mechanism on the list that is both available and satisfies the optionally specified policies is used. That is, properties with the prefix "javax.security.sasl.policy." can be used to control the security characteristics of the selected SASL mechanism.

Some SASL mechanisms require the identity of the entity being authenticated. This is known as the authentication ID. Some SASL mechanisms, like DIGEST-MD5, require the use of a password and/or a realm. By default, the provider supplies the value of java.naming.security.principal property as the authentication ID to any SASL mechanism that requires the authentication ID, the value of the java.naming.security.credentials property as the password, and the value of the java.naming.security.sasl.realm property as the realm. To override these defaults, use the java.naming.security.sasl.callback property.

SASL mechanisms support the notion of authorization identity or authorization ID, which is the entity to which the server should grant access if the authentication succeeds.  If the java.naming.security.sasl.authorizationId property has been set, then its value is used as the authorization ID. Otherwise, the empty string is used as the authorization ID, which directs the server to derive an authorization ID from the client's authentication credentials.

See SASL properties for a description of the properties used by an LDAP service provider for supporting SASL.

In addition to these properties, there might be properties required for specific SASL mechanisms. For example, a SASL mechanism that supports privacy and integrity needs to know the quality of protection that the client requires. Properties such as these are passed to the SASL mechanism via the environment properties. See the JNDI documentation for how to set environment properties.

For example, if the application needs privacy, it can do so by using a call such as:

     env.put("javax.security.sasl.qop", "auth-conf");

before passing env to the initial context constructor. See the Java SASL API for details about these properties.

12.2 SASL Mechanism Drivers

The Java SASL API provides a framework for dynamically plugging in SASL mechanism drivers. The LDAP provider might provide a few default drivers. See the Java SASL API for details.

13. Extensions and Controls

The provider supports LDAP extensions and controls using the javax.naming.ldap package. In addition, the provider supports LDAP unsolicited notifications (which are transmitted in LDAP extended operation responses) using the services of the javax.naming.event package.

Several LDAP extensions and controls are defined by the IETF LDAPEXT working group.

The "Start TLS" extension ("1.3.6.1.4.1.1466.20037") is supported by the StartTlsRequest and StartTlsResponse classes. The LDAP provider must provide a concrete implementation of the abstract StartTlsResponse class and make its implementation available to the LDAP provider. See the description in StartTlsRequest.createExtendedResponse. Typically, the StartTlsResponse implementation would need access to the LDAP provider's data structures.

The LDAP service provider should perform hostname verification after Start TLS negotiation as specified in RFC 2830. If the LDAP server was discovered automatically by using information in DNS (as described in the URLs section), the provider should use the domain name derived from the distinguished name as the hostname to verify, as recommended by draft-ietf-ldapext-locate-08.txt.


14. Event Notification

The provider supports event notification using the javax.naming.event package.

A JNDI application can register for events that occur in the directory, such as the addition or removal of an entry, or the modification of an entry. Applications can also register for unsolicited notifications.



15. SSL

The provider supports SSL according to the Java Secure Socket Extension (JSSE) specification. SSL is activated by setting the java.naming.security.protocol environment property as follows:
env.put(Context.SECURITY_PROTOCOL, "ssl");
and by selecting the hostname and port number of an LDAP server that supports SSL. Once an SSL connection has been established subsequent LDAP protocol exchanges take place over that secure connection.

If, in addition, LDAP authentication is also required then the java.naming.security.authentication, java.naming.security.principal, and java.naming.security.credentials environment properties should be set, as appropriate. If LDAP authentication is required and the SSL credentials should be reused for LDAP authentication then set the java.naming.security.authentication environment property to select the SASL EXTERNAL mechanism, as follows:

        env.put(Context.SECURITY_AUTHENTICATION, "EXTERNAL");
 


Oracle and/or its affiliates
Java Technology

Copyright © 1993, 2011, Oracle and/or its affiliates. All rights reserved.

Contact Us