0N/A/*
0N/A * CDDL HEADER START
0N/A *
0N/A * The contents of this file are subject to the terms of the
0N/A * Common Development and Distribution License, Version 1.0 only
0N/A * (the "License"). You may not use this file except in compliance
0N/A * with the License.
0N/A *
0N/A * You can obtain a copy of the license at
0N/A * trunk/opends/resource/legal-notices/OpenDS.LICENSE
0N/A * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
0N/A * See the License for the specific language governing permissions
0N/A * and limitations under the License.
0N/A *
0N/A * When distributing Covered Code, include this CDDL HEADER in each
0N/A * file and include the License file at
0N/A * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
0N/A * add the following below this CDDL HEADER, with the fields enclosed
873N/A * by brackets "[]" replaced with your own identifying information:
0N/A * Portions Copyright [yyyy] [name of copyright owner]
0N/A *
0N/A * CDDL HEADER END
0N/A *
0N/A *
4129N/A * Copyright 2006-2009 Sun Microsystems, Inc.
6191N/A * Portions copyright 2011-2013 ForgeRock AS
0N/A */
0N/Apackage org.opends.server.api;
0N/A
0N/A
0N/A
0N/Aimport java.net.InetAddress;
5734N/Aimport java.nio.channels.ByteChannel;
2366N/Aimport java.nio.channels.Selector;
4170N/Aimport java.nio.channels.SocketChannel;
0N/Aimport java.util.Collection;
3902N/Aimport java.util.Collections;
756N/Aimport java.util.HashSet;
776N/Aimport java.util.List;
655N/Aimport java.util.Set;
0N/Aimport java.util.concurrent.CopyOnWriteArrayList;
4426N/Aimport java.util.concurrent.atomic.AtomicBoolean;
0N/A
2366N/Aimport org.opends.messages.Message;
3352N/Aimport org.opends.server.api.plugin.PluginResult;
0N/Aimport org.opends.server.core.DirectoryServer;
0N/Aimport org.opends.server.core.PersistentSearch;
0N/Aimport org.opends.server.core.PluginConfigManager;
0N/Aimport org.opends.server.core.SearchOperation;
3853N/Aimport org.opends.server.core.networkgroups.NetworkGroup;
2366N/Aimport org.opends.server.loggers.debug.DebugTracer;
776N/Aimport org.opends.server.types.Attribute;
776N/Aimport org.opends.server.types.AttributeType;
776N/Aimport org.opends.server.types.AttributeValue;
0N/Aimport org.opends.server.types.AuthenticationInfo;
338N/Aimport org.opends.server.types.CancelRequest;
338N/Aimport org.opends.server.types.CancelResult;
6198N/Aimport org.opends.server.types.DN;
1177N/Aimport org.opends.server.types.DebugLogLevel;
655N/Aimport org.opends.server.types.DirectoryException;
0N/Aimport org.opends.server.types.DisconnectReason;
756N/Aimport org.opends.server.types.Entry;
0N/Aimport org.opends.server.types.IntermediateResponse;
1177N/Aimport org.opends.server.types.Operation;
3861N/Aimport org.opends.server.types.OperationType;
776N/Aimport org.opends.server.types.Privilege;
0N/Aimport org.opends.server.types.SearchResultEntry;
0N/Aimport org.opends.server.types.SearchResultReference;
3861N/Aimport org.opends.server.types.operation.PreParseOperation;
629N/Aimport org.opends.server.util.TimeThread;
0N/A
2366N/Aimport static org.opends.messages.CoreMessages.*;
776N/Aimport static org.opends.server.config.ConfigConstants.*;
974N/Aimport static org.opends.server.loggers.debug.DebugLogger.*;
776N/Aimport static org.opends.server.util.StaticUtils.*;
0N/A
0N/A/**
0N/A * This class defines the set of methods and structures that must be
0N/A * implemented by a Directory Server client connection.
0N/A */
2095N/A@org.opends.server.types.PublicAPI(
2095N/A stability=org.opends.server.types.StabilityLevel.VOLATILE,
2095N/A mayInstantiate=true,
2095N/A mayExtend=true,
2095N/A mayInvoke=true)
0N/Apublic abstract class ClientConnection
0N/A{
1400N/A /**
1400N/A * The tracer object for the debug logger.
1400N/A */
1400N/A private static final DebugTracer TRACER = getTracer();
1400N/A
5553N/A /**
5553N/A * The set of authentication information for this client connection.
5553N/A */
5553N/A protected AuthenticationInfo authenticationInfo;
0N/A
4426N/A /**
4426N/A * Indicates whether a multistage SASL bind is currently in progress
4426N/A * on this client connection. If so, then no other operations
4426N/A * should be allowed until the bind completes.
4426N/A */
4426N/A protected AtomicBoolean saslBindInProgress;
4426N/A
4426N/A /**
4426N/A * Indicates if a bind or start TLS request is currently in progress
4426N/A * on this client connection. If so, then no further socket reads
4426N/A * will occur until the request completes.
4426N/A */
4426N/A protected AtomicBoolean bindOrStartTLSInProgress;
0N/A
6191N/A /**
6191N/A * Indicates whether any necessary finalization work has been done for this
6191N/A * client connection.
6191N/A */
773N/A private boolean finalized;
773N/A
6191N/A /** The set of privileges assigned to this client connection. */
776N/A private HashSet<Privilege> privileges;
776N/A
6191N/A /** The size limit for use with this client connection. */
0N/A private int sizeLimit;
0N/A
6191N/A /** The time limit for use with this client connection. */
0N/A private int timeLimit;
0N/A
6191N/A /** The lookthrough limit for use with this client connection. */
96N/A private int lookthroughLimit;
96N/A
6191N/A /** The time that this client connection was established. */
4129N/A private final long connectTime;
629N/A
6191N/A /** The idle time limit for this client connection. */
1963N/A private long idleTimeLimit;
1963N/A
6191N/A /**
6191N/A * The opaque information used for storing intermediate state information
6191N/A * needed across multi-stage SASL binds.
6191N/A */
0N/A private Object saslAuthState;
0N/A
6191N/A /**
6191N/A * A string representation of the time that this client connection was
6191N/A * established.
6191N/A */
4129N/A private final String connectTimeString;
629N/A
6191N/A /** A set of persistent searches registered for this client. */
4129N/A private final CopyOnWriteArrayList<PersistentSearch>
4129N/A persistentSearches;
0N/A
6191N/A /** The network group to which the connection belongs to. */
1689N/A private NetworkGroup networkGroup;
1689N/A
3853N/A /** Need to evaluate the network group for the first operation. */
3853N/A protected boolean mustEvaluateNetworkGroup;
0N/A
0N/A
0N/A /**
0N/A * Performs the appropriate initialization generic to all client
0N/A * connections.
0N/A */
0N/A protected ClientConnection()
0N/A {
629N/A connectTime = TimeThread.getTime();
908N/A connectTimeString = TimeThread.getGMTTime();
0N/A authenticationInfo = new AuthenticationInfo();
0N/A saslAuthState = null;
4426N/A saslBindInProgress = new AtomicBoolean(false);
4426N/A bindOrStartTLSInProgress = new AtomicBoolean(false);
0N/A persistentSearches = new CopyOnWriteArrayList<PersistentSearch>();
0N/A sizeLimit = DirectoryServer.getSizeLimit();
0N/A timeLimit = DirectoryServer.getTimeLimit();
1963N/A idleTimeLimit = DirectoryServer.getIdleTimeLimit();
96N/A lookthroughLimit = DirectoryServer.getLookthroughLimit();
773N/A finalized = false;
776N/A privileges = new HashSet<Privilege>();
1689N/A networkGroup = NetworkGroup.getDefaultNetworkGroup();
3853N/A networkGroup.addConnection(this);
3853N/A mustEvaluateNetworkGroup = true;
3853N/A if (debugEnabled())
3853N/A {
3853N/A Message message =
3853N/A INFO_CHANGE_NETWORK_GROUP.get(
3853N/A getConnectionID(),
3853N/A "null",
3853N/A networkGroup.getID());
3853N/A TRACER.debugMessage(DebugLogLevel.INFO, message.toString());
3853N/A }
3853N/A
773N/A }
773N/A
773N/A
773N/A
773N/A /**
773N/A * Performs any internal cleanup that may be necessary when this
5553N/A * client connection is disconnected. In
773N/A * this case, it will be used to ensure that the connection is
773N/A * deregistered with the {@code AuthenticatedUsers} manager, and
773N/A * will then invoke the {@code finalizeClientConnection} method.
773N/A */
2095N/A @org.opends.server.types.PublicAPI(
2095N/A stability=org.opends.server.types.StabilityLevel.PRIVATE,
2095N/A mayInstantiate=false,
2095N/A mayExtend=false,
2095N/A mayInvoke=true,
2095N/A notes="This method should only be invoked by connection " +
2095N/A "handlers.")
773N/A protected final void finalizeConnectionInternal()
773N/A {
773N/A if (finalized)
773N/A {
773N/A return;
773N/A }
773N/A
773N/A finalized = true;
773N/A
773N/A // Deregister with the set of authenticated users.
773N/A Entry authNEntry = authenticationInfo.getAuthenticationEntry();
773N/A Entry authZEntry = authenticationInfo.getAuthorizationEntry();
773N/A
773N/A if (authNEntry != null)
773N/A {
773N/A if ((authZEntry == null) ||
773N/A authZEntry.getDN().equals(authNEntry.getDN()))
773N/A {
773N/A DirectoryServer.getAuthenticatedUsers().remove(
773N/A authNEntry.getDN(), this);
773N/A }
773N/A else
773N/A {
773N/A DirectoryServer.getAuthenticatedUsers().remove(
773N/A authNEntry.getDN(), this);
773N/A DirectoryServer.getAuthenticatedUsers().remove(
773N/A authZEntry.getDN(), this);
773N/A }
773N/A }
773N/A else if (authZEntry != null)
773N/A {
773N/A DirectoryServer.getAuthenticatedUsers().remove(
773N/A authZEntry.getDN(), this);
773N/A }
773N/A
3853N/A networkGroup.removeConnection(this);
0N/A }
0N/A
0N/A
0N/A
0N/A /**
629N/A * Retrieves the time that this connection was established, measured
629N/A * in the number of milliseconds since January 1, 1970 UTC.
629N/A *
629N/A * @return The time that this connection was established, measured
629N/A * in the number of milliseconds since January 1, 1970 UTC.
629N/A */
2095N/A public final long getConnectTime()
629N/A {
629N/A return connectTime;
629N/A }
629N/A
629N/A
629N/A
629N/A /**
629N/A * Retrieves a string representation of the time that this
629N/A * connection was established.
629N/A *
629N/A * @return A string representation of the time that this connection
629N/A * was established.
629N/A */
2095N/A public final String getConnectTimeString()
629N/A {
629N/A return connectTimeString;
629N/A }
629N/A
629N/A
629N/A
629N/A /**
0N/A * Retrieves the unique identifier that has been assigned to this
0N/A * connection.
0N/A *
0N/A * @return The unique identifier that has been assigned to this
0N/A * connection.
0N/A */
0N/A public abstract long getConnectionID();
0N/A
0N/A
0N/A
0N/A /**
0N/A * Retrieves the connection handler that accepted this client
0N/A * connection.
0N/A *
0N/A * @return The connection handler that accepted this client
0N/A * connection.
0N/A */
3888N/A public abstract ConnectionHandler<?> getConnectionHandler();
0N/A
0N/A
0N/A
0N/A /**
0N/A * Retrieves the protocol that the client is using to communicate
0N/A * with the Directory Server.
0N/A *
0N/A * @return The protocol that the client is using to communicate
0N/A * with the Directory Server.
0N/A */
0N/A public abstract String getProtocol();
0N/A
0N/A
0N/A
0N/A /**
0N/A * Retrieves a string representation of the address of the client.
0N/A *
0N/A * @return A string representation of the address of the client.
0N/A */
0N/A public abstract String getClientAddress();
0N/A
0N/A
0N/A
0N/A /**
3853N/A * Retrieves the port number for this connection on the client
3853N/A * system if available.
3853N/A *
3853N/A * @return The port number for this connection on the client system
3853N/A * or -1 if there is no client port associated with this
3853N/A * connection (e.g. internal client).
3853N/A */
3853N/A public abstract int getClientPort();
3853N/A
3853N/A
3853N/A
3853N/A /**
3853N/A * Retrieves the address and port (if available) of the client
3853N/A * system, separated by a colon.
3853N/A *
3853N/A * @return The address and port of the client system, separated by a
3853N/A * colon.
3853N/A */
3853N/A public final String getClientHostPort()
3853N/A {
3853N/A int port = getClientPort();
3853N/A if (port >= 0)
3853N/A {
3853N/A return getClientAddress() + ":" + port;
3853N/A }
3853N/A else
3853N/A {
3853N/A return getClientAddress();
3853N/A }
3853N/A }
3853N/A
3853N/A
3853N/A
3853N/A /**
0N/A * Retrieves a string representation of the address on the server to
0N/A * which the client connected.
0N/A *
0N/A * @return A string representation of the address on the server to
0N/A * which the client connected.
0N/A */
0N/A public abstract String getServerAddress();
0N/A
0N/A
0N/A
3853N/A
3853N/A /**
3853N/A * Retrieves the port number for this connection on the server
3853N/A * system if available.
3853N/A *
3853N/A * @return The port number for this connection on the server system
3853N/A * or -1 if there is no server port associated with this
3853N/A * connection (e.g. internal client).
3853N/A */
3853N/A public abstract int getServerPort();
3853N/A
3853N/A
3853N/A
3853N/A /**
3853N/A * Retrieves the address and port of the server system, separated by
3853N/A * a colon.
3853N/A *
3853N/A * @return The address and port of the server system, separated by a
3853N/A * colon.
3853N/A */
3853N/A public final String getServerHostPort()
3853N/A {
3853N/A int port = getServerPort();
3853N/A if (port >= 0)
3853N/A {
3853N/A return getServerAddress() + ":" + port;
3853N/A }
3853N/A else
3853N/A {
3853N/A return getServerAddress();
3853N/A }
3853N/A }
3853N/A
3853N/A
3853N/A
0N/A /**
2095N/A * Retrieves the {@code java.net.InetAddress} associated with the
2095N/A * remote client system.
0N/A *
2095N/A * @return The {@code java.net.InetAddress} associated with the
2095N/A * remote client system. It may be {@code null} if the
2095N/A * client is not connected over an IP-based connection.
0N/A */
0N/A public abstract InetAddress getRemoteAddress();
0N/A
0N/A
0N/A
0N/A /**
2095N/A * Retrieves the {@code java.net.InetAddress} for the Directory
0N/A * Server system to which the client has established the connection.
0N/A *
2095N/A * @return The {@code java.net.InetAddress} for the Directory
0N/A * Server system to which the client has established the
2095N/A * connection. It may be {@code null} if the client is not
2095N/A * connected over an IP-based connection.
0N/A */
0N/A public abstract InetAddress getLocalAddress();
0N/A
6198N/A /**
6198N/A * Returns whether the Directory Server believes this connection to be valid
6198N/A * and available for communication.
6198N/A *
6198N/A * @return true if the connection is valid, false otherwise
6198N/A */
6198N/A public abstract boolean isConnectionValid();
0N/A
0N/A /**
0N/A * Indicates whether this client connection is currently using a
0N/A * secure mechanism to communicate with the server. Note that this
0N/A * may change over time based on operations performed by the client
2095N/A * or server (e.g., it may go from {@code false} to {@code true} if
2095N/A * if the client uses the StartTLS extended operation).
0N/A *
2095N/A * @return {@code true} if the client connection is currently using
2095N/A * a secure mechanism to communicate with the server, or
2095N/A * {@code false} if not.
0N/A */
0N/A public abstract boolean isSecure();
0N/A
0N/A
0N/A /**
2366N/A * Retrieves a {@code Selector} that may be used to ensure that
2366N/A * write operations complete in a timely manner, or terminate the
2366N/A * connection in the event that they fail to do so. This is an
2366N/A * optional method for client connections, and the default
2366N/A * implementation returns {@code null} to indicate that the maximum
2366N/A * blocked write time limit is not supported for this connection.
2366N/A * Subclasses that do wish to support this functionality should
2366N/A * return a valid {@code Selector} object.
2366N/A *
2366N/A * @return The {@code Selector} that may be used to ensure that
2366N/A * write operations complete in a timely manner, or
2366N/A * {@code null} if this client connection does not support
2366N/A * maximum blocked write time limit functionality.
2366N/A */
2366N/A public Selector getWriteSelector()
2366N/A {
2366N/A // There will not be a write selector in the default
2366N/A // implementation.
2366N/A return null;
2366N/A }
2366N/A
2366N/A
2366N/A
2366N/A /**
2366N/A * Retrieves the maximum length of time in milliseconds that
2366N/A * attempts to write data to the client should be allowed to block.
2366N/A * A value of zero indicates there should be no limit.
2366N/A *
2366N/A * @return The maximum length of time in milliseconds that attempts
2366N/A * to write data to the client should be allowed to block,
2366N/A * or zero if there should be no limit.
2366N/A */
2366N/A public long getMaxBlockedWriteTimeLimit()
2366N/A {
2366N/A // By default, we'll return 0, which indicates that there should
2366N/A // be no maximum time limit. Subclasses should override this if
2366N/A // they want to support a maximum blocked write time limit.
2366N/A return 0L;
2366N/A }
2366N/A
2366N/A
2366N/A
2366N/A /**
3853N/A * Retrieves the total number of operations performed
3853N/A * on this connection.
3853N/A *
3853N/A * @return The total number of operations performed
3853N/A * on this connection.
3853N/A */
3853N/A public abstract long getNumberOfOperations();
3853N/A
3853N/A /**
3853N/A * Indicates whether the network group must be evaluated for
3853N/A * the next connection.
3861N/A * @param operation The operation going to be performed. Bind
3861N/A * operations imply a network group evaluation.
3853N/A * @return boolean indicating if the network group must be evaluated
3853N/A */
3861N/A public boolean mustEvaluateNetworkGroup(
3861N/A PreParseOperation operation) {
3861N/A // Connections inside the internal network group MUST NOT
3861N/A // change network group
3861N/A if (this.networkGroup == NetworkGroup.getInternalNetworkGroup()) {
3861N/A return false;
3861N/A }
3861N/A // Connections inside the admin network group MUST NOT
3861N/A // change network group
3861N/A if (this.networkGroup == NetworkGroup.getAdminNetworkGroup()) {
3861N/A return false;
3861N/A }
3861N/A
3861N/A // If the operation is a BIND, the network group MUST be evaluated
3861N/A if (operation != null
3861N/A && operation.getOperationType() == OperationType.BIND) {
3861N/A return true;
3861N/A }
3861N/A
3853N/A return mustEvaluateNetworkGroup;
3853N/A }
3853N/A
3853N/A /**
3853N/A * Indicates that the network group will have to be evaluated
3853N/A * for the next connection.
3853N/A *
3853N/A * @param bool true if the network group must be evaluated
3853N/A */
3853N/A public void mustEvaluateNetworkGroup(boolean bool) {
3853N/A mustEvaluateNetworkGroup = bool;
3853N/A }
3853N/A
0N/A
0N/A
0N/A /**
0N/A * Sends a response to the client based on the information in the
0N/A * provided operation.
0N/A *
0N/A * @param operation The operation for which to send the response.
0N/A */
0N/A public abstract void sendResponse(Operation operation);
0N/A
0N/A
0N/A
0N/A /**
0N/A * Sends the provided search result entry to the client.
0N/A *
0N/A * @param searchOperation The search operation with which the
0N/A * entry is associated.
0N/A * @param searchEntry The search result entry to be sent to
0N/A * the client.
988N/A *
988N/A * @throws DirectoryException If a problem occurs while attempting
988N/A * to send the entry to the client and
988N/A * the search should be terminated.
0N/A */
0N/A public abstract void sendSearchEntry(
0N/A SearchOperation searchOperation,
988N/A SearchResultEntry searchEntry)
988N/A throws DirectoryException;
0N/A
0N/A
0N/A
0N/A /**
0N/A * Sends the provided search result reference to the client.
0N/A *
0N/A * @param searchOperation The search operation with which the
0N/A * reference is associated.
0N/A * @param searchReference The search result reference to be sent
0N/A * to the client.
0N/A *
2095N/A * @return {@code true} if the client is able to accept referrals,
2095N/A * or {@code false} if the client cannot handle referrals
2095N/A * and no more attempts should be made to send them for the
2095N/A * associated search operation.
988N/A *
988N/A * @throws DirectoryException If a problem occurs while attempting
988N/A * to send the reference to the client
988N/A * and the search should be terminated.
0N/A */
0N/A public abstract boolean sendSearchReference(
0N/A SearchOperation searchOperation,
988N/A SearchResultReference searchReference)
988N/A throws DirectoryException;
0N/A
0N/A
0N/A
0N/A /**
0N/A * Invokes the intermediate response plugins on the provided
0N/A * response message and sends it to the client.
0N/A *
0N/A * @param intermediateResponse The intermediate response message
0N/A * to be sent.
0N/A *
2095N/A * @return {@code true} if processing on the associated operation
2095N/A * should continue, or {@code false} if not.
0N/A */
0N/A public final boolean sendIntermediateResponse(
0N/A IntermediateResponse intermediateResponse)
0N/A {
0N/A // Invoke the intermediate response plugins for the response
0N/A // message.
0N/A PluginConfigManager pluginConfigManager =
0N/A DirectoryServer.getPluginConfigManager();
3352N/A PluginResult.IntermediateResponse pluginResult =
0N/A pluginConfigManager.invokeIntermediateResponsePlugins(
0N/A intermediateResponse);
0N/A
0N/A boolean continueProcessing = true;
3352N/A if (pluginResult.sendResponse())
0N/A {
0N/A continueProcessing =
0N/A sendIntermediateResponseMessage(intermediateResponse);
0N/A }
0N/A
3352N/A return (continueProcessing && pluginResult.continueProcessing());
0N/A }
0N/A
0N/A
0N/A
0N/A
0N/A /**
0N/A * Sends the provided intermediate response message to the client.
0N/A *
0N/A * @param intermediateResponse The intermediate response message
0N/A * to be sent.
0N/A *
2095N/A * @return {@code true} if processing on the associated operation
2095N/A * should continue, or {@code false} if not.
0N/A */
0N/A protected abstract boolean
0N/A sendIntermediateResponseMessage(
0N/A IntermediateResponse intermediateResponse);
0N/A
0N/A
0N/A
0N/A /**
0N/A * Closes the connection to the client, optionally sending it a
0N/A * message indicating the reason for the closure. Note that the
0N/A * ability to send a notice of disconnection may not be available
403N/A * for all protocols or under all circumstances. Also note that
403N/A * when attempting to disconnect a client connection as a part of
403N/A * operation processing (e.g., within a plugin or other extension),
2095N/A * the {@code disconnectClient} method within that operation should
2095N/A * be called rather than invoking this method directly.
773N/A * <BR><BR>
773N/A * All subclasses must invoke the {@code finalizeConnectionInternal}
773N/A * method during the course of processing this method.
0N/A *
0N/A * @param disconnectReason The disconnect reason that provides the
0N/A * generic cause for the disconnect.
0N/A * @param sendNotification Indicates whether to try to provide
0N/A * notification to the client that the
0N/A * connection will be closed.
0N/A * @param message The message to send to the client. It
2095N/A * may be {@code null} if no notification
2095N/A * is to be sent.
0N/A */
0N/A public abstract void disconnect(DisconnectReason disconnectReason,
0N/A boolean sendNotification,
2086N/A Message message);
0N/A
0N/A
0N/A
0N/A /**
0N/A * Indicates whether the user associated with this client connection
0N/A * must change their password before they will be allowed to do
0N/A * anything else.
0N/A *
2095N/A * @return {@code true} if the user associated with this client
2095N/A * connection must change their password before they will
2095N/A * be allowed to do anything else, or {@code false} if not.
0N/A */
2095N/A public final boolean mustChangePassword()
0N/A {
0N/A if (authenticationInfo == null)
0N/A {
0N/A return false;
0N/A }
0N/A else
0N/A {
0N/A return authenticationInfo.mustChangePassword();
0N/A }
0N/A }
0N/A
0N/A
0N/A
0N/A /**
0N/A * Specifies whether the user associated with this client connection
0N/A * must change their password before they will be allowed to do
0N/A * anything else.
0N/A *
0N/A * @param mustChangePassword Specifies whether the user associated
0N/A * with this client connection must
0N/A * change their password before they
0N/A * will be allowed to do anything else.
0N/A */
2095N/A public final void setMustChangePassword(boolean mustChangePassword)
0N/A {
0N/A if (authenticationInfo == null)
0N/A {
978N/A setAuthenticationInfo(new AuthenticationInfo());
0N/A }
0N/A
0N/A authenticationInfo.setMustChangePassword(mustChangePassword);
0N/A }
0N/A
0N/A
0N/A
0N/A /**
0N/A * Retrieves the set of operations in progress for this client
0N/A * connection. This list must not be altered by any caller.
0N/A *
0N/A * @return The set of operations in progress for this client
0N/A * connection.
0N/A */
3902N/A public abstract Collection<Operation> getOperationsInProgress();
0N/A
0N/A
0N/A
0N/A /**
0N/A * Retrieves the operation in progress with the specified message
0N/A * ID.
0N/A *
0N/A * @param messageID The message ID of the operation to retrieve.
0N/A *
0N/A * @return The operation in progress with the specified message ID,
2095N/A * or {@code null} if no such operation could be found.
0N/A */
3902N/A public abstract Operation getOperationInProgress(int messageID);
0N/A
0N/A
0N/A
0N/A /**
0N/A * Removes the provided operation from the set of operations in
0N/A * progress for this client connection. Note that this does not
0N/A * make any attempt to cancel any processing that may already be in
0N/A * progress for the operation.
0N/A *
0N/A * @param messageID The message ID of the operation to remove from
0N/A * the set of operations in progress.
0N/A *
2095N/A * @return {@code true} if the operation was found and removed from
2095N/A * the set of operations in progress, or {@code false} if
2095N/A * not.
0N/A */
0N/A public abstract boolean removeOperationInProgress(int messageID);
0N/A
0N/A
0N/A
0N/A /**
0N/A * Retrieves the set of persistent searches registered for this
0N/A * client.
0N/A *
0N/A * @return The set of persistent searches registered for this
0N/A * client.
0N/A */
3902N/A public final List<PersistentSearch> getPersistentSearches()
0N/A {
0N/A return persistentSearches;
0N/A }
0N/A
0N/A
0N/A
0N/A /**
0N/A * Registers the provided persistent search for this client. Note
0N/A * that this should only be called by
2095N/A * {@code DirectoryServer.registerPersistentSearch} and not through
2095N/A * any other means.
0N/A *
0N/A * @param persistentSearch The persistent search to register for
0N/A * this client.
0N/A */
2095N/A @org.opends.server.types.PublicAPI(
2095N/A stability=org.opends.server.types.StabilityLevel.PRIVATE,
2095N/A mayInstantiate=false,
2095N/A mayExtend=false,
2095N/A mayInvoke=false)
2095N/A public final void registerPersistentSearch(PersistentSearch
2095N/A persistentSearch)
0N/A {
0N/A persistentSearches.add(persistentSearch);
0N/A }
0N/A
0N/A
0N/A
0N/A /**
0N/A * Deregisters the provided persistent search for this client. Note
0N/A * that this should only be called by
2095N/A * {@code DirectoryServer.deregisterPersistentSearch} and not
0N/A * through any other means.
0N/A *
0N/A * @param persistentSearch The persistent search to deregister for
0N/A * this client.
0N/A */
2095N/A @org.opends.server.types.PublicAPI(
2095N/A stability=org.opends.server.types.StabilityLevel.PRIVATE,
2095N/A mayInstantiate=false,
2095N/A mayExtend=false,
2095N/A mayInvoke=false)
2095N/A public final void deregisterPersistentSearch(PersistentSearch
2095N/A persistentSearch)
0N/A {
0N/A persistentSearches.remove(persistentSearch);
0N/A }
0N/A
0N/A
0N/A
0N/A /**
0N/A * Attempts to cancel the specified operation.
0N/A *
0N/A * @param messageID The message ID of the operation to cancel.
0N/A * @param cancelRequest An object providing additional information
0N/A * about how the cancel should be processed.
0N/A *
0N/A * @return A cancel result that either indicates that the cancel
0N/A * was successful or provides a reason that it was not.
0N/A */
0N/A public abstract CancelResult cancelOperation(int messageID,
0N/A CancelRequest cancelRequest);
0N/A
0N/A
0N/A
0N/A /**
0N/A * Attempts to cancel all operations in progress on this connection.
0N/A *
0N/A * @param cancelRequest An object providing additional information
0N/A * about how the cancel should be processed.
0N/A */
0N/A public abstract void cancelAllOperations(
0N/A CancelRequest cancelRequest);
0N/A
0N/A
0N/A
0N/A /**
0N/A * Attempts to cancel all operations in progress on this connection
0N/A * except the operation with the specified message ID.
0N/A *
0N/A * @param cancelRequest An object providing additional information
0N/A * about how the cancel should be processed.
0N/A * @param messageID The message ID of the operation that
0N/A * should not be canceled.
0N/A */
0N/A public abstract void cancelAllOperationsExcept(
0N/A CancelRequest cancelRequest,
0N/A int messageID);
0N/A
0N/A
0N/A
0N/A /**
0N/A * Retrieves information about the authentication that has been
0N/A * performed for this connection.
0N/A *
0N/A * @return Information about the user that is currently
0N/A * authenticated on this connection.
0N/A */
0N/A public AuthenticationInfo getAuthenticationInfo()
0N/A {
0N/A return authenticationInfo;
0N/A }
0N/A
0N/A
0N/A
0N/A /**
0N/A * Specifies information about the authentication that has been
0N/A * performed for this connection.
0N/A *
0N/A * @param authenticationInfo Information about the authentication
0N/A * that has been performed for this
0N/A * connection. It should not be
2095N/A * {@code null}.
0N/A */
0N/A public void setAuthenticationInfo(AuthenticationInfo
0N/A authenticationInfo)
0N/A {
773N/A if (this.authenticationInfo != null)
773N/A {
773N/A Entry authNEntry =
773N/A this.authenticationInfo.getAuthenticationEntry();
773N/A Entry authZEntry =
773N/A this.authenticationInfo.getAuthorizationEntry();
773N/A
773N/A if (authNEntry != null)
773N/A {
773N/A if ((authZEntry == null) ||
773N/A authZEntry.getDN().equals(authNEntry.getDN()))
773N/A {
773N/A DirectoryServer.getAuthenticatedUsers().remove(
773N/A authNEntry.getDN(), this);
773N/A }
773N/A else
773N/A {
773N/A DirectoryServer.getAuthenticatedUsers().remove(
773N/A authNEntry.getDN(), this);
773N/A DirectoryServer.getAuthenticatedUsers().remove(
773N/A authZEntry.getDN(), this);
773N/A }
773N/A }
773N/A else if (authZEntry != null)
773N/A {
773N/A DirectoryServer.getAuthenticatedUsers().remove(
773N/A authZEntry.getDN(), this);
773N/A }
773N/A }
773N/A
0N/A if (authenticationInfo == null)
0N/A {
0N/A this.authenticationInfo = new AuthenticationInfo();
1454N/A updatePrivileges(null, false);
0N/A }
0N/A else
0N/A {
0N/A this.authenticationInfo = authenticationInfo;
773N/A
773N/A Entry authNEntry = authenticationInfo.getAuthenticationEntry();
773N/A Entry authZEntry = authenticationInfo.getAuthorizationEntry();
773N/A
773N/A if (authNEntry != null)
773N/A {
773N/A if ((authZEntry == null) ||
773N/A authZEntry.getDN().equals(authNEntry.getDN()))
773N/A {
773N/A DirectoryServer.getAuthenticatedUsers().put(
773N/A authNEntry.getDN(), this);
773N/A }
773N/A else
773N/A {
773N/A DirectoryServer.getAuthenticatedUsers().put(
773N/A authNEntry.getDN(), this);
773N/A DirectoryServer.getAuthenticatedUsers().put(
773N/A authZEntry.getDN(), this);
773N/A }
773N/A }
776N/A else
773N/A {
776N/A if (authZEntry != null)
776N/A {
776N/A DirectoryServer.getAuthenticatedUsers().put(
776N/A authZEntry.getDN(), this);
776N/A }
1454N/A }
776N/A
1454N/A updatePrivileges(authZEntry, authenticationInfo.isRoot());
773N/A }
773N/A }
773N/A
773N/A
773N/A
773N/A /**
773N/A * Updates the cached entry associated with either the
773N/A * authentication and/or authorization identity with the provided
773N/A * version.
773N/A *
773N/A * @param oldEntry The user entry currently serving as the
773N/A * authentication and/or authorization identity.
773N/A * @param newEntry The updated entry that should replace the
773N/A * existing entry. It may optionally have a
773N/A * different DN than the old entry.
773N/A */
2095N/A public final void updateAuthenticationInfo(Entry oldEntry,
2095N/A Entry newEntry)
773N/A {
773N/A Entry authNEntry = authenticationInfo.getAuthenticationEntry();
773N/A Entry authZEntry = authenticationInfo.getAuthorizationEntry();
773N/A
773N/A if ((authNEntry != null) &&
773N/A authNEntry.getDN().equals(oldEntry.getDN()))
773N/A {
773N/A if ((authZEntry == null) ||
773N/A (! authZEntry.getDN().equals(authNEntry.getDN())))
773N/A {
978N/A setAuthenticationInfo(
978N/A authenticationInfo.duplicate(newEntry, authZEntry));
776N/A updatePrivileges(newEntry, authenticationInfo.isRoot());
773N/A }
773N/A else
773N/A {
978N/A setAuthenticationInfo(
978N/A authenticationInfo.duplicate(newEntry, newEntry));
776N/A updatePrivileges(newEntry, authenticationInfo.isRoot());
773N/A }
773N/A }
773N/A else if ((authZEntry != null) &&
773N/A (authZEntry.getDN().equals(oldEntry.getDN())))
773N/A {
978N/A setAuthenticationInfo(
978N/A authenticationInfo.duplicate(authNEntry, newEntry));
0N/A }
0N/A }
0N/A
0N/A
0N/A
0N/A /**
0N/A * Sets properties in this client connection to indicate that the
0N/A * client is unauthenticated. This includes setting the
0N/A * authentication info structure to an empty default, as well as
0N/A * setting the size and time limit values to their defaults.
0N/A */
0N/A public void setUnauthenticated()
0N/A {
978N/A setAuthenticationInfo(new AuthenticationInfo());
4129N/A this.sizeLimit = networkGroup.getSizeLimit();
4129N/A this.timeLimit = networkGroup.getTimeLimit();
0N/A }
0N/A
0N/A
3888N/A /**
3888N/A * Indicate whether the specified authorization entry parameter
3888N/A * has the specified privilege. The method can be used to perform
3888N/A * a "what-if" scenario.
3888N/A *
3888N/A * @param authorizationEntry The authentication entry to use.
3888N/A * @param privilege The privilege to check for.
3888N/A *
3888N/A * @return {@code true} if the authentication entry has the
3888N/A * specified privilege, or {@code false} if not.
3888N/A */
3888N/A public static boolean hasPrivilege(Entry authorizationEntry,
3888N/A Privilege privilege) {
3888N/A boolean isRoot =
3888N/A DirectoryServer.isRootDN(authorizationEntry.getDN());
3888N/A return getPrivileges(authorizationEntry,
3888N/A isRoot).contains(privilege) ||
3888N/A DirectoryServer.isDisabled(privilege);
3888N/A }
3888N/A
0N/A
0N/A /**
776N/A * Indicates whether the authenticated client has the specified
776N/A * privilege.
776N/A *
776N/A * @param privilege The privilege for which to make the
776N/A * determination.
776N/A * @param operation The operation being processed which needs to
776N/A * make the privilege determination, or
776N/A * {@code null} if there is no associated
776N/A * operation.
776N/A *
776N/A * @return {@code true} if the authenticated client has the
776N/A * specified privilege, or {@code false} if not.
776N/A */
776N/A public boolean hasPrivilege(Privilege privilege,
776N/A Operation operation)
776N/A {
1454N/A if (privilege == Privilege.PROXIED_AUTH)
776N/A {
1454N/A // This determination should always be made against the
1454N/A // authentication identity rather than the authorization
1454N/A // identity.
1454N/A Entry authEntry = authenticationInfo.getAuthenticationEntry();
1454N/A boolean isRoot = authenticationInfo.isRoot();
1454N/A return getPrivileges(authEntry,
1957N/A isRoot).contains(Privilege.PROXIED_AUTH) ||
1957N/A DirectoryServer.isDisabled(Privilege.PROXIED_AUTH);
1454N/A }
1454N/A
1957N/A boolean result;
1454N/A if (operation == null)
1454N/A {
1454N/A result = privileges.contains(privilege);
1454N/A if (debugEnabled())
974N/A {
974N/A DN authDN = authenticationInfo.getAuthenticationDN();
776N/A
2086N/A Message message = INFO_CLIENTCONNECTION_AUDIT_HASPRIVILEGE
2086N/A .get(getConnectionID(), -1L,
2086N/A String.valueOf(authDN),
2086N/A privilege.getName(), result);
2086N/A TRACER.debugMessage(DebugLogLevel.INFO, message.toString());
974N/A }
1454N/A }
1454N/A else
1454N/A {
1454N/A if (operation.getAuthorizationDN().equals(
3192N/A authenticationInfo.getAuthorizationDN()) ||
3192N/A (operation.getAuthorizationDN().equals(DN.NULL_DN) &&
3192N/A !authenticationInfo.isAuthenticated())) {
1957N/A result = privileges.contains(privilege) ||
1957N/A DirectoryServer.isDisabled(privilege);
1454N/A if (debugEnabled())
1454N/A {
1454N/A DN authDN = authenticationInfo.getAuthenticationDN();
1454N/A
2086N/A Message message =
2086N/A INFO_CLIENTCONNECTION_AUDIT_HASPRIVILEGE.get(
2086N/A getConnectionID(),
2086N/A operation.getOperationID(),
2086N/A String.valueOf(authDN),
2086N/A privilege.getName(), result);
2086N/A TRACER.debugMessage(DebugLogLevel.INFO, message.toString());
1454N/A }
1454N/A }
974N/A else
974N/A {
1454N/A Entry authorizationEntry = operation.getAuthorizationEntry();
1454N/A if (authorizationEntry == null)
1454N/A {
1454N/A result = false;
1454N/A }
1454N/A else
1454N/A {
1454N/A boolean isRoot =
1454N/A DirectoryServer.isRootDN(authorizationEntry.getDN());
1454N/A result = getPrivileges(authorizationEntry,
1957N/A isRoot).contains(privilege) ||
1957N/A DirectoryServer.isDisabled(privilege);
1454N/A }
974N/A }
776N/A }
776N/A
776N/A return result;
776N/A }
776N/A
776N/A
776N/A
776N/A /**
776N/A * Indicates whether the authenticate client has all of the
776N/A * specified privileges.
776N/A *
776N/A * @param privileges The array of privileges for which to make the
776N/A * determination.
776N/A * @param operation The operation being processed which needs to
776N/A * make the privilege determination, or
776N/A * {@code null} if there is no associated
776N/A * operation.
776N/A *
776N/A * @return {@code true} if the authenticated client has all of the
776N/A * specified privileges, or {@code false} if not.
776N/A */
776N/A public boolean hasAllPrivileges(Privilege[] privileges,
776N/A Operation operation)
776N/A {
776N/A HashSet<Privilege> privSet = this.privileges;
776N/A
974N/A if (debugEnabled())
776N/A {
974N/A for (Privilege p : privileges)
776N/A {
974N/A if (! privSet.contains(p))
974N/A {
974N/A return false;
974N/A }
776N/A }
776N/A
974N/A return true;
776N/A }
776N/A else
776N/A {
974N/A boolean result = true;
974N/A StringBuilder buffer = new StringBuilder();
974N/A buffer.append("{");
974N/A
974N/A for (int i=0; i < privileges.length; i++)
974N/A {
974N/A if (i > 0)
974N/A {
974N/A buffer.append(",");
974N/A }
974N/A
974N/A buffer.append(privileges[i].getName());
974N/A
974N/A if (! privSet.contains(privileges[i]))
974N/A {
974N/A result = false;
974N/A }
974N/A }
974N/A
974N/A buffer.append(" }");
776N/A
974N/A if (operation == null)
974N/A {
974N/A DN authDN = authenticationInfo.getAuthenticationDN();
974N/A
2086N/A Message message =
2086N/A INFO_CLIENTCONNECTION_AUDIT_HASPRIVILEGES.get(
2086N/A getConnectionID(), -1L,
2086N/A String.valueOf(authDN),
2086N/A buffer.toString(), result);
2086N/A TRACER.debugMessage(DebugLogLevel.INFO,
2086N/A message.toString());
974N/A }
974N/A else
974N/A {
974N/A DN authDN = authenticationInfo.getAuthenticationDN();
974N/A
2086N/A Message message = INFO_CLIENTCONNECTION_AUDIT_HASPRIVILEGES
2086N/A .get(
2086N/A getConnectionID(),
2086N/A operation.getOperationID(),
2086N/A String.valueOf(authDN),
2086N/A buffer.toString(), result);
2086N/A TRACER.debugMessage(DebugLogLevel.INFO, message.toString());
974N/A }
974N/A
974N/A return result;
776N/A }
776N/A }
776N/A
776N/A
776N/A
776N/A /**
1454N/A * Retrieves the set of privileges encoded in the provided entry.
1454N/A *
1454N/A * @param entry The entry to use to obtain the privilege
1454N/A * information.
1454N/A * @param isRoot Indicates whether the set of root privileges
1454N/A * should be automatically included in the
1454N/A * privilege set.
776N/A *
1454N/A * @return A set of the privileges that should be assigned.
776N/A */
3888N/A private static HashSet<Privilege> getPrivileges(Entry entry,
1454N/A boolean isRoot)
776N/A {
1454N/A if (entry == null)
1454N/A {
1454N/A return new HashSet<Privilege>(0);
1454N/A }
1454N/A
776N/A HashSet<Privilege> newPrivileges = new HashSet<Privilege>();
776N/A HashSet<Privilege> removePrivileges = new HashSet<Privilege>();
776N/A
776N/A if (isRoot)
776N/A {
776N/A newPrivileges.addAll(DirectoryServer.getRootPrivileges());
776N/A }
776N/A
776N/A AttributeType privType =
776N/A DirectoryServer.getAttributeType(OP_ATTR_PRIVILEGE_NAME);
776N/A List<Attribute> attrList = entry.getAttribute(privType);
776N/A if (attrList != null)
776N/A {
776N/A for (Attribute a : attrList)
776N/A {
3853N/A for (AttributeValue v : a)
776N/A {
4134N/A String privName = toLowerCase(v.getValue().toString());
776N/A
776N/A // If the name of the privilege is prefixed with a minus
776N/A // sign, then we will take away that privilege from the
776N/A // user. We'll handle that at the end so that we can make
776N/A // sure it's not added back later.
776N/A if (privName.startsWith("-"))
776N/A {
776N/A privName = privName.substring(1);
776N/A Privilege p = Privilege.privilegeForName(privName);
776N/A if (p == null)
776N/A {
776N/A // FIXME -- Generate an administrative alert.
776N/A
776N/A // We don't know what privilege to remove, so we'll
776N/A // remove all of them.
776N/A newPrivileges.clear();
1454N/A return newPrivileges;
776N/A }
776N/A else
776N/A {
776N/A removePrivileges.add(p);
776N/A }
776N/A }
776N/A else
776N/A {
776N/A Privilege p = Privilege.privilegeForName(privName);
776N/A if (p == null)
776N/A {
776N/A // FIXME -- Generate an administrative alert.
776N/A }
776N/A else
776N/A {
776N/A newPrivileges.add(p);
776N/A }
776N/A }
776N/A }
776N/A }
776N/A }
776N/A
776N/A for (Privilege p : removePrivileges)
776N/A {
776N/A newPrivileges.remove(p);
776N/A }
776N/A
1454N/A return newPrivileges;
1454N/A }
1454N/A
1454N/A
1454N/A
1454N/A /**
1454N/A * Updates the privileges associated with this client connection
1454N/A * object based on the provided entry for the authentication
1454N/A * identity.
1454N/A *
1454N/A * @param entry The entry for the authentication identity
1454N/A * associated with this client connection.
1454N/A * @param isRoot Indicates whether the associated user is a root
1454N/A * user and should automatically inherit the root
1454N/A * privilege set.
1454N/A */
5553N/A protected void updatePrivileges(Entry entry, boolean isRoot)
1454N/A {
1454N/A privileges = getPrivileges(entry, isRoot);
776N/A }
776N/A
776N/A
776N/A
776N/A /**
0N/A * Retrieves an opaque set of information that may be used for
0N/A * processing multi-stage SASL binds.
0N/A *
0N/A * @return An opaque set of information that may be used for
0N/A * processing multi-stage SASL binds.
0N/A */
0N/A public final Object getSASLAuthStateInfo()
0N/A {
0N/A return saslAuthState;
0N/A }
0N/A
0N/A
0N/A
0N/A /**
0N/A * Specifies an opaque set of information that may be used for
0N/A * processing multi-stage SASL binds.
0N/A *
0N/A * @param saslAuthState An opaque set of information that may be
0N/A * used for processing multi-stage SASL
0N/A * binds.
0N/A */
0N/A public final void setSASLAuthStateInfo(Object saslAuthState)
0N/A {
0N/A this.saslAuthState = saslAuthState;
0N/A }
0N/A
0N/A
4170N/A /**
4170N/A * Return the lowest level channel associated with a connection.
4170N/A * This is normally the channel associated with the socket
4170N/A * channel.
4170N/A *
4170N/A * @return The lowest level channel associated with a connection.
4170N/A */
5734N/A public ByteChannel getChannel() {
4170N/A // By default, return null, which indicates that there should
4170N/A // be no channel. Subclasses should override this if
4170N/A // they want to support a channel.
4170N/A return null;
4170N/A }
4170N/A
4170N/A
4170N/A
4170N/A /**
4170N/A * Return the Socket channel associated with a connection.
4170N/A *
4170N/A * @return The Socket channel associated with a connection.
4170N/A */
4170N/A public SocketChannel getSocketChannel() {
4170N/A // By default, return null, which indicates that there should
4170N/A // be no socket channel. Subclasses should override this if
4170N/A // they want to support a socket channel.
4170N/A return null;
4170N/A }
4170N/A
4170N/A
4170N/A
4170N/A /**
0N/A * Retrieves the size limit that will be enforced for searches
0N/A * performed using this client connection.
0N/A *
0N/A * @return The size limit that will be enforced for searches
0N/A * performed using this client connection.
0N/A */
0N/A public final int getSizeLimit()
0N/A {
0N/A return sizeLimit;
0N/A }
0N/A
0N/A
0N/A
0N/A /**
0N/A * Specifies the size limit that will be enforced for searches
0N/A * performed using this client connection.
0N/A *
0N/A * @param sizeLimit The size limit that will be enforced for
0N/A * searches performed using this client
0N/A * connection.
0N/A */
1057N/A public void setSizeLimit(int sizeLimit)
0N/A {
0N/A this.sizeLimit = sizeLimit;
0N/A }
0N/A
0N/A
0N/A
0N/A /**
1963N/A * Retrieves the maximum length of time in milliseconds that this
1963N/A * client connection will be allowed to remain idle before it should
1963N/A * be disconnected.
1963N/A *
1963N/A * @return The maximum length of time in milliseconds that this
1963N/A * client connection will be allowed to remain idle before
1963N/A * it should be disconnected.
1963N/A */
1963N/A public final long getIdleTimeLimit()
1963N/A {
1963N/A return idleTimeLimit;
1963N/A }
1963N/A
1963N/A
1963N/A
1963N/A /**
1963N/A * Specifies the maximum length of time in milliseconds that this
1963N/A * client connection will be allowed to remain idle before it should
1963N/A * be disconnected.
1963N/A *
1963N/A * @param idleTimeLimit The maximum length of time in milliseconds
1963N/A * that this client connection will be
1963N/A * allowed to remain idle before it should be
1963N/A * disconnected.
1963N/A */
1963N/A public void setIdleTimeLimit(long idleTimeLimit)
1963N/A {
1963N/A this.idleTimeLimit = idleTimeLimit;
1963N/A }
1963N/A
1963N/A
1963N/A
1963N/A /**
96N/A * Retrieves the default maximum number of entries that should
96N/A * checked for matches during a search.
96N/A *
96N/A * @return The default maximum number of entries that should
96N/A * checked for matches during a search.
96N/A */
96N/A public final int getLookthroughLimit()
96N/A {
96N/A return lookthroughLimit;
96N/A }
96N/A
96N/A
96N/A
96N/A /**
96N/A * Specifies the default maximum number of entries that should
96N/A * be checked for matches during a search.
96N/A *
96N/A * @param lookthroughLimit The default maximum number of
96N/A * entries that should be check for
96N/A * matches during a search.
96N/A */
1057N/A public void setLookthroughLimit(int lookthroughLimit)
96N/A {
96N/A this.lookthroughLimit = lookthroughLimit;
96N/A }
96N/A
96N/A
96N/A
96N/A /**
0N/A * Retrieves the time limit that will be enforced for searches
0N/A * performed using this client connection.
0N/A *
0N/A * @return The time limit that will be enforced for searches
0N/A * performed using this client connection.
0N/A */
0N/A public final int getTimeLimit()
0N/A {
0N/A return timeLimit;
0N/A }
0N/A
0N/A
0N/A
0N/A /**
0N/A * Specifies the time limit that will be enforced for searches
0N/A * performed using this client connection.
0N/A *
0N/A * @param timeLimit The time limit that will be enforced for
0N/A * searches performed using this client
0N/A * connection.
0N/A */
1057N/A public void setTimeLimit(int timeLimit)
0N/A {
0N/A this.timeLimit = timeLimit;
0N/A }
0N/A
0N/A
0N/A
0N/A /**
629N/A * Retrieves a one-line summary of this client connection in a form
629N/A * that is suitable for including in the monitor entry for the
629N/A * associated connection handler. It should be in a format that is
629N/A * both humand readable and machine parseable (e.g., a
629N/A * space-delimited name-value list, with quotes around the values).
629N/A *
629N/A * @return A one-line summary of this client connection in a form
629N/A * that is suitable for including in the monitor entry for
629N/A * the associated connection handler.
629N/A */
629N/A public abstract String getMonitorSummary();
629N/A
629N/A
629N/A
629N/A /**
655N/A * Indicates whether the user associated with this client connection
655N/A * should be considered a member of the specified group, optionally
655N/A * evaluated within the context of the provided operation. If an
655N/A * operation is given, then the determination should be made based
655N/A * on the authorization identity for that operation. If the
655N/A * operation is {@code null}, then the determination should be made
655N/A * based on the authorization identity for this client connection.
655N/A * Note that this is a point-in-time determination and the caller
655N/A * must not cache the result.
655N/A *
655N/A * @param group The group for which to make the determination.
655N/A * @param operation The operation to use to obtain the
655N/A * authorization identity for which to make the
655N/A * determination, or {@code null} if the
655N/A * authorization identity should be obtained from
655N/A * this client connection.
655N/A *
655N/A * @return {@code true} if the target user is currently a member of
655N/A * the specified group, or {@code false} if not.
655N/A *
655N/A * @throws DirectoryException If a problem occurs while attempting
655N/A * to make the determination.
655N/A */
3888N/A public boolean isMemberOf(Group<?> group, Operation operation)
655N/A throws DirectoryException
655N/A {
655N/A if (operation == null)
655N/A {
655N/A return group.isMember(authenticationInfo.getAuthorizationDN());
655N/A }
655N/A else
655N/A {
655N/A return group.isMember(operation.getAuthorizationDN());
655N/A }
655N/A }
655N/A
655N/A
655N/A
655N/A /**
655N/A * Retrieves the set of groups in which the user associated with
655N/A * this client connection may be considered to be a member. If an
655N/A * operation is provided, then the determination should be made
655N/A * based on the authorization identity for that operation. If the
655N/A * operation is {@code null}, then it should be made based on the
655N/A * authorization identity for this client connection. Note that
655N/A * this is a point-in-time determination and the caller must not
655N/A * cache the result.
655N/A *
655N/A * @param operation The operation to use to obtain the
655N/A * authorization identity for which to retrieve
655N/A * the associated groups, or {@code null} if the
655N/A * authorization identity should be obtained from
655N/A * this client connection.
655N/A *
655N/A * @return The set of groups in which the target user is currently
655N/A * a member.
655N/A *
655N/A * @throws DirectoryException If a problem occurs while attempting
655N/A * to make the determination.
655N/A */
5553N/A public Set<Group<?>> getGroups(Operation operation)
655N/A throws DirectoryException
655N/A {
756N/A // FIXME -- This probably isn't the most efficient implementation.
756N/A DN authzDN;
756N/A if (operation == null)
756N/A {
756N/A if ((authenticationInfo == null) ||
756N/A (! authenticationInfo.isAuthenticated()))
756N/A {
756N/A authzDN = null;
756N/A }
756N/A else
756N/A {
756N/A authzDN = authenticationInfo.getAuthorizationDN();
756N/A }
756N/A }
756N/A else
756N/A {
756N/A authzDN = operation.getAuthorizationDN();
756N/A }
756N/A
756N/A if ((authzDN == null) || authzDN.isNullDN())
756N/A {
5553N/A return Collections.<Group<?>>emptySet();
756N/A }
756N/A
756N/A Entry userEntry = DirectoryServer.getEntry(authzDN);
756N/A if (userEntry == null)
756N/A {
5553N/A return Collections.<Group<?>>emptySet();
756N/A }
756N/A
5553N/A HashSet<Group<?>> groupSet = new HashSet<Group<?>>();
5553N/A for (Group<?> g :
756N/A DirectoryServer.getGroupManager().getGroupInstances())
756N/A {
756N/A if (g.isMember(userEntry))
756N/A {
756N/A groupSet.add(g);
756N/A }
756N/A }
756N/A
756N/A return groupSet;
655N/A }
655N/A
655N/A
655N/A
655N/A /**
824N/A * Retrieves the DN of the key manager provider that should be used
824N/A * for operations requiring access to a key manager. The default
824N/A * implementation returns {@code null} to indicate that no key
3888N/A * manager provider is available, but subclasses should override
824N/A * this method to return a valid DN if they perform operations which
824N/A * may need access to a key manager.
824N/A *
824N/A * @return The DN of the key manager provider that should be used
824N/A * for operations requiring access to a key manager, or
824N/A * {@code null} if there is no key manager provider
824N/A * configured for this client connection.
824N/A */
824N/A public DN getKeyManagerProviderDN()
824N/A {
824N/A // In the default implementation, we'll return null.
824N/A return null;
824N/A }
824N/A
824N/A
824N/A
824N/A /**
824N/A * Retrieves the DN of the trust manager provider that should be
824N/A * used for operations requiring access to a trust manager. The
824N/A * default implementation returns {@code null} to indicate that no
824N/A * trust manager provider is avaialble, but subclasses should
824N/A * override this method to return a valid DN if they perform
824N/A * operations which may need access to a trust manager.
824N/A *
824N/A * @return The DN of the trust manager provider that should be used
824N/A * for operations requiring access to a trust manager, or
824N/A * {@code null} if there is no trust manager provider
824N/A * configured for this client connection.
824N/A */
824N/A public DN getTrustManagerProviderDN()
824N/A {
824N/A // In the default implementation, we'll return null.
824N/A return null;
824N/A }
824N/A
824N/A
824N/A
824N/A /**
867N/A * Retrieves the alias of the server certificate that should be used
867N/A * for operations requiring a server certificate. The default
867N/A * implementation returns {@code null} to indicate that any alias is
867N/A * acceptable.
867N/A *
867N/A * @return The alias of the server certificate that should be used
867N/A * for operations requring a server certificate, or
867N/A * {@code null} if any alias is acceptable.
867N/A */
867N/A public String getCertificateAlias()
867N/A {
867N/A // In the default implementation, we'll return null.
867N/A return null;
867N/A }
867N/A
867N/A
867N/A
867N/A /**
0N/A * Retrieves a string representation of this client connection.
0N/A *
0N/A * @return A string representation of this client connection.
0N/A */
4129N/A @Override
0N/A public final String toString()
0N/A {
0N/A StringBuilder buffer = new StringBuilder();
0N/A toString(buffer);
0N/A return buffer.toString();
0N/A }
0N/A
0N/A
0N/A
0N/A /**
0N/A * Appends a string representation of this client connection to the
0N/A * provided buffer.
0N/A *
0N/A * @param buffer The buffer to which the information should be
0N/A * appended.
0N/A */
0N/A public abstract void toString(StringBuilder buffer);
773N/A
773N/A
1689N/A /**
1689N/A * Returns the network group to which the connection belongs.
1689N/A *
1689N/A * @return the network group attached to the connection
1689N/A */
2095N/A public final NetworkGroup getNetworkGroup()
1689N/A {
1689N/A return networkGroup;
1689N/A }
1689N/A
1689N/A /**
1689N/A * Sets the network group to which the connection belongs.
1689N/A *
1689N/A * @param networkGroup the network group to which the
1689N/A * connections belongs to
1689N/A */
2095N/A public final void setNetworkGroup (NetworkGroup networkGroup)
1689N/A {
3853N/A if (this.networkGroup != networkGroup) {
3853N/A if (debugEnabled())
3853N/A {
3853N/A Message message =
3853N/A INFO_CHANGE_NETWORK_GROUP.get(
3853N/A getConnectionID(),
3853N/A this.networkGroup.getID(),
3853N/A networkGroup.getID());
3853N/A TRACER.debugMessage(DebugLogLevel.INFO, message.toString());
3853N/A }
3853N/A
3853N/A // If there is a change, first remove this connection
3853N/A // from the current network group
3853N/A this.networkGroup.removeConnection(this);
3853N/A // Then set the new network group
3853N/A this.networkGroup = networkGroup;
3853N/A // And add the connection to the new ng
3853N/A this.networkGroup.addConnection(this);
3853N/A
3853N/A // The client connection inherits the resource limits
4129N/A sizeLimit = networkGroup.getSizeLimit();
4129N/A timeLimit = networkGroup.getTimeLimit();
3853N/A }
1689N/A }
1689N/A
1963N/A
1963N/A
1963N/A /**
1963N/A * Retrieves the length of time in milliseconds that this client
1963N/A * connection has been idle.
1963N/A * <BR><BR>
1963N/A * Note that the default implementation will always return zero.
1963N/A * Subclasses associated with connection handlers should override
1963N/A * this method if they wish to provided idle time limit
1963N/A * functionality.
1963N/A *
1963N/A * @return The length of time in milliseconds that this client
1963N/A * connection has been idle.
1963N/A */
1963N/A public long getIdleTime()
1963N/A {
1963N/A return 0L;
1963N/A }
4134N/A
4134N/A /**
4134N/A * Return the Security Strength Factor of a client connection.
4134N/A *
4134N/A * @return An integer representing the SSF value of a connection.
4134N/A */
4134N/A public abstract int getSSF();
4426N/A
4426N/A /**
4426N/A * Indicates a bind or start TLS request processing is finished
4426N/A * and the client connection may start processing data read from
4426N/A * the socket again. This must be called after processing each
4426N/A * bind request in a multistage SASL bind.
4426N/A */
4426N/A public void finishBindOrStartTLS()
4426N/A {
4426N/A bindOrStartTLSInProgress.set(false);
4426N/A }
4426N/A
4426N/A /**
4426N/A * Indicates a multistage SASL bind operation is finished and the
4426N/A * client connection may accept additional LDAP messages.
4426N/A */
4426N/A public void finishSaslBind()
4426N/A {
4426N/A saslBindInProgress.set(false);
4426N/A }
6191N/A
6191N/A /**
6191N/A * Returns whether this connection is used for inner work not directly
6191N/A * requested by an external client.
6191N/A *
6191N/A * @return {@code true} if this is an inner connection, {@code false}
6191N/A * otherwise
6191N/A */
6191N/A public boolean isInnerConnection()
6191N/A {
6191N/A return getConnectionID() < 0;
6191N/A }
6191N/A
0N/A}