/*
* 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 2008-2010 Sun Microsystems, Inc.
* Portions Copyright 2014 ForgeRock AS
*/
/**
* An LDAPConnectionPool is a pool of LDAPConnection.
* <BR><BR>
* When a client class needs to access an LDAPUrl, it simply passes
* this URL to getConnection() and gets an LDAPConnection back.
* When the client has finished with this LDAPConnection, it *must*
* pass it releaseConnection() which will take care of its disconnection
* or caching.
* <BR><BR>
* LDAPConnectionPool maintains a pool of authentications. This pool
* is populated using registerAuth(). When getConnection() has created
* a new connection for accessing a host:port, it looks in the authentication
* pool if any authentication is available for this host:port and, if yes,
* tries to bind the connection. If no authentication is available, the
* returned connection is simply connected (ie anonymous bind).
* <BR><BR>
* LDAPConnectionPool shares connections and maintains a usage counter
* for each connection: two calls to getConnection() with the same URL
* will return the same connection. Two calls to releaseConnection() will
* be needed to make the connection 'potentially disconnectable'.
* <BR><BR>
* releaseConnection() does not disconnect systematically a connection
* whose usage counter is null. It keeps it connected a while (TODO:
* to be implemented).
* <BR><BR>
* TODO: synchronization is a bit simplistic...
*/
public class LDAPConnectionPool {
/**
* Returns <CODE>true</CODE> if the connection passed is registered in the
* connection pool, <CODE>false</CODE> otherwise.
* @param ctx the connection.
* @return <CODE>true</CODE> if the connection passed is registered in the
* connection pool, <CODE>false</CODE> otherwise.
*/
{
return true;
}
}
return false;
}
/**
* Registers a connection in this connection pool.
* @param ctx the connection to be registered.
*/
cr.disconnectAfterUse = false;
}
/**
* Unregisters a connection from this connection pool.
* @param ctx the connection to be unregistered.
* @throws NamingException if there is a problem unregistering the connection.
*/
throws NamingException
{
}
/**
* Adds a referral authentication listener.
* @param listener the referral authentication listener.
*/
public void addReferralAuthenticationListener(
}
}
/**
* Returns an LDAPConnection for accessing the specified url.
* of the URL, getConnection() makes a new one and call connect().
* getConnection() call bind() on the new connection.
* If connect() or bind() failed, getConnection() forward the
* NamingException.
* When getConnection() succeeds, the returned connection must
* be passed to releaseConnection() after use.
* @param ldapUrl the LDAP URL to which the connection must connect.
* @return a connection to the provided LDAP URL.
* @throws NamingException if there was an error connecting.
*/
throws NamingException {
synchronized(this) {
cr = new ConnectionRecord();
cr.disconnectAfterUse = false;
}
else {
}
}
synchronized(cr) {
try {
boolean registerAuth = false;
if (authRecord == null)
{
// Best-effort: try with an already registered authentication
registerAuth = true;
}
if (registerAuth)
{
}
}
}
catch(NamingException x) {
synchronized (this) {
}
}
throw x;
}
}
}
/**
* Sets the request controls to be used by the connections of this connection
* pool.
* @param ctls the request controls.
* @throws NamingException if an error occurs updating the connections.
*/
throws NamingException
{
{
{
}
}
}
/**
* Release an LDAPConnection created by getConnection().
* The connection should be considered as virtually disconnected
* and not be used anymore.
* @param ctx the connection to be released.
*/
synchronized(this) {
targetRecord = cr;
{
break;
}
}
}
}
throw new IllegalArgumentException("Invalid LDAP connection");
}
synchronized (targetRecord)
{
{
}
}
}
/**
* Register authentication data.
* specified in the LDAPURl, they are replaced by the new data.
* If true is passed as 'connect' parameter, registerAuth() creates the
* connection and attempts to connect() and bind() . If connect() or bind()
* fail, registerAuth() forwards the NamingException and does not register
* the authentication data.
* @param ldapUrl the LDAP URL of the server.
* @param dn the bind DN.
* @param pw the password.
* @param connect whether to connect or not to the server with the
* provided authentication (for testing purposes).
* @throws NamingException if an error occurs connecting.
*/
boolean connect) throws NamingException {
if (connect) {
}
synchronized(this) {
}
else {
cr.disconnectAfterUse = true;
}
}
}
}
/**
* Register authentication data from an existing connection.
* This routine recreates the LDAP URL corresponding to
* the connection and passes it to registerAuth(LDAPURL).
* @param ctx the connection that we retrieve the authentication information
* from.
*/
try {
}
catch (NamingException x) {
throw new RuntimeException("Bug");
}
}
/**
* Unregister authentication data.
* If for the given url there's a connection, try to bind as anonymous.
* If unbind fails throw NamingException.
* @param ldapUrl the url associated with the authentication to be
* unregistered.
* @throws NamingException if the unbind fails.
*/
}
/**
* Disconnect the connection associated to a record
* and remove the record from connectionTable.
* @param cr the ConnectionRecord to remove.
*/
{
try
{
}
catch (NamingException x)
{
// Bizarre. However it's not really a problem here.
}
}
/**
* Notifies the listeners that a referral authentication change happened.
*
*/
private void notifyListeners()
{
{
}
}
/**
* Make the key string for an LDAP URL.
* @param url the LDAP URL.
* @return the key to be used in Maps for the provided LDAP URL.
*/
}
/**
* Make the key string for an connection record.
* @param rec the connection record.
* @return the key to be used in Maps for the provided connection record.
*/
}
/**
* Creates an LDAP Connection for a given LDAP URL and using the
* authentication of a AuthRecord.
* @param ldapUrl the LDAP URL.
* @param ar the authentication information.
* @return a connection.
* @throws NamingException if an error occurs when connecting.
*/
{
// Take the base DN out of the URL and only keep the protocol, host and port
if (isSecureLDAPUrl(ldapUrl))
{
getTrustManager(), getKeyManager());
}
}
/**
* Sets the ApplicationTrustManager used by the connection pool to
* connect to servers.
* @param trustManager the ApplicationTrustManager.
*/
{
this.trustManager = trustManager;
}
/**
* Returns the ApplicationTrustManager used by the connection pool to
* connect to servers.
* @return the ApplicationTrustManager used by the connection pool to
* connect to servers.
*/
{
return trustManager;
}
/**
* Returns the timeout to establish the connection in milliseconds.
* @return the timeout to establish the connection in milliseconds.
*/
public int getConnectTimeout()
{
return connectTimeout;
}
/**
* Sets the timeout to establish the connection in milliseconds.
* Use {@code 0} to express no timeout.
* @param connectTimeout the timeout to establish the connection in
* milliseconds.
* Use {@code 0} to express no timeout.
*/
{
this.connectTimeout = connectTimeout;
}
{
// TODO: we should get it from ControlPanelInfo
return null;
}
/**
* Returns whether the URL is ldaps URL or not.
* @param url the URL.
* @return <CODE>true</CODE> if the LDAP URL is secure and <CODE>false</CODE>
* otherwise.
*/
}
return new LDAPURL(
"",
null, // no attributes
null, // No filter
null); // No extensions
}
/**
* Make an url from the specified arguments.
* @param ctx the connection to the server.
* @param dn the base DN of the URL.
* @return an LDAP URL from the specified arguments.
*/
return new LDAPURL(
dn,
null, // No attributes
null,
null); // No filter
}
/**
* Make an url from the specified arguments.
* @param url an LDAP URL to use as base of the new LDAP URL.
* @param dn the base DN for the new LDAP URL.
* @return an LDAP URL from the specified arguments.
*/
return new LDAPURL(
dn,
null, // no attributes
null, // No filter
null); // No extensions
}
}
/**
* A structure representing authentication data.
*/
class AuthRecord {
}
/**
* A structure representing an active connection.
*/
class ConnectionRecord {
int counter;
boolean disconnectAfterUse;
}