/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package netscape.ldap; import java.util.*; import netscape.ldap.client.*; import netscape.ldap.client.opers.*; import netscape.ldap.ber.stream.*; import netscape.ldap.util.*; import java.io.*; import java.net.*; /** * Represents a connection to an LDAP server.
* * Use objects of this class to perform LDAP operations (such as * search, modify, and add) on an LDAP server.
* * To perform an LDAP operation on a server, you need to follow * these steps:
* *
LDAPConnection object.
* connect method to connect to the
* LDAP server.
* authenticate method to authenticate
* to server.
* disconnect method to disconnect from
* the server when done.
* * * All operations block until completion (with the exception of * the search method in which the results may not all return at * the same time). *
*
* This class also specifies a default set of constraints
* (such as the maximum length of time to allow for an operation before timing out)
* which apply to all operations. To get and set these constraints,
* use the getOption and setOption methods.
* To override these constraints for an individual operation,
* define a new set of constraints by creating a LDAPConstraints
* object and pass the object to the method for the operation. For search
* operations, additional constraints are defined in LDAPSearchConstraints
* (a subclass of LDAPConstraints). To override the default search
* constraints, create an LDAPSearchConstraints object and pass it
* to the search method.
*
*
* If you set up your client to follow referrals automatically,
* an operation that results in a referral will create a new connection
* to the LDAP server identified in the referral. In order to have
* your client authenticate to that LDAP server automatically, you need
* to define a class that implements the LDAPRebind interface.
* In your definition of the class, you need to define a
* getRebindAuthentication method that creates an LDAPRebindAuth
* object containing the distinguished name and password to use for reauthentication.
*
*
* Most errors that occur raise the same exception (LDAPException).
* In order to determine the exact problem that occurred, you can retrieve the
* result code from this exception and compare its value against a set of defined
* result codes.
*
*
* @version 1.0
* @see netscape.ldap.LDAPConstraints
* @see netscape.ldap.LDAPSearchConstraints
* @see netscape.ldap.LDAPRebind
* @see netscape.ldap.LDAPRebindAuth
* @see netscape.ldap.LDAPException
*/
public class LDAPConnection
implements LDAPv3, LDAPAsynchronousConnection, Cloneable, Serializable {
static final long serialVersionUID = -8698420087475771145L;
/**
* Version of the LDAP protocol used by default.
* LDAP_VERSION is 2, so your client will
* attempt to authenticate to LDAP servers as an LDAP v2 client.
* The following is an example of some code that prints the
* value of this variable:
*
* *
* LDAPConnection ld = new LDAPConnection();
* System.out.println( "The default LDAP protocol version used is "
* ld.LDAP_VERSION );
*
*
* If you want to authenticate as an LDAP v3 client,
* use the authenticate(int version, String dn, String passwd) method.
* For example:
* * *
* ld.authenticate( 3, myDN, myPW );
*
*
* @see netscape.ldap.LDAPConnection#authenticate(int, java.lang.String, java.lang.String)
*/
public final static int LDAP_VERSION = 2;
/**
* Name of the property specifying the version of the SDK.
*
* To get the version number, pass this name to the
* getProperty method. The SDK version number
* is of the type Float. For example:
*
* ...
* Float sdkVersion = ( Float )myConn.getProperty( myConn.LDAP_PROPERTY_SDK );
* System.out.println( "SDK version: " + sdkVersion );
* ...
* @see netscape.ldap.LDAPConnection#getProperty(java.lang.String)
*/
public final static String LDAP_PROPERTY_SDK = "version.sdk";
/**
* Name of the property specifying the highest supported version of
* the LDAP protocol.
*
* To get the version number, pass this name to the
* getProperty method. The LDAP protocol version number
* is of the type Float. For example:
*
* ...
* Float LDAPVersion = ( Float )myConn.getProperty( myConn.LDAP_PROPERTY_PROTOCOL );
* System.out.println( "Highest supported LDAP protocol version: " + LDAPVersion );
* ...
* @see netscape.ldap.LDAPConnection#getProperty(java.lang.String)
*/
public final static String LDAP_PROPERTY_PROTOCOL = "version.protocol";
/**
* Name of the property specifying the types of authentication allowed by this
* API (for example, anonymous authentication and simple authentication).
*
* To get the supported types, pass this name to the
* getProperty method. The value of this property is
* of the type String. For example:
*
* ...
* String authTypes = ( String )myConn.getProperty( myConn.LDAP_PROPERTY_SECURITY );
* System.out.println( "Supported authentication types: " + authTypes );
* ...
* @see netscape.ldap.LDAPConnection#getProperty(java.lang.String)
*/
public final static String LDAP_PROPERTY_SECURITY = "version.security";
/**
* Name of the property to enable/disable LDAP message trace.
*
* The property can be specified either as a system property
* (java -D command line option), or programmatically with the
* setProperty method.
*
* When -D command line option is used, defining the property with * no value will send the trace output to the standard error. If the * value is defined, it is assumed to be the name of an output file. * If the file name is prefixed with a '+' character, the file is * opened in append mode. *
* When the property is set with the getProperty method,
* the property value must be either a String (represents a file name)
* an OutputStream or an instance of LDAPTraceWriter. To stop tracing,
* null should be passed as the property value.
*
* @see netscape.ldap.LDAPConnection#setProperty(java.lang.String, java.lang.Object)
*/
public final static String TRACE_PROPERTY = "com.netscape.ldap.trace";
/**
* Specifies the serial connection setup policy when a list of hosts is
* passed to the connect method.
* @see netscape.ldap.LDAPConnection#setConnSetupDelay(int)
*/
public final static int NODELAY_SERIAL = -1;
/**
* Specifies the parallel connection setup policy with no delay when a
* list of hosts is passed to the connect method.
* For each host in the list, a separate thread is created to attempt
* to connect to the host. All threads are started simultaneously.
* @see netscape.ldap.LDAPConnection#setConnSetupDelay(int)
*/
public final static int NODELAY_PARALLEL = 0;
/**
* Constants
*/
private final static String defaultFilter = "(objectClass=*)";
/**
* Internal variables
*/
private LDAPSearchConstraints m_defaultConstraints =
new LDAPSearchConstraints();
// A clone of constraints for the successful bind. Used by
// "smart failover" for the automatic rebind
private LDAPConstraints m_rebindConstraints;
private Vector m_responseListeners;
private Vector m_searchListeners;
private String m_boundDN;
private String m_boundPasswd;
private int m_protocolVersion = LDAP_VERSION;
private LDAPConnSetupMgr m_connMgr;
private int m_connSetupDelay = -1;
private int m_connectTimeout = 0;
private LDAPSocketFactory m_factory;
// A flag if m_factory is used to start TLS
private boolean m_isTLSFactory;
/* m_thread does all socket i/o for the object and any clones */
private transient LDAPConnThread m_thread = null;
/* To manage received server controls on a per-thread basis */
private Hashtable m_responseControlTable = new Hashtable();
private LDAPCache m_cache = null;
// A flag set if startTLS() called successfully
private boolean m_useTLS;
// OID for the extended operation startTLS
final static String OID_startTLS = "1.3.6.1.4.1.1466.20037";
private Object m_security = null;
private LDAPSaslBind m_saslBinder = null;
private Properties m_securityProperties;
private Hashtable m_properties = new Hashtable();
private LDAPConnection m_referralConnection;
/**
* Properties
*/
private final static Float SdkVersion = new Float(4.18f);
private final static Float ProtocolVersion = new Float(3.0f);
private final static String SecurityVersion = new String("none,simple,sasl");
private final static Float MajorVersion = new Float(4.0f);
private final static Float MinorVersion = new Float(0.18f);
private final static String DELIM = "#";
private final static String PersistSearchPackageName =
"netscape.ldap.controls.LDAPPersistSearchControl";
final static String EXTERNAL_MECHANISM = "external";
private final static String EXTERNAL_MECHANISM_PACKAGE =
"com.netscape.sasl";
final static String DEFAULT_SASL_PACKAGE =
"com.netscape.sasl";
final static String SCHEMA_BUG_PROPERTY =
"com.netscape.ldap.schema.quoting";
final static String SASL_PACKAGE_PROPERTY =
"com.netscape.ldap.saslpackage";
/**
* Constructs a new LDAPConnection object,
* which represents a connection to an LDAP server.
*
* Calling the constructor does not actually establish
* the connection. To connect to the LDAP server, use the
* connect method.
*
* @see netscape.ldap.LDAPConnection#connect(java.lang.String, int)
* @see netscape.ldap.LDAPConnection#authenticate(java.lang.String, java.lang.String)
*/
public LDAPConnection () {
super();
m_factory = null;
m_properties.put(LDAP_PROPERTY_SDK, SdkVersion);
m_properties.put(LDAP_PROPERTY_PROTOCOL, ProtocolVersion);
m_properties.put(LDAP_PROPERTY_SECURITY, SecurityVersion);
m_properties.put("version.major", MajorVersion);
m_properties.put("version.minor", MinorVersion);
}
/**
* Constructs a new LDAPConnection object that
* will use the specified socket factory class to create
* socket connections. The socket factory class must implement
* the LDAPSocketFactory interface.
* (For example, the LDAPSSLSocketFactory
* class implements this interface.)
*
*
* Note that calling the LDAPConnection constructor
* does not actually establish a connection to an LDAP server.
* To connect to an LDAP server, use the
* connect method. The socket connection will be
* constructed when this method is called.
*
*
* @see netscape.ldap.LDAPSocketFactory
* @see netscape.ldap.LDAPSSLSocketFactory
* @see netscape.ldap.LDAPConnection#connect(java.lang.String, int)
* @see netscape.ldap.LDAPConnection#authenticate(java.lang.String, java.lang.String)
* @see netscape.ldap.LDAPConnection#getSocketFactory
* @see netscape.ldap.LDAPConnection#setSocketFactory(netscape.ldap.LDAPSocketFactory)
*/
public LDAPConnection ( LDAPSocketFactory factory ) {
this();
m_factory = factory;
}
/**
* Finalize method, which disconnects from the LDAP server.
* @exception LDAPException Thrown when the connection cannot be disconnected.
*/
public void finalize() throws LDAPException {
if (isConnected()) {
disconnect();
}
}
/**
* Sets the specified LDAPCache object as the
* cache for the LDAPConnection object.
*
*
* @param cache the LDAPCache object representing
* the cache that the current connection should use
* @see netscape.ldap.LDAPCache
* @see netscape.ldap.LDAPConnection#getCache
*/
public void setCache(LDAPCache cache) {
if (m_cache != null) {
m_cache.removeReference();
}
if (cache != null) {
cache.addReference();
}
m_cache = cache;
if ( m_thread != null ) {
m_thread.setCache( cache );
}
}
/**
* Gets the LDAPCache object associated with
* the current LDAPConnection object.
*
*
* @return the LDAPCache object representing
* the cache that the current connection should use
* @see netscape.ldap.LDAPCache
* @see netscape.ldap.LDAPConnection#setCache(netscape.ldap.LDAPCache)
*/
public LDAPCache getCache() {
return m_cache;
}
/**
* Gets a property of a connection.
* * You can get the following properties for a given connection:
*
LDAP_PROPERTY_SDK
* To get the version of this SDK, get this property. The value of
* this property is of the type Float.
*
LDAP_PROPERTY_PROTOCOL
* To get the highest supported version of the LDAP protocol, get
* this property.
* The value of this property is of the type Float.
*
LDAP_PROPERTY_SECURITY
* To get a comma-separated list of the types of authentication
* supported, get this property. The value of this property is of the
* type String.
*
* * For example, the following section of code gets the version of * the SDK.
* *
* ...
* Float sdkVersion = ( Float )myConn.getProperty( myConn.LDAP_PROPERTY_SDK );
* System.out.println( "SDK version: " + sdkVersion );
* ...
*
* @param name name of the property (for example, LDAP_PROPERTY_SDK) * * @return the value of the property.
*
* Since the return value is an object, you should recast it as the appropriate type.
* (For example, when getting the LDAP_PROPERTY_SDK property,
* recast the return value as a Float.)
* * If you pass this method an unknown property name, the method * returns null.
* * @exception LDAPException Unable to get the value of the * specified property.
* * @see netscape.ldap.LDAPConnection#LDAP_PROPERTY_SDK * @see netscape.ldap.LDAPConnection#LDAP_PROPERTY_PROTOCOL * @see netscape.ldap.LDAPConnection#LDAP_PROPERTY_SECURITY */ public Object getProperty(String name) throws LDAPException { return m_properties.get( name ); } /** * Change a property of a connection.
*
* The following properties are defined:
* com.netscape.ldap.schema.quoting - "standard" or "NetscapeBug"
* Note: if this property is not set, the SDK will query the server
* to determine if attribute syntax values and objectclass superior
* values must be quoted when adding schema.
* com.netscape.ldap.saslpackage - the default is "com.netscape.sasl"
*
* * @param name name of the property to set * @param val value to set * @exception LDAPException Unable to set the value of the specified * property. */ public void setProperty(String name, Object val) throws LDAPException { if ( name.equalsIgnoreCase( SCHEMA_BUG_PROPERTY ) ) { m_properties.put( SCHEMA_BUG_PROPERTY, val ); } else if ( name.equalsIgnoreCase( SASL_PACKAGE_PROPERTY ) ) { m_properties.put( SASL_PACKAGE_PROPERTY, val ); } else if ( name.equalsIgnoreCase( "debug" ) ) { debug = ((String)val).equalsIgnoreCase( "true" ); } else if ( name.equalsIgnoreCase( TRACE_PROPERTY ) ) { Object traceOutput = null; if (val == null) { m_properties.remove(TRACE_PROPERTY); } else { if (m_thread != null) { traceOutput = createTraceOutput(val); } m_properties.put( TRACE_PROPERTY, val ); } if (m_thread != null) { m_thread.setTraceOutput(traceOutput); } // This is used only by the ldapjdk test cases to simulate a // server problem and to test fail-over and rebind } else if ( name.equalsIgnoreCase( "breakConnection" ) ) { m_connMgr.breakConnection(); } else { throw new LDAPException("Unknown property: " + name); } } /** * Evaluate the TRACE_PROPERTY value and create output stream. * The value can be of type String, OutputStream or LDAPTraceWriter. * The String value represents output file name. If the name is an empty * string, the output is sent to System.err. If the file name is * prefixed with a '+' character, the file is opened in append mode. * * @param out Trace output specifier. A file name, an output stream * or an instance of LDAPTraceWriter * @return An output stream or an LDAPTraceWriter instance */ Object createTraceOutput(Object out) throws LDAPException { if (out instanceof String) { // trace file name OutputStream os = null; String file = (String)out; if (file.length() == 0) { os = System.err; } else { try { boolean appendMode = (file.charAt(0) == '+'); if (appendMode) { file = file.substring(1); } FileOutputStream fos = new FileOutputStream(file, appendMode); os = new BufferedOutputStream(fos); } catch (IOException e) { throw new LDAPException( "Can not open output trace file " + file + " " + e); } } return os; } else if (out instanceof OutputStream) { return out; } else if (out instanceof LDAPTraceWriter) { return out; } else { throw new LDAPException(TRACE_PROPERTY + " must be an OutputStream, a file name or an instance of LDAPTraceWriter" ); } } /** * Sets the LDAP protocol version that your client prefers to use when * connecting to the LDAP server. *
*
* @param version the LDAP protocol version that your client uses
*/
private void setProtocolVersion(int version) {
m_protocolVersion = version;
}
/**
* Returns the host name of the LDAP server to which you are connected.
* @return host name of the LDAP server.
*/
public String getHost () {
if (m_connMgr != null) {
return m_connMgr.getHost();
}
return null;
}
/**
* Returns the port number of the LDAP server to which you are connected.
* @return port number of the LDAP server.
*/
public int getPort () {
if (m_connMgr != null) {
return m_connMgr.getPort();
}
return -1;
}
/**
* Returns the distinguished name (DN) used for authentication over
* this connection.
* @return distinguished name used for authentication over this connection.
*/
public String getAuthenticationDN () {
return m_boundDN;
}
/**
* Returns the password used for authentication over this connection.
* @return password used for authentication over this connection.
*/
public String getAuthenticationPassword () {
return m_boundPasswd;
}
/**
* Returns the maximum time to wait for the connection to be established.
* @return the maximum connect time in seconds or 0 (unlimited)
* @see netscape.ldap.LDAPConnection#setConnectTimeout
*/
public int getConnectTimeout () {
return m_connectTimeout;
}
/**
* Specifies the maximum time to wait for the connection to be established.
* If the value is 0, the time is not limited.
* @param timeout the maximum connect time in seconds or 0 (unlimited)
*/
public void setConnectTimeout (int timeout) {
if (timeout < 0) {
throw new IllegalArgumentException("Timeout value can not be negative");
}
m_connectTimeout = timeout;
if (m_connMgr != null) {
m_connMgr.setConnectTimeout(m_connectTimeout);
}
}
/**
* Returns the delay in seconds when making concurrent connection attempts to
* multiple servers.
* @return the delay in seconds between connection attempts:
* NODELAY_SERIAL The serial connection setup policy is enabled
* (no concurrency).
* NODELAY_PARALLEL The parallel connection setup policy with no delay
* is enabled.
* delay > 0 The parallel connection setup policy with the delay of
* delay seconds is enabled.
* @see netscape.ldap.LDAPConnection#setConnSetupDelay
*/
public int getConnSetupDelay () {
return m_connSetupDelay;
}
/**
* Specifies the delay in seconds when making concurrent connection attempts to
* multiple servers.
*
Effectively, selects the connection setup policy when a list of hosts is passed
* to the connect method.
*
*
If the serial policy is selected, the default one, an attempt is made to
* connect to the first host in the list. The next entry in
* the list is tried only if the attempt to connect to the current host fails.
* This might cause your application to block for unacceptably long time if a host is down.
*
*
If the parallel policy is selected, multiple connection attempts may run
* concurrently on a separate thread. A new connection attempt to the next entry
* in the list can be started with or without delay.
*
You must set the ConnSetupDelay before making the call to the
* connect method.
*
* @param delay the delay in seconds between connection attempts. Possible values are:
* NODELAY_SERIAL Use the serial connection setup policy.
* NODELAY_PARALLEL Use the parallel connection setup policy with no delay.
* Start all connection setup threads immediately.
* delay > 0 Use the parallel connection setup policy with delay.
* Start another connection setup thread after delay seconds.
* @see netscape.ldap.LDAPConnection#NODELAY_SERIAL
* @see netscape.ldap.LDAPConnection#NODELAY_PARALLEL
* @see netscape.ldap.LDAPConnection#connect(java.lang.String, int)
*/
public void setConnSetupDelay (int delay) {
m_connSetupDelay = delay;
if (m_connMgr != null) {
m_connMgr.setConnSetupDelay(delay);
}
}
/**
* Gets the object representing the socket factory used to establish
* a connection to the LDAP server or for the start TLS operation.
*
* * @return the object representing the socket factory used to * establish a connection to a server or for the start TLS operation. * @see netscape.ldap.LDAPSocketFactory * @see netscape.ldap.LDAPSSLSocketFactory * @see netscape.ldap.LDAPConnection#setSocketFactory(netscape.ldap.LDAPSocketFactory) * @see netscape.ldap.LDAPConnection#startTLS */ public LDAPSocketFactory getSocketFactory () { return m_factory; } /** * Specifies the object representing the socket factory that you * want to use to establish a connection to a server or for the * start TLS operation. *
* If the socket factory is to be used to establish a connection
* setSocketFactory() must be called before
* connect(). For the start TLS operation
* setSocketFactory() must be called after connect().
* @param factory the object representing the socket factory that
* you want to use to establish a connection to a server or for
* the start TLS operation.
* @see netscape.ldap.LDAPSocketFactory
* @see netscape.ldap.LDAPSSLSocketFactory
* @see netscape.ldap.LDAPConnection#getSocketFactory
* @see netscape.ldap.LDAPConnection#startTLS
*/
public void setSocketFactory (LDAPSocketFactory factory) {
m_factory = factory;
m_isTLSFactory = false;
}
/**
* Indicates whether the connection represented by this object
* is open at this time.
* @return true if connected to an LDAP server over this connection.
* If not connected to an LDAP server, returns false.
*/
public synchronized boolean isConnected() {
return m_thread != null && m_thread.isConnected();
}
/**
* Indicates whether this client has authenticated to the LDAP server
* @return true,, if authenticated. If not
* authenticated, or if authenticated as an anonymous user (with
* either a blank name or password), returns false.
*/
public boolean isAuthenticated () {
boolean bound = false;
synchronized (this) {
bound = (m_thread != null) && m_thread.isBound();
}
return bound;
}
/**
* Mark the connection bind state
*/
synchronized void setBound(boolean bound) {
if (m_thread != null) {
if (!bound) {
m_thread.setBound(false);
}
// sasl bind
else if (m_saslBinder != null) {
m_thread.setBound(true);
}
// simple bind
else {
m_thread.setBound(!isAnonymousUser());
}
}
}
boolean isAnonymousUser() {
return (m_boundDN == null) || m_boundDN.equals("") ||
(m_boundPasswd == null) || m_boundPasswd.equals("");
}
/**
* 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.
*
* * For example, the following section of code establishes a connection with * the LDAP server running on the host ldap.netscape.com and the port 389. *
* *
* String ldapHost = "ldap.netscape.com";
* int ldapPort = 389;
* LDAPConnection myConn = new LDAPConnection();
* try {
* myConn.connect( ldapHost, ldapPort );
* } catch ( LDAPException e ) {
* System.out.println( "Unable to connect to " + ldapHost +
* " at port " + ldapPort );
* return;
* }
* System.out.println( "Connected to " + ldapHost + " at port " + ldapPort )
*
*
* You can limit the time spent waiting for the connection to be established
* by calling setConnectTimeout before connect.
*
* @param host host name of the LDAP server to which you want to connect.
* This value can also be a space-delimited list of hostnames or
* hostnames and port numbers (using the syntax
* hostname:portnumber). For example, you can specify
* the following values for the host argument:
*
* myhost
* myhost hishost:389 herhost:5000 whathost
* myhost:686 myhost:389 hishost:5000 whathost:1024
*
* If multiple servers are specified in the host list, the connection
* setup policy specified with the ConnSetupDelay property controls
* whether connection attempts are made serially or concurrently.
*
* @param port port number of the LDAP server to which you want to connect.
* This parameter is ignored for any host in the host
* parameter which includes a colon and port number.
* @exception LDAPException The connection failed.
* @see netscape.ldap.LDAPConnection#setConnSetupDelay
* @see netscape.ldap.LDAPConnection#setConnectTimeout
*/
public void connect(String host, int port) throws LDAPException {
connect( host, port, null, null, m_defaultConstraints, false );
}
/**
* 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.
*
* * For example, the following section of code establishes a connection * with the LDAP server running on ldap.netscape.com at port 389. The * example also attempts to authenticate the client as Barbara Jensen. *
* *
* String ldapHost = "ldap.netscape.com";
* int ldapPort = 389;
* String myDN = "cn=Barbara Jensen,ou=Product Development,o=Ace Industry,c=US";
* String myPW = "hifalutin";
* LDAPConnection myConn = new LDAPConnection();
* try {
* myConn.connect( ldapHost, ldapPort, myDN, myPW );
* } catch ( LDAPException e ) {
* switch( e.getLDAPResultCode() ) {
* case e.NO_SUCH_OBJECT:
* System.out.println( "The specified user does not exist." );
* break;
* case e.INVALID_CREDENTIALS:
* System.out.println( "Invalid password." );
* break;
* default:
* System.out.println( "Error number: " + e.getLDAPResultCode() );
* System.out.println( "Failed to connect to " + ldapHost + " at port " + ldapPort );
* break;
* }
* return;
* }
* System.out.println( "Connected to " + ldapHost + " at port " + ldapPort );
*
*
* You can limit the time spent waiting for the connection to be established
* by calling setConnectTimeout before connect.
*
* @param host host name of the LDAP server to which you want to connect.
* This value can also be a space-delimited list of hostnames or
* hostnames and port numbers (using the syntax
* hostname:portnumber). For example, you can specify
* the following values for the host argument:
*
* myhost
* myhost hishost:389 herhost:5000 whathost
* myhost:686 myhost:389 hishost:5000 whathost:1024
*
* If multiple servers are specified in the host list, the connection
* setup policy specified with the ConnSetupDelay property controls
* whether connection attempts are made serially or concurrently.
*
* @param port port number of the LDAP server to which you want to connect.
* This parameter is ignored for any host in the host
* parameter which includes a colon and port number.
* @param dn distinguished name used for authentication
* @param passwd password used for authentication
* @exception LDAPException The connection or authentication failed.
* @see netscape.ldap.LDAPConnection#setConnSetupDelay
* @see netscape.ldap.LDAPConnection#setConnectTimeout
*/
public void connect(String host, int port, String dn, String passwd)
throws LDAPException {
connect(host, port, dn, passwd, m_defaultConstraints, true);
}
/**
* 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 method allows the user to
* specify the preferences for the bind operation.
*
* You can limit the time spent waiting for the connection to be established
* by calling setConnectTimeout before connect.
*
* @param host host name of the LDAP server to which you want to connect.
* This value can also be a space-delimited list of hostnames or
* hostnames and port numbers (using the syntax
* hostname:portnumber). For example, you can specify
* the following values for the host argument:
*
* myhost
* myhost hishost:389 herhost:5000 whathost
* myhost:686 myhost:389 hishost:5000 whathost:1024
*
* If multiple servers are specified in the host list, the connection
* setup policy specified with the ConnSetupDelay property controls
* whether connection attempts are made serially or concurrently.
*
* @param port port number of the LDAP server to which you want to connect.
* This parameter is ignored for any host in the host
* parameter which includes a colon and port number.
* @param dn distinguished name used for authentication
* @param passwd password used for authentication
* @param cons preferences for the bind operation
* @exception LDAPException The connection or authentication failed.
* @see netscape.ldap.LDAPConnection#setConnSetupDelay
* @see netscape.ldap.LDAPConnection#setConnectTimeout
*/
public void connect(String host, int port, String dn, String passwd,
LDAPConstraints cons) throws LDAPException {
connect(host, port, dn, passwd, cons, true);
}
/**
* @deprecated Please use the method signature where cons is
* LDAPConstraints instead of LDAPSearchConstraints
*/
public void connect(String host, int port, String dn, String passwd,
LDAPSearchConstraints cons) throws LDAPException {
connect(host, port, dn, passwd, (LDAPConstraints)cons);
}
private void connect(String host, int port, String dn, String passwd,
LDAPConstraints cons, boolean doAuthenticate)
throws LDAPException {
if ( isConnected() ) {
disconnect ();
}
if ((host == null) || (host.equals(""))) {
throw new LDAPException ( "no host for connection",
LDAPException.PARAM_ERROR );
}
/* Parse the list of hosts */
int defaultPort = port;
StringTokenizer st = new StringTokenizer( host );
String hostList[] = new String[st.countTokens()];
int portList[] = new int[st.countTokens()];
int i = 0;
while( st.hasMoreTokens() ) {
String s = st.nextToken();
int colon = s.indexOf( ':' );
if ( colon > 0 ) {
hostList[i] = s.substring( 0, colon );
portList[i] = Integer.parseInt( s.substring( colon+1 ) );
} else {
hostList[i] = s;
portList[i] = defaultPort;
}
i++;
}
/* Create the Connection Setup Manager */
m_connMgr = new LDAPConnSetupMgr(hostList, portList,
m_isTLSFactory ? null : m_factory);
m_connMgr.setConnSetupDelay(m_connSetupDelay);
m_connMgr.setConnectTimeout(m_connectTimeout);
connect();
if (doAuthenticate) {
authenticate(dn, passwd, cons);
}
}
void connect(LDAPUrl[] urls) throws LDAPException {
m_connMgr = new LDAPConnSetupMgr(urls, m_factory);
m_connMgr.setConnSetupDelay(m_connSetupDelay);
m_connMgr.setConnectTimeout(m_connectTimeout);
connect();
}
/**
* Connects to the specified host and port and uses the specified DN and
* password to authenticate to the server, with the specified LDAP
* protocol version. If the server does not support the requested
* protocol version, an exception is thrown. 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(version, dn, passwd).
*
* @param version requested version of LDAP: currently 2 or 3
* @param host a hostname to which to connect or a dotted string representing
* the IP address of this host.
* Alternatively, this can be a space-delimited list of host names.
* Each host name may include a trailing colon and port number. In the
* case where more than one host name is specified, the connection setup
* policy specified with the ConnSetupDelay property controls
* whether connection attempts are made serially or concurrently.
* *
* Examples:
* "directory.knowledge.com"
* "199.254.1.2"
* "directory.knowledge.com:1050 people.catalog.com 199.254.1.2"
*
* @param port the TCP or UDP port number to which to connect or contact.
* The default LDAP port is 389. "port" is ignored for any host name which
* includes a colon and port number.
* @param dn if non-null and non-empty, specifies that the connection and
* all operations through it should authenticate with dn as the
* distinguished name
* @param passwd if non-null and non-empty, specifies that the connection and
* all operations through it should authenticate with dn as the
* distinguished name and passwd as password.
* @exception LDAPException The connection or authentication failed.
* @see netscape.ldap.LDAPConnection#setConnSetupDelay
*/
public void connect(int version, String host, int port, String dn,
String passwd) throws LDAPException {
connect(version, host, port, dn, passwd, m_defaultConstraints);
}
/**
* Connects to the specified host and port and uses the specified DN and
* password to authenticate to the server, with the specified LDAP
* protocol version. If the server does not support the requested
* protocol version, an exception is thrown. This method allows the user
* to specify preferences for the bind operation. 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(version, dn, passwd).
*
* @param version requested version of LDAP: currently 2 or 3
* @param host a hostname to which to connect or a dotted string representing
* the IP address of this host.
* Alternatively, this can be a space-delimited list of host names.
* Each host name may include a trailing colon and port number. In the
* case where more than one host name is specified, the connection setup
* policy specified with the ConnSetupDelay property controls
* whether connection attempts are made serially or concurrently.
* *
* Examples:
* "directory.knowledge.com"
* "199.254.1.2"
* "directory.knowledge.com:1050 people.catalog.com 199.254.1.2"
*
* @param port the TCP or UDP port number to which to connect or contact.
* The default LDAP port is 389. "port" is ignored for any host name which
* includes a colon and port number.
* @param dn if non-null and non-empty, specifies that the connection and
* all operations through it should authenticate with dn as the
* distinguished name
* @param passwd if non-null and non-empty, specifies that the connection and
* all operations through it should authenticate with dn as the
* distinguished name and passwd as password
* @param cons preferences for the bind operation
* @exception LDAPException The connection or authentication failed.
* @see netscape.ldap.LDAPConnection#setConnSetupDelay
*/
public void connect(int version, String host, int port, String dn,
String passwd, LDAPConstraints cons) throws LDAPException {
setProtocolVersion(version);
connect(host, port, dn, passwd, cons);
}
/**
* @deprecated Please use the method signature where cons is
* LDAPConstraints instead of LDAPSearchConstraints
*/
public void connect(int version, String host, int port, String dn,
String passwd, LDAPSearchConstraints cons) throws LDAPException {
connect(version, host, port, dn, passwd, (LDAPConstraints)cons);
}
/**
* Internal routine to connect with internal params
* @exception LDAPException failed to connect
*/
private synchronized void connect () throws LDAPException {
if ( isConnected() ) {
return;
}
if (m_connMgr == null) {
throw new LDAPException ( "no connection parameters",
LDAPException.PARAM_ERROR );
}
if (m_thread == null) {
m_thread = new LDAPConnThread(m_connMgr, m_cache, getTraceOutput());
}
m_thread.connect(this);
checkClientAuth();
}
/**
* Returns the trace output object if set by the user
*/
Object getTraceOutput() throws LDAPException {
// Check first if trace output has been set using setProperty()
Object traceOut = m_properties.get(TRACE_PROPERTY);
if (traceOut != null) {
return createTraceOutput(traceOut);
}
// Check if the property has been set with java -Dcom.netscape.ldap.trace
// If the property does not have a value, send the trace to the System.err,
// otherwise use the value as the output file name
try {
traceOut = System.getProperty(TRACE_PROPERTY);
if (traceOut != null) {
return createTraceOutput(traceOut);
}
}
catch (Exception e) {
;// In browser access to property might not be allowed
}
return null;
}
/**
* Performs certificate-based authentication if client authentication was
* specified at construction time.
* @exception LDAPException if certificate-based authentication fails.
*/
private void checkClientAuth() throws LDAPException {
// if this is SSL
if ((m_factory != null) &&
(m_factory instanceof LDAPSSLSocketFactoryExt)) {
if (((LDAPSSLSocketFactoryExt)m_factory).isClientAuth()) {
authenticate(null, EXTERNAL_MECHANISM,
EXTERNAL_MECHANISM_PACKAGE, null, null);
}
}
}
/**
* Abandons a current search operation, notifying the server not
* to send additional search results.
*
* @param searchResults the search results returned when the search
* was started
* @exception LDAPException Failed to notify the LDAP server.
* @see netscape.ldap.LDAPConnection#search(java.lang.String, int, java.lang.String, java.lang.String[], boolean, netscape.ldap.LDAPSearchConstraints)
* @see netscape.ldap.LDAPSearchResults
*/
public void abandon( LDAPSearchResults searchResults )
throws LDAPException {
if ( (!isConnected()) || (searchResults == null) ) {
return;
}
int id = searchResults.getMessageID();
if ( id != -1 ) {
abandon( id );
}
}
/**
* Authenticates to the LDAP server (to which you are currently
* connected) using the specified name and password.
* If you are not connected to the LDAP server, this
* method attempts to reconnect to the server.
* * * For example, the following section of code authenticates the * client as Barbara Jensen. The code assumes that the client * has already established a connection with an LDAP server. *
* *
* String myDN = "cn=Barbara Jensen,ou=Product Development,o=Ace Industry,c=US";
* String myPW = "hifalutin";
* try {
* myConn.authenticate( myDN, myPW );
* } catch ( LDAPException e ) {
* switch( e.getLDAPResultCode() ) {
* case e.NO_SUCH_OBJECT:
* System.out.println( "The specified user does not exist." );
* break;
* case e.INVALID_CREDENTIALS:
* System.out.println( "Invalid password." );
* break;
* default:
* System.out.println( "Error number: " + e.getLDAPResultCode() );
* System.out.println( "Failed to authentice as " + myDN );
* break;
* }
* return;
* }
* System.out.println( "Authenticated as " + myDN );
*
*
* @param dn distinguished name used for authentication
* @param passwd password used for authentication
* @exception LDAPException Failed to authenticate to the LDAP server.
*/
public void authenticate(String dn, String passwd) throws LDAPException {
authenticate(m_protocolVersion, dn, passwd, m_defaultConstraints);
}
/**
* Authenticates to the LDAP server (to which you are currently
* connected) using the specified name and password. The
* default protocol version (version 2) is used. If the server
* doesn't support the default version, an LDAPException is thrown
* with the error code PROTOCOL_ERROR. This method allows the
* user to specify the preferences for the bind operation.
*
* @param dn distinguished name used for authentication
* @param passwd password used for authentication
* @param cons preferences for the bind operation
* @exception LDAPException Failed to authenticate to the LDAP server.
*/
public void authenticate(String dn, String passwd,
LDAPConstraints cons) throws LDAPException {
authenticate(m_protocolVersion, dn, passwd, cons);
}
/**
* @deprecated Please use the method signature where cons is
* LDAPConstraints instead of LDAPSearchConstraints
*/
public void authenticate(String dn, String passwd,
LDAPSearchConstraints cons) throws LDAPException {
authenticate(dn, passwd, (LDAPConstraints)cons);
}
/**
* Authenticates to the LDAP server (that you are currently
* connected to) using the specified name and password, and
* requesting that the server use at least the specified
* protocol version. If the server doesn't support that
* level, an LDAPException is thrown with the error code
* PROTOCOL_ERROR.
*
* @param version required LDAP protocol version
* @param dn distinguished name used for authentication
* @param passwd password used for authentication
* @exception LDAPException Failed to authenticate to the LDAP server.
*/
public void authenticate(int version, String dn, String passwd)
throws LDAPException {
authenticate(version, dn, passwd, m_defaultConstraints);
}
/**
* Authenticates to the LDAP server (to which you are currently
* connected) using the specified name and password, and
* requesting that the server use at least the specified
* protocol version. If the server doesn't support that
* level, an LDAPException is thrown with the error code
* PROTOCOL_ERROR. This method allows the user to specify the
* preferences for the bind operation.
*
* @param version required LDAP protocol version
* @param dn distinguished name used for authentication
* @param passwd password used for authentication
* @param cons preferences for the bind operation
* @exception LDAPException Failed to authenticate to the LDAP server.
*/
public void authenticate(int version, String dn, String passwd,
LDAPConstraints cons) throws LDAPException {
m_protocolVersion = version;
m_boundDN = dn;
m_boundPasswd = passwd;
forceNonSharedConnection();
simpleBind(cons);
}
/**
* @deprecated Please use the method signature where cons is
* LDAPConstraints instead of LDAPSearchConstraints
*/
public void authenticate(int version, String dn, String passwd,
LDAPSearchConstraints cons) throws LDAPException {
authenticate(version, dn, passwd, (LDAPConstraints)cons);
}
/**
* Authenticates to the LDAP server (that the object is currently
* connected to) using the specified name and whatever SASL mechanisms
* are supported by the server. Each supported mechanism in turn
* is tried until authentication succeeds or an exception is thrown.
* If the object has been disconnected from an LDAP server, this
* method attempts to reconnect to the server. If the object had
* already authenticated, the old authentication is discarded.
*
* @param dn if non-null and non-empty, specifies that the connection and
* all operations through it should authenticate with dn as the
* distinguished name
* @param cbh a class which the SASL framework can call to obtain
* additional required information
* @exception LDAPException Failed to authenticate to the LDAP server.
*/
public void authenticate(String dn, Hashtable props,
/*CallbackHandler*/ Object cbh)
throws LDAPException {
// Get the list of mechanisms from the server
String[] attrs = { "supportedSaslMechanisms" };
LDAPEntry entry = read( "", attrs );
LDAPAttribute attr = entry.getAttribute( attrs[0] );
if ( attr == null ) {
throw new LDAPException( "Not found in root DSE: " +
attrs[0],
LDAPException.NO_SUCH_ATTRIBUTE );
}
authenticate( dn, attr.getStringValueArray(), props, cbh );
}
/**
* Authenticates to the LDAP server (to which the object is currently
* connected) using the specified name and a specified SASL mechanism
* or set of mechanisms. If the requested SASL mechanism is not
* available, an exception is thrown. If the object has been
* disconnected from an LDAP server, this method attempts to reconnect
* to the server. If the object had already authenticated, the old
* authentication is discarded.
*
* @param dn if non-null and non-empty, specifies that the connection and
* all operations through it should authenticate with dn as the
* distinguished name
* @param mechanisms a list of acceptable mechanisms. The first one
* for which a Mechanism Driver can be instantiated is returned.
* @param cbh a class which the SASL framework can call to
* obtain additional required information
* @exception LDAPException Failed to authenticate to the LDAP server.
* @see netscape.ldap.LDAPConnection#authenticate(java.lang.String,
* java.util.Hashtable, java.lang.Object)
*/
public void authenticate(String dn, String[] mechanisms,
Hashtable props, /*CallbackHandler*/ Object cbh)
throws LDAPException {
authenticate( dn, mechanisms, DEFAULT_SASL_PACKAGE, props, cbh );
}
/**
* Authenticates to the LDAP server (to which the object is currently
* connected) using the specified name and a specified SASL mechanism
* or set of mechanisms. If the requested SASL mechanism is not
* available, an exception is thrown. If the object has been
* disconnected from an LDAP server, this method attempts to reconnect
* to the server. If the object had already authenticated, the old
* authentication is discarded.
*
* @param dn if non-null and non-empty, specifies that the connection and
* all operations through it should authenticate with dn as the
* distinguished name
* @param mechanism a single mechanism name, e.g. "GSSAPI"
* @param packageName a package containing a SASL ClientFactory,
* e.g. "myclasses.SASL". If null, a system default is used.
* @param cbh a class which the SASL framework can call to
* obtain additional required information
* @exception LDAPException Failed to authenticate to the LDAP server.
* @deprecated Please use authenticate without packageName
* instead.
*/
public void authenticate(String dn, String mechanism, String packageName,
Hashtable props, /*CallbackHandler*/ Object cbh)
throws LDAPException {
authenticate( dn, new String[] {mechanism}, packageName, props, cbh );
}
/**
* Authenticates to the LDAP server (to which the object is currently
* connected) using the specified name and a specified SASL mechanism
* or set of mechanisms. If the requested SASL mechanism is not
* available, an exception is thrown. If the object has been
* disconnected from an LDAP server, this method attempts to reconnect
* to the server. If the object had already authenticated, the old
* authentication is discarded.
*
* @param dn if non-null and non-empty, specifies that the connection and
* all operations through it should authenticate with dn as the
* distinguished name
* @param mechanisms a list of acceptable mechanisms. The first one
* for which a Mechanism Driver can be instantiated is returned.
* @param packageName a package containing a SASL ClientFactory,
* e.g. "myclasses.SASL". If null, a system default is used.
* @param cbh a class which the SASL framework can call to
* obtain additional required information
* @exception LDAPException Failed to authenticate to the LDAP server.
* @deprecated Please use authenticate without packageName
* instead.
*/
public void authenticate(String dn, String[] mechanisms,
String packageName,
Hashtable props, /*CallbackHandler*/ Object cbh)
throws LDAPException {
forceNonSharedConnection();
m_boundDN = null;
m_protocolVersion = 3; // Must be 3 for SASL
if ( props == null ) {
props = new Hashtable();
}
m_saslBinder = new LDAPSaslBind( dn, mechanisms, packageName,
props, cbh );
m_saslBinder.bind( this );
m_boundDN = dn;
}
/**
* Authenticates to the LDAP server (that the object is currently
* connected to) using the specified name and password and allows you
* to specify constraints for this LDAP add operation by using an
* LDAPConstraints object. If the object
* has been disconnected from an LDAP server, this method attempts to
* reconnect to the server. If the object had already authenticated, the
* old authentication is discarded.
*
* @param version Required LDAP protocol version.
* @param dn If non-null and non-empty, specifies that the connection
* and all operations through it should be authenticated with dn as the
* distinguished name.
* @param passwd If non-null and non-empty, specifies that the connection
* and all operations through it should be authenticated with dn as the
* distinguished name and passwd as password.
* @param listener Handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @param cons Constraints specific to the operation.
* @return LDAPResponseListener Handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPResponseListener
* @see netscape.ldap.LDAPConstraints
*/
public LDAPResponseListener authenticate(int version,
String dn,
String passwd,
LDAPResponseListener listener,
LDAPConstraints cons)
throws LDAPException{
if (cons == null) {
cons = m_defaultConstraints;
}
m_boundDN = dn;
m_boundPasswd = passwd;
m_protocolVersion = version;
forceNonSharedConnection();
if (listener == null) {
listener = new LDAPResponseListener(/*asynchOp=*/true);
}
sendRequest(new JDAPBindRequest(version, m_boundDN, m_boundPasswd),
listener, cons);
return listener;
}
/**
* Authenticates to the LDAP server (that the object is currently
* connected to) using the specified name and password and allows you
* to specify constraints for this LDAP add operation by using an
* LDAPConstraints object. If the object
* has been disconnected from an LDAP server, this method attempts to
* reconnect to the server. If the object had already authenticated, the
* old authentication is discarded.
*
* @param version Required LDAP protocol version.
* @param dn If non-null and non-empty, specifies that the connection
* and all operations through it should be authenticated with dn as the
* distinguished name.
* @param passwd If non-null and non-empty, specifies that the connection
* and all operations through it should be authenticated with dn as the
* distinguished name and passwd as password.
* @param listener Handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @return LDAPResponseListener Handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPResponseListener
* @see netscape.ldap.LDAPConstraints
*/
public LDAPResponseListener authenticate(int version,
String dn,
String passwd,
LDAPResponseListener listener)
throws LDAPException{
return authenticate( version, dn, passwd, listener, m_defaultConstraints );
}
/**
* Authenticates to the LDAP server (to which you are currently
* connected) using the specified name and password.
* If you are not already connected to the LDAP server, this
* method attempts to reconnect to the server.
* * * For example, the following section of code authenticates the * client as Barbara Jensen. The code assumes that the client * has already established a connection with an LDAP server. *
* *
* String myDN = "cn=Barbara Jensen,ou=Product Development,o=Ace Industry,c=US";
* String myPW = "hifalutin";
* try {
* myConn.bind( myDN, myPW );
* } catch ( LDAPException e ) {
* switch( e.getLDAPResultCode() ) {
* case e.NO_SUCH_OBJECT:
* System.out.println( "The specified user does not exist." );
* break;
* case e.INVALID_CREDENTIALS:
* System.out.println( "Invalid password." );
* break;
* default:
* System.out.println( "Error number: " + e.getLDAPResultCode() );
* System.out.println( "Failed to authentice as " + myDN );
* break;
* }
* return;
* }
* System.out.println( "Authenticated as " + myDN );
*
*
* @param dn distinguished name used for authentication
* @param passwd password used for authentication
* @exception LDAPException Failed to authenticate to the LDAP server.
*/
public void bind(String dn, String passwd) throws LDAPException {
authenticate(m_protocolVersion, dn, passwd, m_defaultConstraints);
}
/**
* Authenticates to the LDAP server (to which you are currently
* connected) using the specified name and password. The
* default protocol version (version 2) is used. If the server
* doesn't support the default version, an LDAPException is thrown
* with the error code PROTOCOL_ERROR. This method allows the
* user to specify the preferences for the bind operation.
*
* @param dn distinguished name used for authentication
* @param passwd password used for authentication
* @param cons preferences for the bind operation
* @exception LDAPException Failed to authenticate to the LDAP server.
*/
public void bind(String dn, String passwd,
LDAPConstraints cons) throws LDAPException {
authenticate(m_protocolVersion, dn, passwd, cons);
}
/**
* Authenticates to the LDAP server (to which you are currently
* connected) using the specified name and password, and
* requests that the server use at least the specified
* protocol version. If the server doesn't support that
* level, an LDAPException is thrown with the error code
* PROTOCOL_ERROR.
*
* @param version required LDAP protocol version
* @param dn distinguished name used for authentication
* @param passwd password used for authentication
* @exception LDAPException Failed to authenticate to the LDAP server.
*/
public void bind(int version, String dn, String passwd)
throws LDAPException {
authenticate(version, dn, passwd, m_defaultConstraints);
}
/**
* Authenticates to the LDAP server (to which you are currently
* connected) using the specified name and password, and
* requesting that the server use at least the specified
* protocol version. If the server doesn't support that
* level, an LDAPException is thrown with the error code
* PROTOCOL_ERROR. This method allows the user to specify the
* preferences for the bind operation.
*
* @param version required LDAP protocol version
* @param dn distinguished name used for authentication
* @param passwd password used for authentication
* @param cons preferences for the bind operation
* @exception LDAPException Failed to authenticate to the LDAP server.
*/
public void bind(int version, String dn, String passwd,
LDAPConstraints cons) throws LDAPException {
authenticate(version, dn, passwd, cons);
}
/**
* Authenticates to the LDAP server (to which the object is currently
* connected) using the specified name and whatever SASL mechanisms
* are supported by the server. Each supported mechanism in turn
* is tried until authentication succeeds or an exception is thrown.
* If the object has been disconnected from an LDAP server, this
* method attempts to reconnect to the server. If the object had
* already authenticated, the old authentication is discarded.
*
* @param dn if non-null and non-empty, specifies that the connection and
* all operations through it should authenticate with dn as the
* distinguished name
* @param cbh a class which the SASL framework can call to
* obtain additional required information
* @exception LDAPException Failed to authenticate to the LDAP server.
*/
public void bind(String dn, Hashtable props,
/*CallbackHandler*/ Object cbh)
throws LDAPException {
authenticate(dn, props, cbh);
}
/**
* Authenticates to the LDAP server (to which the object is currently
* connected) using the specified name and a specified SASL mechanism
* or set of mechanisms. If the requested SASL mechanism is not
* available, an exception is thrown. If the object has been
* disconnected from an LDAP server, this method attempts to reconnect
* to the server. If the object had already authenticated, the old
* authentication is discarded.
*
* @param dn if non-null and non-empty, specifies that the connection and
* all operations through it should authenticate with dn as the
* distinguished name
* @param mechanisms a list of acceptable mechanisms. The first one
* for which a Mechanism Driver can be instantiated is returned.
* @param cbh a class which the SASL framework can call to
* obtain additional required information
* @exception LDAPException Failed to authenticate to the LDAP server.
* @see netscape.ldap.LDAPConnection#bind(java.lang.String,
* java.util.Hashtable, java.lang.Object)
*/
public void bind(String dn, String[] mechanisms,
Hashtable props, /*CallbackHandler*/ Object cbh)
throws LDAPException {
authenticate(dn, mechanisms, props, cbh);
}
/**
* Begin using the Transport Layer Security (TLS) protocol for session
* privacy.
*
* Before startTLS() is called, a socket factory of type
* LDAPTLSSocketFactory must be set for the connection.
* The factory must be set after the connect() call.
*
*
* LDAPConnection ldc = new LDAPConnection();
* try {
* ldc.connect(host, port);
* ldc.setSocketFactory(new JSSSocketFactory());
* ldc.startTLS();
* ldc.autheticate(3, userdn, userpw);
* }
* catch (LDAPException e) {
* ...
* }
*
* * If the socket factory of the connection is not capable of initiating a * TLS session , an LDAPException is thrown with the error code * TLS_NOT_SUPPORTED. *
* If the server does not support the transition to a TLS session, an
* LDAPException is thrown with the error code returned by the server.
* If there are outstanding LDAP operations on the connection or the
* connection is already in the secure mode, an LDAPException is thrown.
*
* @exception LDAPException Failed to convert to a TLS session.
* @see netscape.ldap.LDAPTLSSocketFactory
* @see netscape.ldap.LDAPConnection#setSocketFactory(netscape.ldap.LDAPSocketFactory)
* @see netscape.ldap.LDAPConnection#isTLS
* @since LDAPJDK 4.17
*/
public void startTLS() throws LDAPException {
if (m_useTLS) {
throw new LDAPException("Already using TLS",
LDAPException.OTHER);
}
if (m_factory == null || !( m_factory instanceof LDAPTLSSocketFactory)) {
throw new LDAPException("No socket factory for the startTLS operation",
LDAPException.OTHER);
}
// Denote that m_factory is to be used from now on used for TLS and not for
// SSL connections.
m_isTLSFactory = true;
checkConnection(/*rebind=*/true);
// If some requests still in progress, throw exception
synchronized (this) {
if (isConnected() && m_thread.getRequestCount() != 0) {
throw new LDAPException(
"Connection has outstanding LDAP operations",
LDAPException.OTHER);
}
}
// Send startTLS extended op
try {
LDAPExtendedOperation response =
extendedOperation(new LDAPExtendedOperation(OID_startTLS, null),
m_defaultConstraints);
}
catch (LDAPException ex) {
ex.setExtraMessage("Cannot start TLS");
throw ex;
}
/**
* Server accepted startTLS request, try to initiate TLS over the
* current socket.
*/
try {
m_thread.layerSocket((LDAPTLSSocketFactory)m_factory);
m_useTLS = true;
}
catch (LDAPException ex) {
ex.setExtraMessage("Failed to start TLS");
throw ex;
}
catch (Exception ex) {
throw new LDAPException("Failed to start TLS",
LDAPException.OTHER);
}
}
/**
* Indicates if the session is currently protected by TLS.
* @return true if TLS was activated.
* @since LDAPJDK 4.17
* @see netscape.ldap.LDAPConnection#startTLS
*/
public boolean isTLS() {
return m_useTLS;
}
/**
* If this connection is cloned (the physical connection is shared),
* create a new physical connection.
*/
void forceNonSharedConnection() throws LDAPException{
checkConnection(/*rebind=*/false);
if (m_thread != null && m_thread.getClientCount() > 1) {
reconnect(/*rebind=*/false);
}
}
/**
* Internal routine. Binds to the LDAP server.
* @exception LDAPException failed to bind
*/
private void simpleBind (LDAPConstraints cons) throws LDAPException {
m_saslBinder = null;
LDAPResponseListener myListener = new LDAPResponseListener ( /*asynchOp=*/false );
try {
if (m_referralConnection != null && m_referralConnection.isConnected()) {
m_referralConnection.disconnect();
}
m_referralConnection = null;
setBound(false);
sendRequest(new JDAPBindRequest(m_protocolVersion, m_boundDN,
m_boundPasswd),
myListener, cons);
checkMsg( myListener.getResponse() );
setBound(true);
m_rebindConstraints = (LDAPConstraints)cons.clone();
} catch (LDAPReferralException e) {
m_referralConnection = createReferralConnection(e, cons);
}
}
/**
* Send a request to the server
*/
synchronized void sendRequest(JDAPProtocolOp oper, LDAPMessageQueue myListener,
LDAPConstraints cons) throws LDAPException {
boolean requestSent=false;
boolean restoreTried=false;
while (!requestSent) {
try {
m_thread.sendRequest(this, oper, myListener, cons);
/**
* In Java, a lost socket connected is often not detected until
* a read is attempted following a write. Wait for the response
* from the server to be sure the connection is really there.
*/
if (!myListener.isAsynchOp()) {
myListener.waitFirstMessage();
}
requestSent=true;
}
catch (IllegalArgumentException e) {
throw new LDAPException(e.getMessage(), LDAPException.PARAM_ERROR);
}
catch(NullPointerException e) {
if (isConnected() || restoreTried) {
break; // give up
}
// else try to restore the connection
}
catch (LDAPException e) {
if (e.getLDAPResultCode() != e.SERVER_DOWN || restoreTried) {
throw e; // give up
}
// else try to restore the connection
}
// Try to restore the connection if needed, but no more then once
if (!requestSent && !restoreTried) {
restoreTried = true;
myListener.reset();
boolean rebind = !(oper instanceof JDAPBindRequest);
restoreConnection(rebind);
}
}
if (!requestSent) {
throw new LDAPException("Failed to send request",
LDAPException.OTHER);
}
}
/**
* Check and restore the connection if needed.
* This method is used by the "smart failover" feature. If a server
* or network error has occurred, an attempt is made to automatically
* restore the connection on the next ldap operation request
* @param rebind true if needs rebind after reconnect
*/
private void checkConnection(boolean rebind) throws LDAPException {
if (isConnected()) {
return;
}
// If the user has invoked disconnect() no attempt is made
// to restore the connection
if (m_connMgr == null) {
throw new LDAPException("not connected", LDAPException.OTHER);
}
restoreConnection(rebind);
}
/**
* Reconnect and reauthenticate
*/
private void restoreConnection(boolean rebind) throws LDAPException {
connect();
if (m_useTLS) {
m_useTLS = false;
startTLS();
}
if (!rebind) {
return;
}
if (m_saslBinder != null) {
m_saslBinder.bind(this, false);
}
else if (m_rebindConstraints != null) {
//Needs bind
simpleBind(m_rebindConstraints);
}
}
/**
* Gets the authentication method used to bind:
* "none", "simple", or "sasl"
*
* @return the authentication method, or "none"
*/
public String getAuthenticationMethod() {
if (!isAuthenticated()) {
return "none";
}
else {
return (m_saslBinder == null) ? "simple" : "sasl";
}
}
/**
* Disconnect from the server and then reconnect using the current
* credentials and authentication method.
* If TLS was enabled with the startTLS() call, reenable TLS after
* reconnect.
* @exception LDAPException if not previously connected, or if
* there is a failure on disconnecting or on connecting
*/
public void reconnect() throws LDAPException {
reconnect(/*rebind=*/true);
}
void reconnect(boolean rebind) throws LDAPException {
// Save connect parameters that get cleared by disconnect()
boolean useTLS = m_useTLS;
LDAPConnSetupMgr connMgr = m_connMgr;
LDAPConstraints rebindCons = m_rebindConstraints;
disconnect();
m_useTLS = useTLS;
m_connMgr = connMgr;
m_rebindConstraints = rebindCons;
restoreConnection(rebind);
}
/**
* Disconnects from the LDAP server. Before you can perform LDAP operations
* again, you need to reconnect to the server by calling
* connect.
* @exception LDAPException Failed to disconnect from the LDAP server.
* @see netscape.ldap.LDAPConnection#connect(java.lang.String, int)
* @see netscape.ldap.LDAPConnection#connect(java.lang.String, int, java.lang.String, java.lang.String)
*/
public synchronized void disconnect() throws LDAPException {
if (!isConnected()) {
return;
}
m_thread.deregister(this);
if (m_referralConnection != null && m_referralConnection.isConnected()) {
m_referralConnection.disconnect();
}
m_referralConnection = null;
if (m_cache != null) {
m_cache.removeReference();
m_cache = null;
}
m_responseControlTable.clear();
m_rebindConstraints = null;
m_thread = null;
m_connMgr = null;
m_useTLS = false;
}
/**
* Reads the entry for the specified distiguished name (DN) and retrieves all
* attributes for the entry.
*
* * For example, the following section of code reads the entry for * Barbara Jensen and retrieves all attributes for that entry. *
* *
* String findDN = "cn=Barbara Jensen,ou=Product Development,o=Ace Industry,c=US";
* LDAPEntry foundEntry = null;
* try {
* foundEntry = myConn.read( findDN );
* } catch ( LDAPException e ) {
* switch( e.getLDAPResultCode() ) {
* case e.NO_SUCH_OBJECT:
* System.out.println( "The specified entry does not exist." );
* break;
* case e.LDAP_PARTIAL_RESULTS:
* System.out.println( "Entry served by a different LDAP server." );
* break;
* case e.INSUFFICIENT_ACCESS_RIGHTS:
* System.out.println( "You do not have the access rights to perform this operation." );
* break;
* default:
* System.out.println( "Error number: " + e.getLDAPResultCode() );
* System.out.println( "Could not read the specified entry." );
* break;
* }
* return;
* }
* System.out.println( "Found the specified entry." );
*
*
* @param DN distinguished name of the entry to retrieve
* @exception LDAPException Failed to find or read the specified entry
* from the directory.
* @return LDAPEntry returns the specified entry or raises an exception
* if the entry is not found.
*/
public LDAPEntry read (String DN) throws LDAPException {
return read (DN, null, m_defaultConstraints);
}
/**
* Reads the entry for the specified distiguished name (DN) and retrieves all
* attributes for the entry. This method allows the user to specify the
* preferences for the read operation.
* * * For example, the following section of code reads the entry for * Barbara Jensen and retrieves all attributes for that entry. *
* *
* String findDN = "cn=Barbara Jensen,ou=Product Development,o=Ace Industry,c=US";
* LDAPEntry foundEntry = null;
* try {
* foundEntry = myConn.read( findDN );
* } catch ( LDAPException e ) {
* switch( e.getLDAPResultCode() ) {
* case e.NO_SUCH_OBJECT:
* System.out.println( "The specified entry does not exist." );
* break;
* case e.LDAP_PARTIAL_RESULTS:
* System.out.println( "Entry served by a different LDAP server." );
* break;
* case e.INSUFFICIENT_ACCESS_RIGHTS:
* System.out.println( "You do not have the access rights to perform this operation." );
* break;
* default:
* System.out.println( "Error number: " + e.getLDAPResultCode() );
* System.out.println( "Could not read the specified entry." );
* break;
* }
* return;
* }
* System.out.println( "Found the specified entry." );
*
*
* @param DN distinguished name of the entry to retrieve
* @param cons preferences for the read operation
* @exception LDAPException Failed to find or read the specified entry
* from the directory.
* @return LDAPEntry returns the specified entry or raises an exception
* if the entry is not found.
*/
public LDAPEntry read (String DN, LDAPSearchConstraints cons)
throws LDAPException {
return read (DN, null, cons);
}
/**
* Reads the entry for the specified distinguished name (DN) and
* retrieves only the specified attributes from the entry.
*
*
* For example, the following section of code reads the entry for
* Barbara Jensen and retrieves only the cn and
* sn attributes.
* The example prints out all attributes that have been retrieved
* (the two specified attributes).
*
* *
* String findDN = "cn=Barbara Jensen,ou=Product Development,o=Ace Industry,c=US";
* LDAPEntry foundEntry = null;
* String getAttrs[] = { "cn", "sn" };
* try {
* foundEntry = myConn.read( findDN, getAttrs );
* } catch ( LDAPException e ) {
* switch( e.getLDAPResultCode() ) {
* case e.NO_SUCH_OBJECT:
* System.out.println( "The specified entry does not exist." );
* break;
* case e.LDAP_PARTIAL_RESULTS:
* System.out.println( "Entry served by a different LDAP server." );
* break;
* case e.INSUFFICIENT_ACCESS_RIGHTS:
* System.out.println( "You do not have the access " +
* "rights to perform this operation." );
* break;
* default:
* System.out.println( "Error number: " + e.getLDAPResultCode() );
* System.out.println( "Could not read the specified entry." );
* break;
* }
* return;
* }
*
* LDAPAttributeSet foundAttrs = foundEntry.getAttributeSet();
* int size = foundAttrs.size();
* Enumeration itrAttrs = foundAttrs.getAttributes();
* System.out.println( "Attributes: " );
*
* while ( itrAttrs.hasMoreElements() ) {
* LDAPAttribute anAttr = ( LDAPAttribute )itrAttrs.nextElement();
* String attrName = anAttr.getName();
* System.out.println( "\t" + attrName );
* Enumeration itrVals = anAttr.getStringValues();
* while ( itrVals.hasMoreElements() ) {
* String aVal = ( String )itrVals.nextElement();
* System.out.println( "\t\t" + aVal );
* }
* }
*
*
* @param DN distinguished name of the entry to retrieve
* @param attrs names of attributes to retrieve
* @return LDAPEntry returns the specified entry (or raises an
* exception if the entry is not found).
* @exception LDAPException Failed to read the specified entry from
* the directory.
*/
public LDAPEntry read (String DN, String attrs[]) throws LDAPException {
return read(DN, attrs, m_defaultConstraints);
}
public LDAPEntry read (String DN, String attrs[],
LDAPSearchConstraints cons) throws LDAPException {
LDAPSearchResults results =
search (DN, SCOPE_BASE,
"(|(objectclass=*)(objectclass=ldapsubentry))",
attrs, false, cons);
if (results == null) {
return null;
}
LDAPEntry entry = results.next();
// cleanup required for referral connections
while (results.hasMoreElements()) {
results.nextElement();
}
return entry;
}
/**
* Reads the entry specified by the LDAP URL. * * When you call this method, a new connection is created automatically, * using the host and port specified in the URL. After finding the entry, * the method closes this 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.
*
* (Note: If you want to search for more than one entry, use the
* search( LDAPUrl ) method instead.)
* * For example, the following section of code reads the entry specified * by the LDAP URL. *
* *
* String flatURL = "ldap://alway.mcom.com:3890/cn=Barbara Jenson,ou=Product Development,o=Ace Industry,c=US?cn,sn,mail";
* LDAPUrl myURL;
* try {
* myURL = new LDAPUrl( flatURL );
* } catch ( java.net.MalformedURLException e ) {
* System.out.println( "BAD URL!!! BAD, BAD, BAD URL!!!" );
* return;
* }
* LDAPEntry myEntry = null;
* try {
* myEntry = myConn.read( myURL );
* } catch ( LDAPException e ) {
* int errCode = e.getLDAPResultCode();
* switch( errCode ) {
* case ( e.NO_SUCH_OBJECT ):
* System.out.println( "The specified entry " + myDN +
* " does not exist in the directory." );
* return;
* default:
* System.out.println( "An internal error occurred." );
* return;
* }
* }
*
*
* @param toGet LDAP URL specifying the entry to read
* @return LDAPEntry returns the entry specified by the URL (or raises
* an exception if the entry is not found).
* @exception LDAPException Failed to read the specified entry from
* the directory.
* @see netscape.ldap.LDAPUrl
* @see netscape.ldap.LDAPConnection#search(netscape.ldap.LDAPUrl)
*/
public static LDAPEntry read (LDAPUrl toGet) throws LDAPException {
String host = toGet.getHost ();
int port = toGet.getPort();
if (host == null) {
throw new LDAPException ( "no host for connection",
LDAPException.PARAM_ERROR );
}
String[] attributes = toGet.getAttributeArray ();
String DN = toGet.getDN();
LDAPEntry returnValue;
LDAPConnection connection = new LDAPConnection ();
if (toGet.isSecure()) {
LDAPSocketFactory factory = toGet.getSocketFactory();
if (factory == null) {
throw new LDAPException("No socket factory for LDAPUrl",
LDAPException.OTHER);
}
connection.setSocketFactory(factory);
}
connection.connect (host, port);
returnValue = connection.read (DN, attributes);
connection.disconnect ();
return returnValue;
}
/**
* Performs the search specified by the LDAP URL.
*
* For example, the following section of code searches for all entries under
* the ou=Product Development,o=Ace Industry,c=US subtree of a
* directory. The example gets and prints the mail attribute for each entry
* found.
* *
* String flatURL = "ldap://alway.mcom.com:3890/ou=Product Development,o=Ace Industry,c=US?mail?sub?objectclass=*";
* LDAPUrl myURL;
* try {
* myURL = new LDAPUrl( flatURL );
* } catch ( java.net.MalformedURLException e ) {
* System.out.println( "Incorrect URL syntax." );
* return;
* }
*
* LDAPSearchResults myResults = null;
* try {
* myResults = myConn.search( myURL );
* } catch ( LDAPException e ) {
* int errCode = e.getLDAPResultCode();
* System.out.println( "LDAPException: return code:" + errCode );
* return;
* }
*
* while ( myResults.hasMoreElements() ) {
* LDAPEntry myEntry = myResults.next();
* String nextDN = myEntry.getDN();
* System.out.println( nextDN );
* LDAPAttributeSet entryAttrs = myEntry.getAttributeSet();
* Enumeration attrsInSet = entryAttrs.getAttributes();
* while ( attrsInSet.hasMoreElements() ) {
* LDAPAttribute nextAttr = (LDAPAttribute)attrsInSet.nextElement();
* String attrName = nextAttr.getName();
* System.out.print( "\t" + attrName + ": " );
* Enumeration valsInAttr = nextAttr.getStringValues();
* while ( valsInAttr.hasMoreElements() ) {
* String nextValue = (String)valsInAttr.nextElement();
* System.out.println( nextValue );
* }
* }
* }
*
*
*
* To abandon the search, use the abandon method.
*
* @param toGet LDAP URL representing the search to perform
* @return LDAPSearchResults the results of the search as an enumeration.
* @exception LDAPException Failed to complete the search specified by
* the LDAP URL.
* @see netscape.ldap.LDAPUrl
* @see netscape.ldap.LDAPSearchResults
* @see netscape.ldap.LDAPConnection#abandon(netscape.ldap.LDAPSearchResults)
*/
public static LDAPSearchResults search (LDAPUrl toGet) throws LDAPException {
return search (toGet, null);
}
/**
* Performs the search specified by the LDAP URL. This method also
* allows you to specify 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, you can specify whether or not you * want the results delivered all at once or in smaller batches. * If you specify the results delivered in smaller * batches, each iteration blocks until the next batch of results is * returned.
* * For example, the following section of code retrieves the first 5 * matching entries for the search specified by the LDAP URL. The * example accomplishes this by creating a new set of search * constraints where the maximum number of search results is 5.
* *
* LDAPSearchConstraints mySearchConstraints = myConn.getSearchConstraints();
* mySearchConstraints.setMaxResults( 5 );
* String flatURL = "ldap://alway.mcom.com:3890/ou=Product Development,o=Ace Industry,c=US?mail?sub?objectclass=*";
* LDAPUrl myURL;
* try {
* myURL = new LDAPUrl( flatURL );
* } catch ( java.net.MalformedURLException e ) {
* System.out.println( "Incorrect URL syntax." );
* return;
* }
* LDAPSearchResults myResults = null;
* try {
* myResults = myConn.search( myURL, mySearchConstraints );
* } catch ( LDAPException e ) {
* int errCode = e.getLDAPResultCode();
* System.out.println( "LDAPException: return code:" + errCode );
* return;
* }
*
*
*
* To abandon the search, use the abandon method.
*
* @param toGet LDAP URL representing the search to run
* @param cons constraints specific to the search
* @return LDAPSearchResults the results of the search as an enumeration.
* @exception LDAPException Failed to complete the search specified
* by the LDAP URL.
* @see netscape.ldap.LDAPUrl
* @see netscape.ldap.LDAPSearchResults
* @see netscape.ldap.LDAPConnection#abandon(netscape.ldap.LDAPSearchResults)
*/
public static LDAPSearchResults search (LDAPUrl toGet,
LDAPSearchConstraints cons) throws LDAPException {
String host = toGet.getHost ();
int port = toGet.getPort();
if (host == null) {
throw new LDAPException ( "no host for connection",
LDAPException.PARAM_ERROR );
}
String[] attributes = toGet.getAttributeArray ();
String DN = toGet.getDN();
String filter = toGet.getFilter();
if (filter == null) {
filter = defaultFilter;
}
int scope = toGet.getScope ();
LDAPConnection connection = new LDAPConnection ();
if (toGet.isSecure()) {
LDAPSocketFactory factory = toGet.getSocketFactory();
if (factory == null) {
throw new LDAPException("No socket factory for LDAPUrl",
LDAPException.OTHER);
}
connection.setSocketFactory(factory);
}
connection.connect (host, port);
LDAPSearchResults results;
if (cons != null) {
results = connection.search (DN, scope, filter, attributes, false, cons);
} else {
results = connection.search (DN, scope, filter, attributes, false);
}
results.closeOnCompletion(connection);
return results;
}
/**
* Performs the search specified by the criteria that you enter.
*
* For example, the following section of code searches for all entries under
* the ou=Product Development,o=Ace Industry,c=US subtree of a
* directory. The example gets and prints the mail attribute for each entry
* found.
* *
* String myBaseDN = "ou=Product Development,o=Ace Industry,c=US";
* String myFilter="(objectclass=*)";
* String[] myAttrs = { "mail" };
*
* LDAPSearchResults myResults = null;
* try {
* myResults = myConn.search( myBaseDN, LDAPv2.SCOPE_SUB, myFilter, myAttrs, false );
* } catch ( LDAPException e ) {
* int errCode = e.getLDAPResultCode();
* System.out.println( "LDAPException: return code:" + errCode );
* return;
* }
*
* while ( myResults.hasMoreElements() ) {
* LDAPEntry myEntry = myResults.next();
* String nextDN = myEntry.getDN();
* System.out.println( nextDN );
* LDAPAttributeSet entryAttrs = myEntry.getAttributeSet();
* Enumeration attrsInSet = entryAttrs.getAttributes();
* while ( attrsInSet.hasMoreElements() ) {
* LDAPAttribute nextAttr = (LDAPAttribute)attrsInSet.nextElement();
* String attrName = nextAttr.getName();
* System.out.println( "\t" + attrName + ":" );
* Enumeration valsInAttr = nextAttr.getStringValues();
* while ( valsInAttr.hasMoreElements() ) {
* String nextValue = (String)valsInAttr.nextElement();
* System.out.println( "\t\t" + nextValue );
* }
* }
* }
*
*
*
* To abandon the search, use the abandon method.
*
* @param base the base distinguished name from which to search
* @param scope the scope of the entries to search. You can specify one
* of the following:
*
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) *
* @param filter search filter specifying the search criteria * @param attrs list of attributes that you want returned in the * search results * @param attrsOnly if true, returns the names but not the values of the * attributes found. If false, returns the names and values for * attributes found * @return LDAPSearchResults the results of the search as an enumeration. * @exception LDAPException Failed to complete the specified search. * @see netscape.ldap.LDAPConnection#abandon(netscape.ldap.LDAPSearchResults) */ public LDAPSearchResults search( String base, int scope, String filter, String[] attrs, boolean attrsOnly ) throws LDAPException { return search( base, scope, filter, attrs, attrsOnly, m_defaultConstraints); } /** * Performs the search specified by the criteria that you enter. * This method also allows you to specify 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, you can specify whether or not * you want the * results delivered all at once or in smaller batches. If you * specify that you want the results delivered in smaller batches, * each iteration blocks until the * next batch of results is returned.
* * For example, the following section of code retrieves the first 5 entries * matching the specified search criteria. The example accomplishes * this by creating a new set of search constraints where the maximum * number of search results is 5.
* *
* String myBaseDN = "ou=Product Development,o=Ace Industry,c=US";
* String myFilter="(objectclass=*)";
* String[] myAttrs = { "mail" };
* LDAPSearchConstraints mySearchConstraints = myConn.getSearchConstraints();
* mySearchConstraints.setMaxResults( 5 );
*
* LDAPSearchResults myResults = null;
* try {
* myResults = myConn.search( myBaseDN, LDAPv2.SCOPE_SUB, myFilter, myAttrs, false, mySearchConstraints );
* } catch ( LDAPException e ) {
* int errCode = e.getLDAPResultCode();
* System.out.println( "LDAPException: return code:" + errCode );
* return;
* }
*
*
*
* To abandon the search, use the abandon method.
*
* @param base the base distinguished name from which to search
* @param scope the scope of the entries to search. You can specify one
* of the following:
*
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) *
* @param filter search filter specifying the search criteria
* @param attrs list of attributes to return in the search
* results
* @param cons constraints specific to this search (for example, the
* maximum number of entries to return)
* @param attrsOnly if true, returns the names but not the values of the
* attributes found. If false, returns the names and values for
* attributes found
* @return LDAPSearchResults the results of the search as an enumeration.
* @exception LDAPException Failed to complete the specified search.
* @see netscape.ldap.LDAPConnection#abandon(netscape.ldap.LDAPSearchResults)
*/
public LDAPSearchResults search( String base, int scope, String filter,
String[] attrs, boolean attrsOnly, LDAPSearchConstraints cons )
throws LDAPException {
if (cons == null) {
cons = m_defaultConstraints;
}
LDAPSearchResults returnValue =
new LDAPSearchResults(this, cons, base, scope, filter,
attrs, attrsOnly);
Vector cacheValue = null;
Long key = null;
boolean isKeyValid = true;
try {
// get entry from cache which is a vector of JDAPMessages
if (m_cache != null) {
// create key for cache entry using search arguments
key = m_cache.createKey(getHost(), getPort(),base, filter,
scope, attrs, m_boundDN, cons);
cacheValue = (Vector)m_cache.getEntry(key);
if (cacheValue != null) {
return (new LDAPSearchResults(cacheValue, this, cons, base, scope,
filter, attrs, attrsOnly));
}
}
} catch (LDAPException e) {
isKeyValid = false;
printDebug("Exception: "+e);
}
checkConnection(/*rebind=*/true);
/* Is this a persistent search? */
boolean isPersistentSearch = false;
LDAPControl[] controls =
(LDAPControl[])getOption(LDAPv3.SERVERCONTROLS, cons);
for (int i = 0; (controls != null) && (i < controls.length); i++) {
if ( controls[i] instanceof
netscape.ldap.controls.LDAPPersistSearchControl ) {
isPersistentSearch = true;
break;
}
}
// Persistent search is an asynchronous operation
LDAPSearchListener myListener = isPersistentSearch ? new LDAPSearchListener(/*asynchOp=*/true, cons) :
getSearchListener ( cons );
int deref = cons.getDereference();
JDAPSearchRequest request = null;
try {
request = new JDAPSearchRequest (base, scope, deref,
cons.getMaxResults(), cons.getServerTimeLimit(),
attrsOnly, filter, attrs);
} catch (IllegalArgumentException e) {
throw new LDAPException(e.getMessage(), LDAPException.PARAM_ERROR);
}
// if using cache, then need to add the key to the search listener.
if ((m_cache != null) && (isKeyValid)) {
myListener.setKey(key);
}
try {
sendRequest (request, myListener, cons);
}
catch (LDAPException e) {
releaseSearchListener (myListener);
throw e;
}
/* For a persistent search, don't wait for a first result, because
there may be none at this time if changesOnly was specified in
the control.
*/
if ( isPersistentSearch ) {
returnValue.associatePersistentSearch (myListener);
} else if ( cons.getBatchSize() == 0 ) {
/* Synchronous search if all requested at once */
try {
/* Block until all results are in */
LDAPMessage response = myListener.completeSearchOperation();
Enumeration results = myListener.getAllMessages().elements();
checkSearchMsg(returnValue, response, cons, base, scope,
filter, attrs, attrsOnly);
while (results.hasMoreElements ()) {
LDAPMessage msg = (LDAPMessage)results.nextElement();
checkSearchMsg(returnValue, msg, cons, base, scope, filter, attrs,
attrsOnly);
}
} finally {
releaseSearchListener (myListener);
}
} else {
/*
* Asynchronous to retrieve one at a time, check to make sure
* the search didn't fail
*/
LDAPMessage firstResult = myListener.nextMessage ();
if ( firstResult instanceof LDAPResponse ) {
try {
checkSearchMsg(returnValue, firstResult, cons, base, scope,
filter, attrs, attrsOnly);
} finally {
releaseSearchListener (myListener);
}
} else {
try {
checkSearchMsg(returnValue, firstResult, cons, base,
scope, filter, attrs, attrsOnly);
} catch ( LDAPException ex ) {
releaseSearchListener (myListener);
throw ex;
}
/* we let this listener get garbage collected.. */
returnValue.associate (myListener);
}
}
return returnValue;
}
void checkSearchMsg(LDAPSearchResults value, LDAPMessage msg,
LDAPSearchConstraints cons, String dn, int scope, String filter,
String attrs[], boolean attrsOnly) throws LDAPException {
value.setMsgID(msg.getMessageID());
try {
checkMsg (msg);
// not the JDAPResult
if (msg.getProtocolOp().getType() != JDAPProtocolOp.SEARCH_RESULT) {
value.add (msg);
}
} catch (LDAPReferralException e) {
Vector res = new Vector();
try {
performReferrals(e, cons, JDAPProtocolOp.SEARCH_REQUEST, dn,
scope, filter, attrs, attrsOnly, null, null, null, res);
}
catch (LDAPException ex) {
if (msg.getProtocolOp() instanceof JDAPSearchResultReference) {
// Ignore Search Result Referral Errors ?
if (cons.getReferralErrors() == cons.REFERRAL_ERROR_CONTINUE) {
return; // Don't want to miss all remaining results
}
else {
throw ex;
}
}
throw ex;
}
// the size of the vector can be more than 1 because it is possible
// to visit more than one referral url to retrieve the entries
for (int i=0; i
*
* Note that only string values can be compared.
*
* For example, the following section of code checks to see if the entry
* "cn=Barbara Jensen,ou=Product Development,o=Ace Industry,c=US" contains
* the attribute "mail" with the value "bjensen@aceindustry.com".
*
*
*
* Before using this method, you need to create an
*
*
* For example, the following section of code creates an
*
*
*
*
* @param entry LDAPEntry object specifying the distinguished name and
* attributes of the new entry
* @param cons the set of preferences to apply to this operation
* @exception LDAPException Failed to add the specified entry to the
* directory.
* @see netscape.ldap.LDAPEntry
* @see netscape.ldap.LDAPConstraints
*/
public void add( LDAPEntry entry, LDAPConstraints cons )
throws LDAPException {
checkConnection(/*rebind=*/true);
LDAPResponseListener myListener = getResponseListener ();
LDAPAttributeSet attrs = entry.getAttributeSet ();
LDAPAttribute[] attrList = new LDAPAttribute[attrs.size()];
for( int i = 0; i < attrs.size(); i++ ) {
attrList[i] = (LDAPAttribute)attrs.elementAt( i );
}
int attrPosition = 0;
LDAPMessage response;
try {
sendRequest (new JDAPAddRequest (entry.getDN(), attrList),
myListener, cons);
response = myListener.getResponse();
checkMsg (response);
} catch (LDAPReferralException e) {
performReferrals(e, cons, JDAPProtocolOp.ADD_REQUEST,
null, 0, null, null, false, null, entry, null, null);
} finally {
releaseResponseListener (myListener);
}
}
/**
* @deprecated Please use the method signature where
*
* Note that in order for the extended operation to work, the server
* that you are connecting to must support LDAP v3 and must be configured
* to process the specified extended operation.
*
* @param op LDAPExtendedOperation object specifying the OID of the
* extended operation and the data to use in the operation
* @exception LDAPException Failed to execute the operation
* @return LDAPExtendedOperation object representing the extended response
* returned by the server.
* @see netscape.ldap.LDAPExtendedOperation
*/
public LDAPExtendedOperation extendedOperation( LDAPExtendedOperation op )
throws LDAPException {
return extendedOperation(op, m_defaultConstraints);
}
/**
* Performs an extended operation on the directory. Extended operations
* are part of version 3 of the LDAP protocol. This method allows the
* user to set the preferences for the operation.
*
* Note that in order for the extended operation to work, the server
* that you are connecting to must support LDAP v3 and must be configured
* to process the specified extended operation.
*
* @param op LDAPExtendedOperation object specifying the OID of the
* extended operation and the data to use in the operation
* @param cons preferences for the extended operation
* @exception LDAPException Failed to execute the operation
* @return LDAPExtendedOperation object representing the extended response
* returned by the server.
* @see netscape.ldap.LDAPExtendedOperation
*/
public LDAPExtendedOperation extendedOperation( LDAPExtendedOperation op,
LDAPConstraints cons)
throws LDAPException {
checkConnection(/*rebind=*/true);
LDAPResponseListener myListener = getResponseListener ();
LDAPMessage response = null;
byte[] results = null;
String resultID;
try {
sendRequest ( new JDAPExtendedRequest( op.getID(),
op.getValue() ),
myListener, cons );
response = myListener.getResponse();
checkMsg (response);
JDAPExtendedResponse res = (JDAPExtendedResponse)response.getProtocolOp();
results = res.getValue();
resultID = res.getID();
} catch (LDAPReferralException e) {
return performExtendedReferrals( e, cons, op );
} finally {
releaseResponseListener (myListener);
}
return new LDAPExtendedOperation( resultID, results );
}
/**
* @deprecated Please use the method signature where
*
* Use the
*
* For example, the following section of code changes Barbara Jensen's email
* address in the directory to babs@aceindustry.com.
*
*
*
* @param DN the distinguished name of the entry to modify
* @param mod a single change to make to the entry
* @param cons the set of preferences to apply to this operation
* @exception LDAPException Failed to make the specified change to the
* directory entry.
* @see netscape.ldap.LDAPModification
* @see netscape.ldap.LDAPConstraints
*/
public void modify( String DN, LDAPModification mod,
LDAPConstraints cons ) throws LDAPException {
LDAPModification[] mods = { mod };
modify (DN, mods, cons);
}
/**
* @deprecated Please use the method signature where
*
* Use the
*
* For example, the following section of code changes Barbara Jensen's
* title, adds a telephone number to the entry, and removes the room
* number from the entry.
*
*
*
* @param DN the distinguished name of the entry to modify
* @param mods a set of changes to make to the entry
* @param cons the set of preferences to apply to this operation
* @exception LDAPException Failed to make the specified changes to the
* directory entry.
* @see netscape.ldap.LDAPModificationSet
* @see netscape.ldap.LDAPConstraints
*/
public void modify (String DN, LDAPModificationSet mods,
LDAPConstraints cons) throws LDAPException {
LDAPModification[] modList = new LDAPModification[mods.size()];
for( int i = 0; i < mods.size(); i++ ) {
modList[i] = mods.elementAt( i );
}
modify (DN, modList, cons);
}
/**
* @deprecated Please use the method signature where
*
* Use an array of
*
* @param DN the distinguished name of the entry to modify
* @param mods an array of objects representing the changes to make
* to the entry
* @exception LDAPException Failed to make the specified changes to the
* directory entry.
* @see netscape.ldap.LDAPModification
*/
public void modify (String DN, LDAPModification[] mods)
throws LDAPException {
modify(DN, mods, m_defaultConstraints);
}
/**
* Makes a set of changes to an existing entry in the directory and
* allows you to specify preferences for this LDAP modify operation
* by using an
*
* @param DN the distinguished name of the entry to modify
* @param mods an array of objects representing the changes to make
* to the entry
* @param cons the set of preferences to apply to this operation
* @exception LDAPException Failed to make the specified changes to the
* directory entry.
* @see netscape.ldap.LDAPModification
* @see netscape.ldap.LDAPConstraints
*/
public void modify (String DN, LDAPModification[] mods,
LDAPConstraints cons) throws LDAPException {
checkConnection(/*rebind=*/true);
LDAPResponseListener myListener = getResponseListener ();
LDAPMessage response = null;
try {
sendRequest (new JDAPModifyRequest (DN, mods), myListener, cons);
response = myListener.getResponse();
checkMsg (response);
} catch (LDAPReferralException e) {
performReferrals(e, cons, JDAPProtocolOp.MODIFY_REQUEST,
DN, 0, null, null, false, mods, null, null, null);
} finally {
releaseResponseListener (myListener);
}
}
/**
* @deprecated Please use the method signature where
*
* For example, the following section of code deletes the entry for
* Barbara Jensen from the directory.
*
*
*
* @param DN distinguished name identifying the entry
* to remove from the directory
* @param cons the set of preferences to apply to this operation
* @exception LDAPException Failed to delete the specified entry from
* the directory.
* @see netscape.ldap.LDAPConstraints
*/
public void delete( String DN, LDAPConstraints cons )
throws LDAPException {
checkConnection(/*rebind=*/true);
LDAPResponseListener myListener = getResponseListener ();
LDAPMessage response;
try {
sendRequest (new JDAPDeleteRequest (DN), myListener, cons);
response = myListener.getResponse();
checkMsg (response);
} catch (LDAPReferralException e) {
performReferrals(e, cons, JDAPProtocolOp.DEL_REQUEST,
DN, 0, null, null, false, null, null, null, null);
} finally {
releaseResponseListener (myListener);
}
}
/**
* @deprecated Please use the method signature where
*
* You can specify whether or not the original name of the entry is
* retained as a value in the entry. For example, suppose you rename
* the entry "cn=Barbara" to "cn=Babs". You can keep "cn=Barbara"
* as a value in the entry so that the cn attribute has two values:
*
*
*
*
*
* You can specify whether or not the original name of the entry is
* retained as a value in the entry. For example, suppose you rename
* the entry "cn=Barbara" to "cn=Babs". You can keep "cn=Barbara"
* as a value in the entry so that the cn attribute has two values:
*
*
*
*
*
* NOTE: Netscape Directory Server 3.0 does not support the
* capability to move an entry to a different location in the
* directory tree. If you specify a value for the
*
* @param dn current distinguished name of the entry
* @param newRDN new relative distinguished name for the entry (for example,
* "cn=newName")
* @param newParentDN if not null, the distinguished name for the
* entry under which the entry should be moved (for example, to move
* an entry under the Accounting subtree, specify this argument as
* "ou=Accounting, o=Ace Industry, c=US")
* @param deleteOldRDN if
*
* NOTE: Netscape Directory Server 3.0 does not support the
* capability to move an entry to a different location in the
* directory tree. If you specify a value for the
*
* @param DN current distinguished name of the entry
* @param newRDN new relative distinguished name for the entry (for example,
* "cn=newName")
* @param newParentDN if not null, the distinguished name for the
* entry under which the entry should be moved (for example, to move
* an entry under the Accounting subtree, specify this argument as
* "ou=Accounting, o=Ace Industry, c=US")
* @param deleteOldRDN if
*
* @param entry LDAPEntry object specifying the distinguished name and
* attributes of the new entry
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @param cons constraints specific to the operation
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPEntry
* @see netscape.ldap.LDAPResponseListener
* @see netscape.ldap.LDAPConstraints
*/
public LDAPResponseListener add(LDAPEntry entry,
LDAPResponseListener listener,
LDAPConstraints cons)
throws LDAPException{
if (cons == null) {
cons = m_defaultConstraints;
}
checkConnection(/*rebind=*/true);
if (listener == null) {
listener = new LDAPResponseListener(/*asynchOp=*/true);
}
LDAPAttributeSet attrs = entry.getAttributeSet ();
LDAPAttribute[] attrList = new LDAPAttribute[attrs.size()];
for( int i = 0; i < attrs.size(); i++ )
attrList[i] = (LDAPAttribute)attrs.elementAt( i );
int attrPosition = 0;
sendRequest (new JDAPAddRequest (entry.getDN(), attrList),
listener, cons);
return listener;
}
/**
* Authenticates to the LDAP server (to which the object is currently
* connected) using the specified name and password. If the object
* has been disconnected from an LDAP server, this method attempts to
* reconnect to the server. If the object had already authenticated, the
* old authentication is discarded.
*
* @param version required LDAP protocol version
* @param dn if non-null and non-empty, specifies that the connection
* and all operations through it should authenticate with dn as the
* distinguished name
* @param passwd if non-null and non-empty, specifies that the connection
* and all operations through it should authenticate with dn as the
* distinguished name and passwd as password
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPResponseListener
*/
public LDAPResponseListener bind(int version,
String dn,
String passwd,
LDAPResponseListener listener)
throws LDAPException{
return bind(version, dn, passwd, listener, m_defaultConstraints);
}
/**
* Authenticates to the LDAP server (to which the object is currently
* connected) using the specified name and password. If the object
* has been disconnected from an LDAP server, this method attempts to
* reconnect to the server. If the object had already authenticated, the
* old authentication is discarded.
*
* @param dn if non-null and non-empty, specifies that the connection
* and all operations through it should authenticate with dn as the
* distinguished name
* @param passwd if non-null and non-empty, specifies that the connection
* and all operations through it should authenticate with dn as the
* distinguished name and passwd as password
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPResponseListener
*/
public LDAPResponseListener bind(String dn,
String passwd,
LDAPResponseListener listener)
throws LDAPException{
return bind(m_protocolVersion, dn, passwd, listener,
m_defaultConstraints);
}
/**
* Authenticates to the LDAP server (to which the object is currently
* connected) using the specified name and password and allows you
* to specify constraints for this LDAP add operation by using an
*
* @param dn distinguished name of the entry to modify
* @param mods a set of changes to make to the entry
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPModificationSet
* @see netscape.ldap.LDAPResponseListener
*/
public LDAPResponseListener modify(String dn,
LDAPModificationSet mods,
LDAPResponseListener listener)
throws LDAPException{
return modify(dn,mods, listener, m_defaultConstraints);
}
/**
* 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).
*
* @param dn distinguished name of the entry to modify
* @param mods a set of changes to make to the entry
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @param cons Constraints specific to the operation
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPModificationSet
* @see netscape.ldap.LDAPResponseListener
* @see netscape.ldap.LDAPConstraints
*/
public LDAPResponseListener modify(String dn,
LDAPModificationSet mods,
LDAPResponseListener listener,
LDAPConstraints cons)
throws LDAPException{
if (cons == null) {
cons = m_defaultConstraints;
}
checkConnection(/*rebind=*/true);
if (listener == null) {
listener = new LDAPResponseListener(/*asynchOp=*/true);
}
LDAPModification[] modList = new LDAPModification[mods.size()];
for( int i = 0; i < mods.size(); i++ ) {
modList[i] = mods.elementAt( i );
}
sendRequest (new JDAPModifyRequest (dn, modList), listener, cons);
return listener;
}
/**
* Renames an existing entry in the directory.
*
* @param dn current distinguished name of the entry
* @param newRdn new relative distinguished name for the entry
* @param deleteOldRdn if true, the old name is not retained as an
* attribute value
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPResponseListener
*/
public LDAPResponseListener rename(String dn,
String newRdn,
boolean deleteOldRdn,
LDAPResponseListener listener)
throws LDAPException{
return rename(dn, newRdn, deleteOldRdn, listener, m_defaultConstraints);
}
/**
* Renames an existing entry in the directory.
*
* @param dn current distinguished name of the entry
* @param newRdn new relative distinguished name for the entry
* @param deleteOldRdn if true, the old name is not retained as an attribute
* value
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @param cons constraints specific to the operation
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPResponseListener
* @see netscape.ldap.LDAPConstraints
*/
public LDAPResponseListener rename(String dn,
String newRdn,
boolean deleteOldRdn,
LDAPResponseListener listener,
LDAPConstraints cons)
throws LDAPException{
if (cons == null) {
cons = m_defaultConstraints;
}
checkConnection(/*rebind=*/true);
if (listener == null) {
listener = new LDAPResponseListener(/*asynchOp=*/true);
}
sendRequest (new JDAPModifyRDNRequest (dn, newRdn, deleteOldRdn),
listener, cons);
return listener;
}
/**
* Performs the search specified by the criteria that you enter.
* To abandon the search, use the
*
*
*
*
* @param filter search filter specifying the search criteria
* @param attrs list of attributes that you want returned in the
* search results
* @param typesOnly if true, returns the names but not the values of the
* attributes found. If false, returns the names and values for
* attributes found
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @return LDAPSearchListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPConnection#abandon(netscape.ldap.LDAPSearchListener)
*/
public LDAPSearchListener search(String base,
int scope,
String filter,
String attrs[],
boolean typesOnly,
LDAPSearchListener listener)
throws LDAPException {
return search(base, scope, filter, attrs, typesOnly,
listener, m_defaultConstraints);
}
/**
* Performs the search specified by the criteria that you enter.
* This method also allows you to specify constraints for the search
* (such as the maximum number of entries to find or the
* maximum time to wait for search results).
* To abandon the search, use the
*
*
*
*
* @param filter search filter specifying the search criteria
* @param attrs list of attributes that you want returned in the search
* results
* @param typesOnly if true, returns the names but not the values of the
* attributes found. If false, returns the names and values for
* attributes found.
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @param cons constraints specific to this search (for example, the
* maximum number of entries to return)
* @return LDAPSearchListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPConnection#abandon(netscape.ldap.LDAPSearchListener)
*/
public LDAPSearchListener search(String base,
int scope,
String filter,
String attrs[],
boolean typesOnly,
LDAPSearchListener listener,
LDAPSearchConstraints cons)
throws LDAPException {
if (cons == null) {
cons = m_defaultConstraints;
}
checkConnection(/*rebind=*/true);
if (listener == null) {
listener = new LDAPSearchListener(/*asynchOp=*/true, cons);
}
JDAPSearchRequest request = null;
try {
request = new JDAPSearchRequest (base, scope, cons.getDereference(),
cons.getMaxResults(), cons.getServerTimeLimit(),
typesOnly, filter, attrs);
}
catch (IllegalArgumentException e) {
throw new LDAPException(e.getMessage(), LDAPException.PARAM_ERROR);
}
sendRequest (request, listener, cons);
return listener;
}
/**
* Compare an attribute value with one in the directory. The result can
* be obtained by calling
*
* These options represent the constraints for the current connection.
* To get all constraints for the current connection, call the
*
*
* By default, the constraints apply to all operations performed
* through the current connection. You can change these constraints:
*
*
*
*
*
*
*
*
* For example, the following section of code gets and prints the
* maximum number of search results that are returned for searches
* performed through this connection. (This applies to all searches
* unless a different set of search constraints is specified in an
*
*
* By default, the value of this option is 2. By default, the value of this option is
* By default, the value of this option is 1000. By default, the value of this option is 0. By default, the value of this option is By default, the value of this option is By default, the value of this option is By default, the value of this option is 10. By default, the value of this option is 1. By default, the value of this option is 100. The value 0 means there
* is no limit.
* @return the value for the option wrapped in an object. (You
* need to cast the returned value as its appropriate type. For
* example, when getting the SIZELIMIT option, cast the returned
* value as an
*
* These options represent the constraints for the current
* connection.
* To get all constraints for the current connection, call the
*
*
* By default, the option that you set applies to all subsequent
* operations performed through the current connection. If you want to
* set a constraint only for a particular operation, create an
*
*
* For example, the following section of code changes the constraint for
* the maximum number of search results that are returned for searches
* performed through this connection. (This applies to all searches
* unless a different set of search constraints is specified in an
*
*
* By default, the value of this option is 2. If you want
* to use LDAP v3 features (such as extended operations or
* controls), you need to set this value to 3. By default, the value of this option is
* By default, the value of this option is 1000. By default, the value of this option is 0. By default, the value of this option is By default, the value of this option is By default, the value of this option is By default, the value of this option is 10. By default, the value of this option is 1. By default, the value of this option is 100. The value 0 means there
* is no limit.
* @param value the value to assign to the option. The value must be
* the java.lang object wrapper for the appropriate parameter
* (e.g. boolean->Boolean,
* integer->Integer)
* @exception LDAPException Failed to set the specified option.
* @see netscape.ldap.LDAPRebind
* @see netscape.ldap.LDAPConstraints
* @see netscape.ldap.LDAPSearchConstraints
* @see netscape.ldap.LDAPReferralException
* @see netscape.ldap.LDAPControl
* @see netscape.ldap.LDAPConnection#getSearchConstraints
* @see netscape.ldap.LDAPConnection#search(java.lang.String, int, java.lang.String, java.lang.String[], boolean, netscape.ldap.LDAPSearchConstraints)
*/
public void setOption( int option, Object value ) throws LDAPException {
if (option == LDAPv2.PROTOCOL_VERSION) {
setProtocolVersion(((Integer)value).intValue());
return;
}
setOption(option, value, m_defaultConstraints);
}
private static void setOption( int option, Object value, LDAPSearchConstraints cons ) throws LDAPException {
try {
switch (option) {
case LDAPv2.DEREF:
cons.setDereference(((Integer)value).intValue());
return;
case LDAPv2.SIZELIMIT:
cons.setMaxResults(((Integer)value).intValue());
return;
case LDAPv2.TIMELIMIT:
cons.setTimeLimit(((Integer)value).intValue());
return;
case LDAPv2.SERVER_TIMELIMIT:
cons.setServerTimeLimit(((Integer)value).intValue());
return;
case LDAPv2.REFERRALS:
cons.setReferrals(((Boolean)value).booleanValue());
return;
case LDAPv2.BIND:
cons.setBindProc((LDAPBind)value);
return;
case LDAPv2.REFERRALS_REBIND_PROC:
cons.setRebindProc((LDAPRebind)value);
return;
case LDAPv2.REFERRALS_HOP_LIMIT:
cons.setHopLimit(((Integer)value).intValue());
return;
case LDAPv2.BATCHSIZE:
cons.setBatchSize(((Integer)value).intValue());
return;
case LDAPv3.CLIENTCONTROLS:
if ( value == null )
cons.setClientControls( (LDAPControl[]) null );
else if ( value instanceof LDAPControl )
cons.setClientControls( (LDAPControl) value );
else if ( value instanceof LDAPControl[] )
cons.setClientControls( (LDAPControl[])value );
else
throw new LDAPException ( "invalid LDAPControl",
LDAPException.PARAM_ERROR );
return;
case LDAPv3.SERVERCONTROLS:
if ( value == null )
cons.setServerControls( (LDAPControl[]) null );
else if ( value instanceof LDAPControl )
cons.setServerControls( (LDAPControl) value );
else if ( value instanceof LDAPControl[] )
cons.setServerControls( (LDAPControl[])value );
else
throw new LDAPException ( "invalid LDAPControl",
LDAPException.PARAM_ERROR );
return;
case MAXBACKLOG:
cons.setMaxBacklog(((Integer)value).intValue());
return;
default:
throw new LDAPException ("invalid option",
LDAPException.PARAM_ERROR );
}
} catch (ClassCastException cc) {
throw new LDAPException ("invalid option value",
LDAPException.PARAM_ERROR );
}
}
/**
* Returns an array of the latest controls (if any) from server.
*
* To retrieve the controls from a search result, call the
*
* @param msdid Message ID
*/
LDAPControl[] getResponseControls(int msgID) {
LDAPControl[] controls = null;
synchronized(m_responseControlTable) {
Enumeration itr = m_responseControlTable.keys();
while (itr.hasMoreElements()) {
Object client = itr.nextElement();
ResponseControls rspCtrls = (ResponseControls)m_responseControlTable.get(client);
if (msgID == rspCtrls.msgID) {
Vector v = rspCtrls.ctrls;
controls = (LDAPControl[]) v.elementAt(0);
v.removeElementAt(0);
if (v.size() == 0) {
m_responseControlTable.remove(client);
}
break;
}
}
}
return controls;
}
/**
* Returns the set of constraints that apply to all operations
* performed through this connection (unless you specify a different
* set of constraints when calling a method).
*
*
* Note that if you want to get individual constraints (rather than
* getting the
* entire set of constraints), call the
*
* Typically, you might call the
*
* For example, the following section of code changes the timeout
* to 3000 milliseconds for a specific rename. Rather than construct a new
* set of constraints from scratch, the example gets the current
* settings for the connections and just changes the setting for the
* timeout.
*
*
* Note that this change only applies to the searches performed with this
* custom set of constraints. All other searches performed through this
* connection use the original set of search constraints.
*
*
*
*
* Note that if you want to get individual constraints (rather than
* getting the
* entire set of constraints), call the
*
* Typically, you might call the
*
* For example, the following section of code changes the maximum number
* of results to 10 for a specific search. Rather than construct a new
* set of search constraints from scratch, the example gets the current
* settings for the connections and just changes the setting for the
* maximum results.
*
*
* Note that this change only applies to the searches performed with this
* custom set of constraints. All other searches performed through this
* connection use the original set of search constraints.
*
*
*
* @return the
* For example:
*
* false if the entry does not have the value or the
* attribute. To represent the value that you want compared, you need
* to create an LDAPAttribute object.
* ...
* LDAPConnection myConn = new LDAPConnection();
* ...
* String myDN = "cn=Barbara Jensen,ou=Product Development,o=Ace Industry,c=US";
* String nameOfAttr = "mail";
* String valOfAttr = "bjensen@aceindustry.com";
* LDAPAttribute cmpThisAttr = new LDAPAttribute( nameOfAttr, valOfAttr );
* boolean hasValue = myConn.compare( myDN, cmpThisAttr );
* if ( hasValue ) {
* System.out.println( "Attribute and value found in entry." );
* } else {
* System.out.println( "Attribute and value not found in entry." );
* }
* ...
*
* @param DN the distinguished name of the entry to use in
* the comparison
* @param 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.)
* @return true if the entry contains the specified attribute and value.
* @exception LDAPException Failed to perform the comparison.
* @see netscape.ldap.LDAPAttribute
*/
public boolean compare( String DN, LDAPAttribute attr )
throws LDAPException {
return compare(DN, attr, m_defaultConstraints);
}
public boolean compare( String DN, LDAPAttribute attr,
LDAPConstraints cons) throws LDAPException {
checkConnection(/*rebind=*/true);
LDAPResponseListener myListener = getResponseListener ();
Enumeration en = attr.getStringValues();
String val = (String)en.nextElement();
JDAPAVA ass = new JDAPAVA(attr.getName(), val);
LDAPMessage response;
try {
sendRequest (new JDAPCompareRequest (DN, ass), myListener, cons);
response = myListener.getResponse ();
int resultCode = ((JDAPResult)response.getProtocolOp()).getResultCode();
if (resultCode == JDAPResult.COMPARE_FALSE) {
return false;
}
if (resultCode == JDAPResult.COMPARE_TRUE) {
return true;
}
checkMsg (response);
} catch (LDAPReferralException e) {
Vector res = new Vector();
performReferrals(e, cons, JDAPProtocolOp.COMPARE_REQUEST,
DN, 0, null, null, false, null, null, attr, res);
boolean bool = false;
if (res.size() > 0) {
bool = ((Boolean)res.elementAt(0)).booleanValue();
}
return bool;
} finally {
releaseResponseListener (myListener);
}
return false; /* this should never be executed */
}
/**
* @deprecated Please use the method signature where cons is
* LDAPConstraints instead of LDAPSearchConstraints
*/
public boolean compare( String DN, LDAPAttribute attr,
LDAPSearchConstraints cons) throws LDAPException {
return compare(DN, attr, (LDAPConstraints) cons);
}
/**
* Adds an entry to the directory. LDAPEntry object and use it to specify the
* distinguished name and attributes of the new entry. Make sure
* to specify values for all required attributes in the
* entry. If all required attributes are not specified and the LDAP server
* checks the entry against the schema, an LDAPException
* may be thrown (where the LDAP result code is
* OBJECT_CLASS_VIOLATION).LDAPEntry object for a new entry and uses the object
* to add the new entry to the directory. Because the definition of
* the LDAP inetOrgPerson class specifies that the
* cn, sn, and objectclass
* attributes are required, these attributes are specified as part
* of the new entry. (mail is not required but is shown
* here as an example of specifying additional attributes.)
*
* ...
* String myDN = "cn=Barbara Jensen,ou=Product Development,o=Ace Industry,c=US";
*
* LDAPAttribute attr1 = new LDAPAttribute( "cn", "Barbara Jensen" );
* LDAPAttribute attr2 = new LDAPAttribute( "sn", "Jensen" );
* LDAPAttribute attr3 = new LDAPAttribute( "objectclass", "top" );
* LDAPAttribute attr4 = new LDAPAttribute( "objectclass", "person" );
* LDAPAttribute attr5 = new LDAPAttribute( "objectclass", "organizationalPerson" );
* LDAPAttribute attr6 = new LDAPAttribute( "objectclass", "inetOrgPerson" );
* LDAPAttribute attr7 = new LDAPAttribute( "mail", "bjensen@aceindustry.com" );
*
* LDAPAttributeSet myAttrs = new LDAPAttributeSet();
* myAttrs.add( attr1 );
* myAttrs.add( attr2 );
* myAttrs.add( attr3 );
* myAttrs.add( attr4 );
* myAttrs.add( attr5 );
* myAttrs.add( attr6 );
* myAttrs.add( attr7 );
*
* LDAPEntry myEntry = new LDAPEntry( myDN, myAttrs );
*
* myConn.add( myEntry );
* ...
*
* @param entry LDAPEntry object specifying the distinguished name and
* attributes of the new entry
* @exception LDAPException Failed to add the specified entry to the
* directory.
* @see netscape.ldap.LDAPEntry
*/
public void add( LDAPEntry entry ) throws LDAPException {
add(entry, m_defaultConstraints);
}
/**
* Adds an entry to the directory and allows you to specify preferences
* for this LDAP add operation by using an
* LDAPConstraints object. For
* example, you can specify whether or not to follow referrals.
* You can also apply LDAP v3 controls to the operation.
* cons is
* LDAPConstraints instead of LDAPSearchConstraints
*/
public void add( LDAPEntry entry, LDAPSearchConstraints cons )
throws LDAPException {
add(entry, (LDAPConstraints) cons);
}
/**
* Performs an extended operation on the directory. Extended operations
* are part of version 3 of the LDAP protocol.cons is
* LDAPConstraints instead of LDAPSearchConstraints
*/
public LDAPExtendedOperation extendedOperation( LDAPExtendedOperation op,
LDAPSearchConstraints cons)
throws LDAPException {
return extendedOperation(op, (LDAPConstraints)cons);
}
/**
* 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. LDAPModification object to specify the change
* to make and the LDAPAttribute object
* to specify the attribute value to change. The
* LDAPModification object allows you add an attribute
* value, change an attibute value, or remove an attribute
* value.
* ...
* String myEntryDN = "cn=Barbara Jensen,ou=Product Development,o=Ace Industry,c=US";
*
* LDAPAttribute attrEmail = new LDAPAttribute( "mail", "babs@aceindustry.com" );
* LDAPModification singleChange = new LDAPModification( LDAPModification.REPLACE, attrEmail );
*
* myConn.modify( myEntryDN, singleChange );
* ...
*
* @param DN the distinguished name of the entry to modify
* @param mod a single change to make to the entry
* @exception LDAPException Failed to make the specified change to the
* directory entry.
* @see netscape.ldap.LDAPModification
*/
public void modify( String DN, LDAPModification mod ) throws LDAPException {
modify(DN, mod, m_defaultConstraints);
}
/**
* Makes a single change to an existing entry in the directory and
* allows you to specify preferences for this LDAP modify operation
* by using an LDAPConstraints object.
* For example, you can specify whether or not to follow referrals.
* You can also apply LDAP v3 controls to the operation.
* cons is
* LDAPConstraints instead of LDAPSearchConstraints
*/
public void modify( String DN, LDAPModification mod,
LDAPSearchConstraints cons ) throws LDAPException {
modify (DN, mod, (LDAPConstraints)cons);
}
/**
* 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. LDAPModificationSet object to specify the set
* of changes to make. Changes are specified in terms
* of attribute values. You must specify each attribute value to modify, add,
* or remove by an LDAPAttribute object.
*
* ...
* String myEntryDN = "cn=Barbara Jensen,ou=Product Development,o=Ace Industry,c=US";
*
* LDAPModificationSet manyChanges = new LDAPModificationSet();
* LDAPAttribute attrTelephoneNumber = new LDAPAttribute( "telephoneNumber",
* "555-1212" );
* manyChanges.add( LDAPModification.ADD, attrTelephoneNumber );
* LDAPAttribute attrRoomNumber = new LDAPAttribute( "roomnumber", "222" );
* manyChanges.add( LDAPModification.DELETE, attrRoomNumber );
* LDAPAttribute attrTitle = new LDAPAttribute( "title",
* "Manager of Product Development" );
* manyChanges.add( LDAPModification.REPLACE, attrTitle );
*
* myConn.modify( myEntryDN, manyChanges );
* ...
*
* @param DN the distinguished name of the entry to modify
* @param mods a set of changes to make to the entry
* @exception LDAPException Failed to make the specified changes to the
* directory entry.
* @see netscape.ldap.LDAPModificationSet
*/
public void modify (String DN, LDAPModificationSet mods)
throws LDAPException {
modify(DN, mods, m_defaultConstraints);
}
/**
* Makes a set of changes to an existing entry in the directory and
* allows you to specify preferences for this LDAP modify operation
* by using an LDAPConstraints object.
* For example, you can specify whether or not to follow referrals.
* You can also apply LDAP v3 controls to the operation.
* cons is
* LDAPConstraints instead of LDAPSearchConstraints
*/
public void modify (String DN, LDAPModificationSet mods,
LDAPSearchConstraints cons) throws LDAPException {
modify(DN, mods, (LDAPConstraints)cons);
}
/**
* 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. LDAPModification objects to specify the
* changes to make. Each change must be specified by
* an LDAPModification object, and you must specify each
* attribute value to modify, add, or remove by an LDAPAttribute
* object. LDAPConstraints object.
* For example, you can specify whether or not to follow referrals.
* You can also apply LDAP v3 controls to the operation.
* cons is
* LDAPConstraints instead of LDAPSearchConstraints
*/
public void modify (String DN, LDAPModification[] mods,
LDAPSearchConstraints cons) throws LDAPException {
modify(DN, mods, (LDAPConstraints)cons);
}
/**
* Deletes the entry for the specified DN from the directory.
* ...
* String myEntryDN = "cn=Barbara Jensen,ou=Product Development,o=Ace Industry,c=US";
* myConn.delete( myEntryDN );
* ...
*
* @param DN distinguished name identifying the entry
* to remove from the directory
* @exception LDAPException Failed to delete the specified entry from
* the directory.
*/
public void delete( String DN ) throws LDAPException {
delete(DN, m_defaultConstraints);
}
/**
* Deletes the entry for the specified DN from the directory and
* allows you to specify preferences for this LDAP delete operation
* by using an LDAPConstraints object. For
* example, you can specify whether or not to follow referrals.
* You can also apply LDAP v3 controls to the operation.
* cons is
* LDAPConstraints instead of LDAPSearchConstraints
*/
public void delete( String DN, LDAPSearchConstraints cons )
throws LDAPException {
delete(DN, (LDAPConstraints)cons);
}
/**
* Renames an existing entry in the directory.
* cn=Barbara
* cn=Babs
*
* The following example renames an entry. The old name of the entry
* is kept as a value in the entry.
* ...
* String myEntryDN = "cn=Barbara Jensen,ou=Product Development,o=Ace Industry,c=US";
* String newRDN = "cn=Babs Jensen";
* myConn.rename( myEntryDN, newRDN, false );
* ...
*
* @param DN current distinguished name of the entry
* @param newRDN new relative distinguished name for the entry (for example,
* "cn=newName")
* @param deleteOldRDN if true, the old name is not retained
* as an attribute value (for example, the attribute value "cn=oldName" is
* removed). If false, the old name is retained
* as an attribute value (for example, the entry might now have two values
* for the cn attribute: "cn=oldName" and "cn=newName").
* @exception LDAPException Failed to rename the specified entry.
*/
public void rename (String DN, String newRDN, boolean deleteOldRDN )
throws LDAPException {
rename(DN, newRDN, null, deleteOldRDN);
}
/**
* Renames an existing entry in the directory.
* cn=Barbara
* cn=Babs
*
* The following example renames an entry. The old name of the entry
* is kept as a value in the entry.
* ...
* String myEntryDN = "cn=Barbara Jensen,ou=Product Development,o=Ace Industry,c=US";
* String newRDN = "cn=Babs Jensen";
* myConn.rename( myEntryDN, newRDN, false );
* ...
*
* @param DN current distinguished name of the entry
* @param newRDN new relative distinguished name for the entry (for example,
* "cn=newName")
* @param deleteOldRDN if true, the old name is not retained
* as an attribute value (for example, the attribute value "cn=oldName" is
* removed). If false, the old name is retained
* as an attribute value (for example, the entry might now have two values
* for the cn attribute: "cn=oldName" and "cn=newName").
* @param cons the set of preferences to apply to this operation
* @exception LDAPException Failed to rename the specified entry.
*/
public void rename (String DN, String newRDN, boolean deleteOldRDN,
LDAPConstraints cons )
throws LDAPException {
rename(DN, newRDN, null, deleteOldRDN, cons);
}
/**
* @deprecated Please use the method signature where cons is
* LDAPConstraints instead of LDAPSearchConstraints
*/
public void rename (String DN, String newRDN, boolean deleteOldRDN,
LDAPSearchConstraints cons )
throws LDAPException {
rename(DN, newRDN, deleteOldRDN, (LDAPConstraints)cons);
}
/**
* Renames an existing entry in the directory and (optionally)
* changes the location of the entry in the directory tree.newParentDN
* argument, an LDAPException will be thrown.
* true, the old name is not retained
* as an attribute value (for example, the attribute value "cn=oldName" is
* removed). If false, the old name is retained
* as an attribute value (for example, the entry might now have two values
* for the cn attribute: "cn=oldName" and "cn=newName").
* @exception LDAPException Failed to rename the specified entry.
*/
public void rename(String dn,
String newRDN,
String newParentDN,
boolean deleteOldRDN) throws LDAPException {
rename(dn, newRDN, newParentDN, deleteOldRDN, m_defaultConstraints);
}
/**
* Renames an existing entry in the directory and (optionally)
* changes the location of the entry in the directory tree. Also
* allows you to specify preferences for this LDAP modify DN operation
* by using an LDAPConstraints object. For
* example, you can specify whether or not to follow referrals.
* You can also apply LDAP v3 controls to the operation.
* newParentDN
* argument, an LDAPException will be thrown.
* true, the old name is not retained
* as an attribute value (for example, the attribute value "cn=oldName" is
* removed). If false, the old name is retained
* as an attribute value (for example, the entry might now have two values
* for the cn attribute: "cn=oldName" and "cn=newName").
* @param cons the set of preferences to apply to this operation
* @exception LDAPException Failed to rename the specified entry.
* @see netscape.ldap.LDAPConstraints
*/
public void rename (String DN,
String newRDN,
String newParentDN,
boolean deleteOldRDN,
LDAPConstraints cons)
throws LDAPException {
checkConnection(/*rebind=*/true);
LDAPResponseListener myListener = getResponseListener ();
try {
JDAPModifyRDNRequest request = null;
if ( newParentDN != null ) {
request = new JDAPModifyRDNRequest (DN,
newRDN,
deleteOldRDN,
newParentDN);
} else {
request = new JDAPModifyRDNRequest (DN,
newRDN,
deleteOldRDN);
}
sendRequest (request, myListener, cons);
LDAPMessage response = myListener.getResponse();
checkMsg (response);
} catch (LDAPReferralException e) {
performReferrals(e, cons, JDAPProtocolOp.MODIFY_RDN_REQUEST,
DN, 0, newRDN, null, deleteOldRDN, null, null,
null, null);
} finally {
releaseResponseListener (myListener);
}
}
/**
* @deprecated Please use the method signature where cons is
* LDAPConstraints instead of LDAPSearchConstraints
*/
public void rename (String DN,
String newRDN,
String newParentDN,
boolean deleteOldRDN,
LDAPSearchConstraints cons)
throws LDAPException {
rename(DN, newRDN, newParentDN, deleteOldRDN, (LDAPConstraints)cons);
}
/**
* Adds an entry to the directory.
*
* @param entry LDAPEntry object specifying the distinguished name and
* attributes of the new entry
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPEntry
* @see netscape.ldap.LDAPResponseListener
*/
public LDAPResponseListener add(LDAPEntry entry,
LDAPResponseListener listener)
throws LDAPException{
return add(entry, listener, m_defaultConstraints);
}
/**
* Adds an entry to the directory and allows you to specify constraints
* for this LDAP add operation by using an LDAPConstraints
* object. For example, you can specify whether or not to follow referrals.
* You can also apply LDAP v3 controls to the operation.
* LDAPConstraints object. If the object
* has been disconnected from an LDAP server, this method attempts to
* reconnect to the server. If the object had already authenticated, the
* old authentication is discarded.
*
* @param dn if non-null and non-empty, specifies that the connection
* and all operations through it should authenticate with dn as the
* distinguished name
* @param passwd if non-null and non-empty, specifies that the connection
* and all operations through it should authenticate with dn as the
* distinguished name and passwd as password
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @param cons constraints specific to the operation
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPResponseListener
* @see netscape.ldap.LDAPConstraints
*/
public LDAPResponseListener bind(String dn,
String passwd,
LDAPResponseListener listener,
LDAPConstraints cons)
throws LDAPException{
return bind( m_protocolVersion, dn, passwd, listener, cons );
}
/**
* Authenticates to the LDAP server (to which the object is currently
* connected) using the specified name and password and allows you
* to specify constraints for this LDAP add operation by using an
* LDAPConstraints object. If the object
* has been disconnected from an LDAP server, this method attempts to
* reconnect to the server. If the object had already authenticated, the
* old authentication is discarded.
*
* @param version required LDAP protocol version
* @param dn if non-null and non-empty, specifies that the connection
* and all operations through it should authenticate with dn as the
* distinguished name
* @param passwd if non-null and non-empty, specifies that the connection
* and all operations through it should authenticate with dn as the
* distinguished name and passwd as password
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @param cons constraints specific to the operation
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPResponseListener
* @see netscape.ldap.LDAPConstraints
*/
public LDAPResponseListener bind(int version,
String dn,
String passwd,
LDAPResponseListener listener,
LDAPConstraints cons)
throws LDAPException{
return authenticate( version, dn, passwd, listener, cons );
}
/**
* Deletes the entry for the specified DN from the directory.
*
* @param dn distinguished name of the entry to delete
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPResponseListener
* @see netscape.ldap.LDAPConstraints
*/
public LDAPResponseListener delete(String dn,
LDAPResponseListener listener)
throws LDAPException{
return delete(dn, listener, m_defaultConstraints);
}
/**
* Deletes the entry for the specified DN from the directory.
*
* @param dn distinguished name of the entry to delete
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @param cons constraints specific to the operation
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPResponseListener
* @see netscape.ldap.LDAPConstraints
*/
public LDAPResponseListener delete(String dn,
LDAPResponseListener listener,
LDAPConstraints cons)
throws LDAPException{
if (cons == null) {
cons = m_defaultConstraints;
}
checkConnection(/*rebind=*/true);
if (listener == null) {
listener = new LDAPResponseListener(/*asynchOp=*/true);
}
sendRequest (new JDAPDeleteRequest(dn), listener, cons);
return listener;
}
/**
* 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 make and
* the LDAPAttribute value to be changed.
*
* @param dn distinguished name of the entry to modify
* @param mod a single change to make to an entry
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPModification
* @see netscape.ldap.LDAPResponseListener
*/
public LDAPResponseListener modify(String dn,
LDAPModification mod,
LDAPResponseListener listener)
throws LDAPException{
return modify(dn, mod, listener, m_defaultConstraints);
}
/**
* 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 make and
* the LDAPAttribute value to be changed.
*
* @param dn distinguished name of the entry to modify
* @param mod a single change to make to an entry
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @param cons constraints specific to the operation
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
* @see netscape.ldap.LDAPModification
* @see netscape.ldap.LDAPResponseListener
* @see netscape.ldap.LDAPConstraints
*/
public LDAPResponseListener modify(String dn,
LDAPModification mod,
LDAPResponseListener listener,
LDAPConstraints cons)
throws LDAPException{
if (cons == null) {
cons = m_defaultConstraints;
}
checkConnection(/*rebind=*/true);
if (listener == null) {
listener = new LDAPResponseListener(/*asynchOp=*/true);
}
LDAPModification[] modList = { mod };
sendRequest (new JDAPModifyRequest (dn, modList), listener, cons);
return listener;
}
/**
* 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.
* abandon method.
*
* @param base the base distinguished name from which to search
* @param scope the scope of the entries to search. You can specify one
* of the following:
*
* 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) abandon method.
*
* @param base the base distinguished name from which to search
* @param scope the scope of the entries to search. You can specify one
* of the following:
*
* 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) getResultCode on the
* LDAPResponse from the LDAPResponseListener.
* The code will be LDAPException.COMPARE_TRUE or
* LDAPException.COMPARE_FALSE.
*
* @param dn distinguished name of the entry to compare
* @param attr attribute with a value to compare
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
*/
public LDAPResponseListener compare(String dn,
LDAPAttribute attr,
LDAPResponseListener listener)
throws LDAPException {
return compare(dn, attr, listener, m_defaultConstraints);
}
/**
* Compare an attribute value with one in the directory. The result can
* be obtained by calling getResultCode on the
* LDAPResponse from the LDAPResponseListener.
* The code will be LDAPException.COMPARE_TRUE or
* LDAPException.COMPARE_FALSE.
*
* @param dn distinguished name of the entry to compare
* @param attr attribute with a value to compare
* @param listener handler for messages returned from a server in response
* to this request. If it is null, a listener object is created internally.
* @param cons constraints specific to this operation
* @return LDAPResponseListener handler for messages returned from a server
* in response to this request.
* @exception LDAPException Failed to send request.
*/
public LDAPResponseListener compare(String dn,
LDAPAttribute attr,
LDAPResponseListener listener,
LDAPConstraints cons)
throws LDAPException {
if (cons == null) {
cons = m_defaultConstraints;
}
checkConnection(/*rebind=*/true);
if (listener == null) {
listener = new LDAPResponseListener(/*asynchOp=*/true);
}
Enumeration en = attr.getStringValues();
String val = (String)en.nextElement();
JDAPAVA ava = new JDAPAVA(attr.getName(), val);
sendRequest (new JDAPCompareRequest (dn, ava), listener, cons);
return listener;
}
/**
* Cancels the ldap request with the specified id and discards
* any results already received.
*
* @param id an LDAP request id
* @exception LDAPException Failed to send request.
*/
public void abandon(int id) throws LDAPException {
if (!isConnected()) {
return;
}
try {
/* Tell listener thread to discard results and send an abandon request */
LDAPControl ctrls[] = m_defaultConstraints.getServerControls();
m_thread.abandon( id, ctrls );
} catch (Exception ignore) {}
}
/**
* Cancels all outstanding search requests associated with this
* LDAPSearchListener object and discards any results already received.
*
* @param searchlistener a search listener returned from a search
* @exception LDAPException Failed to send request.
*/
public void abandon(LDAPSearchListener searchlistener)throws LDAPException {
int[] ids = searchlistener.getMessageIDs();
for (int i=0; i < ids.length; i++) {
searchlistener.removeRequest(ids[i]);
abandon(ids[i]);
}
}
/**
* Returns the value of the specified option for this
* LDAPConnection object. getSearchConstraints method.
*
*
* LDAPConstraints object (or a
* LDAPSearchConstraints object for a search or find operation)
* with your new constraints
* and pass it to the LDAPConnection method that performs the
* operation.
* setOption method to change the constraint.
* LDAPSearchConstraints object.)
*
* LDAPConnection ld = new LDAPConnection();
* int sizeLimit = ( (Integer)ld.getOption( LDAPv2.SIZELIMIT ) ).intValue();
* System.out.println( "Maximum number of results: " + sizeLimit );
*
*
* @param option you can specify one of the following options:
*
*
*
* Option Data Type Description
*
*
* LDAPv2.PROTOCOL_VERSION
* IntegerSpecifies the version of the LDAP protocol used by the
* client.
*
*
*
* LDAPv2.DEREF
* IntegerSpecifies when your client dereferences aliases.
*
* Legal values for this option are:
*
* DEREF_NEVER Aliases are never dereferenced.
*
* DEREF_FINDING Aliases are dereferenced when find-
* ing the starting point for the
* search (but not when searching
* under that starting entry).
*
* DEREF_SEARCHING Aliases are dereferenced when
* searching the entries beneath the
* starting point of the search (but
* not when finding the starting
* entry).
*
* DEREF_ALWAYS Aliases are always dereferenced.
*
* DEREF_NEVER.
*
*
* LDAPv2.SIZELIMIT
* IntegerSpecifies the maximum number of search results to return.
* If this option is set to 0, there is no maximum limit.
*
*
*
* LDAPv2.TIMELIMIT
* IntegerSpecifies 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.
*
*
*
* LDAPv2.REFERRALS
* BooleanSpecifies whether or not your client follows referrals automatically.
* If true, your client follows referrals automatically.
* If false, an LDAPReferralException is raised
* when referral is detected.
* false.
*
*
* LDAPv2.REFERRALS_REBIND_PROC
* LDAPRebindSpecifies an object with a class that implements the
* LDAPRebind interface. You must define this class and
* the getRebindAuthentication method that will be used to
* get the distinguished name and password to use for authentication.
* Modifying this option sets the LDAPv2.BIND option to null.
* null.
*
*
* LDAPv2.BIND
* LDAPBindSpecifies an object with a class that implements the
* LDAPBind
* interface. You must define this class and the
* bind method that will be used to authenticate
* to the server on referrals. Modifying this option sets the
* LDAPv2.REFERRALS_REBIND_PROC to null.
* null.
*
*
* LDAPv2.REFERRALS_HOP_LIMIT
* IntegerSpecifies the maximum number of referrals in a sequence that
* your client will follow. (For example, if REFERRALS_HOP_LIMIT is 5,
* your client will follow no more than 5 referrals in a row when resolving
* a single LDAP request.)
*
*
*
* LDAPv2.BATCHSIZE
* IntegerSpecifies the number of search results to return at a time.
* (For example, if BATCHSIZE is 1, results are returned one at a time.)
*
*
*
* LDAPv3.CLIENTCONTROLS
* LDAPControl[]Specifies the client controls that may affect the handling of LDAP
* operations in the LDAP classes. These controls are used by the client
* and are not passed to the LDAP server. At this time, no client controls
* are defined for clients built with the Netscape LDAP classes.
*
*
* LDAPv3.SERVERCONTROLS
* LDAPControl[]Specifies the server controls that are passed to the LDAP
* server on each LDAP operation. Not all servers support server
* controls; a particular server may or may not support a given
* server control.
*
*
* MAXBACKLOG
* IntegerSpecifies the maximum number of search results to accumulate in an
* LDAPSearchResults before suspending the reading of input from the server.
* Integer.)
* @exception LDAPException Failed to get the specified option.
* @see netscape.ldap.LDAPRebind
* @see netscape.ldap.LDAPConstraints
* @see netscape.ldap.LDAPSearchConstraints
* @see netscape.ldap.LDAPReferralException
* @see netscape.ldap.LDAPControl
* @see netscape.ldap.LDAPConnection#getSearchConstraints
* @see netscape.ldap.LDAPConnection#search(java.lang.String, int, java.lang.String, java.lang.String[], boolean, netscape.ldap.LDAPSearchConstraints)
*/
public Object getOption( int option ) throws LDAPException {
if (option == LDAPv2.PROTOCOL_VERSION) {
return new Integer(m_protocolVersion);
}
return getOption(option, m_defaultConstraints);
}
private static Object getOption( int option, LDAPSearchConstraints cons )
throws LDAPException {
switch (option) {
case LDAPv2.DEREF:
return new Integer (cons.getDereference());
case LDAPv2.SIZELIMIT:
return new Integer (cons.getMaxResults());
case LDAPv2.TIMELIMIT:
return new Integer (cons.getServerTimeLimit());
case LDAPv2.REFERRALS:
return new Boolean (cons.getReferrals());
case LDAPv2.REFERRALS_REBIND_PROC:
return cons.getRebindProc();
case LDAPv2.BIND:
return cons.getBindProc();
case LDAPv2.REFERRALS_HOP_LIMIT:
return new Integer (cons.getHopLimit());
case LDAPv2.BATCHSIZE:
return new Integer (cons.getBatchSize());
case LDAPv3.CLIENTCONTROLS:
return cons.getClientControls();
case LDAPv3.SERVERCONTROLS:
return cons.getServerControls();
case MAXBACKLOG:
return new Integer (cons.getMaxBacklog());
default:
throw new LDAPException ( "invalid option",
LDAPException.PARAM_ERROR );
}
}
/**
* Sets the value of the specified option for this
* LDAPConnection object. getSearchConstraints method.
* LDAPConstraints object (or a
* LDAPSearchConstraints object for a search or find operation)
* with your new constraints
* and pass it to the LDAPConnection method that performs the
* operation.
* LDAPSearchConstraints object.)
*
* LDAPConnection ld = new LDAPConnection();
* Integer newLimit = new Integer( 20 );
* ld.setOption( LDAPv2.SIZELIMIT, newLimit );
* System.out.println( "Changed the maximum number of results to " + newLimit.intValue() );
*
*
* @param option you can specify one of the following options:
*
*
*
* Option Data Type Description
*
*
* LDAPv2.PROTOCOL_VERSION
* IntegerSpecifies the version of the LDAP protocol used by the
* client.
*
*
*
* LDAPv2.DEREF
* IntegerSpecifies when your client dereferences aliases.
*
* Legal values for this option are:
*
* DEREF_NEVER Aliases are never dereferenced.
*
* DEREF_FINDING Aliases are dereferenced when find-
* ing the starting point for the
* search (but not when searching
* under that starting entry).
*
* DEREF_SEARCHING Aliases are dereferenced when
* searching the entries beneath the
* starting point of the search (but
* not when finding the starting
* entry).
*
* DEREF_ALWAYS Aliases are always dereferenced.
*
* DEREF_NEVER.
*
*
* LDAPv2.SIZELIMIT
* IntegerSpecifies the maximum number of search results to return.
* If this option is set to 0, there is no maximum limit.
*
*
*
* LDAPv2.TIMELIMIT
* IntegerSpecifies 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.
*
*
*
* LDAPv2.REFERRALS
* BooleanSpecifies whether or not your client follows referrals automatically.
* If true, your client follows referrals automatically.
* If false, an LDAPReferralException is
* raised when a referral is detected.
* false.
*
*
* LDAPv2.REFERRALS_REBIND_PROC
* LDAPRebindSpecifies an object with a class that implements the
* LDAPRebind
* interface. You must define this class and the
* getRebindAuthentication method that will be used to get
* the distinguished name and password to use for authentication.
* Modifying this option sets the LDAPv2.BIND option to null.
* null.
*
*
* LDAPv2.BIND
* LDAPBindSpecifies an object with a class that implements the
* LDAPBind
* interface. You must define this class and the
* bind method that will be used to autheniticate
* to the server on referrals. Modifying this option sets the
* LDAPv2.REFERRALS_REBIND_PROC to null.
* null.
*
*
* LDAPv2.REFERRALS_HOP_LIMIT
* IntegerSpecifies the maximum number of referrals in a sequence that
* your client will follow. (For example, if REFERRALS_HOP_LIMIT is 5,
* your client will follow no more than 5 referrals in a row when resolving
* a single LDAP request.)
*
*
*
* LDAPv2.BATCHSIZE
* IntegerSpecifies the number of search results to return at a time.
* (For example, if BATCHSIZE is 1, results are returned one at a time.)
*
*
*
* LDAPv3.CLIENTCONTROLS
* LDAPControl[]Specifies the client controls that may affect handling of LDAP
* operations in the LDAP classes. These controls are used by the client
* and are not passed to the server. At this time, no client controls
* are defined for clients built with the Netscape LDAP classes.
*
*
* LDAPv3.SERVERCONTROLS
* LDAPControl[]Specifies the server controls that are passed to the LDAP
* server on each LDAP operation. Not all servers support server
* controls; a particular server may or may not support a particular
* control.
*
*
* MAXBACKLOG
* IntegerSpecifies the maximum number of search results to accumulate in an
* LDAPSearchResults before suspending the reading of input from the server.
* getResponseControls method from the LDAPSearchResults
* object returned with the result.
* @return an array of the controls returned by an operation, or
* null if none.
* @see netscape.ldap.LDAPControl
* @see netscape.ldap.LDAPSearchResults#getResponseControls
*/
public LDAPControl[] getResponseControls() {
LDAPControl[] controls = null;
Thread caller = Thread.currentThread();
/* Get the latest controls for the caller thread */
synchronized(m_responseControlTable) {
ResponseControls rspCtrls =
(ResponseControls) m_responseControlTable.get(caller);
if (rspCtrls != null) {
Vector v = rspCtrls.ctrls;
controls = (LDAPControl[]) v.elementAt(0);
v.removeElementAt(0);
if (v.size() == 0) {
m_responseControlTable.remove(caller);
}
}
}
return controls;
}
/**
* Returns an array of the latest controls associated with the
* particular request. Used internally by LDAPSearchResults to
* get response controls returned for a search request.
* getOption method.
* getConstraints method
* to create a slightly different set of constraints for a particular
* operation.
*
* ...
* LDAPConstraints myOptions = ld.getConstraints();
* myOptions.setTimeout( 3000 );
* ld.search( "cn=William Jensen, ou=Accounting, o=Ace Industry,c=US",
* "cn=Will Jensen",
* null,
* false,
* myOptions );
* ...
*
*
* @return a copy of the LDAPConstraints object representing the
* set of constraints that apply (by default) to all operations
* performed through this connection.
* @see netscape.ldap.LDAPConstraints
* @see netscape.ldap.LDAPConnection#getOption
*/
public LDAPConstraints getConstraints () {
return (LDAPConstraints)getSearchConstraints();
}
/**
* Returns the set of search constraints that apply to all searches
* performed through this connection (unless you specify a different
* set of search constraints when calling the search
* method).
* getOption method.
* getSearchConstraints method
* to create a slightly different set of search constraints
* to apply to a particular search.
*
* ...
* LDAPSearchConstraints myOptions = ld.getSearchConstraints();
* myOptions.setMaxResults( 10 );
* String[] myAttrs = { "objectclass" };
* LDAPSearchResults myResults = ld.search( "o=Ace Industry,c=US",
* LDAPv2.SCOPE_SUB,
* "(objectclass=*)",
* myAttrs,
* false,
* myOptions );
* ...
*
*
* @return a copy of the LDAPSearchConstraints object
* representing the set of search constraints that apply (by default) to
* all searches performed through this connection.
* @see netscape.ldap.LDAPSearchConstraints
* @see netscape.ldap.LDAPConnection#getOption
* @see netscape.ldap.LDAPConnection#search(java.lang.String, int, java.lang.String, java.lang.String[], boolean, netscape.ldap.LDAPSearchConstraints)
*/
public LDAPSearchConstraints getSearchConstraints () {
return (LDAPSearchConstraints)m_defaultConstraints.clone();
}
/**
* Set the default constraint set for all operations.
* @param cons LDAPConstraints object to use as the default
* constraint set
* @see netscape.ldap.LDAPConnection#getConstraints
* @see netscape.ldap.LDAPConstraints
*/
public void setConstraints(LDAPConstraints cons) {
m_defaultConstraints.setHopLimit(cons.getHopLimit());
m_defaultConstraints.setReferrals(cons.getReferrals());
m_defaultConstraints.setTimeLimit(cons.getTimeLimit());
m_defaultConstraints.setBindProc(cons.getBindProc());
m_defaultConstraints.setRebindProc(cons.getRebindProc());
LDAPControl[] tClientControls = cons.getClientControls();
LDAPControl[] oClientControls = null;
if ( (tClientControls != null) &&
(tClientControls.length > 0) ) {
oClientControls = new LDAPControl[tClientControls.length];
for( int i = 0; i < tClientControls.length; i++ ) {
oClientControls[i] = (LDAPControl)tClientControls[i].clone();
}
}
m_defaultConstraints.setClientControls(oClientControls);
LDAPControl[] tServerControls = cons.getServerControls();
LDAPControl[] oServerControls = null;
if ( (tServerControls != null) &&
(tServerControls.length > 0) ) {
oServerControls = new LDAPControl[tServerControls.length];
for( int i = 0; i < tServerControls.length; i++ ) {
oServerControls[i] = (LDAPControl)tServerControls[i].clone();
}
}
m_defaultConstraints.setServerControls(oServerControls);
}
/**
* Set the default constraint set for all search operations.
* @param cons LDAPSearchConstraints object to use as the
* default constraint set
* @see netscape.ldap.LDAPConnection#getSearchConstraints
* @see netscape.ldap.LDAPSearchConstraints
*/
public void setSearchConstraints(LDAPSearchConstraints cons) {
m_defaultConstraints = (LDAPSearchConstraints)cons.clone();
}
/**
* Gets the stream for reading from the listener socket
*
* @return the stream for reading from the listener socket, or
* null if there is none
*/
public InputStream getInputStream() {
return (m_thread != null) ? m_thread.getInputStream() : null;
}
/**
* Sets the stream for reading from the listener socket if
* there is one
*
* @param is the stream for reading from the listener socket
*/
public void setInputStream( InputStream is ) {
if ( m_thread != null ) {
m_thread.setInputStream( is );
}
}
/**
* Gets the stream for writing to the socket
*
* @return the stream for writing to the socket, or
* null if there is none
*/
public OutputStream getOutputStream() {
return (m_thread != null) ? m_thread.getOutputStream() : null;
}
/**
* Sets the stream for writing to the socket
*
* @param os the stream for writing to the socket, if there is one
*/
public void setOutputStream( OutputStream os ) {
if ( m_thread != null ) {
m_thread.setOutputStream( os );
}
}
/**
* Get a new listening agent from the internal buffer of available agents.
* These objects are used to make the asynchronous LDAP operations
* synchronous.
* @return response listener object
*/
synchronized LDAPResponseListener getResponseListener () {
if (m_responseListeners == null) {
m_responseListeners = new Vector (5);
}
LDAPResponseListener l;
if ( m_responseListeners.size() < 1 ) {
l = new LDAPResponseListener ( /*asynchOp=*/false );
}
else {
l = (LDAPResponseListener)m_responseListeners.elementAt (0);
m_responseListeners.removeElementAt (0);
}
return l;
}
/**
* Get a new search listening agent from the internal buffer of available
* agents. These objects are used to make the asynchronous LDAP operations
* synchronous.
* @return a search response listener object
*/
private synchronized LDAPSearchListener getSearchListener (
LDAPSearchConstraints cons ) {
if (m_searchListeners == null) {
m_searchListeners = new Vector (5);
}
LDAPSearchListener l;
if ( m_searchListeners.size() < 1 ) {
l = new LDAPSearchListener ( /*asynchOp=*/false, cons );
}
else {
l = (LDAPSearchListener)m_searchListeners.elementAt (0);
m_searchListeners.removeElementAt (0);
l.setSearchConstraints(cons);
}
return l;
}
/**
* Put a listening agent into the internal buffer of available agents.
* These objects are used to make the asynchronous LDAP operations
* synchronous.
* @param l listener to buffer
*/
synchronized void releaseResponseListener (LDAPResponseListener l) {
if (m_responseListeners == null) {
m_responseListeners = new Vector (5);
}
l.reset ();
m_responseListeners.addElement (l);
}
/**
* Put a search listening agent into the internal buffer of available
* agents. These objects are used to make the asynchronous LDAP
* operations synchronous.
* @param l listener to buffer
*/
synchronized void releaseSearchListener (LDAPSearchListener l) {
if (l.isAsynchOp()) { // persistent search
return;
}
if (m_searchListeners == null) {
m_searchListeners = new Vector (5);
}
l.reset ();
m_searchListeners.addElement (l);
}
/**
* Checks the message (assumed to be a return value). If the resultCode
* is anything other than SUCCESS, it throws an LDAPException describing
* the server's (error) response.
* Extract response controls from the message, if any avaialble.
* @param m server response to validate
* @exception LDAPException failed to check message
*/
void checkMsg (LDAPMessage m) throws LDAPException {
// Check for response controls
LDAPControl[] ctrls = m.getControls();
if (ctrls != null) {
int msgID = m.getMessageID();
setResponseControls(Thread.currentThread(), msgID, ctrls);
}
if (m.getProtocolOp() instanceof JDAPResult) {
JDAPResult response = (JDAPResult)(m.getProtocolOp());
int resultCode = response.getResultCode ();
if (resultCode == JDAPResult.SUCCESS) {
return;
}
if (resultCode == JDAPResult.REFERRAL) {
throw new LDAPReferralException ("referral", resultCode,
response.getReferrals());
}
if (resultCode == JDAPResult.LDAP_PARTIAL_RESULTS) {
throw new LDAPReferralException ("referral", resultCode,
response.getErrorMessage());
} else {
throw new LDAPException ("error result", resultCode,
response.getErrorMessage(),
response.getMatchedDN());
}
} else if (m.getProtocolOp() instanceof JDAPSearchResultReference) {
String[] referrals =
((JDAPSearchResultReference)m.getProtocolOp()).getUrls();
throw new LDAPReferralException ("referral",
JDAPResult.SUCCESS, referrals);
} else {
return;
}
}
/**
* Set response controls for the current connection for a particular
* thread. Get the oldest returned controls and remove them from the
* queue. If the connection is executing a persistent search, there may
* be more than one set of controls in the queue. For any other
* operation, there will only ever be at most one set of controls
* (controls from any earlier operation are replaced by controls
* received on the latest operation on this connection by this thread).
* @param current the target thread
* @param con the server response controls
*/
void setResponseControls( Thread client, int msgID, LDAPControl[] ctrls ) {
synchronized(m_responseControlTable) {
ResponseControls rspCtrls = (ResponseControls)m_responseControlTable.get(client);
if (rspCtrls == null || rspCtrls.msgID != msgID) {
rspCtrls = new ResponseControls(msgID, ctrls);
m_responseControlTable.put(client, rspCtrls);
}
else {
rspCtrls.addControls(ctrls);
}
}
}
/**
* Set up connection for referral.
* @param u referral URL
* @param cons search constraints
* @return new LDAPConnection, already connected and authenticated
*/
private LDAPConnection referralConnect( LDAPUrl[] refList,
LDAPConstraints cons )
throws LDAPException {
LDAPConnection connection = new LDAPConnection (getSocketFactory());
// Set the same connection setup failover policy as for this connection
connection.setConnSetupDelay(getConnSetupDelay());
connection.setOption(REFERRALS, new Boolean(true));
connection.setOption(REFERRALS_REBIND_PROC, cons.getRebindProc());
connection.setOption(BIND, cons.getBindProc());
Object traceOut = getProperty(TRACE_PROPERTY);
if (traceOut != null) {
connection.setProperty(TRACE_PROPERTY, traceOut);
}
// need to set the protocol version which gets passed to connection
connection.setOption(PROTOCOL_VERSION,
new Integer(m_protocolVersion));
connection.setOption(REFERRALS_HOP_LIMIT,
new Integer(cons.getHopLimit()-1));
try {
connection.connect (refList);
}
catch (LDAPException e) {
throw new LDAPException("Referral connect failed: " + e.getMessage(),
e.getLDAPResultCode());
}
return connection;
}
private void referralRebind(LDAPConnection ldc, LDAPConstraints cons)
throws LDAPException{
try {
if (cons.getRebindProc() == null && cons.getBindProc() == null) {
ldc.authenticate (m_protocolVersion, null, null);
} else if (cons.getBindProc() == null) {
LDAPRebindAuth auth =
cons.getRebindProc().getRebindAuthentication(ldc.getHost(),
ldc.getPort());
ldc.authenticate(m_protocolVersion, auth.getDN(), auth.getPassword());
} else {
cons.getBindProc().bind(ldc);
}
}
catch (LDAPException e) {
throw new LDAPException("Referral bind failed: " + e.getMessage(),
e.getLDAPResultCode());
}
}
/**
* Check for "ldap(s):///" referrals (no host:port) and replace them with
* "ldap(s)://currentHost:currentPort".
*/
private void adjustReferrals(LDAPUrl[] urls) {
String host = null;
int port =0;
for (int i=0; urls != null && i < urls.length; i++) {
host = urls[i].getHost();
port = urls[i].getPort();
if ( (host == null) || (host.length() < 1) ) {
// If no host:port was specified, use the latest (hop-wise) parameters
host = getHost();
port = getPort();
urls[i] = new LDAPUrl (host, port,
urls[i].getDN(),
urls[i].getAttributeArray(),
urls[i].getScope(),
urls[i].getFilter(),
urls[i].isSecure());
}
}
}
/**
* Establish the LDAPConnection to the referred server. This one is used
* for bind operation only since we need to keep this new connection for
* the subsequent operations. This new connection will be destroyed in
* two circumstances: disconnect gets called or the client binds as
* someone else.
* @return the new LDAPConnection to the referred server
*/
LDAPConnection createReferralConnection(LDAPReferralException e,
LDAPConstraints cons) throws LDAPException {
if (cons.getHopLimit() <= 0) {
throw new LDAPException("exceed hop limit",
e.getLDAPResultCode(), e.getLDAPErrorMessage());
}
if (!cons.getReferrals()) {
throw e;
}
LDAPUrl[] refList = e.getURLs();
// If there are no referrals (because the server isn't set up for
// them), give up here
if (refList == null) {
throw new LDAPException("No target URL in referral",
LDAPException.NO_RESULTS_RETURNED);
}
adjustReferrals(refList);
LDAPConnection connection = referralConnect(refList, cons);
// which one did we connect to...
LDAPUrl refURL = connection.m_connMgr.getLDAPUrl();
String refDN = refURL.getDN();
if ((refDN == null) || (refDN.equals(""))) {
refDN = m_boundDN;
}
try {
connection.authenticate(m_protocolVersion, refDN, m_boundPasswd);
}
catch (LDAPException authEx) {
// Disconnect needed to terminate the LDAPConnThread
try {
connection.disconnect();
}
catch (LDAPException ignore) {}
throw authEx;
}
return connection;
}
/**
* Follows a referral.
* @param e referral exception
* @param cons search constraints
*/
void performReferrals(LDAPReferralException e,
LDAPConstraints cons, int ops,
/* unions of different operation parameters */
String dn, int scope, String filter, String types[],
boolean attrsOnly, LDAPModification mods[],
LDAPEntry entry,
LDAPAttribute attr,
/* result */
Vector results
) throws LDAPException {
LDAPUrl refURL = null;
LDAPConnection connection = null;
try {
if (cons.getHopLimit() <= 0) {
throw new LDAPException("exceed hop limit",
e.getLDAPResultCode(),
e.getLDAPErrorMessage());
}
if (!cons.getReferrals()) {
if (ops == JDAPProtocolOp.SEARCH_REQUEST) {
LDAPSearchResults res = new LDAPSearchResults();
res.add(e);
results.addElement(res);
return;
} else {
throw e;
}
}
LDAPUrl urls[] = e.getURLs();
// If there are no referrals (because the server isn't configured to
// return one), give up here
if ( urls == null || urls.length == 0) {
return;
}
adjustReferrals(urls);
// Check if we can use m_referralConnection to follow this referral
if (m_referralConnection != null && m_referralConnection.isConnected()) {
String refHost = m_referralConnection.getHost();
int refPort = m_referralConnection.getPort();
try {
// Compare ipAddr:port for each referral with the m_referralConnection
String refAddr = InetAddress.getByName(refHost).getHostAddress();
for (int i = 0; i < urls.length; i++) {
String urlHost = urls[i].getHost();
int urlPort = urls[i].getPort();
String urlAddr = InetAddress.getByName(urlHost).getHostAddress();
if (refAddr == urlAddr && refPort == urlPort) {
refURL = urls[i];
break;
}
}
}
catch (UnknownHostException ex) {
// Compare host names rather than ip addr
for (int i = 0; i < urls.length; i++) {
if (refHost == urls[i].getHost() &&
refPort == urls[i].getPort()) {
refURL = urls[i];
break;
}
}
}
}
if (refURL != null) {
connection = m_referralConnection;
}
else {
connection = referralConnect( urls, cons );
// which one did we connect to...
refURL = connection.m_connMgr.getLDAPUrl();
// Authenticate
referralRebind(connection, cons);
}
String newDN = refURL.getDN();
String DN = null;
if ((newDN == null) || (newDN.equals(""))) {
DN = dn;
} else {
DN = newDN;
}
// If this was a one-level search, and a direct subordinate
// has a referral, there will be a "?base" in the URL, and
// we have to rewrite the scope from one to base
if ( refURL.getUrl().indexOf("?base") > -1 ) {
scope = SCOPE_BASE;
}
LDAPSearchConstraints newcons = (LDAPSearchConstraints)cons.clone();
newcons.setHopLimit( cons.getHopLimit()-1 );
referralOperation(connection, newcons, ops, DN, scope, filter,
types, attrsOnly, mods, entry, attr, results);
}
catch (LDAPException ex) {
if (refURL != null) {
ex.setExtraMessage("Failed to follow referral to " + refURL);
}
else {
ex.setExtraMessage("Failed to follow referral");
}
throw ex;
}
}
void referralOperation(LDAPConnection connection,
LDAPConstraints cons, int ops, String dn, int scope,
String filter, String types[], boolean attrsOnly,
LDAPModification mods[], LDAPEntry entry,
LDAPAttribute attr,
Vector results) throws LDAPException {
LDAPSearchResults res = null;
try {
switch (ops) {
case JDAPProtocolOp.SEARCH_REQUEST:
res = connection.search(dn, scope, filter,
types, attrsOnly,
(LDAPSearchConstraints)cons);
if (res != null) {
res.closeOnCompletion(connection);
results.addElement(res);
} else {
if ((m_referralConnection == null) ||
(!connection.equals(m_referralConnection)))
connection.disconnect();
}
break;
case JDAPProtocolOp.MODIFY_REQUEST:
connection.modify(dn, mods, cons);
break;
case JDAPProtocolOp.ADD_REQUEST:
if ((dn != null) && (!dn.equals("")))
entry.setDN(dn);
connection.add(entry, cons);
break;
case JDAPProtocolOp.DEL_REQUEST:
connection.delete(dn, cons);
break;
case JDAPProtocolOp.MODIFY_RDN_REQUEST:
connection.rename(dn, filter /* newRDN */,
attrsOnly /* deleteOld */, cons);
break;
case JDAPProtocolOp.COMPARE_REQUEST:
boolean bool = connection.compare(dn, attr, cons);
results.addElement(new Boolean(bool));
break;
default:
/* impossible */
break;
}
} catch (LDAPException ee) {
throw ee;
} finally {
if ((connection != null) &&
((ops != JDAPProtocolOp.SEARCH_REQUEST) || (res == null)) &&
((m_referralConnection == null) ||
(!connection.equals(m_referralConnection)))) {
connection.disconnect();
}
}
}
/**
* Follows a referral for an extended operation.
* @param e referral exception
* @param cons search constraints
*/
private LDAPExtendedOperation performExtendedReferrals(
LDAPReferralException e,
LDAPConstraints cons, LDAPExtendedOperation op )
throws LDAPException {
if (cons.getHopLimit() <= 0) {
throw new LDAPException("exceed hop limit",
e.getLDAPResultCode(),
e.getLDAPErrorMessage());
}
if (!cons.getReferrals()) {
throw e;
}
LDAPUrl u[] = e.getURLs();
// If there are no referrals (because the server isn't configured to
// return one), give up here
if ( u == null || u.length == 0) {
return null;
}
adjustReferrals(u);
LDAPConnection connection = referralConnect( u, cons);
referralRebind(connection, cons);
LDAPExtendedOperation results =
connection.extendedOperation( op );
connection.disconnect();
return results; /* return right away if operation is successful */
}
/**
* Returns a new LDAPConnection object that shares
* the physical connection to the LDAP server but has its own state.
*
* The returned LDAPConnection object contains the same
* state as the current connection, including:
*
*
* LDAPconnection object representing the
* new object.
*/
public synchronized Object clone() {
LDAPConnection c = null;
try {
if (m_thread != null) {
checkConnection(/*rebind=*/true);
}
}
catch (LDAPException ignore) {}
try {
c = (LDAPConnection)super.clone();
c.m_defaultConstraints =
(LDAPSearchConstraints)m_defaultConstraints.clone();
c.m_responseListeners = null;
c.m_searchListeners = null;
c.m_properties = (Hashtable)m_properties.clone();
c.m_responseControlTable = new Hashtable();
if (c.m_cache != null) {
c.m_cache.addReference();
}
if (isConnected()) {
/* share current connection thread */
c.m_thread.register(c);
}
else {
c.m_thread = null;
c.m_connMgr = null;
}
} catch (Exception ignore) {}
return c;
}
/**
* Sets up basic connection privileges for Communicator.
* @return true if in Communicator and connections okay.
*/
private static boolean checkCommunicator() {
try {
java.lang.reflect.Method m = LDAPCheckComm.getMethod(
"netscape.security.PrivilegeManager", "enablePrivilege");
if (m == null) {
printDebug("Method is null");
return false;
}
Object[] args = new Object[1];
args[0] = new String("UniversalConnect");
m.invoke( null, args);
printDebug( "UniversalConnect enabled" );
args[0] = new String("UniversalPropertyRead");
m.invoke( null, args);
printDebug( "UniversalPropertyRead enabled" );
return true;
} catch (LDAPException e) {
printDebug("Exception: "+e.toString());
} catch (Exception ie) {
printDebug("Exception on invoking " + "enablePrivilege: "+ie.toString());
}
return false;
}
/**
* Reports if the class is running in a Netscape browser.
* @return true if the class is running in a Netscape browser.
*/
public static boolean isNetscape() {
return isCommunicator;
}
static void printDebug( String msg ) {
if ( debug ) {
System.out.println( msg );
}
}
/**
* Returns the string representation for this LDAPConnection.
* LDAPConnection {ldap://dilly:389 (2) ldapVersion:3 bindDN:"uid=admin,o=iplanet.com"}
*
* For cloned connections, the number of LDAPConnection instances sharing the
* same physical connection is shown in parenthesis following the ldap url.
* If a LDAPConnection is not cloned, this number is omitted from the string
* representation.
*
* @return string representation of the connection.
* @see netscape.ldap.LDAPConnection#clone
*/
public String toString() {
int cloneCnt = (m_thread == null) ? 0 : m_thread.getClientCount();
StringBuffer sb = new StringBuffer("LDAPConnection {");
//url
if (m_connMgr != null) {
sb.append(m_connMgr.getLDAPUrl().getServerUrl());
}
// clone count
if (cloneCnt > 1) {
sb.append(" (");
sb.append(cloneCnt);
sb.append(")");
}
// ldap version
sb.append(" ldapVersion:");
sb.append(m_protocolVersion);
// bind DN
sb.append(" bindDN:\"");
if (getAuthenticationDN() != null) {
sb.append(getAuthenticationDN());
}
sb.append("\"}");
return sb.toString();
}
/**
* A helper class for collecting response controls. Used as a value
* in m_responseControlTable
*/
class ResponseControls {
int msgID;
Vector ctrls;
public ResponseControls(int msgID, LDAPControl[] ctrls) {
this.msgID = msgID;
this.ctrls = new Vector();
this.ctrls.addElement(ctrls);
}
void addControls(LDAPControl[] ctrls) {
this.ctrls.addElement(ctrls);
}
}
/**
* Prints out the LDAP Java SDK version and the highest LDAP
* protocol version supported by the SDK. To view this
* information, open a terminal window, and enter:
* java netscape.ldap.LDAPConnection
*
* @param args not currently used
*/
public static void main(String[] args) {
System.out.println("LDAP SDK Version is "+SdkVersion);
System.out.println("LDAP Protocol Version is "+ProtocolVersion);
}
/**
* Option specifying the maximum number of unread entries to be cached in any
* LDAPSearchResults without suspending reading from the server.
* @see netscape.ldap.LDAPConnection#getOption
* @see netscape.ldap.LDAPConnection#setOption
*/
public static final int MAXBACKLOG = 30;
private static boolean isCommunicator = checkCommunicator();
private static boolean debug = false;
}