From 74d7af9059994d7c6e1b08316429b8dcb017a70b Mon Sep 17 00:00:00 2001
From: Chris Ridd <chris.ridd@forgerock.com>
Date: Thu, 04 Jun 2015 10:53:55 +0000
Subject: [PATCH] FR-721 OPENDJ-2071 improve aci checks for proxy auth controls
---
opendj-server-legacy/src/main/java/org/opends/server/core/DeleteOperationWrapper.java | 16 -
opendj-server-legacy/src/main/java/org/opends/server/core/ModifyOperationWrapper.java | 15
opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java | 42 --
opendj-server-legacy/src/messages/org/opends/messages/protocol.properties | 4
opendj-server-legacy/src/main/java/org/opends/server/core/CompareOperationWrapper.java | 15 -
opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciHandler.java | 30 --
opendj-server-legacy/src/main/java/org/opends/server/extensions/WhoAmIExtendedOperation.java | 11
opendj-server-legacy/src/main/java/org/opends/server/core/UnbindOperationBasis.java | 14
opendj-server-legacy/src/main/java/org/opends/server/core/SearchOperationWrapper.java | 15
opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java | 42 --
opendj-server-legacy/src/main/java/org/opends/server/core/AddOperationWrapper.java | 16 -
opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java | 41 --
opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/ProxyTestCase.java | 211 ++++++++++++++
opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java | 54 ---
opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java | 42 --
opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java | 101 ++++++
opendj-server-legacy/src/main/java/org/opends/server/core/BindOperationBasis.java | 15
opendj-server-legacy/src/main/java/org/opends/server/core/ExtendedOperationBasis.java | 16 +
opendj-server-legacy/src/main/java/org/opends/server/core/AbandonOperationBasis.java | 17 +
opendj-server-legacy/src/main/java/org/opends/server/core/ModifyDNOperationWrapper.java | 15
opendj-server-legacy/src/main/java/org/opends/server/types/Operation.java | 23 +
opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/AciTestCase.java | 26 +
opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciContainer.java | 34 --
opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java | 40 --
opendj-server-legacy/src/main/java/org/opends/server/core/OperationWrapper.java | 14
25 files changed, 468 insertions(+), 401 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciContainer.java b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciContainer.java
index 47c8145..aefa568 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciContainer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciContainer.java
@@ -118,18 +118,6 @@
private Entry authorizationEntry;
/**
- * Used to save the current authorization entry when the authorization
- * entry is switched during a proxy access check.
- */
- private final Entry saveAuthorizationEntry;
-
- /**
- * This entry is only used if proxied authorization is being used. It is
- * the original authorization entry before the proxied authorization change.
- */
- private Entry origAuthorizationEntry;
-
- /**
* True if proxied authorization is being used.
*/
private boolean proxiedAuthorization;
@@ -248,8 +236,7 @@
//If the proxied authorization control was processed, then the operation
//will contain an attachment containing the original authorization entry.
- this.origAuthorizationEntry =
- (Entry) operation.getAttachment(ORIG_AUTH_ENTRY);
+ final Entry origAuthorizationEntry = (Entry) operation.getAttachment(ORIG_AUTH_ENTRY);
this.proxiedAuthorization = origAuthorizationEntry != null;
this.authorizationEntry=operation.getAuthorizationEntry();
@@ -292,8 +279,7 @@
//Reference the current authorization entry, so it can be put back
//if an access proxy check was performed.
- this.saveAuthorizationEntry=this.authorizationEntry;
- this.rightsMask = rights;
+ this.rightsMask = rights;
}
/**
@@ -312,7 +298,6 @@
this.clientConnection=operation.getClientConnection();
this.authInfo = authInfo;
this.authorizationEntry = authInfo.getAuthorizationEntry();
- this.saveAuthorizationEntry=this.authorizationEntry;
this.rightsMask = rights;
}
/**
@@ -489,21 +474,6 @@
return this.authzid.equals(this.authorizationEntry.getName());
}
- /**
- * If the specified value is true, then the original authorization entry,
- * which is the entry before the switch performed by the proxied
- * authorization control processing should be set to the current
- * authorization entry. If the specified value is false then the proxied
- * authorization entry is switched back using the saved copy.
- * @param val The value used to select the authorization entry to use.
- */
- public void useOrigAuthorizationEntry(boolean val) {
- if(val)
- authorizationEntry=origAuthorizationEntry;
- else
- authorizationEntry=saveAuthorizationEntry;
- }
-
/** {@inheritDoc} */
@Override
public void setDenyList(List<Aci> denys) {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciHandler.java b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciHandler.java
index 938995e..e59db6d 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciHandler.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciHandler.java
@@ -559,36 +559,6 @@
}
}
- // Check proxy authorization only if the entry has not already been
- // processed (working on a new entry). If working on a new entry,
- // then only do a proxy check if the right is not set to ACI_PROXY
- // and the proxied authorization control has been decoded.
- if (!container.hasSeenEntry())
- {
- if (container.isProxiedAuthorization()
- && !container.hasRights(ACI_PROXY)
- && !container.hasRights(ACI_SKIP_PROXY_CHECK))
- {
- int currentRights = container.getRights();
- // Save the current rights so they can be put back if on success.
- container.setRights(ACI_PROXY);
- // Switch to the original authorization entry, not the proxied one.
- container.useOrigAuthorizationEntry(true);
- if (!accessAllowed(container))
- {
- return false;
- }
- // Access is ok, put the original rights back.
- container.setRights(currentRights);
- // Put the proxied authorization entry back to the current
- // authorization entry.
- container.useOrigAuthorizationEntry(false);
- }
- // Set the seen flag so proxy processing is not performed for this
- // entry again.
- container.setSeenEntry(true);
- }
-
// First get all allowed candidate ACIs.
List<Aci> candidates = aciList.getCandidateAcis(dn);
/*
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/AbandonOperationBasis.java b/opendj-server-legacy/src/main/java/org/opends/server/core/AbandonOperationBasis.java
index d8b4b81..c05f050 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/AbandonOperationBasis.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/AbandonOperationBasis.java
@@ -97,6 +97,23 @@
/** {@inheritDoc} */
@Override
+ public DN getProxiedAuthorizationDN()
+ {
+ return null;
+ }
+
+
+
+ /** {@inheritDoc} */
+ @Override
+ public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN)
+ {
+ }
+
+
+
+ /** {@inheritDoc} */
+ @Override
public final OperationType getOperationType()
{
// Note that no debugging will be done in this method because it is a likely
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/AddOperationWrapper.java b/opendj-server-legacy/src/main/java/org/opends/server/core/AddOperationWrapper.java
index 367077b..bd3c7af 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/AddOperationWrapper.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/AddOperationWrapper.java
@@ -22,7 +22,7 @@
*
*
* Copyright 2008 Sun Microsystems, Inc.
- * Portions Copyright 2013-2014 ForgeRock AS
+ * Portions Copyright 2013-2015 ForgeRock AS
*/
package org.opends.server.core;
@@ -150,18 +150,4 @@
return getOperation().toString();
}
- /** {@inheritDoc} */
- @Override
- public DN getProxiedAuthorizationDN()
- {
- return getOperation().getProxiedAuthorizationDN();
- }
-
- /** {@inheritDoc} */
- @Override
- public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN)
- {
- getOperation().setProxiedAuthorizationDN(proxiedAuthorizationDN);
- }
-
}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/BindOperationBasis.java b/opendj-server-legacy/src/main/java/org/opends/server/core/BindOperationBasis.java
index 6f33b29..b2e7b38 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/BindOperationBasis.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/BindOperationBasis.java
@@ -22,7 +22,7 @@
*
*
* Copyright 2007-2010 Sun Microsystems, Inc.
- * Portions Copyright 2013-2014 ForgeRock AS
+ * Portions Copyright 2013-2015 ForgeRock AS
*/
package org.opends.server.core;
@@ -257,6 +257,19 @@
/** {@inheritDoc} */
@Override
+ public DN getProxiedAuthorizationDN()
+ {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN)
+ {
+ }
+
+ /** {@inheritDoc} */
+ @Override
public final AuthenticationType getAuthenticationType()
{
return authType;
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/CompareOperationWrapper.java b/opendj-server-legacy/src/main/java/org/opends/server/core/CompareOperationWrapper.java
index b9a877a..f7d67db 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/CompareOperationWrapper.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/CompareOperationWrapper.java
@@ -140,19 +140,4 @@
}
- /** {@inheritDoc} */
- @Override
- public DN getProxiedAuthorizationDN()
- {
- return getOperation().getProxiedAuthorizationDN();
- }
-
-
- /** {@inheritDoc} */
- @Override
- public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN)
- {
- getOperation().setProxiedAuthorizationDN(proxiedAuthorizationDN);
- }
-
}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/DeleteOperationWrapper.java b/opendj-server-legacy/src/main/java/org/opends/server/core/DeleteOperationWrapper.java
index 612333b..e77158b 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/DeleteOperationWrapper.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/DeleteOperationWrapper.java
@@ -22,7 +22,7 @@
*
*
* Copyright 2008 Sun Microsystems, Inc.
- * Portions Copyright 2013-2014 ForgeRock AS
+ * Portions Copyright 2013-2015 ForgeRock AS
*/
package org.opends.server.core;
@@ -76,18 +76,4 @@
return getOperation().toString();
}
- /** {@inheritDoc} */
- @Override
- public DN getProxiedAuthorizationDN()
- {
- return getOperation().getProxiedAuthorizationDN();
- }
-
- /** {@inheritDoc} */
- @Override
- public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN)
- {
- getOperation().setProxiedAuthorizationDN(proxiedAuthorizationDN);
- }
-
}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/ExtendedOperationBasis.java b/opendj-server-legacy/src/main/java/org/opends/server/core/ExtendedOperationBasis.java
index 369738d..a4355b0 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/ExtendedOperationBasis.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/ExtendedOperationBasis.java
@@ -147,6 +147,22 @@
/** {@inheritDoc} */
@Override
+ public DN getProxiedAuthorizationDN()
+ {
+ return null;
+ }
+
+
+
+ /** {@inheritDoc} */
+ @Override
+ public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN)
+ {
+ }
+
+
+ /** {@inheritDoc} */
+ @Override
public final ByteString getRequestValue()
{
return requestValue;
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyDNOperationWrapper.java b/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyDNOperationWrapper.java
index 47e6410..d829234 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyDNOperationWrapper.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyDNOperationWrapper.java
@@ -22,7 +22,7 @@
*
*
* Copyright 2008 Sun Microsystems, Inc.
- * Portions Copyright 2013-2014 ForgeRock AS
+ * Portions Copyright 2013-2015 ForgeRock AS
*/
package org.opends.server.core;
@@ -94,12 +94,6 @@
/** {@inheritDoc} */
@Override
- public DN getProxiedAuthorizationDN() {
- return getOperation().getProxiedAuthorizationDN();
- }
-
- /** {@inheritDoc} */
- @Override
public ByteString getRawEntryDN() {
return getOperation().getRawEntryDN();
}
@@ -148,13 +142,6 @@
/** {@inheritDoc} */
@Override
- public void setProxiedAuthorizationDN(DN dn)
- {
- getOperation().setProxiedAuthorizationDN(dn);
- }
-
- /** {@inheritDoc} */
- @Override
public DN getNewDN()
{
return getOperation().getNewDN();
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyOperationWrapper.java b/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyOperationWrapper.java
index c14a3f8..ab55238 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyOperationWrapper.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/ModifyOperationWrapper.java
@@ -22,7 +22,7 @@
*
*
* Copyright 2008 Sun Microsystems, Inc.
- * Portions Copyright 2011-2014 ForgeRock AS
+ * Portions Copyright 2011-2015 ForgeRock AS
*/
package org.opends.server.core;
@@ -114,17 +114,4 @@
return getOperation().toString();
}
- /** {@inheritDoc} */
- @Override
- public DN getProxiedAuthorizationDN()
- {
- return getOperation().getProxiedAuthorizationDN();
- }
-
- /** {@inheritDoc} */
- @Override
- public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN){
- getOperation().setProxiedAuthorizationDN(proxiedAuthorizationDN);
- }
-
}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/OperationWrapper.java b/opendj-server-legacy/src/main/java/org/opends/server/core/OperationWrapper.java
index 37faadf..d308c95 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/OperationWrapper.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/OperationWrapper.java
@@ -160,6 +160,20 @@
/** {@inheritDoc} */
@Override
+ public DN getProxiedAuthorizationDN()
+ {
+ return operation.getProxiedAuthorizationDN();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN)
+ {
+ operation.setProxiedAuthorizationDN(proxiedAuthorizationDN);
+ }
+
+ /** {@inheritDoc} */
+ @Override
public CancelRequest getCancelRequest()
{
return operation.getCancelRequest();
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/SearchOperationWrapper.java b/opendj-server-legacy/src/main/java/org/opends/server/core/SearchOperationWrapper.java
index a0bc3f4..dedb840 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/SearchOperationWrapper.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/SearchOperationWrapper.java
@@ -22,7 +22,7 @@
*
*
* Copyright 2008-2009 Sun Microsystems, Inc.
- * Portions Copyright 2011-2014 ForgeRock AS
+ * Portions Copyright 2011-2015 ForgeRock AS
*/
package org.opends.server.core;
@@ -370,17 +370,4 @@
return getOperation().sendSearchReference(reference);
}
- /** {@inheritDoc} */
- @Override
- public DN getProxiedAuthorizationDN()
- {
- return getOperation().getProxiedAuthorizationDN();
- }
-
- /** {@inheritDoc} */
- @Override
- public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN){
- getOperation().setProxiedAuthorizationDN(proxiedAuthorizationDN);
- }
-
}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/UnbindOperationBasis.java b/opendj-server-legacy/src/main/java/org/opends/server/core/UnbindOperationBasis.java
index a4d5d19..305a382 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/UnbindOperationBasis.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/UnbindOperationBasis.java
@@ -78,6 +78,20 @@
// candidate for being called by the logging subsystem.
return OperationType.UNBIND;
}
+
+ /** {@inheritDoc} */
+ @Override
+ public DN getProxiedAuthorizationDN()
+ {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setProxiedAuthorizationDN(DN proxiedAuthorizationDN)
+ {
+ }
+
/** {@inheritDoc} */
@Override
public final List<Control> getResponseControls()
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/extensions/WhoAmIExtendedOperation.java b/opendj-server-legacy/src/main/java/org/opends/server/extensions/WhoAmIExtendedOperation.java
index ad1ebe8..f6d42b1 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/extensions/WhoAmIExtendedOperation.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/extensions/WhoAmIExtendedOperation.java
@@ -35,12 +35,14 @@
import org.forgerock.opendj.config.server.ConfigException;
import org.opends.server.controls.ProxiedAuthV1Control;
import org.opends.server.controls.ProxiedAuthV2Control;
+import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.ExtendedOperation;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.opends.server.types.*;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.ByteString;
import static org.opends.messages.ExtensionMessages.*;
+import static org.opends.messages.ProtocolMessages.ERR_PROXYAUTH_AUTHZ_NOT_PERMITTED;
import static org.opends.server.util.ServerConstants.*;
/**
@@ -111,6 +113,15 @@
authorizationEntry = proxyControlV1.getAuthorizationEntry();
}
+ // Check the requester has the authz user in scope of their proxy aci.
+ if (! AccessControlConfigManager.getInstance().getAccessControlHandler()
+ .mayProxy(clientConnection.getAuthenticationInfo().getAuthenticationEntry(),
+ authorizationEntry, operation))
+ {
+ final DN dn = authorizationEntry.getName();
+ throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
+ ERR_PROXYAUTH_AUTHZ_NOT_PERMITTED.get(dn));
+ }
operation.setAuthorizationEntry(authorizationEntry);
}
}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/types/Operation.java b/opendj-server-legacy/src/main/java/org/opends/server/types/Operation.java
index d423987..12b4e32 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/types/Operation.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/types/Operation.java
@@ -22,7 +22,7 @@
*
*
* Copyright 2006-2009 Sun Microsystems, Inc.
- * Portions Copyright 2011-2014 ForgeRock AS.
+ * Portions Copyright 2011-2015 ForgeRock AS.
*/
package org.opends.server.types;
@@ -459,6 +459,27 @@
DN getAuthorizationDN();
/**
+ * Retrieves the proxied authorization DN for this operation if proxied
+ * authorization has been requested.
+ *
+ * @return The proxied authorization DN for this operation if proxied
+ * authorization has been requested, or {@code null} if proxied
+ * authorization has not been requested.
+ */
+ DN getProxiedAuthorizationDN();
+
+ /**
+ * Set the proxied authorization DN for this operation if proxied
+ * authorization has been requested.
+ *
+ * @param proxiedAuthorizationDN
+ * The proxied authorization DN for this operation if proxied
+ * authorization has been requested, or {@code null} if proxied
+ * authorization has not been requested.
+ */
+ void setProxiedAuthorizationDN(DN proxiedAuthorizationDN);
+
+ /**
* Retrieves the set of attachments defined for this operation, as a
* mapping between the attachment name and the associated object.
*
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
index dad3411..8874250 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
@@ -49,8 +49,6 @@
import org.opends.server.controls.LDAPPostReadRequestControl;
import org.opends.server.controls.PasswordPolicyErrorType;
import org.opends.server.controls.PasswordPolicyResponseControl;
-import org.opends.server.controls.ProxiedAuthV1Control;
-import org.opends.server.controls.ProxiedAuthV2Control;
import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.AddOperation;
import org.opends.server.core.AddOperationWrapper;
@@ -60,7 +58,6 @@
import org.opends.server.core.PluginConfigManager;
import org.opends.server.schema.AuthPasswordSyntax;
import org.opends.server.schema.UserPasswordSyntax;
-import org.opends.server.types.AdditionalLogItem;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeBuilder;
import org.opends.server.types.AttributeType;
@@ -1106,44 +1103,9 @@
postReadRequest =
getRequestControl(LDAPPostReadRequestControl.DECODER);
}
- else if (OID_PROXIED_AUTH_V1.equals(oid))
+ else if (LocalBackendWorkflowElement.processProxyAuthControls(this, oid))
{
- // Log usage of legacy proxy authz V1 control.
- addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
- "obsoleteProxiedAuthzV1Control"));
-
- // The requester must have the PROXIED_AUTH privilege in order to
- // be able to use this control.
- if (!getClientConnection().hasPrivilege(Privilege.PROXIED_AUTH, this))
- {
- throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
- ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get());
- }
-
- ProxiedAuthV1Control proxyControl =
- getRequestControl(ProxiedAuthV1Control.DECODER);
-
- Entry authorizationEntry = proxyControl.getAuthorizationEntry();
- setAuthorizationEntry(authorizationEntry);
- setProxiedAuthorizationDN(getName(authorizationEntry));
- }
- else if (OID_PROXIED_AUTH_V2.equals(oid))
- {
- // The requester must have the PROXIED_AUTH privilege in order to
- // be able to use this control.
- if (! getClientConnection().hasPrivilege(Privilege.PROXIED_AUTH,
- this))
- {
- throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
- ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get());
- }
-
- ProxiedAuthV2Control proxyControl =
- getRequestControl(ProxiedAuthV2Control.DECODER);
-
- Entry authorizationEntry = proxyControl.getAuthorizationEntry();
- setAuthorizationEntry(authorizationEntry);
- setProxiedAuthorizationDN(getName(authorizationEntry));
+ continue;
}
else if (OID_PASSWORD_POLICY_CONTROL.equals(oid))
{
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
index 51de57e..80008b5 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
@@ -35,8 +35,6 @@
import org.opends.server.api.ClientConnection;
import org.opends.server.api.plugin.PluginResult;
import org.opends.server.controls.LDAPAssertionRequestControl;
-import org.opends.server.controls.ProxiedAuthV1Control;
-import org.opends.server.controls.ProxiedAuthV2Control;
import org.opends.server.core.*;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.opends.server.types.*;
@@ -414,57 +412,9 @@
ERR_COMPARE_CANNOT_PROCESS_ASSERTION_FILTER.get(entryDN, de.getMessageObject()));
}
}
- else if (oid.equals(OID_PROXIED_AUTH_V1))
+ else if (LocalBackendWorkflowElement.processProxyAuthControls(this, oid))
{
- // Log usage of legacy proxy authz V1 control.
- addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
- "obsoleteProxiedAuthzV1Control"));
-
- // The requester must have the PROXIED_AUTH privilege in order to
- // be able to use this control.
- if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
- {
- throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
- ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get());
- }
-
- ProxiedAuthV1Control proxyControl =
- getRequestControl(ProxiedAuthV1Control.DECODER);
-
- Entry authorizationEntry = proxyControl.getAuthorizationEntry();
- setAuthorizationEntry(authorizationEntry);
- if (authorizationEntry == null)
- {
- setProxiedAuthorizationDN(DN.rootDN());
- }
- else
- {
- setProxiedAuthorizationDN(authorizationEntry.getName());
- }
- }
- else if (oid.equals(OID_PROXIED_AUTH_V2))
- {
- // The requester must have the PROXIED_AUTH privilege in order to
- // be able to use this control.
- if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
- {
- throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
- ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get());
- }
-
- ProxiedAuthV2Control proxyControl =
- getRequestControl(ProxiedAuthV2Control.DECODER);
-
- Entry authorizationEntry = proxyControl.getAuthorizationEntry();
- setAuthorizationEntry(authorizationEntry);
- if (authorizationEntry == null)
- {
- setProxiedAuthorizationDN(DN.rootDN());
- }
- else
- {
- setProxiedAuthorizationDN(authorizationEntry.getName());
- }
+ continue;
}
// NYI -- Add support for additional controls.
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
index b62a56f..df7673e 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
@@ -38,21 +38,17 @@
import org.opends.server.api.plugin.PluginResult;
import org.opends.server.controls.LDAPAssertionRequestControl;
import org.opends.server.controls.LDAPPreReadRequestControl;
-import org.opends.server.controls.ProxiedAuthV1Control;
-import org.opends.server.controls.ProxiedAuthV2Control;
import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.DeleteOperation;
import org.opends.server.core.DeleteOperationWrapper;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PersistentSearch;
import org.opends.server.core.PluginConfigManager;
-import org.opends.server.types.AdditionalLogItem;
import org.opends.server.types.CanceledOperationException;
import org.opends.server.types.Control;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
-import org.opends.server.types.Privilege;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SynchronizationProviderResult;
import org.opends.server.types.LockManager.DNLock;
@@ -470,43 +466,9 @@
preReadRequest =
getRequestControl(LDAPPreReadRequestControl.DECODER);
}
- else if (OID_PROXIED_AUTH_V1.equals(oid))
+ else if (LocalBackendWorkflowElement.processProxyAuthControls(this, oid))
{
- // Log usage of legacy proxy authz V1 control.
- addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
- "obsoleteProxiedAuthzV1Control"));
-
- // The requester must have the PROXIED_AUTH privilege in order to
- // be able to use this control.
- if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
- {
- throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
- ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get());
- }
-
- ProxiedAuthV1Control proxyControl =
- getRequestControl(ProxiedAuthV1Control.DECODER);
-
- Entry authorizationEntry = proxyControl.getAuthorizationEntry();
- setAuthorizationEntry(authorizationEntry);
- setProxiedAuthorizationDN(getName(authorizationEntry));
- }
- else if (OID_PROXIED_AUTH_V2.equals(oid))
- {
- // The requester must have the PROXIED_AUTH privilege in order to
- // be able to use this control.
- if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
- {
- throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
- ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get());
- }
-
- ProxiedAuthV2Control proxyControl =
- getRequestControl(ProxiedAuthV2Control.DECODER);
-
- Entry authorizationEntry = proxyControl.getAuthorizationEntry();
- setAuthorizationEntry(authorizationEntry);
- setProxiedAuthorizationDN(getName(authorizationEntry));
+ continue;
}
// NYI -- Add support for additional controls.
else if (c.isCritical()
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
index ca9c21d..ae33640 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
@@ -44,15 +44,12 @@
import org.opends.server.controls.LDAPAssertionRequestControl;
import org.opends.server.controls.LDAPPostReadRequestControl;
import org.opends.server.controls.LDAPPreReadRequestControl;
-import org.opends.server.controls.ProxiedAuthV1Control;
-import org.opends.server.controls.ProxiedAuthV2Control;
import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.ModifyDNOperationWrapper;
import org.opends.server.core.PersistentSearch;
import org.opends.server.core.PluginConfigManager;
-import org.opends.server.types.AdditionalLogItem;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.Attributes;
@@ -62,7 +59,6 @@
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.Modification;
-import org.opends.server.types.Privilege;
import org.opends.server.types.RDN;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SynchronizationProviderResult;
@@ -625,43 +621,9 @@
iter.set(postReadRequest);
}
}
- else if (OID_PROXIED_AUTH_V1.equals(oid))
+ else if (LocalBackendWorkflowElement.processProxyAuthControls(this, oid))
{
- // Log usage of legacy proxy authz V1 control.
- addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
- "obsoleteProxiedAuthzV1Control"));
-
- // The requester must have the PROXIED_AUTH privilege in order to
- // be able to use this control.
- if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
- {
- throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
- ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get());
- }
-
- ProxiedAuthV1Control proxyControl =
- getRequestControl(ProxiedAuthV1Control.DECODER);
-
- Entry authorizationEntry = proxyControl.getAuthorizationEntry();
- setAuthorizationEntry(authorizationEntry);
- setProxiedAuthorizationDN(getName(authorizationEntry));
- }
- else if (OID_PROXIED_AUTH_V2.equals(oid))
- {
- // The requester must have the PROXIED_AUTH privilege in order to
- // be able to use this control.
- if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
- {
- throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
- ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get());
- }
-
- ProxiedAuthV2Control proxyControl =
- getRequestControl(ProxiedAuthV2Control.DECODER);
-
- Entry authorizationEntry = proxyControl.getAuthorizationEntry();
- setAuthorizationEntry(authorizationEntry);
- setProxiedAuthorizationDN(getName(authorizationEntry));
+ continue;
}
else if (c.isCritical()
&& (backend == null || !backend.supportsControl(oid)))
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
index 292dc79..cbbaa9c 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
@@ -53,8 +53,6 @@
import org.opends.server.controls.LDAPPreReadRequestControl;
import org.opends.server.controls.PasswordPolicyErrorType;
import org.opends.server.controls.PasswordPolicyResponseControl;
-import org.opends.server.controls.ProxiedAuthV1Control;
-import org.opends.server.controls.ProxiedAuthV2Control;
import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ModifyOperation;
@@ -68,7 +66,6 @@
import org.opends.server.types.AcceptRejectWarn;
import org.opends.server.types.AccountStatusNotification;
import org.opends.server.types.AccountStatusNotificationType;
-import org.opends.server.types.AdditionalLogItem;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeBuilder;
import org.opends.server.types.AttributeType;
@@ -741,43 +738,9 @@
iter.set(postReadRequest);
}
}
- else if (OID_PROXIED_AUTH_V1.equals(oid))
+ else if (LocalBackendWorkflowElement.processProxyAuthControls(this, oid))
{
- // Log usage of legacy proxy authz V1 control.
- addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
- "obsoleteProxiedAuthzV1Control"));
-
- // The requester must have the PROXIED_AUTH privilege in order to
- // be able to use this control.
- if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
- {
- throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
- ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get());
- }
-
- ProxiedAuthV1Control proxyControl =
- getRequestControl(ProxiedAuthV1Control.DECODER);
-
- Entry authorizationEntry = proxyControl.getAuthorizationEntry();
- setAuthorizationEntry(authorizationEntry);
- setProxiedAuthorizationDN(getName(authorizationEntry));
- }
- else if (OID_PROXIED_AUTH_V2.equals(oid))
- {
- // The requester must have the PROXIED_AUTH privilege in order to
- // be able to use this control.
- if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
- {
- throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
- ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get());
- }
-
- ProxiedAuthV2Control proxyControl =
- getRequestControl(ProxiedAuthV2Control.DECODER);
-
- Entry authorizationEntry = proxyControl.getAuthorizationEntry();
- setAuthorizationEntry(authorizationEntry);
- setProxiedAuthorizationDN(getName(authorizationEntry));
+ continue;
}
else if (OID_PASSWORD_POLICY_CONTROL.equals(oid))
{
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
index 8f1299e..d3c2504 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
@@ -22,7 +22,7 @@
*
*
* Copyright 2008-2010 Sun Microsystems, Inc.
- * Portions Copyright 2011-2014 ForgeRock AS
+ * Portions Copyright 2011-2015 ForgeRock AS
*/
package org.opends.server.workflowelement.localbackend;
@@ -377,43 +377,9 @@
de.getMessageObject()), de);
}
}
- else if (OID_PROXIED_AUTH_V1.equals(oid))
+ else if (LocalBackendWorkflowElement.processProxyAuthControls(this, oid))
{
- // Log usage of legacy proxy authz V1 control.
- addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(),
- "obsoleteProxiedAuthzV1Control"));
-
- // The requester must have the PROXIED_AUTH privilege in order to be
- // able to use this control.
- if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
- {
- throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
- ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get());
- }
-
- ProxiedAuthV1Control proxyControl =
- getRequestControl(ProxiedAuthV1Control.DECODER);
-
- Entry authorizationEntry = proxyControl.getAuthorizationEntry();
- setAuthorizationEntry(authorizationEntry);
- setProxiedAuthorizationDN(getName(authorizationEntry));
- }
- else if (OID_PROXIED_AUTH_V2.equals(oid))
- {
- // The requester must have the PROXIED_AUTH privilege in order to be
- // able to use this control.
- if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
- {
- throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
- ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get());
- }
-
- ProxiedAuthV2Control proxyControl =
- getRequestControl(ProxiedAuthV2Control.DECODER);
-
- Entry authorizationEntry = proxyControl.getAuthorizationEntry();
- setAuthorizationEntry(authorizationEntry);
- setProxiedAuthorizationDN(getName(authorizationEntry));
+ continue;
}
else if (OID_PERSISTENT_SEARCH.equals(oid))
{
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
index f92d2ed..5d6b17e 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -45,10 +45,14 @@
import org.opends.server.controls.LDAPPostReadResponseControl;
import org.opends.server.controls.LDAPPreReadRequestControl;
import org.opends.server.controls.LDAPPreReadResponseControl;
+import org.opends.server.controls.ProxiedAuthV1Control;
+import org.opends.server.controls.ProxiedAuthV2Control;
import org.opends.server.core.*;
import org.opends.server.types.*;
import static org.opends.messages.CoreMessages.*;
+import static org.opends.messages.ProtocolMessages.ERR_PROXYAUTH_AUTHZ_NOT_PERMITTED;
+import static org.opends.server.util.ServerConstants.*;
/**
* This class defines a local backend workflow element; e-g an entity that
@@ -312,8 +316,20 @@
for (Iterator<Control> iter = requestControls.iterator(); iter.hasNext();)
{
final Control control = iter.next();
+ // The aci check for the proxy auth controls needs to check the authentication DN,
+ // not the operation target.
+ // TODO should we check the authentication DN for all controls?
+ final DN aciTarget;
+ if (OID_PROXIED_AUTH_V1.equals(control.getOID()) || OID_PROXIED_AUTH_V2.equals(control.getOID()))
+ {
+ aciTarget= op.getClientConnection().getAuthenticationInfo().getAuthenticationDN();
+ }
+ else
+ {
+ aciTarget = targetDN;
+ }
- if (!getAccessControlHandler().isAllowed(targetDN, op, control))
+ if (!getAccessControlHandler().isAllowed(aciTarget, op, control))
{
// As per RFC 4511 4.1.11.
if (control.isCritical())
@@ -332,6 +348,89 @@
}
/**
+ * Check the requester has the PROXIED_AUTH privilege in order to be able to use a proxy auth control.
+ *
+ * @param operation The operation being checked
+ * @throws DirectoryException If insufficient privileges are detected
+ */
+ static void checkPrivilegeForProxyAuthControl(Operation operation) throws DirectoryException
+ {
+ if (! operation.getClientConnection().hasPrivilege(Privilege.PROXIED_AUTH, operation))
+ {
+ throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
+ ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get());
+ }
+ }
+
+ /**
+ * Check the requester has the authorization user in scope of proxy aci.
+ *
+ * @param operation The operation being checked
+ * @param authorizationEntry The entry being authorized as (e.g. from a proxy auth control)
+ * @throws DirectoryException If no proxy permission is allowed
+ */
+ static void checkAciForProxyAuthControl(Operation operation, Entry authorizationEntry) throws DirectoryException
+ {
+ if (! AccessControlConfigManager.getInstance().getAccessControlHandler()
+ .mayProxy(operation.getClientConnection().getAuthenticationInfo().getAuthenticationEntry(),
+ authorizationEntry, operation))
+ {
+ throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
+ ERR_PROXYAUTH_AUTHZ_NOT_PERMITTED.get(authorizationEntry.getName()));
+ }
+ }
+ /**
+ * Process the operation control with the given oid if it is a proxy auth control.
+ *
+ * Privilege and initial aci checks on the authenticating user are performed. The authenticating
+ * user must have the proxied-auth privilege, and the authz user must be in the scope of aci
+ * allowing the proxy right to the authenticating user.
+ *
+ * @param operation The operation containing the control(s)
+ * @param oid The OID of the detected proxy auth control
+ * @return <code>true</code> if the control has been processed, <code>false</code> if not
+ * @throws DirectoryException
+ */
+ static boolean processProxyAuthControls(Operation operation, String oid)
+ throws DirectoryException
+ {
+ final Entry authorizationEntry;
+
+ if (OID_PROXIED_AUTH_V1.equals(oid))
+ {
+ final ProxiedAuthV1Control proxyControlV1 = operation.getRequestControl(ProxiedAuthV1Control.DECODER);
+ // Log usage of legacy proxy authz V1 control.
+ operation.addAdditionalLogItem(AdditionalLogItem.keyOnly(operation.getClass(),
+ "obsoleteProxiedAuthzV1Control"));
+ checkPrivilegeForProxyAuthControl(operation);
+ authorizationEntry = proxyControlV1.getAuthorizationEntry();
+ }
+ else if (OID_PROXIED_AUTH_V2.equals(oid))
+ {
+ final ProxiedAuthV2Control proxyControlV2 = operation.getRequestControl(ProxiedAuthV2Control.DECODER);
+ checkPrivilegeForProxyAuthControl(operation);
+ authorizationEntry = proxyControlV2.getAuthorizationEntry();
+ }
+ else
+ {
+ return false;
+ }
+
+ checkAciForProxyAuthControl(operation, authorizationEntry);
+ operation.setAuthorizationEntry(authorizationEntry);
+
+ if (authorizationEntry == null)
+ {
+ operation.setProxiedAuthorizationDN(DN.NULL_DN);
+ }
+ else
+ {
+ operation.setProxiedAuthorizationDN(authorizationEntry.getName());
+ }
+ return true;
+ }
+
+ /**
* Returns a new {@link DirectoryException} built from the provided
* resultCodes and messages. Depending on whether ACIs prevent information
* disclosure, the provided resultCode and message will be masked and
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/protocol.properties b/opendj-server-legacy/src/messages/org/opends/messages/protocol.properties
index 8a7daca..ddca568 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/protocol.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/protocol.properties
@@ -908,4 +908,6 @@
ERR_GSER_NO_VALID_IDENTIFIEDCHOICE_1523=The GSER value does not \
contain a valid IdentifiedChoiceValue at the current position: %s
INFO_NULL_KEY_PROVIDER_MANAGER_1524=The keystore %s seems to be missing, \
- this may render the secure port inoperative for '%s'
\ No newline at end of file
+ this may render the secure port inoperative for '%s'
+ERR_PROXYAUTH_AUTHZ_NOT_PERMITTED_1525=Authorization as '%s' specified in \
+ the proxied authorization control is not permitted
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/AciTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/AciTestCase.java
index 5c6ae62..972e12e 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/AciTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/AciTestCase.java
@@ -432,6 +432,32 @@
Assert.assertEquals(LDAPResultCode.SUCCESS, expectedRc, "");
}
+ void proxyModify(String ldif, String bindDn, String bindPassword,
+ String proxyUser, int expectedRc)
+ throws IOException
+ {
+ File tempFile = getTemporaryLdifFile();
+ TestCaseUtils.writeFile(tempFile, ldif);
+
+ ArrayList<String> argList=new ArrayList<>();
+ argList.add("-h");
+ argList.add("127.0.0.1");
+ argList.add("-p");
+ argList.add(String.valueOf(TestCaseUtils.getServerLdapPort()));
+ argList.add("-D");
+ argList.add(bindDn);
+ argList.add("-w");
+ argList.add(bindPassword);
+ if (proxyUser != null) {
+ argList.add("-Y");
+ argList.add("dn:" + proxyUser);
+ }
+ argList.add("-f");
+ argList.add(tempFile.getAbsolutePath());
+ String[] args = new String[argList.size()];
+ ldapModify(argList.toArray(args), expectedRc);
+ }
+
private void ldapModify(String[] args, int expectedRc)
{
oStream.reset();
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/ProxyTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/ProxyTestCase.java
new file mode 100644
index 0000000..2ff5475
--- /dev/null
+++ b/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/ProxyTestCase.java
@@ -0,0 +1,211 @@
+/*
+ * 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
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * 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 2015 ForgeRock AS
+ */
+package org.opends.server.authorization.dseecompat;
+
+import org.opends.server.TestCaseUtils;
+import org.opends.server.protocols.ldap.LDAPResultCode;
+import org.opends.server.types.Entry;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+import static org.opends.server.config.ConfigConstants.ATTR_AUTHZ_GLOBAL_ACI;
+
+/**
+ * This class tests ACI behavior with the proxy auth control.
+ */
+public class ProxyTestCase extends AciTestCase
+{
+ static final String TEST_BASE = "o=test";
+ static final String ALICE_DN = "uid=alice,ou=People," + TEST_BASE;
+ static final String BOB_DN = "uid=bob,ou=People," + TEST_BASE;
+ static final String CHARLIE_DN = "uid=charlie,ou=People," + TEST_BASE;
+ static final String PASSWORD = "password";
+
+ @BeforeClass
+ public void setupClass() throws Exception
+ {
+ deleteAttrFromAdminEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
+ TestCaseUtils.initializeTestBackend(true);
+ TestCaseUtils.addEntries(
+ "dn: ou=People," + TEST_BASE,
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People",
+ "aci: (targetcontrol=\"2.16.840.1.113730.3.4.18\")" +
+ "(version 3.0; acl \"Allow proxy auth control\"; " +
+ "allow (read) userdn = \"ldap:///" + ALICE_DN + "\";)",
+ "aci: (target=\"ldap:///" + CHARLIE_DN + "\")(targetattr = \"telephoneNumber\")" +
+ "(version 3.0; acl \"Allow Bob to write Charlie\"; " +
+ "allow (write) userdn = \"ldap:///" + BOB_DN + "\";)",
+ "aci: (target=\"ldap:///ou=People," + TEST_BASE + "\")" +
+ "(version 3.0; acl \"Allow Alice to proxy People\"; " +
+ "allow (proxy) userdn = \"ldap:///" + ALICE_DN + "\";)",
+ "",
+ "dn: " + ALICE_DN,
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: alice",
+ "cn: Alice",
+ "sn: User",
+ "ds-privilege-name: proxied-auth",
+ "userPassword: " + PASSWORD,
+ "",
+ "dn: uid=bob,ou=People," + TEST_BASE,
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: bob",
+ "cn: Bob",
+ "sn: User",
+ "userPassword: " + PASSWORD,
+ "",
+ "dn: uid=charlie,ou=People," + TEST_BASE,
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: charlie",
+ "cn: Charlie",
+ "sn: User",
+ "userPassword: " + PASSWORD,
+ "",
+ "dn: ou=Groups," + TEST_BASE,
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: Groups",
+ "",
+ "dn: cn=Writable by Bob,ou=Groups," + TEST_BASE,
+ "objectClass: top",
+ "objectClass: groupOfEntries",
+ "cn: Writable by Bob",
+ "aci: (targetattr=\"description\")" +
+ "(version 3.0; acl \"Bob writes\"; " +
+ "allow(write) userdn=\"ldap:///" + BOB_DN + "\";)",
+ "",
+ "dn: cn=Visible to Bob,ou=Groups," + TEST_BASE,
+ "objectClass: top",
+ "objectClass: groupOfEntries",
+ "cn: Visible to Bob",
+ "description: Bob can read this group",
+ "aci: (targetattr=\"*||+\")" +
+ "(version 3.0; acl \"Bob visible\"; " +
+ "allow(read,search) userdn=\"ldap:///" + BOB_DN + "\";)",
+ "",
+ "dn: cn=Invisible to Bob,ou=Groups," + TEST_BASE,
+ "objectClass: top",
+ "objectClass: groupOfEntries",
+ "cn: Invisible to Bob",
+ "description: Bob cannot see this group",
+ "aci: (targetattr=\"*||+\")" +
+ "(version 3.0; acl \"Bob invisible\"; " +
+ "deny(read,search) userdn=\"ldap:///" + BOB_DN + "\";)",
+ "");
+ }
+
+
+ @BeforeMethod
+ public void clearBackend() throws Exception
+ {
+ deleteAttrFromAdminEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
+ }
+
+ /**
+ * Test Alice cannot proxy as Root.
+ *
+ * @throws Exception If an unexpected result is returned.
+ */
+ @Test
+ public void testProxyAsRoot() throws Exception
+ {
+ proxyModify(TestCaseUtils.makeLdif(
+ "dn: " + CHARLIE_DN,
+ "changetype: modify",
+ "replace: telephoneNumber",
+ "telephoneNumber: 999"),
+ ALICE_DN, PASSWORD,
+ DIR_MGR_DN,
+ LDAPResultCode.AUTHORIZATION_DENIED);
+ }
+
+ /**
+ * Test Alice (as Bob) modifies Charlie.
+ *
+ * @throws Exception If an unexpected result is returned.
+ */
+ @Test
+ public void testSimpleProxy() throws Exception
+ {
+ proxyModify(TestCaseUtils.makeLdif(
+ "dn: " + CHARLIE_DN,
+ "changetype: modify",
+ "replace: telephoneNumber",
+ "telephoneNumber: 999"),
+ ALICE_DN, PASSWORD,
+ BOB_DN,
+ LDAPResultCode.SUCCESS);
+ }
+
+ /**
+ * Test Alice (as Bob) modifies an entry outside of the proxy target scope.
+ *
+ * @throws Exception If an unexpected result is returned.
+ */
+ @Test
+ public void testUpdateGroup() throws Exception
+ {
+ proxyModify(TestCaseUtils.makeLdif(
+ "dn: cn=Writable by Bob,ou=Groups," + TEST_BASE,
+ "changetype: modify",
+ "replace: description",
+ "description: written by Alice (Bob)"),
+ ALICE_DN, PASSWORD,
+ BOB_DN,
+ LDAPResultCode.SUCCESS);
+ }
+
+ /**
+ * Test Alice (as Bob) can see entries that Bob can see.
+ * Only "cn=Visible to Bob,ou=Groups,..." should be returned.
+ *
+ * @throws Exception If an unexpected result is returned.
+ */
+ @Test
+ public void testProxiedSearch() throws Exception
+ {
+ String results = LDAPSearchParams(ALICE_DN, PASSWORD, BOB_DN, null, null,
+ TEST_BASE, "(&)", null,
+ false, false, LDAPResultCode.SUCCESS);
+ List<Entry> entries = TestCaseUtils.entriesFromLdifString(results);
+ Assert.assertEquals(entries.size(), 1, "Wrong number of results");
+ }
+}
--
Gitblit v1.10.0