diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPAsynchronousConnection.java b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPAsynchronousConnection.java
index a28bb923ba6..abad1d77dc4 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPAsynchronousConnection.java
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPAsynchronousConnection.java
@@ -168,9 +168,9 @@ public interface LDAPAsynchronousConnection {
/**
- * 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).
+ * Makes a single change to an existing entry in the directory.
+ * For example, changes the value of an attribute, adds a new attribute
+ * value, or removes an existing attribute value.
* The LDAPModification object specifies both the change to be made and
* the LDAPAttribute value to be changed.
*
@@ -190,9 +190,9 @@ public interface LDAPAsynchronousConnection {
throws LDAPException;
/**
- * 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).
+ * Makes a single change to an existing entry in the directory.
+ * For example, changes the value of an attribute, adds a new attribute
+ * value, or removes an existing attribute value.
* The LDAPModification object specifies both the change to be made and
* the LDAPAttribute value to be changed.
*
@@ -215,9 +215,9 @@ public interface LDAPAsynchronousConnection {
throws LDAPException;
/**
- * Makes a set of changes to an existing entry in the directory (for
- * example, changes attribute values, adds new attribute values, or
- * removes existing attribute values).
+ * 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 modifications to make to the entry
@@ -235,9 +235,9 @@ public interface LDAPAsynchronousConnection {
throws LDAPException;
/**
- * Makes a set of changes to an existing entry in the directory (for
- * example, changes attribute values, adds new attribute values, or
- * removes existing attribute values).
+ * 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 modifications to make to the entry
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPConnSetupMgr.java b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPConnSetupMgr.java
index 3cad0bb677b..fbebb588d39 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPConnSetupMgr.java
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPConnSetupMgr.java
@@ -38,12 +38,12 @@ import java.net.*;
* When a connection is successfully created, a socket is opened. The socket
* is passed to the LDAPConnThread. The LDAPConnThread must call
* invalidateConnection() if the connection is lost due to a network or
- * server error, or disconnect() if the connection is deliberately terminated
+ * server error, or closeConnection() if the connection is deliberately terminated
* by the user.
*/
-class LDAPConnSetupMgr implements Cloneable, java.io.Serializable {
+class LDAPConnSetupMgr implements java.io.Serializable {
- static final long serialVersionUID = 1519402748245755306L;
+ static final long serialVersionUID = 1519402748245755307L;
/**
* Policy for opening a connection when multiple servers are used
*/
@@ -65,28 +65,32 @@ class LDAPConnSetupMgr implements Cloneable, java.io.Serializable {
* Representation for a server in the server list.
*/
class ServerEntry {
- String host;
- int port;
+ LDAPUrl url;
int connSetupStatus;
Thread connSetupThread;
- ServerEntry(String host, int port, int status) {
- this.host = host;
- this.port = port;
+ ServerEntry(LDAPUrl url, int status) {
+ this.url = url;
connSetupStatus = status;
connSetupThread = null;
- }
-
+ }
public String toString() {
- return "{" +host+":"+port + " status="+connSetupStatus+"}";
+ return "{" + url + " status="+connSetupStatus+"}";
}
}
+
/**
* Socket to the connected server
*/
private Socket m_socket = null;
+ /**
+ * Original, underlying socket to the server, see layerSocket()
+ */
+ private Socket m_origSocket = null;
+
+
/**
* Last exception occured during connection setup
*/
@@ -128,25 +132,50 @@ class LDAPConnSetupMgr implements Cloneable, java.io.Serializable {
*/
private transient int m_attemptCnt = 0;
- /**
- * Connection IDs for ldap trace messages
- */
- private static int m_nextId;
- private int m_id;
-
/**
* Constructor
* @param host list of host names to which to connect
* @param port list of port numbers corresponding to the host list
* @param factory socket factory for SSL connections
*/
- LDAPConnSetupMgr(String[] hosts, int[] ports, LDAPSocketFactory factory) {
+ LDAPConnSetupMgr(String[] hosts, int[] ports, LDAPSocketFactory factory) throws LDAPException{
m_dsList = new ServerEntry[hosts.length];
+ boolean secure = (factory != null);
for (int i=0; i < hosts.length; i++) {
- m_dsList[i] = new ServerEntry(hosts[i], ports[i], NEVER_USED);
+ String url = secure ? "ldaps://" : "ldap://";
+ url += hosts[i] + ":" + ports[i];
+ try {
+ m_dsList[i] = new ServerEntry(new LDAPUrl(url), NEVER_USED);
+ }
+ catch (MalformedURLException ex) {
+ throw new LDAPException("Invalid host:port " + hosts[i]+":"+ports[i],
+ LDAPException.PARAM_ERROR);
+ }
+ }
+ m_factory = factory;
+ }
+
+ LDAPConnSetupMgr(String[] urls, LDAPSocketFactory factory) throws LDAPException{
+ m_dsList = new ServerEntry[urls.length];
+ for (int i=0; i < urls.length; i++) {
+ try {
+ LDAPUrl url = new LDAPUrl(urls[i]);
+ m_dsList[i] = new ServerEntry(url, NEVER_USED);
+ }
+ catch (MalformedURLException ex) {
+ throw new LDAPException("Malformed LDAP URL " + urls[i],
+ LDAPException.PARAM_ERROR);
+ }
+ }
+ m_factory = factory;
+ }
+
+ LDAPConnSetupMgr(LDAPUrl[] urls, LDAPSocketFactory factory) throws LDAPException{
+ m_dsList = new ServerEntry[urls.length];
+ for (int i=0; i < urls.length; i++) {
+ m_dsList[i] = new ServerEntry(urls[i], NEVER_USED);
}
m_factory = factory;
- m_id = m_nextId++;
}
/**
@@ -204,7 +233,7 @@ class LDAPConnSetupMgr implements Cloneable, java.io.Serializable {
th.interrupt();
cleanup();
throw new LDAPException(
- "connect timeout, " + getServerList() + " might be unreachable",
+ "Connect timeout, " + getServerList() + " might be unreachable",
LDAPException.CONNECT_ERROR);
}
@@ -213,12 +242,13 @@ class LDAPConnSetupMgr implements Cloneable, java.io.Serializable {
}
throw new LDAPException(
- "failed to connect to server " + getServerList(),
+ "Failed to connect to server " + getServerList(),
LDAPException.CONNECT_ERROR);
}
private void reset() {
m_socket = null;
+ m_origSocket = null;
m_connException = null;
m_attemptCnt = 0;
@@ -231,9 +261,9 @@ class LDAPConnSetupMgr implements Cloneable, java.io.Serializable {
StringBuffer sb = new StringBuffer();
for (int i=0; i < m_dsList.length; i++) {
sb.append(i==0 ? "" : " ");
- sb.append(m_dsList[i].host);
+ sb.append(m_dsList[i].url.getHost());
sb.append(":");
- sb.append(m_dsList[i].port);
+ sb.append(m_dsList[i].url.getPort());
}
return sb.toString();
}
@@ -268,9 +298,25 @@ class LDAPConnSetupMgr implements Cloneable, java.io.Serializable {
newDsList[j] = m_dsList[m_dsIdx];
m_dsList = newDsList;
m_dsIdx = j;
+
+ try {
+ m_socket.close();
+ } catch (Exception e) {
+ } finally {
+ m_socket = null;
+ }
+
}
-
- m_socket = null;
+
+ if (m_origSocket != null) {
+
+ try {
+ m_origSocket.close();
+ } catch (Exception e) {
+ } finally {
+ m_origSocket = null;
+ }
+ }
}
/**
@@ -278,30 +324,69 @@ class LDAPConnSetupMgr implements Cloneable, java.io.Serializable {
* Mark the connected server status as DISCONNECTED. This will
* put it at top of the server list for the next connect attempt.
*/
- void disconnect() {
+ void closeConnection() {
if (m_socket != null) {
+
m_dsList[m_dsIdx].connSetupStatus = DISCONNECTED;
+
+ try {
+ m_socket.close();
+ } catch (Exception e) {
+ } finally {
+ m_socket = null;
+ }
+ }
+
+ if (m_origSocket != null) {
+
+ try {
+ m_origSocket.close();
+ } catch (Exception e) {
+ } finally {
+ m_origSocket = null;
+ }
}
-
- m_socket = null;
}
Socket getSocket() {
return m_socket;
}
+
+ /**
+ * Layer a new socket over the existing one (used by startTLS)
+ */
+ void layerSocket(LDAPTLSSocketFactory factory) throws LDAPException{
+ Socket s = factory.makeSocket(m_socket);
+ m_origSocket = m_socket;
+ m_socket = s;
+ }
String getHost() {
if (m_dsIdx >= 0) {
- return m_dsList[m_dsIdx].host;
+ return m_dsList[m_dsIdx].url.getHost();
}
- return m_dsList[0].host;
+ return m_dsList[0].url.getHost();
}
int getPort() {
if (m_dsIdx >= 0) {
- return m_dsList[m_dsIdx].port;
+ return m_dsList[m_dsIdx].url.getPort();
}
- return m_dsList[0].port;
+ return m_dsList[0].url.getPort();
+ }
+
+ boolean isSecure() {
+ if (m_dsIdx >= 0) {
+ return m_dsList[m_dsIdx].url.isSecure();
+ }
+ return m_dsList[0].url.isSecure();
+ }
+
+ LDAPUrl getLDAPUrl() {
+ if (m_dsIdx >= 0) {
+ return m_dsList[m_dsIdx].url;
+ }
+ return m_dsList[0].url;
}
int getConnSetupDelay() {
@@ -363,8 +448,7 @@ class LDAPConnSetupMgr implements Cloneable, java.io.Serializable {
//Create a Thread to execute connectSetver()
final int dsIdx = i;
- String threadName = "ConnSetupMgr " +
- m_dsList[dsIdx].host + ":" + m_dsList[dsIdx].port;
+ String threadName = "ConnSetupMgr " + m_dsList[dsIdx].url;
Thread t = new Thread(new Runnable() {
public void run() {
connectServer(dsIdx);
@@ -407,20 +491,29 @@ class LDAPConnSetupMgr implements Cloneable, java.io.Serializable {
Thread currThread = Thread.currentThread();
Socket sock = null;
LDAPException conex = null;
-
+
try {
/* If we are to create a socket ourselves, make sure it has
sufficient privileges to connect to the desired host */
- if (m_factory == null) {
- sock = new Socket (entry.host, entry.port);
- //s.setSoLinger( false, -1 );
+ if (!entry.url.isSecure()) {
+ sock = new Socket (entry.url.getHost(), entry.url.getPort());
} else {
- sock = m_factory.makeSocket(entry.host, entry.port);
+ LDAPSocketFactory factory = m_factory;
+ if (factory == null) {
+ factory = entry.url.getSocketFactory();
+ }
+ if (factory == null) {
+ throw new LDAPException("Can not connect, no socket factory " + entry.url,
+ LDAPException.OTHER);
+ }
+ sock = factory.makeSocket(entry.url.getHost(), entry.url.getPort());
}
+
+ sock.setTcpNoDelay( true );
}
catch (IOException e) {
conex = new LDAPException("failed to connect to server "
- + entry.host+":"+entry.port, LDAPException.CONNECT_ERROR);
+ + entry.url, LDAPException.CONNECT_ERROR);
}
catch (LDAPException e) {
conex = e;
@@ -514,29 +607,5 @@ class LDAPConnSetupMgr implements Cloneable, java.io.Serializable {
str += m_dsList[i]+ " ";
}
return str;
- }
-
- int getID() {
- return m_id;
}
-
- String getLDAPUrl() {
- return ((m_factory == null) ? "ldap" : "ldaps") +
- "://" + getHost() + ":" + getPort();
- }
-
- public Object clone() {
- try {
- LDAPConnSetupMgr cloneMgr = (LDAPConnSetupMgr) super.clone();
- cloneMgr.m_dsList = new ServerEntry[m_dsList.length];
- for (int i=0; i
+ *
* The following properties are defined:
*
* @return the object representing the socket factory used to
- * establish a connection to a server.
+ * 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;
@@ -662,17 +660,24 @@ public class LDAPConnection
/**
* Specifies the object representing the socket factory that you
- * want to use to establish a connection to a server.
+ * 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
+ *
+ * Before
+ *
+ * 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 (!isConnected()) {
- m_bound = false;
- m_authMethod = "none";
- connect ();
- // special case: the connection currently is not bound, and now there is
- // a bind request. The connection needs to reconnect if the thread has
- // more than one LDAPConnection.
- } else if (!m_bound && rebind && m_thread.getClientCount() > 1) {
- disconnect();
- connect();
+ if (m_useTLS) {
+ throw new LDAPException("Already using TLS",
+ LDAPException.OTHER);
}
- // if the connection is still intact and no rebind request
- if (m_bound && !rebind) {
- return;
+ if (m_factory == null || !( m_factory instanceof LDAPTLSSocketFactory)) {
+ throw new LDAPException("No socket factory for the startTLS operation",
+ LDAPException.OTHER);
}
- // if the connection was lost and did not have any kind of bind
- // operation and the current one does not request any bind operation (ie,
- // no authenticate has been called)
- if (!m_anonymousBound &&
- ((m_boundDN == null) || (m_boundPasswd == null)) &&
- !rebind) {
- return;
- }
+ // Denote that m_factory is to be used from now on used for TLS and not for
+ // SSL connections.
+ m_isTLSFactory = true;
- if (m_bound && rebind) {
- if (m_protocolVersion == version) {
- if (m_anonymousBound && ((m_boundDN == null) || (m_boundPasswd == null)))
- return;
+ checkConnection(/*rebind=*/true);
- if (!m_anonymousBound && (m_boundDN != null) && (m_boundPasswd != null) &&
- m_boundDN.equals(m_prevBoundDN) &&
- m_boundPasswd.equals(m_prevBoundPasswd)) {
- return;
- }
- }
-
- // if we got this far, we need to rebind since previous and
- // current credentials are not the same.
- // if the current connection is the only connection of the thread,
- // then reuse this current connection. otherwise, disconnect the current
- // one (ie, detach from the current thread) and reconnect again (ie, get
- // a new thread).
- if (m_thread.getClientCount() > 1) {
- disconnect();
- connect();
+ // 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);
}
}
- m_protocolVersion = version;
-
- LDAPResponseListener myListener = getResponseListener ();
+ // Send startTLS extended op
try {
- if (m_referralConnection != null && m_referralConnection.isConnected()) {
- m_referralConnection.disconnect();
- }
- m_referralConnection = null;
- m_bound = false;
- sendRequest(new JDAPBindRequest(m_protocolVersion, m_boundDN,
- m_boundPasswd),
- myListener, cons);
- checkMsg( myListener.getResponse() );
- markConnAsBound();
- m_rebindConstraints = (LDAPConstraints)cons.clone();
- m_authMethod = "simple";
- } catch (LDAPReferralException e) {
- m_referralConnection = createReferralConnection(e, cons);
- } finally {
- releaseResponseListener(myListener);
+ 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);
}
}
/**
- * Mark this connection as bound in the thread connection table
+ * Indicates if the session is currently protected by TLS.
+ * @return
+ * 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 {
-
+ 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();
- connect();
-
- if (m_saslBinder != null) {
- m_saslBinder.bind(this, true);
- m_authMethod = "sasl";
- } else {
- internalBind (m_protocolVersion, true, m_defaultConstraints);
- }
+ m_useTLS = useTLS;
+ m_connMgr = connMgr;
+ m_rebindConstraints = rebindCons;
+ restoreConnection(rebind);
}
/**
@@ -1895,11 +1911,8 @@ public class LDAPConnection
if (!isConnected()) {
return;
}
- // Clone the Connection Setup Manager if the connection is shared
- if (m_thread.isRunning() && m_thread.getClientCount() > 1) {
- m_connMgr = (LDAPConnSetupMgr) m_connMgr.clone();
- m_connMgr.disconnect();
- }
+
+ m_thread.deregister(this);
if (m_referralConnection != null && m_referralConnection.isConnected()) {
m_referralConnection.disconnect();
@@ -1911,46 +1924,11 @@ public class LDAPConnection
m_cache = null;
}
- //deleteThreadConnEntry();
- deregisterConnection();
- }
-
- /**
- * Remove this connection from the thread connection table
- */
- private void deleteThreadConnEntry() {
- synchronized (m_threadConnTable) {
- Vector connVector = (Vector)m_threadConnTable.get(m_thread);
- if (connVector == null) {
- printDebug("Thread table does not contain the thread of this object");
- return;
- }
- Enumeration enumv = connVector.elements();
- while (enumv.hasMoreElements()) {
- LDAPConnection c = (LDAPConnection)enumv.nextElement();
- if (c.equals(this)) {
- connVector.removeElement(c);
- if (connVector.size() == 0) {
- m_threadConnTable.remove(m_thread);
- }
- return;
- }
- }
- }
- }
-
- /**
- * Remove the association between this object and the connection thread
- */
- synchronized void deregisterConnection() {
- if (m_thread != null) {
- deleteThreadConnEntry();
- if (m_thread.isRunning()) {
- m_thread.deregister(this);
- }
- }
+ m_responseControlTable.clear();
+ m_rebindConstraints = null;
m_thread = null;
- m_bound = false;
+ m_connMgr = null;
+ m_useTLS = false;
}
/**
@@ -2533,9 +2511,24 @@ public class LDAPConnection
printDebug("Exception: "+e);
}
- internalBind(cons);
+ 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 );
- LDAPSearchListener myListener = getSearchListener ( cons );
int deref = cons.getDereference();
JDAPSearchRequest request = null;
@@ -2561,18 +2554,6 @@ public class LDAPConnection
throw e;
}
- /* 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;
- }
- }
-
/* 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.
@@ -2649,15 +2630,13 @@ public class LDAPConnection
}
catch (LDAPException ex) {
if (msg.getProtocolOp() instanceof JDAPSearchResultReference) {
- /*
- Don't want to miss all remaining results, so continue.
- This is very ugly (using println). We should have a
- configurable parameter (probably in LDAPSearchConstraints)
- whether to ignore failed search references or throw exception.
- */
- System.err.println( "LDAPConnection.checkSearchMsg: " +
- "ignoring bad referral" );
- return;
+ // 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;
}
@@ -2725,7 +2704,7 @@ public class LDAPConnection
public boolean compare( String DN, LDAPAttribute attr,
LDAPConstraints cons) throws LDAPException {
- internalBind(cons);
+ checkConnection(/*rebind=*/true);
LDAPResponseListener myListener = getResponseListener ();
Enumeration en = attr.getStringValues();
@@ -2847,7 +2826,7 @@ public class LDAPConnection
*/
public void add( LDAPEntry entry, LDAPConstraints cons )
throws LDAPException {
- internalBind (cons);
+ checkConnection(/*rebind=*/true);
LDAPResponseListener myListener = getResponseListener ();
LDAPAttributeSet attrs = entry.getAttributeSet ();
@@ -2920,7 +2899,7 @@ public class LDAPConnection
public LDAPExtendedOperation extendedOperation( LDAPExtendedOperation op,
LDAPConstraints cons)
throws LDAPException {
- internalBind (cons);
+ checkConnection(/*rebind=*/true);
LDAPResponseListener myListener = getResponseListener ();
LDAPMessage response = null;
@@ -2956,9 +2935,9 @@ public class LDAPConnection
}
/**
- * 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).
+ * 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.
*
* Use the
*
@@ -3022,9 +3001,9 @@ public class LDAPConnection
}
/**
- * 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).
+ * 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.
*
* Use the
*
@@ -3099,9 +3078,9 @@ public class LDAPConnection
}
/**
- * 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).
+ * 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.
*
* Use an array of
*
@@ -3140,7 +3119,7 @@ public class LDAPConnection
*/
public void modify (String DN, LDAPModification[] mods,
LDAPConstraints cons) throws LDAPException {
- internalBind (cons);
+ checkConnection(/*rebind=*/true);
LDAPResponseListener myListener = getResponseListener ();
LDAPMessage response = null;
@@ -3203,7 +3182,7 @@ public class LDAPConnection
*/
public void delete( String DN, LDAPConstraints cons )
throws LDAPException {
- internalBind (cons);
+ checkConnection(/*rebind=*/true);
LDAPResponseListener myListener = getResponseListener ();
LDAPMessage response;
@@ -3382,7 +3361,7 @@ public class LDAPConnection
boolean deleteOldRDN,
LDAPConstraints cons)
throws LDAPException {
- internalBind (cons);
+ checkConnection(/*rebind=*/true);
LDAPResponseListener myListener = getResponseListener ();
try {
@@ -3470,7 +3449,7 @@ public class LDAPConnection
cons = m_defaultConstraints;
}
- internalBind (cons);
+ checkConnection(/*rebind=*/true);
if (listener == null) {
listener = new LDAPResponseListener(/*asynchOp=*/true);
@@ -3651,7 +3630,7 @@ public class LDAPConnection
cons = m_defaultConstraints;
}
- internalBind (cons);
+ checkConnection(/*rebind=*/true);
if (listener == null) {
listener = new LDAPResponseListener(/*asynchOp=*/true);
@@ -3664,9 +3643,9 @@ public class LDAPConnection
}
/**
- * 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).
* @param dn distinguished name of the entry to modify
* @param mods a set of changes to make to the entry
@@ -3751,8 +3730,8 @@ public class LDAPConnection
}
/**
- * Makes a set of changes to an existing entry in the directory (for
- * example, changes attribute values, adds new attribute values, or
+ * 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
@@ -3776,7 +3755,7 @@ public class LDAPConnection
cons = m_defaultConstraints;
}
- internalBind (cons);
+ checkConnection(/*rebind=*/true);
if (listener == null) {
listener = new LDAPResponseListener(/*asynchOp=*/true);
@@ -3840,7 +3819,7 @@ public class LDAPConnection
cons = m_defaultConstraints;
}
- internalBind (cons);
+ checkConnection(/*rebind=*/true);
if (listener == null) {
listener = new LDAPResponseListener(/*asynchOp=*/true);
@@ -3939,7 +3918,7 @@ public class LDAPConnection
cons = m_defaultConstraints;
}
- internalBind (cons);
+ checkConnection(/*rebind=*/true);
if (listener == null) {
listener = new LDAPSearchListener(/*asynchOp=*/true, cons);
@@ -4008,7 +3987,7 @@ public class LDAPConnection
cons = m_defaultConstraints;
}
- internalBind (cons);
+ checkConnection(/*rebind=*/true);
if (listener == null) {
listener = new LDAPResponseListener(/*asynchOp=*/true);
@@ -4035,26 +4014,14 @@ public class LDAPConnection
return;
}
- for (int i=0; i<3; i++) {
- try {
- /* Tell listener thread to discard results */
- m_thread.abandon( id );
-
- /* Tell server to stop sending results */
- m_thread.sendRequest(null, new JDAPAbandonRequest(id), null, m_defaultConstraints);
-
- /* No response is forthcoming */
- break;
- } catch (NullPointerException ne) {
- // do nothing
- }
- }
- if (m_thread == null) {
- throw new LDAPException("Failed to send abandon request to the server.",
- LDAPException.OTHER);
- }
+ 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.
@@ -4520,26 +4487,22 @@ public class LDAPConnection
* @see netscape.ldap.LDAPSearchResults#getResponseControls
*/
public LDAPControl[] getResponseControls() {
- LDAPControl[] controls = null;
+ 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);
- /* Get the latest controls returned for our thread */
- synchronized(m_responseControlTable) {
- Vector responses = (Vector)m_responseControlTable.get(m_thread);
-
- if (responses != null) {
- // iterate through each response control
- for (int i=0,size=responses.size(); i
* @return the
*
@@ -132,7 +133,7 @@ import java.io.*;
public class LDAPException extends java.lang.Exception
implements java.io.Serializable {
- static final long serialVersionUID = -9215007872184847924L;
+ static final long serialVersionUID = -9215007872184847925L;
/**
* (0) The operation completed successfully.
@@ -556,11 +557,21 @@ public class LDAPException extends java.lang.Exception
*/
public final static int REFERRAL_LIMIT_EXCEEDED = 0x61;
+ /**
+ * (112) The socket factory of the connection is not capable
+ * of initiating a TLS session.
+ *
+ *
+ * @see netscape.ldap.LDAPConnection#startTLS
+ */
+ public final static int TLS_NOT_SUPPORTED = 0x70;
+
/**
* Internal variables
*/
private int resultCode = -1;
private String errorMessage = null;
+ private String extraMessage = null;
private String matchedDN = null;
private Locale m_locale = Locale.getDefault();
private static Hashtable cacheResource = new Hashtable();
@@ -733,17 +744,32 @@ public class LDAPException extends java.lang.Exception
public String getLDAPErrorMessage () {
return errorMessage;
}
+
+
+ /**
+ * Adds additional explanation to the error message
+ */
+ void setExtraMessage (String msg) {
+ if (extraMessage == null) {
+ extraMessage = msg;
+ }
+ else {
+ extraMessage += "; " + msg;
+ }
+ }
/**
* Returns the maximal subset of a DN which could be matched by the
- * server, if the server returned one of the following errors:
+ * server.
+ *
+ * The method should be used if the server returned one of the
+ * following errors:
*
+ * If an LDAP server does not contain an entry at the base DN for a search,
+ * it may be configured to return a referral. If it contains an entry at
+ * the base DN of a subtree search, one or more of the child entries may
+ * contain search continuation references. The search continuation
+ * references are returned to the client, which may follow them by issuing
+ * a search request to the host indicated in the search reference.
+ *
+ * If the
+ * Up to version 4.17 of the Java LDAP SDK, the SDK printed an error
+ * message but continued to process the remaining search results and search
+ * continuation references.
+ *
+ * As of SDK version 4.17, the default behavior is still to continue
+ * processing any remaining search results and search continuation
+ * references if there is an error following a referral, but the behavior
+ * may be changed with
+ * If an LDAP server does not contain an entry at the base DN for a search,
+ * it may be configured to return a referral. If it contains an entry at
+ * the base DN of a subtree search, one or more of the child entries may
+ * contain search continuation references. The search continuation
+ * references are returned to the client, which may follow them by issuing
+ * a search request to the host indicated in the search reference.
+ *
+ * If the
+ * Up to version 4.17 of the Java LDAP SDK, the SDK printed an error
+ * message but continued to process the remaining search results and search
+ * continuation references.
+ *
+ * As of SDK version 4.17, the default behavior is still to continue
+ * processing any remaining search results and search continuation
+ * references if there is an error following a referral, but the behavior
+ * may be changed with
+ *
+ * @version 1.0
+ * @since LDAPJDK 4.17
+ */
+public interface LDAPTLSSocketFactory extends LDAPSocketFactory {
+ /**
+ * Creates an SSL socket layered over an existing socket.
+ *
+ * Used for the start TLS operations (RFC2830).
+ *
+ * @param s An existing non-SSL socket
+ * @return A SSL socket layered over the input socket
+ * @exception LDAPException on error creating socket
+ * @see LDAPConnection#startTLS
+ */
+ public Socket makeSocket(Socket s) throws LDAPException;
+}
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPUrl.java b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPUrl.java
index d0620e4046f..d0a8ba29e46 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPUrl.java
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPUrl.java
@@ -24,7 +24,6 @@ package netscape.ldap;
import java.util.*;
import java.io.*;
import java.net.MalformedURLException;
-import netscape.ldap.factory.*;
/**
* Represents an LDAP URL. The complete specification for LDAP URLs is in
@@ -81,7 +80,7 @@ import netscape.ldap.factory.*;
*/
public class LDAPUrl implements java.io.Serializable {
- static final long serialVersionUID = -3245440798565713640L;
+ static final long serialVersionUID = -3245440798565713641L;
public static String defaultFilter = "(objectClass=*)";
private String m_hostName;
@@ -371,7 +370,7 @@ public class LDAPUrl implements java.io.Serializable {
} else
m_attributes = null;
- StringBuffer url = new StringBuffer (secure ? "LDAPS://" :"LDAP://");
+ StringBuffer url = new StringBuffer (secure ? "ldaps://" :"ldap://");
if (host != null) {
url.append (host);
@@ -444,6 +443,15 @@ public class LDAPUrl implements java.io.Serializable {
return m_DN;
}
+ /**
+ * Return the server part of the ldap url, ldap://host:port
+ * @return server url.
+ */
+ String getServerUrl() {
+ return (m_secure ? "ldaps://" : "ldap://") +
+ m_hostName + ":" + m_portNumber;
+ }
+
/**
* Return the collection of attributes specified in the URL, or null
* for "every attribute"
@@ -545,10 +553,10 @@ public class LDAPUrl implements java.io.Serializable {
if (m_factory == null) {
- // No factory explicity set, try to determine
+ // No factory explicitly set, try to determine
// the default one.
try {
- // First try iPlanet JSSSocketFactory
+ // First try Mozilla JSSSocketFactory
Class c = Class.forName("netscape.ldap.factory.JSSSocketFactory");
m_factory = (LDAPSocketFactory) c.newInstance();
}
@@ -561,7 +569,8 @@ public class LDAPUrl implements java.io.Serializable {
try {
// then try Sun JSSESocketFactory
- m_factory = new JSSESocketFactory(null);
+ Class c = Class.forName("netscape.ldap.factory.JSSESocketFactory");
+ m_factory = (LDAPSocketFactory) c.newInstance();
}
catch (Throwable e) {
}
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes.props b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes.props
index ad480130a47..4f13931a46e 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes.props
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes.props
@@ -49,3 +49,4 @@
95=More results to return
96=Client detected loop
97=Referral hop limit exceeded
+112=Cannot start TLS
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes_de.props b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes_de.props
index fed73a874d4..6786f595d45 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes_de.props
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes_de.props
@@ -49,3 +49,4 @@
95=Es stehen noch weitere Ergebnisse zur Verfügung
96=Client stellte Schleife fest
97=Beschränkung für Zwischenschritte bei Referenz überschritten
+112=TLS kann nicht activiert werden
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes_fr.props b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes_fr.props
index 24573d6b7f4..de9524ab855 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes_fr.props
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes_fr.props
@@ -49,3 +49,4 @@
95=Autres résultats à venir
96=Client a détecté la boucle
97=Nombre de rebonds sur référence trop grand
+112=Impossible d'activer TLS
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes_ja.props b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes_ja.props
index f87bea7013e..d8a0c84f10d 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes_ja.props
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/errors/ErrorCodes_ja.props
@@ -49,3 +49,4 @@
95=\u3055\u3089\u306B\u7D50\u679C\u304C\u8FD4\u3055\u308C\u307E\u3059\u3002
96=\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u304C\u30EB\u30FC\u30D7\u3092\u691C\u51FA\u3057\u307E\u3057\u305F\u3002
97=\u30EC\u30D5\u30A7\u30E9\u30EB \u30DB\u30C3\u30D7 \u30EA\u30DF\u30C3\u30C8\u3092\u8D85\u904E\u3057\u307E\u3057\u305F\u3002
+112=TLS\u3092\u-6a75\u59cb\u3067\u304d\u307e\u305b\u3093\u3002
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/factory/JSSESocketFactory.java b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/factory/JSSESocketFactory.java
index 78a2c651645..4e1125c6fa3 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/factory/JSSESocketFactory.java
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/factory/JSSESocketFactory.java
@@ -37,16 +37,23 @@ import netscape.ldap.*;
* @see LDAPSocketFactory
* @see LDAPConnection#LDAPConnection(netscape.ldap.LDAPSocketFactory)
*/
-public class JSSESocketFactory
- implements LDAPSocketFactory, java.io.Serializable {
+public class JSSESocketFactory implements LDAPTLSSocketFactory,
+ java.io.Serializable {
- static final long serialVersionUID = 6834205777733266609L;
+ static final long serialVersionUID = 6834205777733266610L;
// Optional explicit cipher suites to use
- private String[] suites;
+ protected String[] suites;
// The socket factory
- private SSLSocketFactory factory;
+ protected SSLSocketFactory factory;
+ /**
+ * Default factory constructor
+ */
+ public JSSESocketFactory() {
+ this(null, null);
+ }
+
/**
* Factory constructor that uses the default JSSE SSLSocketFactory
*
@@ -73,7 +80,7 @@ public class JSSESocketFactory
}
/**
- * Creates an SSL socket
+ * Creates an SSL socket.
*
* @param host Host name or IP address of SSL server
* @param port Port numbers of SSL server
@@ -98,16 +105,49 @@ public class JSSESocketFactory
sock.startHandshake();
} catch (UnknownHostException e) {
- throw new LDAPException("SSL connection to " + host +
- ":" + port + ", " + e.getMessage(),
+ throw new LDAPException("JSSESocketFactory.makeSocket - Unknown host: " + host,
LDAPException.CONNECT_ERROR);
} catch (IOException f) {
- throw new LDAPException("SSL connection to " + host +
- ":" + port + ", " + f.getMessage(),
+ throw new LDAPException("JSSESocketFactory.makeSocket " +
+ host + ":" + port + ", " + f.getMessage(),
LDAPException.CONNECT_ERROR);
}
return sock;
}
+
+ /**
+ * Creates an SSL socket layered over an existing socket.
+ *
+ * Used for the startTLS implementation (RFC2830).
+ *
+ * @param s An existing non-SSL socket
+ * @return A SSL socket layered over the input socket
+ * @exception LDAPException on error creating socket
+ * @since LDAPJDK 4.17
+ */
+ public Socket makeSocket(Socket s)
+ throws LDAPException {
+
+ SSLSocket sock = null;
+ String host = s.getInetAddress().getHostName();
+ int port = s.getPort();
+
+ try {
+ sock = (SSLSocket)factory.createSocket(s, host, port, /*autoClose=*/ true);
+
+ if (suites != null) {
+ sock.setEnabledCipherSuites(suites);
+ }
+
+ sock.startHandshake();
+
+ } catch (IOException f) {
+ throw new LDAPException("JSSESocketFactory - start TLS, " + f.getMessage(),
+ LDAPException.TLS_NOT_SUPPORTED);
+ }
+
+ return sock;
+ }
}
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/factory/JSSSocketFactory.java b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/factory/JSSSocketFactory.java
new file mode 100644
index 00000000000..ab7c9e7cd3a
--- /dev/null
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/factory/JSSSocketFactory.java
@@ -0,0 +1,291 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 Netscape are
+ * Copyright (C) 2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package netscape.ldap.factory;
+
+import java.net.*;
+import java.io.*;
+
+import netscape.ldap.*;
+
+import org.mozilla.jss.ssl.SSLSocket;
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback.ValidityStatus;
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.crypto.AlreadyInitializedException;
+import org.mozilla.jss.CryptoManager;
+
+/**
+ * Creates an SSL socket connection to a server, using the Netscape/Mozilla
+ * JSS package.
+ * This class implements the
+ * NOTE: This class is internal to Netscape and is distributed only with
+ * Netscape products.
+ *
+ * By default, the factory uses "secmod.db", "key3.db" and "cert7.db"
+ * databases in the current directory. If you need to override this default
+ * setting, then you should call the static
+ *
+ * This method allows you to override the current directory as the
+ * default certificate database directory. The directory is expected
+ * to contain
+ * The method may be called only once, before the first instance of
+ *
+ * @param certdbDir The full path, relative or absolute, of the certificate
+ * database directory.
+ * @exception LDAPException on initialization error
+ * @see netscape.ldap.factory.JSSSocketFactory#JSSSocketFactory(String)
+ */
+ public static void initialize( String certdbDir ) throws LDAPException {
+ moddb = certdbDir + File.separator + JSSSocketFactory.defaultModDB;
+ keydb = certdbDir + File.separator + JSSSocketFactory.defaultKeyDB;
+ certdb = certdbDir + File.separator + JSSSocketFactory.defaultCertDB;
+ try {
+ CryptoManager.initialize( certdbDir );
+ } catch (AlreadyInitializedException e) {
+ // This is ok
+ } catch (Exception e) {
+ throw new LDAPException("Failed to initialize JSSSocketFactory: "
+ + e.getMessage(), LDAPException.OTHER);
+ }
+ }
+
+ /**
+ * Initialize the JSS security subsystem.
+ *
+ * This method allows you to override the default name and location of
+ * the security module database, key database and certificate databases.
+ *
+ * The method may be called only once, before the first instance of
+ *
+ * @param moddb The full path, relative or absolute, of the security
+ * module database.
+ * @param keydb The full path, relative or absolute, of the key database.
+ * @param keydb The full path, relative or absolute, of the certificate
+ * database.
+ * @see netscape.ldap.factory.JSSSocketFactory#JSSSocketFactory
+ * @see netscape.ldap.factory.JSSSocketFactory#initialize(java.lang.String)
+ * @exception LDAPException on initialization error
+ * @deprecated Please call
+ * This default implementation always returns true. If you need to
+ * verify the server certificate validity, then you should override
+ * this method.
+ *
+ * @param serverCert X509 Certificate
+ * @param status The validity of the server certificate
+ * @return
* com.netscape.ldap.schema.quoting - "standard" or "NetscapeBug"
* Note: if this property is not set, the SDK will query the server
@@ -647,14 +644,15 @@ public class LDAPConnection
/**
* Gets the object representing the socket factory used to establish
- * a connection to the LDAP server.
+ * a connection to the LDAP server or for the start TLS operation.
* 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
+ * 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;
}
/**
@@ -681,23 +686,8 @@ public class LDAPConnection
* @return true if connected to an LDAP server over this connection.
* If not connected to an LDAP server, returns false.
*/
- public boolean isConnected() {
- synchronized (this) {
- if (m_thread != null && m_thread.isRunning()) {
- return true;
- }
- }
- // Not connected; If m_thread != null then there was a network
- // error and cleanup is currently in progress. Give it some
- // time to complete.
- if (m_thread != null) {
- try {
- Thread.sleep(500);
- }
- catch (InterruptedException ignore) {}
- Thread.yield();
- }
- return false;
+ public synchronized boolean isConnected() {
+ return m_thread != null && m_thread.isConnected();
}
/**
@@ -707,15 +697,38 @@ public class LDAPConnection
* either a blank name or password), returns false.
*/
public boolean isAuthenticated () {
- if (m_bound) {
- if ((m_boundDN == null) || m_boundDN.equals("") ||
- (m_boundPasswd == null) || m_boundPasswd.equals("")) {
- return false;
- }
+ boolean bound = false;
+ synchronized (this) {
+ bound = (m_thread != null) && m_thread.isBound();
}
- return m_bound;
+ 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
@@ -917,7 +930,8 @@ public class LDAPConnection
}
/* Create the Connection Setup Manager */
- m_connMgr = new LDAPConnSetupMgr(hostList, portList, m_factory);
+ m_connMgr = new LDAPConnSetupMgr(hostList, portList,
+ m_isTLSFactory ? null : m_factory);
m_connMgr.setConnSetupDelay(m_connSetupDelay);
m_connMgr.setConnectTimeout(m_connectTimeout);
@@ -928,6 +942,13 @@ public class LDAPConnection
}
}
+ 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
@@ -1039,9 +1060,13 @@ public class LDAPConnection
LDAPException.PARAM_ERROR );
}
- m_connMgr.openConnection();
- m_thread = getNewThread(m_connMgr, m_cache);
- authenticateSSLConnection();
+ if (m_thread == null) {
+ m_thread = new LDAPConnThread(m_connMgr, m_cache, getTraceOutput());
+ }
+
+ m_thread.connect(this);
+
+ checkClientAuth();
}
/**
@@ -1071,88 +1096,12 @@ public class LDAPConnection
}
- private synchronized LDAPConnThread getNewThread(LDAPConnSetupMgr connMgr,
- LDAPCache cache)
- throws LDAPException {
-
- LDAPConnThread newThread = null;
- Vector v = null;
-
- synchronized(m_threadConnTable) {
-
- Enumeration keys = m_threadConnTable.keys();
- boolean connExists = false;
-
- // transverse each thread
- while (keys.hasMoreElements()) {
- LDAPConnThread connThread = (LDAPConnThread)keys.nextElement();
- Vector connVector = (Vector)m_threadConnTable.get(connThread);
- Enumeration enumv = connVector.elements();
-
- // traverse each LDAPConnection under the same thread
- while (enumv.hasMoreElements()) {
- LDAPConnection conn = (LDAPConnection)enumv.nextElement();
-
- // this is not a brand new connection
- if (conn.equals(this)) {
- connExists = true;
-
- if (!connThread.isRunning()) {
- // need to move all the LDAPConnections from the dead thread
- // to the new thread
- try {
- newThread = new LDAPConnThread(connMgr, cache,
- getTraceOutput());
- v = (Vector)m_threadConnTable.remove(connThread);
- break;
- } catch (Exception e) {
- throw new LDAPException ("unable to establish connection",
- LDAPException.UNAVAILABLE);
- }
- }
- break;
- }
- }
-
- if (connExists) {
- break;
- }
- }
-
- // if this connection is new or the corresponding thread for the current
- // connection is dead
- if (!connExists) {
- try {
- newThread = new LDAPConnThread(connMgr, cache,
- getTraceOutput());
- v = new Vector();
- v.addElement(this);
- } catch (Exception e) {
- throw new LDAPException ("unable to establish connection",
- LDAPException.UNAVAILABLE);
- }
- }
-
- // add new thread to the table
- if (newThread != null) {
- m_threadConnTable.put(newThread, v);
- for (int i=0, n=v.size(); istartTLS() 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) {
+ * ...
+ * }
+ *
+ * true if TLS was activated.
+ * @since LDAPJDK 4.17
+ * @see netscape.ldap.LDAPConnection#startTLS
*/
- void markConnAsBound() {
- synchronized (m_threadConnTable) {
- if (m_threadConnTable.containsKey(m_thread)) {
- Vector v = (Vector)m_threadConnTable.get(m_thread);
- for (int i=0, n=v.size(); iLDAPModification object to specify the change
* to make and the LDAPAttribute object
@@ -2993,8 +2972,8 @@ public class LDAPConnection
/**
* 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.
+ * 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.
* LDAPModificationSet object to specify the set
* of changes to make. Changes are specified in terms
@@ -3067,8 +3046,8 @@ public class LDAPConnection
/**
* 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.
+ * 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.
* LDAPModification objects to specify the
* changes to make. Each change must be specified by
@@ -3124,8 +3103,8 @@ public class LDAPConnection
/**
* 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.
+ * 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.
*
+ * 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.
*
@@ -3689,9 +3668,9 @@ public class LDAPConnection
}
/**
- * 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).
+ * 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.
*
@@ -3716,7 +3695,7 @@ public class LDAPConnection
cons = m_defaultConstraints;
}
- internalBind (cons);
+ checkConnection(/*rebind=*/true);
if (listener == null) {
listener = new LDAPResponseListener(/*asynchOp=*/true);
@@ -3729,9 +3708,9 @@ public class LDAPConnection
}
/**
- * 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).
+ * 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.
* LDAPConnection object that
- * contains the same information as the current connection, including:
+ * 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 {
- LDAPConnection c = (LDAPConnection)super.clone();
-
- if (!isConnected()) {
- this.internalBind(m_defaultConstraints);
+ 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_bound = this.m_bound;
- c.m_connMgr = m_connMgr;
- c.m_connSetupDelay = m_connSetupDelay;
- c.m_boundDN = this.m_boundDN;
- c.m_boundPasswd = this.m_boundPasswd;
- c.m_prevBoundDN = this.m_prevBoundDN;
- c.m_prevBoundPasswd = this.m_prevBoundPasswd;
- c.m_anonymousBound = this.m_anonymousBound;
- c.setCache(this.m_cache); // increments cache reference cnt
- c.m_factory = this.m_factory;
- c.m_thread = this.m_thread; /* share current connection thread */
+ c.m_searchListeners = null;
+ c.m_properties = (Hashtable)m_properties.clone();
+ c.m_responseControlTable = new Hashtable();
- synchronized (m_threadConnTable) {
- Vector v = (Vector)m_threadConnTable.get(this.m_thread);
- if (v != null) {
- v.addElement(c);
- } else {
- printDebug("Failed to clone");
- return null;
- }
+ if (c.m_cache != null) {
+ c.m_cache.addReference();
}
- c.m_thread.register(c);
- return c;
- } catch (Exception e) {
- }
- return null;
+ 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;
}
/**
@@ -5389,11 +5360,9 @@ public class LDAPConnection
int cloneCnt = (m_thread == null) ? 0 : m_thread.getClientCount();
StringBuffer sb = new StringBuffer("LDAPConnection {");
//url
- sb.append((m_factory == null ? "ldap" : "ldaps"));
- sb.append("://");
- sb.append(getHost());
- sb.append(":");
- sb.append(getPort());
+ if (m_connMgr != null) {
+ sb.append(m_connMgr.getLDAPUrl().getServerUrl());
+ }
// clone count
if (cloneCnt > 1) {
sb.append(" (");
@@ -5412,7 +5381,27 @@ public class LDAPConnection
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
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPConstraints.java b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPConstraints.java
index 7e0a000205a..baaa495a512 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPConstraints.java
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPConstraints.java
@@ -360,30 +360,31 @@ public class LDAPConstraints implements Cloneable, java.io.Serializable {
/**
* Makes a copy of an existing set of constraints.
- * @returns a copy of an existing set of constraints
+ * @return a copy of an existing set of constraints
*/
public Object clone() {
- LDAPConstraints o = new LDAPConstraints();
+ try {
+ LDAPConstraints o = (LDAPConstraints) super.clone();
- o.m_time_limit = this.m_time_limit;
- o.referrals = this.referrals;
- o.m_bind_proc = this.m_bind_proc;
- o.m_rebind_proc = this.m_rebind_proc;
- o.m_hop_limit = this.m_hop_limit;
- if ( (this.m_clientControls != null) &&
- (this.m_clientControls.length > 0) ) {
- o.m_clientControls = new LDAPControl[this.m_clientControls.length];
- for( int i = 0; i < this.m_clientControls.length; i++ )
- o.m_clientControls[i] =
- (LDAPControl)this.m_clientControls[i].clone();
+ if ( (this.m_clientControls != null) &&
+ (this.m_clientControls.length > 0) ) {
+ o.m_clientControls = new LDAPControl[this.m_clientControls.length];
+ for( int i = 0; i < this.m_clientControls.length; i++ )
+ o.m_clientControls[i] =
+ (LDAPControl)this.m_clientControls[i].clone();
+ }
+ if ( (this.m_serverControls != null) &&
+ (this.m_serverControls.length > 0) ) {
+ o.m_serverControls = new LDAPControl[this.m_serverControls.length];
+ for( int i = 0; i < this.m_serverControls.length; i++ )
+ o.m_serverControls[i] =
+ (LDAPControl)this.m_serverControls[i].clone();
+ }
+ return o;
}
- if ( (this.m_serverControls != null) &&
- (this.m_serverControls.length > 0) ) {
- o.m_serverControls = new LDAPControl[this.m_serverControls.length];
- for( int i = 0; i < this.m_serverControls.length; i++ )
- o.m_serverControls[i] =
- (LDAPControl)this.m_serverControls[i].clone();
+ catch (CloneNotSupportedException ex) {
+ // shold never happen, the class is Cloneable
+ return null;
}
- return o;
}
}
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPException.java b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPException.java
index ade17e6f330..d28363be4c6 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPException.java
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPException.java
@@ -123,6 +123,7 @@ import java.io.*;
* 95 MORE_RESULTS_TO_RETURN
* 96 CLIENT_LOOP
* 97 REFERRAL_LIMIT_EXCEEDED
+ * 112 TLS_NOT_SUPPORTED (LDAP v3)
*
*
*
- *
* For example, if the DN NO_SUCH_OBJECT
* ALIAS_PROBLEM
* INVALID_DN_SYNTAX
* ALIAS_DEREFERENCING_PROBLEM
* cn=Babs Jensen, o=People, c=Airius.com
* could not be found by the DN o=People, c=Airius.com
* could be found, the matched DN is
@@ -791,14 +817,19 @@ public class LDAPException extends java.lang.Exception
*/
public String toString() {
String str = super.toString() + " (" + resultCode + ")" ;
- if ( (errorMessage != null) && (errorMessage.length() > 0) )
+ if ( (errorMessage != null) && (errorMessage.length() > 0) ) {
str += "; " + errorMessage;
- if ( (matchedDN != null) && (matchedDN.length() > 0) )
+ }
+ if ( (matchedDN != null) && (matchedDN.length() > 0) ) {
str += "; matchedDN = " + matchedDN;
- String errorStr = null;
- if (((errorStr = errorCodeToString(m_locale)) != null) &&
- (errorStr.length() > 0))
- str += "; " + errorStr;
+ }
+ String errorStr = errorCodeToString(m_locale);
+ if ((errorStr != null) && (errorStr.length() > 0)) {
+ str += "; " + errorStr;
+ }
+ if (extraMessage != null) {
+ str += "; " + extraMessage;
+ }
return str;
}
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPMessageQueue.java b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPMessageQueue.java
index ae49fa86db4..d7e3bd53ddb 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPMessageQueue.java
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPMessageQueue.java
@@ -35,7 +35,7 @@ import java.util.Vector;
*/
class LDAPMessageQueue implements java.io.Serializable {
- static final long serialVersionUID = -7163312406176592277L;
+ static final long serialVersionUID = -7163312406176592278L;
/**
* Request entry encapsulates request parameters
@@ -88,6 +88,27 @@ class LDAPMessageQueue implements java.io.Serializable {
return m_asynchOp;
}
+ /**
+ * Blocks until a response is available.
+ * Used by LDAPConnection.sendRequest (synch ops) to test if the server
+ * is really available after a request had been sent.
+ * @exception LDAPException Network error exception
+ * @exception LDAPInterruptedException The invoking thread was interrupted
+ */
+ synchronized void waitFirstMessage () throws LDAPException {
+
+ while(m_requestList.size() != 0 && m_exception == null && m_messageQueue.size() == 0) {
+ waitForMessage();
+ }
+
+ // Network exception occurred ?
+ if (m_exception != null) {
+ LDAPException ex = m_exception;
+ m_exception = null;
+ throw ex;
+ }
+ }
+
/**
* Blocks until a response is available or until all operations
* associated with the object have completed or been canceled.
@@ -287,7 +308,7 @@ class LDAPMessageQueue implements java.io.Serializable {
// Mark conn as bound for asych bind operations
if (isAsynchOp() && msg.getType() == msg.BIND_RESPONSE) {
if (((LDAPResponse) msg).getResultCode() == 0) {
- getConnection(msg.getMessageID()).markConnAsBound();
+ getConnection(msg.getMessageID()).setBound(true);
}
}
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSSLSocketFactory.java b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSSLSocketFactory.java
index f5c95a6f5e1..8bfd22d2aba 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSSLSocketFactory.java
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSSLSocketFactory.java
@@ -178,7 +178,7 @@ public class LDAPSSLSocketFactory
/**
- * This method is currently not implemented.
+ * This method is currently not implemented.
* Enables client authentication for an application that uses
* an external (file-based) certificate database.
* Call this method before you call makeSocket.
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSaslBind.java b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSaslBind.java
index 22963f9c372..74a27eb56f4 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSaslBind.java
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSaslBind.java
@@ -225,7 +225,7 @@ public class LDAPSaslBind implements LDAPBind, java.io.Serializable {
_saslClient,
className, "getOutputStream", args, argNames);
ldc.setOutputStream(os);
- ldc.markConnAsBound();
+ ldc.setBound(true);
} catch (LDAPException e) {
throw e;
} catch (Exception e) {
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSearchConstraints.java b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSearchConstraints.java
index 34d0822d482..e280cde58c7 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSearchConstraints.java
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSearchConstraints.java
@@ -34,11 +34,25 @@ package netscape.ldap;
public class LDAPSearchConstraints extends LDAPConstraints
implements Cloneable {
+
+ // Constants for behavior when a search continuation reference cannot
+ // be followed
+ /**
+ * Continue processing if there is an error following a search continuation
+ * reference
+ */
+ public static final int REFERRAL_ERROR_CONTINUE = 0;
+ /**
+ * Throw exception if there is an error following a search continuation
+ * reference
+ */
+ public static final int REFERRAL_ERROR_EXCEPTION = 1;
private int deref;
private int maxRes;
private int batch;
private int serverTimeLimit;
private int maxBacklog = 100;
+ private int referralErrors = REFERRAL_ERROR_CONTINUE;
/**
* Constructs an LDAPSearchConstraints object that specifies
@@ -81,8 +95,10 @@ public class LDAPSearchConstraints extends LDAPConstraints
* @param hop_limit maximum number of referrals to follow in a
* sequence when attempting to resolve a request
* @see netscape.ldap.LDAPConnection#setOption(int, java.lang.Object)
- * @see netscape.ldap.LDAPConnection#search(netscape.ldap.LDAPUrl, netscape.ldap.LDAPSearchConstraints)
- * @see netscape.ldap.LDAPConnection#search(java.lang.String, int, java.lang.String, java.lang.String[], boolean, netscape.ldap.LDAPSearchConstraints)
+ * @see netscape.ldap.LDAPConnection#search(netscape.ldap.LDAPUrl,
+netscape.ldap.LDAPSearchConstraints)
+ * @see netscape.ldap.LDAPConnection#search(java.lang.String, int, java.lang.String,
+java.lang.String[], boolean, netscape.ldap.LDAPSearchConstraints)
*/
public LDAPSearchConstraints( int msLimit, int dereference,
int maxResults, boolean doReferrals, int batchSize,
@@ -125,8 +141,10 @@ public class LDAPSearchConstraints extends LDAPConstraints
* @param hop_limit maximum number of referrals to follow in a
* sequence when attempting to resolve a request
* @see netscape.ldap.LDAPConnection#setOption(int, java.lang.Object)
- * @see netscape.ldap.LDAPConnection#search(netscape.ldap.LDAPUrl, netscape.ldap.LDAPSearchConstraints)
- * @see netscape.ldap.LDAPConnection#search(java.lang.String, int, java.lang.String, java.lang.String[], boolean, netscape.ldap.LDAPSearchConstraints)
+ * @see netscape.ldap.LDAPConnection#search(netscape.ldap.LDAPUrl,
+netscape.ldap.LDAPSearchConstraints)
+ * @see netscape.ldap.LDAPConnection#search(java.lang.String, int, java.lang.String,
+java.lang.String[], boolean, netscape.ldap.LDAPSearchConstraints)
*/
public LDAPSearchConstraints( int msLimit, int timeLimit,
int dereference,
@@ -171,8 +189,10 @@ public class LDAPSearchConstraints extends LDAPConstraints
* @param hop_limit maximum number of referrals to follow in a
* sequence when attempting to resolve a request
* @see netscape.ldap.LDAPConnection#setOption(int, java.lang.Object)
- * @see netscape.ldap.LDAPConnection#search(netscape.ldap.LDAPUrl, netscape.ldap.LDAPSearchConstraints)
- * @see netscape.ldap.LDAPConnection#search(java.lang.String, int, java.lang.String, java.lang.String[], boolean, netscape.ldap.LDAPSearchConstraints)
+ * @see netscape.ldap.LDAPConnection#search(netscape.ldap.LDAPUrl,
+netscape.ldap.LDAPSearchConstraints)
+ * @see netscape.ldap.LDAPConnection#search(java.lang.String, int, java.lang.String,
+java.lang.String[], boolean, netscape.ldap.LDAPSearchConstraints)
*/
public LDAPSearchConstraints( int msLimit, int timeLimit,
int dereference,
@@ -296,51 +316,101 @@ public class LDAPSearchConstraints extends LDAPConstraints
return maxBacklog;
}
+ /**
+ * Reports if errors when following search continuation references are
+ * to cause processing of the remaining results to be aborted.
+ * LDAPConnection object has been configured to follow
+ * referrals automatically, it may fail when issuing a search request to
+ * the host indicated in a search reference, e.g. because there is no
+ * entry there, because it does not have credentials, because it does not
+ * have sufficient permissions, etc. If the client aborts evaluation of the
+ * search results (obtained through LDAPSearchResults) when a
+ * search reference cannot be followed, any remaining results are discarded.
+ * setReferralErrors to throw an exception
+ * instead.
+ *
+ * @return REFERRAL_ERROR_CONTINUE if remaining results are
+ * to be processed when there is an error following a search continuation
+ * reference, REFERRAL_ERROR_EXCEPTION if such an error is to
+ * cause an LDAPException.
+ *
+ * @see netscape.ldap.LDAPConstraints#setReferrals
+ * @since LDAPJDK 4.17
+ */
+ public int getReferralErrors() {
+ return referralErrors;
+ }
+
+ /**
+ * Specifies if errors when following search continuation references are
+ * to cause processing of the remaining results to be aborted.
+ * LDAPConnection object has been configured to follow
+ * referrals automatically, it may fail when issuing a search request to
+ * the host indicated in a search reference, e.g. because there is no
+ * entry there, because it does not have credentials, because it does not
+ * have sufficient permissions, etc. If the client aborts evaluation of the
+ * search results (obtained through LDAPSearchResults) when a
+ * search reference cannot be followed, any remaining results are discarded.
+ * setReferralErrors to throw an exception
+ * instead.
+ *
+ * @param errorBehavior Either REFERRAL_ERROR_CONTINUE if
+ * remaining results are to be processed when there is an error following a
+ * search continuation reference or REFERRAL_ERROR_EXCEPTION
+ * if such an error is to cause an LDAPException.
+ *
+ * @see netscape.ldap.LDAPSearchConstraints#getReferralErrors
+ * @see netscape.ldap.LDAPSearchResults#next
+ * @see netscape.ldap.LDAPSearchResults#nextElement
+ * @since LDAPJDK 4.17
+ */
+ public void setReferralErrors(int errorBehavior) {
+ if ( (errorBehavior != REFERRAL_ERROR_CONTINUE) &&
+ (errorBehavior != REFERRAL_ERROR_EXCEPTION) ) {
+ throw new IllegalArgumentException( "Invalid error behavior: " +
+ errorBehavior );
+ }
+ referralErrors = errorBehavior;
+ }
+
/**
* Makes a copy of an existing set of search constraints.
* @return a copy of an existing set of search constraints.
*/
public Object clone() {
- LDAPSearchConstraints o = new LDAPSearchConstraints();
-
- o.serverTimeLimit = this.serverTimeLimit;
- o.deref = this.deref;
- o.maxRes = this.maxRes;
- o.batch = this.batch;
- o.maxBacklog = this.maxBacklog;
-
- o.setHopLimit(this.getHopLimit());
- o.setReferrals(this.getReferrals());
- o.setTimeLimit(this.getTimeLimit());
-
- if (this.getBindProc() != null) {
- o.setBindProc(this.getBindProc());
- } else {
- o.setRebindProc(this.getRebindProc());
- }
-
- LDAPControl[] tClientControls = this.getClientControls();
- LDAPControl[] oClientControls;
-
- 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();
- o.setClientControls(oClientControls);
- }
-
- LDAPControl[] tServerControls = this.getServerControls();
- LDAPControl[] oServerControls;
-
- 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();
- o.setServerControls(oServerControls);
- }
-
+ LDAPSearchConstraints o = (LDAPSearchConstraints) super.clone();
return o;
}
@@ -356,7 +426,8 @@ public class LDAPSearchConstraints extends LDAPConstraints
sb.append("server time limit " + serverTimeLimit + ", ");
sb.append("aliases " + deref + ", ");
sb.append("batch size " + batch + ", ");
- sb.append("max backlog " + maxBacklog);
+ sb.append("max backlog " + maxBacklog + ", ");
+ sb.append("referralErrors " + referralErrors);
sb.append('}');
return sb.toString();
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSearchResults.java b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSearchResults.java
index 9ff3e352108..9a09c7b0480 100644
--- a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSearchResults.java
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPSearchResults.java
@@ -549,7 +549,7 @@ public class LDAPSearchResults implements Enumeration, java.io.Serializable {
currBase, currScope, currFilter,
currAttrs, currAttrsOnly);
} catch (LDAPException e) {
- System.err.println("LDAPSearchResults.fetchResult: "+e);
+ add(e);
} finally {
currConn.releaseSearchListener(resultSource);
}
@@ -567,7 +567,7 @@ public class LDAPSearchResults implements Enumeration, java.io.Serializable {
currConn.checkSearchMsg(this, msg, currCons,
currBase, currScope, currFilter, currAttrs, currAttrsOnly);
} catch (LDAPException e) {
- System.err.println("Exception: "+e);
+ add(e);
}
}
}
diff --git a/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPTLSSocketFactory.java b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPTLSSocketFactory.java
new file mode 100644
index 00000000000..553a9598796
--- /dev/null
+++ b/mozilla/directory/java-sdk/ldapjdk/netscape/ldap/LDAPTLSSocketFactory.java
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 Netscape are
+ * Copyright (C) 2002 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package netscape.ldap;
+
+import java.util.*;
+import java.io.*;
+import java.net.*;
+
+/**
+ * A socket factory interface for supporting the start TLS LDAPv3
+ * extension (RFC 2830).
+ * LDAPSocketFactory
+ * interface.
+ * initialize method
+ * before creating the first instance of JSSSocketFactory.
+ *
+ * ...
+ * JSSSocketFactory.initialize("../certDir");
+ * LDAPConnection ld = new LDAPConnection(new JSSSocketFactory());
+ * ...
+ *
+ * @version 1.1
+ * @see LDAPSocketFactory
+ * @see LDAPConnection#LDAPConnection(netscape.ldap.LDAPSocketFactory)
+ */
+
+public class JSSSocketFactory implements Serializable,
+ LDAPTLSSocketFactory,
+ SSLCertificateApprovalCallback
+{
+
+ static final long serialVersionUID = -6926469178017736903L;
+
+ /**
+ * Default security module database path "secmod.db".
+ */
+ public static final String defaultModDB = "secmod.db";
+
+ /**
+ * Default key database path "key3.db".
+ */
+ public static final String defaultKeyDB = "key3.db";
+
+ /**
+ * Default certificate database path "cert7.db".
+ */
+ public static final String defaultCertDB = "cert7.db";
+
+ private static String moddb;
+ private static String keydb;
+ private static String certdb;
+
+
+ /**
+ * Constructs a new JSSSocketFactory.
+ * CryptoManager.initialize(certdbDir) or
+ * JSSSocketFactory.initialize(certdbDir) must be called once in the
+ * application before using the object.
+ *
+ * @exception LDAPException on initialization error
+ * @see netscape.ldap.factory.JSSSocketFactory#JSSSocketFactory(java.lang.String)
+ */
+ public JSSSocketFactory() throws LDAPException{
+ initialize(".");
+ }
+
+ /**
+ * Constructs a new JSSSocketFactory, initializing the
+ * JSS security system if it has not already been initialized
+ *
+ * @param certdbDir The full path, relative or absolute, of the certificate
+ * database directory
+ * @exception LDAPException on initialization error
+ */
+ public JSSSocketFactory( String certdbDir ) throws LDAPException{
+ initialize( certdbDir );
+ }
+
+ /**
+ * Initialize the JSS security subsystem.
+ * secmod.db, key3.db and
+ * cert7.db files as the security module database, key database
+ * and certificate database respectively.
+ * JSSSocketFactory is created. When creating the first
+ * instance, the constructor will automatically initialize the JSS
+ * security subsystem using the defaults, unless it is already initialized.
+ * JSSSocketFactory is created. When creating the first
+ * instance, the constructor will automatically initialize the JSS
+ * security subsystem using the defaults, unless it is already initialized.
+ * JSSSocketFactory(String certDir) instead
+ */
+ public static void initialize( String moddb, String keydb, String certdb )
+ throws LDAPException {
+ JSSSocketFactory.moddb = moddb;
+ JSSSocketFactory.keydb = keydb;
+ JSSSocketFactory.certdb = certdb;
+ int ind = certdb.lastIndexOf( File.separator );
+ String certdbDir = ( ind == 0 ) ? File.separator :
+ ( ind > 0 ) ? certdb.substring( 0, ind ) : ".";
+ initialize( certdbDir );
+ }
+
+ /**
+ * Returns the full path of the security module
+ * database
+ *
+ * @return The full path, relative or absolute, of the security module database
+ */
+ public static String getModDB() {
+ return moddb;
+ }
+
+ /**
+ * Returns the full path of the key database
+ *
+ * @return The full path, relative or absolute, of the key database
+ */
+ public static String getKeyDB() {
+ return keydb;
+ }
+
+ /**
+ * Returns the full path of the certificate database
+ *
+ * @return The full path, relative or absolute, of the certificate database
+ */
+ public static String getCertDB() {
+ return certdb;
+ }
+
+ /**
+ * Creates an SSL socket
+ *
+ * @param host Host name or IP address of SSL server
+ * @param port Port numbers of SSL server
+ * @return A socket for an encrypted session
+ * @exception LDAPException on error creating socket
+ */
+ public Socket makeSocket( String host, int port ) throws LDAPException {
+ SSLSocket socket = null;
+ try {
+
+ socket = new SSLSocket( host, // address
+ port, // port
+ null, // localAddress
+ 0, // localPort
+ this, // certApprovalCallback
+ null // clientCertSelectionCallback
+ );
+
+ socket.forceHandshake();
+
+ }
+ catch (UnknownHostException e) {
+ throw new LDAPException("JSSSocketFactory.makeSocket - Unknown host: " + host,
+ LDAPException.CONNECT_ERROR);
+
+ }
+ catch (Exception e) {
+ throw new LDAPException("JSSSocketFactory.makeSocket " +
+ host + ":" + port + ", " + e.getMessage(),
+ LDAPException.CONNECT_ERROR);
+ }
+
+ return socket;
+ }
+
+ /**
+ * The default implementation of the SSLCertificateApprovalCallback
+ * interface.
+ * true, by default we trust the certificate
+ */
+ public boolean approve(X509Certificate serverCert,
+ ValidityStatus status) {
+
+ return true;
+ }
+
+ /**
+ * Creates an SSL socket layered over an existing socket.
+ *
+ * Used for the startTLS implementation (RFC2830).
+ *
+ * @param s An existing non-SSL socket
+ * @return A SSL socket layered over the input socket
+ * @exception LDAPException on error creating socket
+ * @since LDAPJDK 4.17
+ */
+ public Socket makeSocket(Socket s) throws LDAPException {
+ SSLSocket socket = null;
+ String host = s.getInetAddress().getHostName();
+ int port = s.getPort();
+ try {
+ socket = new SSLSocket( s,
+ host,
+ this, // certApprovalCallback
+ null // clientCertSelectionCallback
+ );
+
+ socket.forceHandshake();
+
+ } catch (Exception e) {
+ throw new LDAPException("JSSSocketFactory - start TLS, " + e.getMessage(),
+ LDAPException.TLS_NOT_SUPPORTED);
+ }
+
+ return socket;
+ }
+}