LDAPConnection.java revision 88f16d892d54fd8c3e190cc1f6363638b11ae1a3
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2009-2010 Sun Microsystems, Inc.
* Portions Copyright 2013-2015 ForgeRock AS
*/
/**
* This class provides a tool that can be used to issue search requests to the
* Directory Server.
*/
public class LDAPConnection
{
// The hostname to connect to.
// The port number on which the directory server is accepting requests.
private int portNumber = 389;
private LDAPConnectionOptions connectionOptions;
private LDAPWriter ldapWriter;
private LDAPReader ldapReader;
private int versionNumber = 3;
private final PrintStream out;
private final PrintStream err;
/**
* Constructor for the LDAPConnection object.
*
* @param host The hostname to send the request to.
* @param port The port number on which the directory server is accepting
* requests.
* @param options The set of options for this connection.
*/
{
}
/**
* Constructor for the LDAPConnection object.
*
* @param host The hostname to send the request to.
* @param port The port number on which the directory server is accepting
* requests.
* @param options The set of options for this connection.
* @param out The print stream to use for standard output.
* @param err The print stream to use for standard error.
*/
{
this.portNumber = port;
this.connectionOptions = options;
}
/**
* Connects to the directory server instance running on specified hostname
* and port number.
*
* @param bindDN The DN to bind with.
* @param bindPassword The password to bind with.
*
* @throws LDAPConnectionException If a problem occurs while attempting to
* establish the connection to the server.
*/
throws LDAPConnectionException
{
}
/**
* Connects to the directory server instance running on specified hostname
* and port number.
*
* @param bindDN The DN to bind with.
* @param bindPassword The password to bind with.
* @param nextMessageID The message ID counter that should be used for
* operations performed while establishing the
* connection.
*
* @throws LDAPConnectionException If a problem occurs while attempting to
* establish the connection to the server.
*/
throws LDAPConnectionException
{
}
/**
* Connects to the directory server instance running on specified hostname
* and port number.
*
* @param bindDN The DN to bind with.
* @param bindPassword The password to bind with.
* @param nextMessageID The message ID counter that should be used for
* operations performed while establishing the
* connection.
* @param timeout The timeout to connect to the specified host. The
* timeout is the timeout at the socket level in
* milliseconds. If the timeout value is {@code 0},
* no timeout is used.
*
* @throws LDAPConnectionException If a problem occurs while attempting to
* establish the connection to the server.
*/
throws LDAPConnectionException
{
int resultCode;
if (connectionOptions.isVerbose())
{
}
else
{
}
if(connectionOptions.useStartTLS())
{
try
{
}
catch (LDAPConnectionException e)
{
throw e;
}
{
}
// Send the StartTLS extended request.
try
{
// Read the response from the server.
}catch (LDAPException ex1)
{
{
}
if(resultCode != SUCCESS)
{
}
}
try
{
} catch(UnknownHostException uhe)
{
uhe);
} catch(ConnectException ce)
{
ce);
} catch (LDAPConnectionException e)
{
throw e;
{
}
// We need this so that we don't run out of addresses when the tool
// commands are called A LOT, as in the unit tests.
try
{
socket.setReuseAddress(true);
if (timeout > 0)
{
}
} catch(IOException e)
{
logger.traceException(e);
// It doesn't matter too much if this throws, so ignore it.
}
{
}
{
}
try
{
{
}
else
{
}
if (bindPassword == null)
{
}
else
{
}
if (connectionOptions.useSASLExternal())
{
}
{
}
{
}
{
}
for (Control c : responseControls)
{
{
if (c instanceof LDAPControl)
{
// We have to decode this control.
}
else
{
// Control should already have been decoded.
}
}
{
}
{
if(c instanceof LDAPControl)
{
// We have to decode this control.
((LDAPControl) c).getValue());
}
else
{
// Control should already have been decoded.
}
}
{
if(c instanceof LDAPControl)
{
}
else
{
}
{
switch (errorType)
{
case PASSWORD_EXPIRED:
break;
case ACCOUNT_LOCKED:
break;
case CHANGE_AFTER_RESET:
break;
}
}
if (warningType != null)
{
switch (warningType)
{
case TIME_BEFORE_EXPIRATION:
break;
case GRACE_LOGINS_REMAINING:
break;
}
}
}
}
} catch(ClientException ce)
{
} catch (LDAPException le) {
le.getResultCode(),
le.getMatchedDN(),
} catch (DirectoryException de)
{
{
throw new LDAPConnectionException(
}
finally
{
if (timeout > 0)
{
try
{
}
catch (SocketException e)
{
e.printStackTrace();
logger.traceException(e);
}
}
}
}
/**
* Creates a socket using the hostName and portNumber encapsulated in the
* current object. For each IP address associated to this host name,
* createSocket() will try to open a socket and it will return the first
* socket for which we successfully establish a connection.
* <p>
* This method can never return null because it will receive
* UnknownHostException before and then throw LDAPConnectionException.
* </p>
*
* @return a new {@link Socket}.
* @throws LDAPConnectionException
* if any exception occurs including UnknownHostException
*/
{
try
{
{
try
{
}
catch (ConnectException ce2)
{
{
}
}
}
}
catch (UnknownHostException uhe)
{
uhe);
}
{
// if we get there, something went awfully wrong while creatng one socket,
// no need to continue the for loop.
}
{
ce);
}
return null;
}
/**
* Creates an SSL socket using the hostName and portNumber encapsulated in the
* current object. For each IP address associated to this host name,
* createSSLSocket() will try to open a socket and it will return the first
* socket for which we successfully establish a connection.
* <p>
* This method can never return null because it will receive
* UnknownHostException before and then throw LDAPConnectionException.
* </p>
*
* @return a new {@link Socket}.
* @throws LDAPConnectionException
* if any exception occurs including UnknownHostException
*/
{
try
{
{
try
{
}
catch (ConnectException ce2)
{
{
}
}
}
}
catch (UnknownHostException uhe)
{
uhe);
}
{
// if we get there, something went awfully wrong while creatng one socket,
// no need to continue the for loop.
}
{
ce);
}
return null;
}
/**
* portNumber encapsulated in the current object, or with the passed in socket
* if it needs to use start TLS.
*
* @param startTLSSocket
* the Socket to use if it needs to use start TLS.
* @param sslConnectionFactory
* the {@link SSLConnectionFactory} for creating SSL sockets
* @return a new {@link Socket}
* @throws SSLConnectionException
* if the SSL socket creation fails
* @throws LDAPConnectionException
* if any other error occurs
*/
{
if (sslConnectionFactory == null)
{
return createSocket();
}
else if (!connectionOptions.useStartTLS())
{
return createSSLSocket(sslConnectionFactory);
}
else
{
try
{
// Use existing socket.
portNumber, true);
}
catch (IOException e)
{
e);
}
}
}
/**
* Close the underlying ASN1 reader and writer, optionally sending an unbind
* request before disconnecting.
*
* @param nextMessageID The message ID counter that should be used for
* the unbind request, or {@code null} if the
* connection should be closed without an unbind
* request.
*/
{
if(ldapWriter != null)
{
if (nextMessageID != null)
{
try
{
new UnbindRequestProtocolOp());
} catch (Exception e) {}
}
ldapWriter.close();
}
if(ldapReader != null)
{
ldapReader.close();
}
}
/**
* Get the underlying LDAP writer.
*
* @return The underlying LDAP writer.
*/
public LDAPWriter getLDAPWriter()
{
return ldapWriter;
}
/**
* Get the underlying LDAP reader.
*
* @return The underlying LDAP reader.
*/
public LDAPReader getLDAPReader()
{
return ldapReader;
}
}