From 534e0fb5a07d53ee0bc4b66e0dcf1261d271296b Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 21 Jul 2011 19:29:23 +0000
Subject: [PATCH] Fix OPENDJ-236: Support dn: and u: authid notation in SambaPasswordPlugin
---
opends/src/server/org/opends/server/plugins/SambaPasswordPlugin.java | 184 ++++++++++++---------------------------------
1 files changed, 50 insertions(+), 134 deletions(-)
diff --git a/opends/src/server/org/opends/server/plugins/SambaPasswordPlugin.java b/opends/src/server/org/opends/server/plugins/SambaPasswordPlugin.java
index e15a47e..268e2c0 100644
--- a/opends/src/server/org/opends/server/plugins/SambaPasswordPlugin.java
+++ b/opends/src/server/org/opends/server/plugins/SambaPasswordPlugin.java
@@ -30,7 +30,6 @@
import static org.opends.messages.PluginMessages.*;
-import static org.opends.server.extensions.ExtensionsConstants.*;
import static org.opends.server.loggers.ErrorLogger.logError;
import static org.opends.server.util.StaticUtils.bytesToHexNoSpace;
import static org.opends.server.util.StaticUtils.toLowerCase;
@@ -54,14 +53,14 @@
import org.opends.server.api.plugin.PluginResult;
import org.opends.server.api.plugin.PluginType;
import org.opends.server.config.ConfigException;
+import org.opends.server.controls.LDAPAssertionRequestControl;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ModifyOperation;
+import org.opends.server.extensions.PasswordModifyExtendedOperation;
import org.opends.server.loggers.debug.DebugLogger;
import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.protocols.asn1.ASN1;
-import org.opends.server.protocols.asn1.ASN1Exception;
-import org.opends.server.protocols.asn1.ASN1Reader;
import org.opends.server.protocols.internal.InternalClientConnection;
+import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.types.*;
import org.opends.server.types.operation.PostOperationExtendedOperation;
import org.opends.server.types.operation.PreOperationModifyOperation;
@@ -694,69 +693,38 @@
}
}
- // Get the request and response value from the operation.
- final ByteString requestValue = extendedOperation.getRequestValue();
- final ByteString responseValue = extendedOperation.getResponseValue();
- ASN1Reader asn1Reader = ASN1.getReader(requestValue.asReader());
+ // Get the name of the entry and clear passwords from the operation
+ // attachments.
+ final DN dn = (DN) extendedOperation
+ .getAttachment(PasswordModifyExtendedOperation.AUTHZ_DN_ATTACHMENT);
+ if (dn == null)
+ {
+ // The attachment is missing which should never happen.
+ if (DebugLogger.debugEnabled())
+ {
+ TRACER.debugInfo("SambaPasswordPlugin: missing DN attachment");
+ }
+ return PluginResult.PostOperation.continueOperationProcessing();
+ }
- DN dn = null;
- String password = null;
+ final String password = extendedOperation.getAttachment(
+ PasswordModifyExtendedOperation.CLEAR_PWD_ATTACHMENT).toString();
+ if (password == null)
+ {
+ if (DebugLogger.debugEnabled())
+ {
+ TRACER.debugInfo("SambaPasswordPlugin: skipping syncing "
+ + "pre-encoded password");
+ }
+ return PluginResult.PostOperation.continueOperationProcessing();
+ }
- // @formatter:off
-
- /*
- * Request and response are defined like this:
- *
- * passwdModifyOID OBJECT IDENTIFIER ::= 1.3.6.1.4.1.4203.1.11.1
- *
- * PasswdModifyRequestValue ::= SEQUENCE
- * {
- * userIdentity [0] OCTET STRING OPTIONAL
- * oldPasswd [1] OCTET STRING OPTIONAL
- * newPasswd [2] OCTET STRING OPTIONAL
- * }
- *
- * PasswdModifyResponseValue ::= SEQUENCE
- * {
- * genPasswd [0] OCTET STRING OPTIONAL
- * }
- */
-
- // @formatter:on
+ @SuppressWarnings("unchecked")
+ final List<ByteString> encPasswords = (List<ByteString>) extendedOperation
+ .getAttachment(PasswordModifyExtendedOperation.ENCODED_PWD_ATTACHMENT);
try
{
- // FIXME: need to handle dn: and a: notation.
-
- // Read the request value first.
- asn1Reader.readStartSequence();
-
- // First get the userIdentity field.
- if (asn1Reader.hasNextElement()
- && asn1Reader.peekType() == TYPE_PASSWORD_MODIFY_USER_ID)
- {
- dn = DN.decode(asn1Reader.readOctetString());
- if (DebugLogger.debugEnabled())
- {
- TRACER.debugInfo("Processing DN:" + dn.toNormalizedString());
- }
- }
-
- if (DebugLogger.debugEnabled())
- {
- TRACER.debugInfo("Authorization DN: " + authDN);
- }
-
- if (dn == null)
- {
- dn = authDN;
- if (DebugLogger.debugEnabled())
- {
- TRACER.debugInfo("The DN was not found in the request, but "
- + "we can use the authorization DN.");
- }
- }
-
// Before proceeding make sure this entry has samba object class.
final Entry entry = DirectoryServer.getEntry(dn);
if (!isSynchronizable(entry))
@@ -768,94 +736,42 @@
return PluginResult.PostOperation.continueOperationProcessing();
}
- // Read the old password field if it exists. Skip it either way.
- if (asn1Reader.hasNextElement()
- && asn1Reader.peekType() == TYPE_PASSWORD_MODIFY_OLD_PASSWORD)
- {
- asn1Reader.skipElement();
- }
-
- // Read the new password field.
- if (asn1Reader.hasNextElement()
- && asn1Reader.peekType() == TYPE_PASSWORD_MODIFY_NEW_PASSWORD)
- {
- password = asn1Reader.readOctetStringAsString();
- if (DebugLogger.debugEnabled())
- {
- TRACER.debugInfo("Got new password from the request.");
- }
- }
-
- // Finish reading the request value.
- asn1Reader.readEndSequence();
-
- /*
- * If the new password was not found in the request, look into the
- * response - this usually the case when the password is changed by the
- * directory manager or when the password is generated.
- */
- if (password == null)
- {
- if (DebugLogger.debugEnabled())
- {
- TRACER.debugInfo("Password couldn't be found in the"
- + " request, getting it from the response.");
- }
-
- // Start reading the response value.
- asn1Reader = ASN1.getReader(responseValue.asReader());
- asn1Reader.readStartSequence();
-
- // Read the generated password field.
- if (asn1Reader.hasNextElement()
- && asn1Reader.peekType() == TYPE_PASSWORD_MODIFY_GENERATED_PASSWORD)
- {
- password = asn1Reader.readOctetStringAsString();
- if (DebugLogger.debugEnabled())
- {
- TRACER.debugInfo("Got the new password from the " + "response.");
- }
- }
-
- // Finish reading.
- asn1Reader.readEndSequence();
- }
-
/*
* Make an internal connection to process the password modification. It
* will not trigger this plugin again with the pre-operation modify since
* the password passed would be encoded hence the pre operation part would
* skip it.
*/
-
- // FIXME: This should be performed with a write lock taken when processing
- // the extended operation. However, this is not yet supported by OpenDJ
- // See OPENDJ-235 - https://bugster.forgerock.org/jira/browse/OPENDJ-235
final InternalClientConnection connection = InternalClientConnection
.getRootConnection();
+ final List<Modification> modifications = getModifications(password);
+
+ // Use an assertion control to avoid race conditions since extended
+ // operation post-ops are done outside of the write lock.
+ List<Control> controls = null;
+ if (!encPasswords.isEmpty())
+ {
+ final AttributeType pwdAttribute = (AttributeType) extendedOperation
+ .getAttachment(
+ PasswordModifyExtendedOperation.PWD_ATTRIBUTE_ATTACHMENT);
+ final LDAPFilter filter = RawFilter.createEqualityFilter(
+ pwdAttribute.getNameOrOID(), encPasswords.get(0));
+ final Control assertionControl = new LDAPAssertionRequestControl(true,
+ filter);
+
+ // FIXME: see OPENDJ-241
+ // controls = Collections.singletonList(assertionControl);
+ }
+
final ModifyOperation modifyOperation = connection.processModify(dn,
- getModifications(password));
+ modifications, controls);
if (DebugLogger.debugEnabled())
{
TRACER.debugInfo(modifyOperation.getResultCode().toString());
}
}
- catch (final ASN1Exception e)
- {
- /*
- * The ASN1 reader was not able to process the request because: - it
- * started reading an element which is not a sequence; or - it was not
- * able to decode an element; or - it was not able to determine the BER
- * type of an element; or - it was not able to decode the value as octet
- * string. Either way, this should not happen, so we just log it.
- */
- if (DebugLogger.debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.WARNING, e);
- }
- }
catch (final DirectoryException e)
{
/*
--
Gitblit v1.10.0