From 4a4a8540f0b64feff6934c3215c6f896c9561c7d Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Thu, 08 Feb 2007 22:27:58 +0000
Subject: [PATCH] Update the AuthenticationInfo object to store the entries for the authentication and authorization identities rather than just their DNs. This includes a mechanism to keep those entries up to date as changes occur in the server, and also includes a hook for ClientConnection subclasses to perform processing whenever a connection is terminated.
---
opends/src/server/org/opends/server/api/ClientConnection.java | 201 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 198 insertions(+), 3 deletions(-)
diff --git a/opends/src/server/org/opends/server/api/ClientConnection.java b/opends/src/server/org/opends/server/api/ClientConnection.java
index 4bfd6e6..c113d31 100644
--- a/opends/src/server/org/opends/server/api/ClientConnection.java
+++ b/opends/src/server/org/opends/server/api/ClientConnection.java
@@ -80,6 +80,10 @@
// until the bind completes.
private boolean bindInProgress;
+ // Indicates whether any necessary finalization work has been done
+ // for this client connection.
+ private boolean finalized;
+
// The size limit for use with this client connection.
private int sizeLimit;
@@ -122,6 +126,79 @@
sizeLimit = DirectoryServer.getSizeLimit();
timeLimit = DirectoryServer.getTimeLimit();
lookthroughLimit = DirectoryServer.getLookthroughLimit();
+ finalized = false;
+ }
+
+
+
+ /**
+ * Performs any internal cleanup that may be necessary when this
+ * client connection is disconnected, or if not on disconnec, then
+ * ultimately whenever it is reaped by the garbage collector. In
+ * this case, it will be used to ensure that the connection is
+ * deregistered with the {@code AuthenticatedUsers} manager, and
+ * will then invoke the {@code finalizeClientConnection} method.
+ */
+ protected final void finalizeConnectionInternal()
+ {
+ if (finalized)
+ {
+ return;
+ }
+
+ finalized = true;
+
+ // Deregister with the set of authenticated users.
+ Entry authNEntry = authenticationInfo.getAuthenticationEntry();
+ Entry authZEntry = authenticationInfo.getAuthorizationEntry();
+
+ if (authNEntry != null)
+ {
+ if ((authZEntry == null) ||
+ authZEntry.getDN().equals(authNEntry.getDN()))
+ {
+ DirectoryServer.getAuthenticatedUsers().remove(
+ authNEntry.getDN(), this);
+ }
+ else
+ {
+ DirectoryServer.getAuthenticatedUsers().remove(
+ authNEntry.getDN(), this);
+ DirectoryServer.getAuthenticatedUsers().remove(
+ authZEntry.getDN(), this);
+ }
+ }
+ else if (authZEntry != null)
+ {
+ DirectoryServer.getAuthenticatedUsers().remove(
+ authZEntry.getDN(), this);
+ }
+
+ try
+ {
+ finalizeClientConnection();
+ }
+ catch (Exception e)
+ {
+ assert debugException(CLASS_NAME, "finalizeConnectionInternal",
+ e);
+ }
+ }
+
+
+
+ /**
+ * Performs any cleanup work that may be necessary when this client
+ * connection is terminated. By default, no action is taken.
+ * <BR><BR>
+ * If possible, this method will be invoked when the client
+ * connection is disconnected. If it isn't invoked at that time,
+ * then it will be called when the client connection object is
+ * finalized by the garbage collector.
+ */
+ protected void finalizeClientConnection()
+ {
+ // No implementation is required by default.
}
@@ -430,9 +507,9 @@
* associated with the provided message
* ID.
*/
- public void disconnect(DisconnectReason disconnectReason,
- boolean sendNotification, int messageID,
- Object... arguments)
+ public final void disconnect(DisconnectReason disconnectReason,
+ boolean sendNotification,
+ int messageID, Object... arguments)
{
assert debugEnter(CLASS_NAME, "disconnect",
String.valueOf(disconnectReason),
@@ -456,6 +533,9 @@
* operation processing (e.g., within a plugin or other extension),
* the <CODE>disconnectClient</CODE> method within that operation
* should be called rather than invoking this method directly.
+ * <BR><BR>
+ * All subclasses must invoke the {@code finalizeConnectionInternal}
+ * method during the course of processing this method.
*
* @param disconnectReason The disconnect reason that provides the
* generic cause for the disconnect.
@@ -733,6 +813,36 @@
assert debugEnter(CLASS_NAME, "setAuthenticationInfo",
String.valueOf(authenticationInfo));
+ if (this.authenticationInfo != null)
+ {
+ Entry authNEntry =
+ this.authenticationInfo.getAuthenticationEntry();
+ Entry authZEntry =
+ this.authenticationInfo.getAuthorizationEntry();
+
+ if (authNEntry != null)
+ {
+ if ((authZEntry == null) ||
+ authZEntry.getDN().equals(authNEntry.getDN()))
+ {
+ DirectoryServer.getAuthenticatedUsers().remove(
+ authNEntry.getDN(), this);
+ }
+ else
+ {
+ DirectoryServer.getAuthenticatedUsers().remove(
+ authNEntry.getDN(), this);
+ DirectoryServer.getAuthenticatedUsers().remove(
+ authZEntry.getDN(), this);
+ }
+ }
+ else if (authZEntry != null)
+ {
+ DirectoryServer.getAuthenticatedUsers().remove(
+ authZEntry.getDN(), this);
+ }
+ }
+
if (authenticationInfo == null)
{
this.authenticationInfo = new AuthenticationInfo();
@@ -740,6 +850,76 @@
else
{
this.authenticationInfo = authenticationInfo;
+
+ Entry authNEntry = authenticationInfo.getAuthenticationEntry();
+ Entry authZEntry = authenticationInfo.getAuthorizationEntry();
+
+ if (authNEntry != null)
+ {
+ if ((authZEntry == null) ||
+ authZEntry.getDN().equals(authNEntry.getDN()))
+ {
+ DirectoryServer.getAuthenticatedUsers().put(
+ authNEntry.getDN(), this);
+ }
+ else
+ {
+ DirectoryServer.getAuthenticatedUsers().put(
+ authNEntry.getDN(), this);
+ DirectoryServer.getAuthenticatedUsers().put(
+ authZEntry.getDN(), this);
+ }
+ }
+ else if (authZEntry != null)
+ {
+ DirectoryServer.getAuthenticatedUsers().put(
+ authZEntry.getDN(), this);
+ }
+ }
+ }
+
+
+
+ /**
+ * Updates the cached entry associated with either the
+ * authentication and/or authorization identity with the provided
+ * version.
+ *
+ * @param oldEntry The user entry currently serving as the
+ * authentication and/or authorization identity.
+ * @param newEntry The updated entry that should replace the
+ * existing entry. It may optionally have a
+ * different DN than the old entry.
+ */
+ public void updateAuthenticationInfo(Entry oldEntry, Entry newEntry)
+ {
+ assert debugEnter(CLASS_NAME, "updateAuthenticationInfo",
+ String.valueOf(oldEntry),
+ String.valueOf(newEntry));
+
+ Entry authNEntry = authenticationInfo.getAuthenticationEntry();
+ Entry authZEntry = authenticationInfo.getAuthorizationEntry();
+
+ if ((authNEntry != null) &&
+ authNEntry.getDN().equals(oldEntry.getDN()))
+ {
+ if ((authZEntry == null) ||
+ (! authZEntry.getDN().equals(authNEntry.getDN())))
+ {
+ authenticationInfo =
+ authenticationInfo.duplicate(newEntry, authZEntry);
+ }
+ else
+ {
+ authenticationInfo =
+ authenticationInfo.duplicate(newEntry, newEntry);
+ }
+ }
+ else if ((authZEntry != null) &&
+ (authZEntry.getDN().equals(oldEntry.getDN())))
+ {
+ authenticationInfo =
+ authenticationInfo.duplicate(authNEntry, newEntry);
}
}
@@ -1053,5 +1233,20 @@
* appended.
*/
public abstract void toString(StringBuilder buffer);
+
+
+
+ /**
+ * Performs any work that may be needed before the JVM invokes
+ * garbage collection for this object. In this case, it makes sure
+ * to deregister with the Directory Server as a change notification
+ * listener. If a subclass wishes to perform custom finalization
+ * processing, then it should override this method and make sure to
+ * invoke {@code super.finalize} as its first call.
+ */
+ protected void finalize()
+ {
+ finalizeConnectionInternal();
+ }
}
--
Gitblit v1.10.0