Network Working Group Rob Weltman INTERNET-DRAFT Netscape Communications Corp. April 22, 1997 The Java LDAP Application Program Interface Status of this Memo This draft document, draft-weltman-java-ldap-00.txt, will be submitted to the RFC Editor as an informational document. Distribution of this memo is unlimited. Please send comments to the authors. This document is an Internet-Draft. Internet-Drafts are working docu- ments of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as ``work in progress.'' To learn the current status of any Internet-Draft, please check the ``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow Directories on ds.internic.net (US East Coast), nic.nordu.net (Europe), ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific Rim). Abstract This document defines a java language application program interface to the lightweight directory access protocol (LDAP), in the form of a class library. It complements but does not replace RFC 1823 ([9]), which describes a C language application program interface. 1. Introduction The LDAP class library is designed to provide powerful, yet simple, access to an LDAP directory services. It defines a synchronous inter- face to LDAP, with support for partial results on searching, to suit a wide variety of applications. This document gives a brief overview of the LDAP model, then an overview of the constituents of the class library. The public class methods are described in detail, followed by an appendix that provides some example code demonstrating the use of the classes. This document provides information to the Internet community. It does not specify any standard. Expires 10/97 [Page 1] JAVA LDAP API April 1997 2. Overview of the LDAP Model LDAP is the lightweight directory access protocol, described in [2] and [7]. It can provide a lightweight frontend to the X.500 directory [1], or to an LDAP server, to which it sends requests and receives responses. LDAPv3 can also be used over UDP transport. The LDAP information model is based on the entry, which contains infor- mation about some object (e.g., a person). Entries are composed of attributes, which have a type and one or more values. Each attribute has a syntax that determines what kinds of values are allowed in the attri- bute (e.g., ASCII characters, a jpeg photograph, etc.) and how those values behave during directory operations (e.g., is case significant during comparisons). Entries may be organized in a tree structure, usually based on politi- cal, geographical, and organizational boundaries. Each entry is uniquely named relative to its sibling entries by its relative distinguished name (RDN) consisting of one or more distinguished attribute values from the entry. At most one value from each attribute may be used in the RDN. For example, the entry for the person Babs Jensen might be named with the "Barbara Jensen" value from the commonName attribute. A globally unique name for an entry, called a distinguished name or DN, is constructed by concatenating the sequence of RDNs from the entry up to the root of the tree. For example, if Babs worked for the University of Michigan, the DN of her U-M entry might be "cn=Barbara Jensen, o=University of Michigan, c=US". The DN format used by LDAP is defined in [4]. Operations are provided to authenticate, search for and retrieve infor- mation, modify information, and add and delete entries from the tree. An LDAP server may return referrals if it cannot completely service a request, for example if the request specifies a directory base outside of the tree managed by the server. The LDAP class library offers the programmer the option of catching such referrals as exceptions and explicitly issuing new requests to the referred-to servers, or having referrals followed automatically by the library. In the latter case, the programmer may also provide a reauthentication object, allowing automatic referrals to procede with appropriate (non-anonymous) creden- tials for each referred-to server. The next sections give an overview of how the class library is used and detailed descriptions of the LDAP class methods that implement all of these functions. Expires 10/97 [Page 2] JAVA LDAP API April 1997 3. Overview of the LDAP classes 3.1. Interfaces LDAPEntryComparator An interface to support arbitrary sorting algo- rithms for entries returned by a search operation. At least one implementation must be provided: LDAPCompareAttrNames, to sort in ascending order based on one or more attribute names. LDAPRebind A programmer desiring reauthentication on automat- ically following referrals must implement this interface. Without it, automatically followed referrals will use anonymous authentication. LDAPSocketFactory Programmers needing to provide or use specialized socket connections, including Secure Socket Layer (SSL) based ones, can provide an object construc- tor to implement them. LDAPv2 This interface defines the functionality of the LDAP version 2 protocol. It is implemented by LDAPConnection. 3.2. Classes LDAPAttribute Represents the name and values of one attribute of a directory entry. LDAPAttributeSet A collection of LDAPAttributes. LDAPCompareAttrNames An implementation of LDAPEntryComparator, to sup- port sorting of search results by one or more attributes. LDAPConnection Implements LDAPv2 and is the central point for interactions with a directory. Expires 10/97 [Page 3] JAVA LDAP API April 1997 LDAPDN A utility class to facilitate composition and decomposition of distinguished names (DNs). LDAPEntry Represents a single entry in a directory. LDAPModification A single add/delete/replace operation to an LDAPAttribute. LDAPModificationSet A collection of LDAPModifications LDAPRebindAuth An implementation of LDAPRebind must be able to provide an LDAPRebindAuth at the time of a refer- ral. The class encapsulates reauthentication credentials. LDAPSearchConstraints Defines the options controlling search operations. LDAPSearchResults The enumerable results of a search operation. LDAPUrl Encapsulates parameters of an LDAP Url query, as defined in [8]. 3.3. Exceptions LDAPException General exception, comprising a code and textual context. LDAPReferralException Derived from LDAPException, contains a list of LDAPUrls corresponding to referrals received on an LDAP operation. LDAPSecurityException Derived from LDAPException, thrown on security mismatches. Expires 10/97 [Page 4] JAVA LDAP API April 1997 4. Overview of LDAP API Use An application generally uses the LDAP API in four steps. - Construct an LDAPConnection. Initialize an LDAP session with a directory server. The LDAPConnection.connect() call establishes a handle to the session, allowing multiple sessions to be open at once, on different instances of LDAPConnection. - Authenticate to the LDAP server with LDAPConnection.authenticate(). - Perform some LDAP operations and obtain some results. LDAPConnection.search() returns an LDAPSearchResults, which can be enumerated to access all entries found. LDAPConnection.read() returns a single entry. - Close the connection. The LDAPConnection.disconnect() call closes the connection. All operations are synchronous - they do not return until the operation has completed. In the java environment, it is appropriate to create a thread for the operation rather than providing parallel synchronous and asynchronous operations, as is the case in the C language API described in [9]. A special accomodation is made for providing intermediate results on searching, to facilitate user feedback: the number of entries to return at a time can be specified. Standard java Enumerations are used to parse search results. Errors result in the throwing of an LDAPException, with a specific error code and context-specific textual information available. The following sec- tions describe the LDAP classes in more detail. 5. The java LDAP classes 5.1. public class LDAPAttribute extends Object The LDAPAttribute class represents the name and values of an attribute in an entry. 5.1.1. Constructors public LDAPAttribute(String attrName) Constructs an attribute with no values. Expires 10/97 [Page 5] JAVA LDAP API April 1997 public LDAPAttribute(String attrName, byte attrBytes[]) Constructs an attribute with a byte-formatted value. public LDAPAttribute(String attrName, String attrString) Constructs an attribute that has a single string value. public LDAPAttribute(String attrName, String attrStrings[]) Constructs an attribute that has an array of string values. Parameters are: attrName Name of the attribute. attrBytes Value of the attribute as raw bytes. attrString Value of the attribute as a String. attrStrings Array of values as Strings. 5.1.2. addValue public synchronized void addValue(String attrString) Adds a string value to the attribute. public synchronized void addValue(byte attrBytes[]) Adds a byte[]-formatted value to the attribute. Parameters are: attrString Value of the attribute as a String. attrBytes Value of the attribute as raw bytes. Expires 10/97 [Page 6] JAVA LDAP API April 1997 5.1.3. getByteValues public Enumeration getByteValues() Returns an enumerator for the values of the attribute in byte[] for- mat. 5.1.4. getStringValues public Enumeration getStringValues() Returns an enumerator for the string values of an attribute. 5.1.5. getName public String getName() Returns the name of the attribute. 5.1.6. removeValue public synchronized void removeValue(String attrString) Removes a string value from the attribute. public synchronized void removeValue(byte attrValue[]) Removes a byte[]-formatted value from the attribute. Parameters are: attrString Value of the attribute as a String. attrBytes Value of the attribute as raw bytes. 5.1.7. size public int size() Returns the number of values of the attribute. Expires 10/97 [Page 7] JAVA LDAP API April 1997 5.2. public class LDAPAttributeSet extends Object An LDAPAttributeSet is a collection of LDAPAttributes, as returned in an entry on a search or read operation, or used to construct an entry to be added to a directory. 5.2.1. Constructors public LDAPAttributeSet() Constructs a new set of attributes. This set is initially empty. 5.2.2. add public synchronized void add(LDAPAttribute attr) Adds the specified attribute to this attribute set. Parameters are: attr Attribute to add to this set. 5.2.3. elementAt public LDAPAttribute elementAt(int index) throws ArrayIndexOutOfBoundsException Returns the attribute at the position specified by the index. The index is 0-based. Parameters are: index Index of the attribute to get. 5.2.4. getAttributes public Enumeration getAttributes() Returns an enumeration of the attributes in this attribute set. 5.2.5. remove public synchronized void remove(String name) Expires 10/97 [Page 8] JAVA LDAP API April 1997 Removes the specified attribute from the set. Parameters are: name Name of the attribute to remove from this set. To remove an LDAPAttribute by object, the LDAPAttribute.getName method can be used: LDAPAttributeSet.remove( attr.getName() ); 5.2.6. removeElementAt public void removeElementAt(int index) throws ArrayIndexOutOfBoundsException Removes the attribute at the position specified by the index. The index is 0-based. Parameters are: index Index of the attribute to remove. 5.2.7. size public int size() Returns the number of attributes in this set. 5.3. public class LDAPCompareAttrNames extends Object implements LDAPEntryComparator An object of this class supports sorting search results by attribute name, in ascending order 5.3.1. Constructors public LDAPCompareAttrNames(String attrName) Constructs an object that will sort results by a single attribute, in ascending order. public LDAPCompareAttrNames(String[] attrNames) Expires 10/97 [Page 9] JAVA LDAP API April 1997 Constructs an object that will sort by one or more attributes, in the order provided, in ascending order. Parameters are: attrName Name of an attribute to sort by. attrNames Array of names of attributes to sort by. 5.3.2. isGreater public boolean isGreater (LDAPEntry e1, LDAPEntry e2) Returns true if entry1 is to be considered greater than or equal to entry2, for the purpose of sorting, based on the attribute name or names provided on object construction. Parameters are: entry1 Target entry for comparison. entry2 Entry to be compared to. 5.4. public class LDAPConnection extends Object implements LDAPv2, Cloneable LDAPConnection is the central class that encapsulates the connection to a Directory Server through the LDAP protocol. It implements the LDAPv2 interface, and will in future releases implement additional LDAP proto- col level interfaces. An LDAPConnection object is not connected on con- struction, and may only be connected to one server at one port. Multiple threads may share this single connection, and an application may have more than one LDAPConnection object, connected to the same or different Directory Servers. Besides the methods described for LDAPv2 above, LDAPConnection provides the following methods. 5.4.1. Constructors public LDAPConnection() Constructs a new LDAPConnection object, which represents a connection to an LDAP server. Calling the constructor does not actually establish the connection. Expires 10/97 [Page 10] JAVA LDAP API April 1997 To connect to the LDAP server, use the connect method. public LDAPConnection(LDAPSocketFactory factory) Constructs a new LDAPConnection object, which will use the supplied class factory to construct a socket connection during LDAPConnection.connect(). 5.4.2. clone public LDAPConnection clone() Returns a copy of the object with a private context, but sharing the network connection if there is one. The network connection remains open until all clones have disconnected or gone out of scope. 5.4.3. getAuthenticationDN public String getAuthenticationDN() Returns the distinguished name (DN) used for authentication by this object. 5.4.4. getAuthenticationPassword public String getAuthenticationPassword() Returns the password used for authentication by this object. 5.4.5. getHost public String getHost() Returns the host name of the LDAP server to which the object is or was last connected. 5.4.6. getPort public int getPort() Returns the port number of the LDAP server to which the object is or was last connected. Expires 10/97 [Page 11] JAVA LDAP API April 1997 5.4.7. getProperty public Object getProperty(String name) throws LDAPException Gets a property of a connection object. The following read-only properties are available for any given con- nection: LDAP_PROPERTY_SDK The version of this SDK, as a Float data type. LDAP_PROPERTY_PROTOCOL The highest supported version of the LDAP protocol, as a Float data type. LDAP_PROPERTY_SECURITY A comma-separated list of the types of authentication supported, as a String. Other properties may be available in particular implementations of the class, and used to modify operations such as search. An LDAPException is thrown if the requested property is not avail- able. 5.4.8. getSearchConstraints public LDAPSearchConstraints getSearchConstraints() Returns the set of search constraints that apply to all searches per- formed through this connection (unless a different set of search con- straints is specified when calling the search method). Note that the getOption method can be used to get individual con- straints (rather than getting the entire set of constraints). Typically, the getSearchConstraints method is used to create a slightly different set of search constraints to apply to a particular search. 5.4.9. getSocketFactory public static LDAPSocketFactory getSocketFactory() Expires 10/97 [Page 12] JAVA LDAP API April 1997 Returns the default LDAPSocketFactory used to establish a connection to a server. 5.4.10. isAuthenticated public boolean isAthenticated() Indicates whether the object has authenticated to the connected LDAP server. 5.4.11. isConnected public boolean isConnected() Indicates whether the connection represented by this object is open at this time. 5.4.12. read public static LDAPEntry read(LDAPUrl toGet) throws LDAPException Reads the entry specified by the LDAP URL. When this method is called, a new connection is created automati- cally, using the host and port specified in the URL. After finding the entry, the method closes the connection (in other words, it disconnects from the LDAP server). If the URL specifies a filter and scope, these are not used. Of the information specified in the URL, this method only uses the LDAP host name and port number, the base distinguished name (DN), and the list of attributes to return. The method returns the entry specified by the base DN. Parameters are: toGet LDAP URL specifying the entry to read. 5.4.13. search public static LDAPSearchResults search(LDAPUrl toGet) throws LDAPEx- ception Expires 10/97 [Page 13] JAVA LDAP API April 1997 Performs the search specified by the LDAP URL, returning an enumer- able LDAPSearchResults object. public static LDAPSearchResults search(LDAPUrl toGet, LDAPSearchConstraints cons) throws LDAPException Perfoms the search specified by the LDAP URL. This method also allows specifying constraints for the search (such as the maximum number of entries to find or the maximum time to wait for search results). As part of the search constraints, a choice can be made as to whether to have the results delivered all at once or in smaller batches. If the results are to be delivered in smaller batches, each iteration blocks only until the next batch of results is returned. Parameters are: toGet LDAP URL specifying the entry to read. 5.4.14. setOption public void setOption(int option, Object value) throws LDAPException Sets the value of the specified option for this LDAPConnection object. These options represent the default search constraints for the current connection. Some of these options are also propagated through the LDAPSearchConstraints, which can be obtained from the connection object with the getSearchConstraints method. The option that is set here applies to all subsequent searches per- formed through the current connection, unless it is overridden with an LDAPSearchConstraints at the time of search. To set a constraint only for a particular search, create an LDAPSear- chConstraints object with the new constraints and pass it to the LDAPConnection.search method. Parameters are: option One of the following options: Expires 10/97 [Page 14] JAVA LDAP API April 1997 Option Type Description LDAPv2.DEREF Boolean Specifies whether or not the object dereferences aliases. If true, it dereferences aliases. By default, the value of this option is true. LDAPv2.SIZELIMIT Integer Specifies the maximum number of search results to return. If this option is set to 0, there is no maximum limit. By default, the value of this option is 1000. LDAPv2.TIMELIMIT Integer Specifies the maximum number of milliseconds to wait for results before timing out. If this option is set to 0, there is no maximum time limit. By default, the value of this option is 0. LDAPv2.REFERRALS Boolean Specifies whether or not the client follows referrals automatically. If true, the client fol- lows referrals automati- cally. If false, an LDAPReferralException is raised when a referral is detected. By default, the value of this option is false. Expires 10/97 [Page 15] JAVA LDAP API April 1997 LDAPv2.REFERRALS_REBIND_PROC LDAPRebind Specifies an object that implements the LDAPRe- bind interface. A user of the class library must define this class and the getRebindAuthen- tication method that will be used to get the distinguished name and password to use for authentication. If this value is null and REFER- RALS is true, referrals will be followed with anonymous (= no) authen- tication. By default, the value of this option is null. LDAPv2.REFERRALS_HOP_LIMIT Integer Specifies the maximum number of referrals in a sequence that the client will follow. For exam- ple, if REFERRALS_HOP_LIMIT is 5, the client will fol- low no more than 5 referrals in a row when resolving a single LDAP request. The default value of this option is 5. LDAPv2.BATCHSIZE Integer Specifies the number of search results to return at a time. For example, if BATCHSIZE is 1, enumerating an LDAPSear- chResults will block only until one entry is available. If it is 0, enumerating will block until all entries have been retrieved from the Expires 10/97 [Page 16] JAVA LDAP API April 1997 server. The default value of this option is 1. value The value to assign to the option. The value must be the java.lang object wrapper for the appropriate param- eter (e.g. boolean->Boolean, int->Integer) . 5.4.15. setProperty public void setProperty(String name, Object value) Sets a property of a connection object. No property names have been defined at this time, but the mechanism is in place in order to support revisional as well as dynamic exten- sions to operation modifiers. 5.4.16. setSocketFactory public static void setSocketFactory(LDAPSocketFactory factory) Establishes the default LDAPSocketFactory used to establish a connec- tion to a server. This method is implemented as once-only. It is useful to be able to change the run-time connection behavior of a whole application with a single instruction, but the results would be confusing, and the side-effects dangerous, if the global default factory could be changed at arbitrary times by different threads. A typical usage would be: if (usingSSL) { LDAPConnection.setSocketFactory(mySSLFactory); } ... LDAPConnection conn = new LDAPConnection(); conn.connect(myHost, myPort); In this example, connections are constructed with the default LDAP- SocketFactory. At application start-up time, the default may be set to use a particular provided SSL socket factory. Parameters are: Expires 10/97 [Page 17] JAVA LDAP API April 1997 factory A factory object which can construct socket connections for an LDAPConnection. 5.5. public class LDAPDN extends Object A utility class representing a distinguished name (DN). 5.5.1. explodeDN public static String[] explodeDN(String dn, boolean noTypes) Returns the individual components of a distinguished name (DN). Parameters are: dn Distinguished name, e.g. "cn=Babs Jensen,ou=Accounting,o=Acme,c=us" noTypes If true, returns only the values of the components, and not the names, e.g. "Babs Jensen", "Accounting", "Acme", "us" - instead of "cn=Babs Jensen", "ou=Accounting", "o=Acme", and "c=us". 5.5.2. explodeRDN public static String[] explodeRDN(String rdn, boolean noTypes) Returns the individual components of a relative distinguished name (RDN). Parameters are: rdn Relative distinguished name, i.e. only those components of a distinguished name which are unique to an entry at its position in a directory tree. noTypes If true, returns only the values of the components, and not the names. 5.6. public class LDAPEntry extends Object An LDAPEntry represents a single entry in a directory, consisting of a Expires 10/97 [Page 18] JAVA LDAP API April 1997 distinguished name (DN) and zero or more attributes. 5.6.1. Constructors public LDAPEntry() Constructs an empty entry. public LDAPEntry(String dn) Constructs a new entry with the specified distinguished name and with an empty attribute set. public LDAPEntry(String dn LDAPAttributeSet attrs) Constructs a new entry with the specified distinguished name and set of attributes. Parameters are: dn The distinguished name of the new entry. attrs The initial set of attributes assigned to the entry. 5.6.2. getAttributeSet public LDAPAttributeSet getAttributeSet() Returns the attribute set of the entry. 5.6.3. getDN public String getDN() Returns the distinguished name of the current entry. 5.7. public interface LDAPEntryComparator An object of this class can implement arbitrary sorting algorithms for search results. Expires 10/97 [Page 19] JAVA LDAP API April 1997 5.7.1. isGreater public boolean isGreater(LDAPEntry entry1, LDAPEntry entry2) Returns true if entry1 is to be considered greater than or equal to entry2, for the purpose of sorting. Parameters are: entry1 Target entry for comparison. entry2 Entry to be compared to. 5.8. public class LDAPException extends Exception Thrown to indicate that an error has occurred. An LDAPException can result from physical problems (such as network errors) as well as prob- lems with LDAP operations (for example, if the LDAP add operation fails because of duplicate entry). Most errors that occur throw this type of exception. In order to The getLDAPResultCode() method returns the specific result code, which can be compared against standard LDAP result codes as defined in [11], sec- tion 4. 5.8.1. Constructors public LDAPException() Constructs a default exception with no specific error information. public LDAPException(String message) Constructs a default exception with a specified string as additional information. This form is used for lower-level errors. public LDAPException(String message, int resultCode, String serverMessage) Constructs a default exception with a specified string as additional information. This form is used for higher-level LDAP operational errors. Expires 10/97 [Page 20] JAVA LDAP API April 1997 Parameters are: message The additional error information. resultCode The result code returned serverMessage Error message specifying additional information from the server. 5.8.2. getLDAPErrorMessage public String getLDAPErrorMessage() Returns the error message from the last error, if this message is available (that is, if this message was set). If the message was not set, this method returns null. 5.8.3. getLDAPResultCode public int getLDAPResultCode() Returns the result code from the last error. The codes are defined as public final static int members of this class. Note that this value is not always valid; -1 indicates this situation. 5.8.4. Error codes See [11] and [7] for a discussion of the meanings of the codes. ADMIN_LIMIT_EXCEEDED AFFECTS_MULTIPLE_DSAS ALIAS_DEREFERENCING_PROBLEM ALIAS_PROBLEM ATTRIBUTE_OR_VALUE_EXISTS AUTH_METHOD_NOT_SUPPORTED BUSY COMPARE_FALSE COMPARE_TRUE CONSTRAINT_VIOLATION ENTRY_ALREADY_EXISTS INAPPROPRIATE_AUTHENTICATION INAPPROPRIATE_MATCHING INSUFFICIENT_ACCESS_RIGHTS INVALID_ATTRIBUTE_SYNTAX INVALID_CREDENTIALS Expires 10/97 [Page 21] JAVA LDAP API April 1997 INVALID_DN_SYNTAX IS_LEAF LDAP_PARTIAL_RESULTS LOOP_DETECT NAMING_VIOLATION NO_SUCH_ATTRIBUTE NO_SUCH_OBJECT NOT_ALLOWED_ON_NONLEAF NOT_ALLOWED_ON_RDN OBJECT_CLASS_MODS_PROHIBITED OBJECT_CLASS_VIOLATION OPERATION_ERROR OTHER PROTOCOL_ERROR REFERRAL SIZE_LIMIT_EXCEEDED STRONG_AUTH_REQUIRED SUCCESS TIME_LIMIT_EXCEEDED UNAVAILABLE UNAVAILABLE_CRITICAL_EXTENSION UNDEFINED_ATTRIBUTE_TYPE UNWILLING_TO_PERFORM 5.9. public class LDAPModification extends Object A single change specification for an LDAPAttribute. 5.9.1. Constructors public LDAPModification(int op, LDAPAttribute attr) Specifies a modification to be made to an attribute. Parameters are: op The type of modification to make, which can be one of the following: LDAPModification.ADD The value should be added to the attri- bute LDAPModification.DELETE The value should be removed from the attribute Expires 10/97 [Page 22] JAVA LDAP API April 1997 LDAPModification.REPLACE The value should replace all existing values of the attribute For a binary value (not a string value), the operation should be Or'd (|) with LDAPModification.BVALUES. attr The attribute (possibly with values) to be modified. 5.9.2. getAttribute public LDAPAttribute getAttribute() Returns the attribute (possibly with values) to be modified. 5.9.3. getOp public int getOp() Returns the type of modification specified by this object. 5.10. public class LDAPModificationSet extends Object A collection of modifications to be made to the attributes of a single entry. 5.10.1. Constructors public LDAPModificationSet() Constructs a new, empty set of modifications. 5.10.2. add public synchronized void add(int op, LDAPAttribute attr) Specifies another modification to be added to the set of modifica- tions. Parameters are: op The type of modification to make, as described for LDAPModification. Expires 10/97 [Page 23] JAVA LDAP API April 1997 attr The attribute (possibly with values) to be modified. 5.10.3. elementAt public LDAPModification elementAt(int index) throws ArrayIndexOutOfBoundsException Retrieves a particular LDAPModification object at the position speci- fied by the index. Parameters are: index Index of the modification to get. 5.10.4. remove public synchronized void remove(String name) Removes the first attribute with the specified name in the set of modifications. Parameters are: name Name of the attribute to be removed. 5.10.5. removeElementAt public void removeElementAt(int index) throws ArrayIndexOutOfBoundsException Removes a particular LDAPModification object at the position speci- fied by the index. index Index of the modification to remove. 5.10.6. size public int size() Retrieves the number of LDAPModification objects in this set. Expires 10/97 [Page 24] JAVA LDAP API April 1997 5.11. public class LDAPRebindAuth extends Object Represents information used to authenticate the client in cases where the client follows referrals automatically. 5.11.1. Constructors public LDAPRebindAuth(String dn, String password) Constructs information that is used by the client for authentication when following referrals automatically. 5.11.2. getDN public String getDN() Returns the distinguished name to be used for reauthentication on automatic referral following. 5.11.3. getPassword public String getPassword() Returns the password to be used for reauthentication on automatic referral following. 5.12. public class LDAPReferralException extends LDAPException This exception, derived from LDAPException, is thrown when a server returns a referral and automatic referral following has not been enabled. 5.12.1. Constructors public LDAPReferralException() Constructs a default exception with no specific error information. public LDAPReferralException(String message) Constructs a default exception with a specified string as additional Expires 10/97 [Page 25] JAVA LDAP API April 1997 information. This form is used for lower-level errors. public LDAPReferralException(String message, int resultCode, String serverMessage) Parameters are: message The additional error information. resultCode The result code returned serverMessage Error message specifying additional information from the server. 5.12.2. getURLs public LDAPUrl[] getURLs() Gets the list of referrals (LDAP URLs to other servers) returned by the LDAP server. This exception is only thrown, and therefor the URL list only available, if automatic referral following is not enabled. 5.13. public class LDAPSearchConstraints extends Object A set of options to control a search operation. There is always an LDAP- SearchConstraints associated with an LDAPConnection object; it's values can be changed with LDAPConnection.setOption, or overridden by passing an LDAPSearchConstraints object to the search operation. 5.13.1. Constructors public LDAPSearchConstraints() Constructs an LDAPSearchConstraints object that specifies the default set of search constraints. public LDAPSearchConstraints(int msLimit, boolean dereference, int maxResults, boolean doReferrals, int batchSize, LDAPRebind rebind_proc, Expires 10/97 [Page 26] JAVA LDAP API April 1997 int hop_limit) Constructs a new LDAPSearchConstraints object and allows specifying the search constraints in that object. Parameters are: msLimit Maximum time in milliseconds to wait for results (0 by default, which means that there is no maximum time limit). dereference Specify true to follow ("dereference") aliases, or false to not follow aliases (true by default). maxResults Maximum number of search results to return (1000 by default). doReferrals Specify true to follow referrals automatically, or false to throw an LDAPReferralException error if the server sends back a referral (false by default) batchSize Specify the number of results to block on during enumeration. 0 means to block until all results are in (1 by default). rebind_proc Specifies an object of the class that implements the LDAPRebind interface. The object will be used when the client follows referrals automatically. The object pro- vides a method for getting the distinguished name and password used to authenticate to another LDAP server during a referral. This field is null by default. hop_limit Maximum number of referrals to follow in a sequence when attempting to resolve a request, when doing automatic referral following. 5.13.2. getBatchSize public int getBatchSize() Returns the suggested number of results to block on during enumera- tion of serach results. This should be 0 if intermediate results are not needed, and 1 if results are to be processed as they come in. Expires 10/97 [Page 27] JAVA LDAP API April 1997 5.13.3. getDereference public boolean getDereference() Specifies whether or not aliases should be dereferenced. Returns true if aliases are to be dereferenced for any operation, or false if aliases should not be dereferenced. NH 3 getHopLimit public int getHopLimit() Returns the maximum number of hops to follow during automatic refer- ral following. 5.13.4. getMaxResults public int getMaxResults() Returns the maximum number of search results to be returned; 0 means no limit. 5.13.5. getRebindProc public LDAPRebind getRebindProc() Returns the object that provides the method for getting authentica- tion information. 5.13.6. getReferrals public boolean getReferrals() Specifies whether nor not referrals are followed automatically. Returns true if referrals are to be followed automatically, or false if referrals throw an LDAPReferralException. 5.13.7. getTimeLimit public int getTimeLimit() Returns the maximum number of milliseconds to wait for any operation under these search constraints. If 0, there is no maximum time limit on waiting for the operation results. Expires 10/97 [Page 28] JAVA LDAP API April 1997 5.13.8. setBatchSize public void setBatchSize(int batchSize) Sets the suggested number of results to block on during enumeration of search results. This should be 0 if intermediate results are not needed, and 1 if results are to be processed as they come in. The default is 1. Parameters are: batchSize Blocking size on search enumerations. 5.13.9. setDereference public void setDereference(boolean dereference) Sets a preference indicating whether or not aliases should be dereferenced. true if aliases are to be dereferenced for any opera- tion, false if aliases should not be dereferenced. Parameters are: dereference true to follow aliases. 5.13.10. setHopLimit public void setHopLimit(int hop_limit) Sets the maximum number of hops to follow in sequence during automatic referral following. The default is 5. Parameters are: hop_limit Maximum number of chained referrals to follow automati- cally. 5.13.11. setMaxResults public void setMaxResults(int maxResults) Sets the maximum number of search results to be returned; 0 means no limit. The default is 1000. Parameters are: Expires 10/97 [Page 29] JAVA LDAP API April 1997 maxResults Maxumum number of search results to return. 5.13.12. setRebindProc public void setRebindProc(LDAPRebind rebind_proc) Specifies the object that provides the method for getting authentica- tion information. The default is null. If referrals is set to true, and the rebindProc is null, referrals will be followed with anonymous (= no) authentication. Parameters are: rebind_proc An object that implements LDAPRebind. 5.13.13. setReferrals public void setReferrals(boolean doReferrals) Specifies whether nor not referrals are followed automatically, or if referrals throw an LDAPReferralException. The default is false. Parameters are: doReferrals True to follow referrals automatically. 5.13.14. setTimeLimit public void setTimeLimit(int msLimit) Sets the maximum number of milliseconds to wait for any operation under these search constraints. If 0, there is no maximum time limit on waiting for the operation results. Parameters are: msLimit Maximum milliseconds to wait. 5.14. public class LDAPSearchResults extends Object An LDAPSearchResults object is returned from a search operation. It implements Enumeration, thereby providing access to all entries retrieved during the operation. Expires 10/97 [Page 30] JAVA LDAP API April 1997 5.14.1. hasMoreElements public boolean hasMoreElements() Specifies whether or not there are more search results in the enumeration. If true, there are more search results. 5.14.2. next public LDAPEntry next() Returns the next result in the enumeration as an LDAPEntry. 5.14.3. nextElement public Object nextElement() Returns the next result in the enumeration as an Object. This the default implementation of Enumeration.nextElement(). 5.14.4. sort public void sort(LDAPEntryComparator comp) Sorts all entries in the results using the provided comparison object. If the object has been partially or completely enumerated, only remaining elements are sorted. Sorting the results requires that they all be present. This implies that LDAPSearchResults.nextElement() will always block until all results have been retrieved, after a sort operation. The LDAPCompareAttrNames class is provided to support the common need to collate by a single or multiple attribute values, in ascending order. Examples are: res.sort(new LDAPCompareAttrNames("cn")); String[] attrNames = { "sn", "givenname" }; res.sort(new LDAPCompareAttrNames(attrNames)); Parameters are: comp An object that implements the LDAPEntryComparator interface to compare two objects of type LDAPEntry. Expires 10/97 [Page 31] JAVA LDAP API April 1997 5.15. public class LDAPSecurityException extends LDAPException This exception, derived from LDAPException, is thrown when a server returns an error indicating a security violation. 5.15.1. Constructors public LDAPSecurityException() Constructs a default exception with no specific error information. public LDAPSecurityException(String message) Constructs a default exception with a specified string as additional information. This form is used for lower-level errors. public LDAPSecurityException(String message, int resultCode, String serverMessage) Parameters are: message The additional error information. resultCode The result code returned serverMessage Error message specifying additional information from the server. 5.16. public interface LDAPSocketFactory Used to construct a socket connection for use in an LDAPConnection. An implementation of this interface may, for example, provide an SSLSocket connected to a secure server. 5.16.1. makeSocket public Socket makeSocket(String host, int port) throws IOException, UnknownHostException Returns a socket connected using the provided host name and port number. Expires 10/97 [Page 32] JAVA LDAP API April 1997 There may be additional makeSocket methods defined when interfaces to establish SSL and SASL authentication in the java environment have been standardized. Parameters are: host Contains a hostname or dotted string representing the IP address of a host running an LDAP server to connect to. port Contains the TCP or UDP port number to connect to or contact. The default LDAP port is 389. 5.17. public class LDAPUrl extends Object Encapsulates parameters of an LDAP Url query, as defined in [8]. An LDAPUrl object can be passed to LDAPConnection.search to retrieve search results. 5.17.1. Constructors public LDAPUrl(String url) throws MalformedURLException Constructs a URL object with the specified string as URL. public LDAPUrl(String host, int port, String dn) Constructs with the specified host, port, and DN. This form is used to create URL references to a particular object in the directory. public LDAPUrl(String host, int port, String dn, String attrNames[], int scope, String filter) Constructs a full-blown LDAP URL to specify an LDAP search operation. Parameters are: url An explicit URL string, e.g. Expires 10/97 [Page 33] JAVA LDAP API April 1997 "ldap://ldap.acme.com:80/o=Ace%20Industry,c=us?cn,sn?sub? (objectclass=inetOrgPerson)". host Host name of LDAP server, or null for "nearest X.500/LDAP". port Port number for LDAP server (use LDAPConnection.DEFAULT_PORT for default port). dn Distinguished name of object to fetch. attrNames Names of attributes to retrieve. null for all attri- butes. scope Depth of search (in DN namespace). Use one of SCOPE_BASE, SCOPE_ONE, SCOPE_SUB from LDAPv2. 5.17.2. decode public static String decode(String URLEncoded) throws MalformedURLEx- ception Decodes a URL-encoded string. Any occurences of %HH are decoded to the hex value represented. However, this routine does NOT decode "+" into " ". See [10] for details on URL encoding/decoding. Parameters are: URLEncoded String to decode. 5.17.3. encode public static String encode(String toEncode) Encodes an arbitrary string. Any illegal characters are encoded as %HH. However, this routine does NOT decode "+" into " ". Parameters are: toEncode String to encode. 5.17.4. getAttributes public String[] getAttributeArray() Expires 10/97 [Page 34] JAVA LDAP API April 1997 Return an array of attribute names specified in the URL 5.17.5. getAttributes public Enumeration getAttributes() Return an Enumerator for the attribute names specified in the URL 5.17.6. getDN public String getDN() Return the distinguished name encapsulated in the URL. 5.17.7. getFilter public String getFilter() Returns the search filter [8], or the default filter - (objectclass=*) - if none was specified. 5.17.8. getHost public String getHost() Returns the host name of the LDAP server to connect to. 5.17.9. getPort public int getPort() Returns the port number of the LDAP server to connect to. 5.17.10. getUrl public String getUrl() Returns a valid string representation of this LDAP URL. 5.18. public interface LDAPv2 As a mechanism to support planned and future LDAP protocol extensions, Expires 10/97 [Page 35] JAVA LDAP API April 1997 functionality is defined in an interface - LDAPv2, corresponding to ver- sion 2 of the LDAP protocol. LDAPConnection implements LDAPv2, and will in future releases also implement LDAPv3, which will define the addi- tional functionality implied by version 3 of the LDAP protocol. Applica- tions can test for support of these protocol levels in a given package with the instanceof operator. 5.18.1. add public void add(LDAPEntry entry) throws LDAPException Adds an entry to the directory. Parameters are: entry LDAPEntry object specifying the distinguished name and attributes of the new entry. 5.18.2. authenticate public void authenticate(String dn, String passwd) throws LDAPException Authenticates to the LDAP server (that the object is currently con- nected to) using the specified name and password. If the object has been disconnected from an LDAP server, this method attempts to recon- nect to the server. If the object had already authenticated, the old authentication is discarded. Parameters are: dn If non-null and non-empty, specifies that the connec- tion and all operations through it should be authenti- cated with dn as the distinguished name. passwd If non-null and non-empty, specifies that the connec- tion and all operations through it should be authenti- cated with dn as the distinguished name and passwd as password. 5.18.3. compare public boolean compare(String dn, LDAPAttribute attr) throws LDAPException Expires 10/97 [Page 36] JAVA LDAP API April 1997 Checks to see if an entry contains an attribute with a specified value. Returns true if the entry has the value, and false if the entry does not have the value or the attribute. Parameters are: dn The distinguished name of the entry to use in the com- parison. attr The attribute to compare against the entry. The method checks to see if the entry has an attribute with the same name and value as this attribute. 5.18.4. connect public void connect(String host, int port) throws LDAPException Connects to the specified host and port. If this LDAPConnection object represents an open connection, the connection is closed first before the new connection is opened. At this point there is no authentication, and any operations will be conducted as an anonymous client. public void connect(String host, int port, String dn, String passwd) throws LDAPException Connects to the specified host and port and uses the specified DN and password to authenticate to the server. If this LDAPConnection object represents an open connection, the connection is closed first before the new connection is opened. This is equivalent to connect(host, port) followed by authenticate(dn, passwd). Parameters are: host Contains a hostname or dotted string representing the IP address of a host running an LDAP server to connect to. port Contains the TCP or UDP port number to connect to or contact. The default LDAP port is 389. Expires 10/97 [Page 37] JAVA LDAP API April 1997 dn If non-null and non-empty, specifies that the connec- tion and all operations through it should be authenti- cated with dn as the distinguished name. passwd If non-null and non-empty, specifies that the connec- tion and all operations through it should be authenti- cated with dn as the distinguished name and passwd as password. 5.18.5. delete public void delete(String dn) throws LDAPException Deletes the entry for the specified DN from the directory. Parameters are: dn Distinguished name of the entry to modify. 5.18.6. disconnect public synchronized void disconnect() throws LDAPException Disconnects from the LDAP server. Before the object can perform LDAP operations again, it must reconnect to the server by calling connect. 5.18.7. getOption public Object getOption(int option) throws LDAPException Returns the value of the specified option for this object. Parameters are: option See LDAPConnection.setOption for a description of valid options. 5.18.8. modify public void modify(String dn, LDAPModification mod) throws LDAPException Expires 10/97 [Page 38] JAVA LDAP API April 1997 Makes a single change to an existing entry in the directory (for example, changes the value of an attribute, adds a new attribute value, or removes an existing attribute value). The LDAPModification object specifies both the change to be made and the LDAPAttribute value to be changed. public void modify(String dn, LDAPModificationSet mods) throws LDAPException Makes a set of changes to an existing entry in the directory (for example, changes attribute values, adds new attribute values, or removes existing attribute values). Parameters are: dn Distinguished name of the entry to modify. mod A single change to be made to the entry. mods A set of changes to be made to the entry. 5.18.9. read public LDAPEntry read(String dn) throws LDAPException Reads the entry for the specified distiguished name (DN) and retrieves all attributes for the entry. public LDAPEntry read(String dn, String attrs[]) throws LDAPException Reads the entry for the specified distinguished name (DN) and retrieves only the specified attributes from the entry. Parameters are: dn Distinguished name of the entry to retrieve. attrs Names of attributes to retrieve. Expires 10/97 [Page 39] JAVA LDAP API April 1997 5.18.10. rename public void rename(String dn, String newRdn, boolean deleteOldRdn) throws LDAPException Renames an existing entry in the directory. Parameters are: dn Current distinguished name of the entry. newRdn New relative distinguished name for the entry. deleteOldRdn If true, the old name is not retained as an attribute value. 5.18.11. search public LDAPSearchResults search(String base, int scope, String filter, String attrs[], boolean attrsOnly) throws LDAPException Performs the search specified by the parameters. public LDAPSearchResults search(String base, int scope, String filter, String attrs[], boolean attrsOnly, LDAPSearchConstraints cons) throws LDAPException Performs the search specified by the parameters, also allowing specification of constraints for the search (such as the maximum number of entries to find or the maximum time to wait for search results). As part of the search constraints, the function allows specifying whether or not the results are to be delivered all at once or in smaller batches. If specified that the results are to be delivered in smaller batches, each iteration blocks only until the next batch of Expires 10/97 [Page 40] JAVA LDAP API April 1997 results is returned. Parameters are: base The base distinguished name to search from. scope The scope of the entries to search. The following are the valid options: LDAPv2.SCOPE_BASE Search only the base DN LDAPv2.SCOPE_ONE Search only entries under the base DN LDAPv2.SCOPE_SUB Search the base DN and all entries within its subtree filter Search filter specifying the search criteria, as defined in [3]. attrs Names of attributes to retrieve. attrsOnly If true, returns the names but not the values of the attributes found. If false, returns the names and values for attributes found cons Constraints specific to the search. 5.18.12. setOption public void setOption(int option, Object value) throws LDAPException Sets the value of the specified option for this LDAPConnection object. See LDAPConnection.setOption for an implementation. 6. Security Considerations LDAP supports security through protocol-level authentication, using clear-text passwords or other more secure mechanisms. It also supports running over SSL, which provides strong security at the transport layer. This draft does not cover SSL implementations, although it identifies a mechanism for supplying one, through the LDAPSocketFactory interface. Expires 10/97 [Page 41] JAVA LDAP API April 1997 7. Acknowledgements The proposed API was defined in collaboration with Tim Howes and Mark Smith of Netscape Communications Corp., and Thomas Kwan and Stephan Gud- mundson of NCware Technologies Corp. 8. Bibliography [1] The Directory: Selected Attribute Syntaxes. CCITT, Recommendation X.520. [2] M. Wahl, A. Coulbeck, T. Howes, S. Kille, "Lightweight Directory Access Protocol: Standard and Pilot Attribute Definitions", Inter- net Draft draft-ietf-asid-ldapv3-attributes-03.txt, October 1996 [3] T. Howes, "A String Representation of LDAP Search Filters," RFC 1960, June 1996. [4] S. Kille, "A String Representation of Distinguished Names," RFC 1779, March 1995. [5] S. Kille, "Using the OSI Directory to Achieve User Friendly Nam- ing," RFC 1781, March 1995. [7] M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access Protocol (v3)", Internet Draft draft-ietf-asid-ldapv3-protocol-04.txt, March 1997. [8] T. Howes, M. Smith, "An LDAP URL Format", RFC 1959, June 1996. [9] T. Howes, M. Smith, "The LDAP Application Program Interface", RFC 1823, August 1995. [10] T. Berners-Lee, L. Masinter, M. McCahill, "Uniform Resource Loca- tors (URL)", RFC 1738, December 1994. [11] W. Yeong, T. Howes, S. Kille, "Lightweight Directory Access Proto- col", RFC 1777, March 1995. 9. Authors' Addresses Rob Weltman Netscape Communications Corp. 501 E. Middlefield Rd. Mountain View, CA 94043 USA +1 415 937-3301 rweltman@netscape.com Expires 10/97 [Page 42] JAVA LDAP API April 1997 Tim Howes Netscape Communications Corp. 501 E. Middlefield Rd. Mountain View, CA 94043 USA +1 415 937-3419 howes@netscape.com Mark Smith Netscape Communications Corp. 501 E. Middlefield Rd. Mountain View, CA 94043 USA +1 313 937-3477 mcs@netscape.com Thomas Kwan NCware Technologies Corp. 15600 NE 8th Suite B1#118 Bellevue WA 98008 USA +1 206 323-5579 thomask@ncware.com Stephan Gudmundson NCware Technologies Corp. 15600 NE 8th Suite B1#118 Bellevue WA 98008 USA +1 206 323-5579 stephang@ncware.com 10. Appendix A - Sample java LDAP program import netscape.ldap.*; import java.util.*; public class Search { public static void main( String[] args ) { try { LDAPConnection ld = new LDAPConnection(); /* Connect to server */ String MY_HOST = "localhost"; int MY_PORT = 389; ld.connect( MY_HOST, MY_PORT ); /* authenticate to the directory as nobody */ Expires 10/97 [Page 43] JAVA LDAP API April 1997 /* This is not really necessary if explicit authentication is not desired, because there is already anonymous authentication at connect time */ ld.authenticate( "", "" ); /* search for all entries with surname of Jensen */ String MY_FILTER = "sn=Jensen"; String MY_SEARCHBASE = "o=Ace Industry, c=US"; LDAPSearchConstraints cons = ld.getSearchConstraints(); /* Setting the batchSize to one will cause the result enumeration below to block on one result at a time, allowing us to update a list or do other things as results come in. */ /* We could set it to 0 if we just wanted to get all results and were willing to block until then */ cons.setBatchSize( 1 ); LDAPSearchResults res = ld.search( MY_SEARCHBASE, LDAPConnection.SCOPE_ONE, MY_FILTER, null, false, cons ); /* Loop on results until finished */ while ( res.hasMoreElements() ) { /* Next directory entry */ LDAPEntry findEntry = (LDAPEntry)res.nextElement(); System.out.println( findEntry.getDN() ); /* Get the attributes of the entry */ LDAPAttributeSet findAttrs = findEntry.getAttributeSet(); Enumeration enumAttrs = findAttrs.getAttributes(); System.out.println( "Attributes: " ); /* Loop on attributes */ while ( enumAttrs.hasMoreElements() ) { LDAPAttribute anAttr = (LDAPAttribute)enumAttrs.nextElement(); String attrName = anAttr.getName(); System.out.println( "" + attrName ); /* Loop on values for this attribute */ Enumeration enumVals = anAttr.getStringValues(); while ( enumVals.hasMoreElements() ) { String aVal = ( String )enumVals.nextElement(); System.out.println( "" + aVal ); } } Expires 10/97 [Page 44] JAVA LDAP API April 1997 } /* Done, so disconnect */ ld.disconnect(); } catch( LDAPException e ) { System.out.println( "Error: " + e.toString() ); } } } Expires 10/97 [Page 45]