From 12823021edd6b9c4262466ddbfbce6aa8d36d0b5 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 25 Aug 2011 16:27:28 +0000
Subject: [PATCH] Final refactoring work for OPENDJ-262: Implement pass through authentication (PTA)
---
opendj-sdk/opends/src/server/org/opends/server/api/AuthenticationPolicy.java | 244 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 243 insertions(+), 1 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/api/AuthenticationPolicy.java b/opendj-sdk/opends/src/server/org/opends/server/api/AuthenticationPolicy.java
index aeb4ef2..5054186 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/api/AuthenticationPolicy.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/api/AuthenticationPolicy.java
@@ -29,7 +29,20 @@
-import org.opends.server.types.DN;
+import static org.opends.messages.CoreMessages.*;
+import static org.opends.server.config.ConfigConstants.*;
+import static org.opends.server.loggers.ErrorLogger.logError;
+import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
+import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
+
+import java.util.List;
+
+import org.opends.messages.Message;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.loggers.debug.DebugLogger;
+import org.opends.server.loggers.debug.DebugTracer;
+import org.opends.server.types.*;
+import org.opends.server.util.TimeThread;
@@ -39,6 +52,173 @@
public abstract class AuthenticationPolicy
{
/**
+ * The tracer object for the debug logger.
+ */
+ private static final DebugTracer TRACER = DebugLogger.getTracer();
+
+
+
+ /**
+ * Returns the authentication policy for the user provided user. The following
+ * algorithm is used in order to obtain the appropriate authentication policy:
+ * <ul>
+ * <li>if the user entry contains the {@code ds-pwp-password-policy-dn}
+ * attribute (whether real or virtual), then the referenced authentication
+ * policy will be returned
+ * <li>otherwise, a search is performed in order to find the nearest
+ * applicable password policy sub-entry to the user entry,
+ * <li>otherwise, the default password policy will be returned.
+ * </ul>
+ *
+ * @param userEntry
+ * The user entry.
+ * @param useDefaultOnError
+ * Indicates whether the server should fall back to using the default
+ * password policy if there is a problem with the configured policy
+ * for the user.
+ * @return The password policy for the user.
+ * @throws DirectoryException
+ * If a problem occurs while attempting to determine the password
+ * policy for the user.
+ */
+ public final static AuthenticationPolicy forUser(Entry userEntry,
+ boolean useDefaultOnError) throws DirectoryException
+ {
+ // First check to see if the ds-pwp-password-policy-dn is present.
+ String userDNString = userEntry.getDN().toString();
+ AttributeType type = DirectoryServer.getAttributeType(
+ OP_ATTR_PWPOLICY_POLICY_DN, true);
+ List<Attribute> attrList = userEntry.getAttribute(type);
+
+ if (attrList != null)
+ {
+ for (Attribute a : attrList)
+ {
+ if (a.isEmpty()) continue;
+
+ AttributeValue v = a.iterator().next();
+ DN subentryDN;
+ try
+ {
+ subentryDN = DN.decode(v.getValue());
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ if (debugEnabled())
+ {
+ TRACER.debugError("Could not parse password policy subentry "
+ + "DN %s for user %s: %s", v.getValue().toString(),
+ userDNString, stackTraceToSingleLineString(e));
+ }
+
+ Message message = ERR_PWPSTATE_CANNOT_DECODE_SUBENTRY_VALUE_AS_DN
+ .get(v.getValue().toString(), userDNString, e.getMessage());
+ if (useDefaultOnError)
+ {
+ logError(message);
+ return DirectoryServer.getDefaultPasswordPolicy();
+ }
+ else
+ {
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message,
+ e);
+ }
+ }
+
+ AuthenticationPolicy policy = DirectoryServer
+ .getAuthenticationPolicy(subentryDN);
+ if (policy == null)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugError("Password policy subentry %s for user %s "
+ + "is not defined in the Directory Server.",
+ String.valueOf(subentryDN), userDNString);
+ }
+
+ Message message = ERR_PWPSTATE_NO_SUCH_POLICY.get(userDNString,
+ String.valueOf(subentryDN));
+ if (useDefaultOnError)
+ {
+ logError(message);
+ return DirectoryServer.getDefaultPasswordPolicy();
+ }
+ else
+ {
+ throw new DirectoryException(
+ DirectoryServer.getServerErrorResultCode(), message);
+ }
+ }
+
+ if (debugEnabled())
+ {
+ TRACER.debugInfo("Using password policy subentry %s for user %s.",
+ String.valueOf(subentryDN), userDNString);
+ }
+
+ return policy;
+ }
+ }
+
+ // The ds-pwp-password-policy-dn attribute was not present, so instead
+ // search for the nearest applicable sub-entry.
+ List<SubEntry> pwpSubEntries = DirectoryServer.getSubentryManager()
+ .getSubentries(userEntry);
+ if ((pwpSubEntries != null) && (!pwpSubEntries.isEmpty()))
+ {
+ for (SubEntry subentry : pwpSubEntries)
+ {
+ try
+ {
+ if (subentry.getEntry().isPasswordPolicySubentry())
+ {
+ AuthenticationPolicy policy = DirectoryServer
+ .getAuthenticationPolicy(subentry.getDN());
+ if (policy == null)
+ {
+ // This shouldn't happen but if it does debug log
+ // this problem and fall back to default policy.
+ if (debugEnabled())
+ {
+ TRACER.debugError("Found unknown password policy subentry "
+ + "DN %s for user %s", subentry.getDN().toString(),
+ userDNString);
+ }
+ break;
+ }
+ return policy;
+ }
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugError("Could not parse password policy subentry "
+ + "DN %s for user %s: %s", subentry.getDN().toString(),
+ userDNString, stackTraceToSingleLineString(e));
+ }
+ }
+ }
+ }
+
+ // No authentication policy found, so use the global default.
+ if (debugEnabled())
+ {
+ TRACER.debugInfo("Using the default password policy for user %s",
+ userDNString);
+ }
+
+ return DirectoryServer.getDefaultPasswordPolicy();
+ }
+
+
+
+ /**
* Creates a new abstract authentication policy.
*/
protected AuthenticationPolicy()
@@ -60,6 +240,68 @@
/**
+ * Returns {@code true} if this authentication policy is a password policy and
+ * the methods {@link #createAuthenticationPolicyState(Entry)} and
+ * {@link #createAuthenticationPolicyState(Entry, long)} will return a
+ * {@code PasswordPolicyState}.
+ * <p>
+ * The default implementation is to return {@code false}.
+ *
+ * @return {@code true} if this authentication policy is a password policy,
+ * otherwise {@code false}.
+ */
+ public boolean isPasswordPolicy()
+ {
+ return false;
+ }
+
+
+
+ /**
+ * Returns the authentication policy state object for the provided user using
+ * the current time as the basis for all time-based state logic (such as
+ * expiring passwords).
+ * <p>
+ * The default implementation is to call
+ * {@link #createAuthenticationPolicyState(Entry, long)} with the current
+ * time.
+ *
+ * @param userEntry
+ * The user's entry.
+ * @return The authentication policy state object for the provided user.
+ * @throws DirectoryException
+ * If a problem occurs while attempting to initialize the state
+ * object from the provided user entry.
+ */
+ public AuthenticationPolicyState createAuthenticationPolicyState(
+ Entry userEntry) throws DirectoryException
+ {
+ return createAuthenticationPolicyState(userEntry, TimeThread.getTime());
+ }
+
+
+
+ /**
+ * Returns an authentication policy state object for the provided user using
+ * the specified time as the basis for all time-based state logic (such as
+ * expiring passwords).
+ *
+ * @param userEntry
+ * The user's entry.
+ * @param time
+ * The time since the epoch to use for all time-based state logic
+ * (such as expiring passwords).
+ * @return The authentication policy state object for the provided user.
+ * @throws DirectoryException
+ * If a problem occurs while attempting to initialize the state
+ * object from the provided user entry.
+ */
+ public abstract AuthenticationPolicyState createAuthenticationPolicyState(
+ Entry userEntry, long time) throws DirectoryException;
+
+
+
+ /**
* Performs any necessary work to finalize this authentication policy.
* <p>
* The default implementation is to do nothing.
--
Gitblit v1.10.0