From 5e4ad386b7091fa5ee4ecbc33182a5493ab14177 Mon Sep 17 00:00:00 2001
From: dugan <dugan@localhost>
Date: Sat, 21 Jul 2007 00:56:42 +0000
Subject: [PATCH] Add the new ACI keyword "targetcontrol" that can be used to enforce access based on the OID of a control. For example, a new global access control rule is also being added:
---
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/EnumTargetKeyword.java | 7
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java | 9
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/GetEffectiveRightsTestCase.java | 41 +
opendj-sdk/opends/src/server/org/opends/server/core/DefaultAccessControlHandler.java | 35
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AlternateRootDN.java | 16
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/Aci.java | 97 +++
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java | 286 +++-------
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/TargetAttr.java | 8
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java | 55 +
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciLDAPOperationContainer.java | 20
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTests.java | 58 +
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java | 56 ++
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/TargetControl.java | 101 +++
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargetMatchContext.java | 7
opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java | 14
opendj-sdk/opends/resource/config/config.ldif | 14
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java | 31 +
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetControlTestCase.java | 342 +++++++++++++
opendj-sdk/opends/src/server/org/opends/server/messages/AciMessages.java | 66 ++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java | 207 +++++++
opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java | 2
opendj-sdk/opends/src/server/org/opends/server/api/AccessControlHandler.java | 59 -
opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java | 10
23 files changed, 1,175 insertions(+), 366 deletions(-)
diff --git a/opendj-sdk/opends/resource/config/config.ldif b/opendj-sdk/opends/resource/config/config.ldif
index 898737d..b15bd6a 100644
--- a/opendj-sdk/opends/resource/config/config.ldif
+++ b/opendj-sdk/opends/resource/config/config.ldif
@@ -51,6 +51,8 @@
objectClass: top
objectClass: ds-cfg-access-control-handler
objectClass: ds-cfg-dseecompat-access-control-handler
+ds-cfg-global-aci: (targetcontrol="2.16.840.1.113730.3.4.2 || 2.16.840.1.113730.3.4.17 || 2.16.840.1.113730.3.4.19 || 1.3.6.1.4.1.4203.1.10.2") (version 3.0; acl "Anonymous control access"; allow(read) userdn="ldap:///anyone";)
+ds-cfg-global-aci: (targetcontrol="*") (version 3.0; acl "control"; allow(read) userdn="ldap:///anyone";)
ds-cfg-global-aci: (targetattr!="userPassword||authPassword")(version 3.0; acl "Anonymous read access"; allow (read,search,compare) userdn="ldap:///anyone";)
ds-cfg-global-aci: (targetattr="*")(version 3.0; acl "Self entry modification"; allow (write) userdn="ldap:///self";)
ds-cfg-global-aci: (target="ldap:///cn=schema")(targetscope="base")(targetattr="attributeTypes||dITContentRules||dITStructureRules||ldapSyntaxes||matchingRules||matchingRuleUse||nameForms||objectClasses")(version 3.0; acl "User-Visible Schema Operational Attributes"; allow (read,search,compare) userdn="ldap:///anyone";)
@@ -95,19 +97,7 @@
objectClass: ds-cfg-alert-handler
cn: JMX Alert Handler
ds-cfg-alert-handler-class: org.opends.server.extensions.JMXAlertHandler
-ds-cfg-alert-handler-enabled: true
-
-dn: cn=SMTP Alert Handler,cn=Alert Handlers,cn=config
-objectClass: top
-objectClass: ds-cfg-alert-handler
-objectClass: ds-cfg-smtp-alert-handler
-cn: JMX Alert Handler
-ds-cfg-alert-handler-class: org.opends.server.extensions.SMTPAlertHandler
ds-cfg-alert-handler-enabled: false
-ds-cfg-sender-address: opends-alerts@example.com
-ds-cfg-recipient-address: directory-administrators@example.com
-ds-cfg-message-subject: OpenDS Alert %%alert-type%%
-ds-cfg-message-body: Alert Type: %%alert-type%%\n\nAlert ID: %%alert-id%%\n\nAlert Message: %%alert-message%%
dn: cn=Backends,cn=config
objectClass: top
diff --git a/opendj-sdk/opends/src/server/org/opends/server/api/AccessControlHandler.java b/opendj-sdk/opends/src/server/org/opends/server/api/AccessControlHandler.java
index 67f4c8e..12200ab 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/api/AccessControlHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/api/AccessControlHandler.java
@@ -133,6 +133,26 @@
addOperation);
+ /**
+ * Indicates whether the provided control is allowed based on
+ * the access control configuration and the specified
+ * operation. This method should not alter the provided
+ * operation in any way.
+ *
+ * @param dn A DN that can be used in the access determination.
+ *
+ * @param op The operation to use in the
+ * determination.
+ *
+ * @param control The control for which to make the determination.
+ *
+ * @return {@code true} if the control should be allowed by the
+ * access control configuration, or {@code false} if not.
+ */
+ public abstract boolean isAllowed(DN dn, Operation op,
+ Control control);
+
+
/**
* Indicates whether the provided bind operation is allowed based on
@@ -302,44 +322,5 @@
public abstract boolean maySend(SearchOperation searchOperation,
SearchResultReference searchReference);
-
-
- /**
- * Indicates whether a proxied authorization control is allowed
- * based on the current operation and the new authorization entry.
- *
- * @param operation The operation with which the
- * proxied authorization control is
- * associated.
- * @param newAuthorizationEntry The new authorization entry
- * related to the proxied
- * authorization control
- * authorization ID.
- *
- * @return {@code true} if the operation should be allowed to use
- * the proxied authorization control, or {@code false} if
- * not.
- */
- public abstract boolean isProxiedAuthAllowed(Operation operation,
- Entry newAuthorizationEntry);
-
-
-
- /**
- * Indicates whether a getEffectiveRights control is allowed
- * based on the current operation and the control contents.
- *
- * @param operation The operation with which the
- * getEffectiveRights control is associated.
- * This is always a SearchOperation.
- * @param control The control class containing the decoded
- * getEffectiveRights control contents.
- *
- * @return {@code true} if the use of the getEffectiveRights
- * control should be allowed, or {@code false} if not.
- */
- public abstract boolean isGetEffectiveRightsAllowed(
- SearchOperation operation,
- Control control);
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/Aci.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/Aci.java
index 272350e..d1ace9d 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/Aci.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/Aci.java
@@ -31,7 +31,10 @@
import org.opends.server.types.DN;
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.messages.AciMessages.*;
+import static org.opends.server.util.StaticUtils.isDigit;
+
import java.util.regex.Pattern;
+import java.util.HashSet;
/**
* The Aci class represents ACI strings.
@@ -107,6 +110,7 @@
ZERO_OR_MORE_WHITESPACE + AciBody.bodyRegx +
ZERO_OR_MORE_WHITESPACE_END_PATTERN;
+
/**
* Regular expression that graciously matches an attribute type name. Must
* begin with an ASCII letter or digit, and contain only ASCII letters,
@@ -162,6 +166,20 @@
ZERO_OR_MORE_WHITESPACE +
"\\+" + ZERO_OR_MORE_WHITESPACE;
+ /*
+ * Regular expression used to do quick check of OID string.
+ */
+ private static final String OID_NAME = "[\\d.\\*]*";
+
+ /*
+ * Regular expression that matches one or more OID_NAME's separated by
+ * the "||" token.
+ */
+ private static final String oidListRegex = ZERO_OR_MORE_WHITESPACE +
+ OID_NAME + ZERO_OR_MORE_WHITESPACE + "(" +
+ LOGICAL_OR + ZERO_OR_MORE_WHITESPACE + OID_NAME +
+ ZERO_OR_MORE_WHITESPACE + ")*";
+
/**
* ACI_ADD is used to set the container rights for a LDAP add operation.
*/
@@ -409,6 +427,7 @@
return false;
}
return AciTargets.isTargetApplicable(aci, matchCtx) &&
+ AciTargets.isTargetControlApplicable(aci, matchCtx) &&
AciTargets.isTargetFilterApplicable(aci, matchCtx) &&
AciTargets.isTargAttrFiltersApplicable(aci, matchCtx) &&
AciTargets.isTargetAttrApplicable(aci, matchCtx);
@@ -455,11 +474,79 @@
return aci.evaluate(evalCtx);
}
- /**
- * Returns the name string of this ACI.
- * @return The name string.
- */
+ /**
+ * Returns the name string of this ACI.
+ * @return The name string.
+ */
public String getName() {
return this.body.getName();
}
-}
+
+
+ /**
+ * Decode an OIDs expression string.
+ *
+ * @param expr A string representing the OID expression.
+ * @param msgID A message ID to be used if there is an exception.
+ *
+ * @return Return a hash set of verfied OID strings parsed from the OID
+ * expression.
+ *
+ * @throws AciException If the specified expression string is invalid.
+ */
+
+ public static HashSet<String> decodeOID(String expr, int msgID)
+ throws AciException {
+ HashSet<String> OIDs = new HashSet<String>();
+ //Quick check to see if the expression is valid.
+ if (Pattern.matches(oidListRegex, expr)) {
+ // Remove the spaces in the oid string and
+ // split the list.
+ Pattern separatorPattern =
+ Pattern.compile(LOGICAL_OR);
+ String oidString =
+ expr.replaceAll(ZERO_OR_MORE_WHITESPACE, "");
+ String[] oidArray=
+ separatorPattern.split(oidString);
+ //More careful analysis of each OID string.
+ for(String oid : oidArray) {
+ verifyOid(oid);
+ OIDs.add(oid);
+ }
+ } else {
+ String message = getMessage(msgID, expr);
+ throw new AciException(msgID, message);
+ }
+ return OIDs;
+ }
+
+ /**
+ * Verfiy the specified OID string.
+ *
+ * @param oidStr The string representing an OID.
+ *
+ * @throws AciException If the specified string is invalid.
+ */
+ private static void verifyOid(String oidStr) throws AciException {
+ int pos=0, length=oidStr.length();
+ char c;
+ if(oidStr.equals("*"))
+ return;
+ boolean lastWasPeriod = false;
+ while ((pos < length) && ((c = oidStr.charAt(pos++)) != ' ')) {
+ if (c == '.') {
+ if (lastWasPeriod) {
+ int msgID = MSGID_ACI_SYNTAX_DOUBLE_PERIOD_IN_NUMERIC_OID;
+ String message = getMessage(msgID, oidStr, c, pos-1);
+ throw new AciException(msgID, message);
+ } else
+ lastWasPeriod = true;
+ } else if (! isDigit(c)) {
+ int msgID = MSGID_ACI_SYNTAX_ILLEGAL_CHAR_IN_NUMERIC_OID;
+ String message = getMessage(msgID, oidStr, c, pos-1);
+ throw new AciException(msgID, message);
+ } else
+ lastWasPeriod = false;
+ }
+ }
+ }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java
index 06e9a8f..54fd4dc 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java
@@ -107,17 +107,17 @@
* restore the current resource entry state after a read right was
* evaluated.
*/
- private Entry saveResourceEntry;
+ private final Entry saveResourceEntry;
/*
* The client connection information.
*/
- private ClientConnection clientConnection;
+ private final ClientConnection clientConnection;
/*
* The operation being evaluated.
*/
- private Operation operation;
+ private final Operation operation;
/*
* True if a targattrfilters match was found.
@@ -138,7 +138,7 @@
* Used to save the current authorization entry when the authorization
* entry is switched during a proxy access check.
*/
- private Entry saveAuthorizationEntry;
+ private final Entry saveAuthorizationEntry;
/*
* This entry is only used if proxied authorization is being used. It is
@@ -196,7 +196,7 @@
* Table of ACIs that have targattrfilter keywords that matched. Used
* in geteffectiverights attributeLevel write evaluation.
*/
- private HashMap<Aci,Aci> targAttrFilterAcis=new HashMap<Aci, Aci>();
+ private final HashMap<Aci,Aci> targAttrFilterAcis=new HashMap<Aci, Aci>();
/*
* The name of a ACI that decided an evaluation and contained a
@@ -236,6 +236,11 @@
*/
private int evalAllAttributes=0;
+ /*
+ * String used to hold a control OID string.
+ */
+ private String controlOID;
+
/**
* This constructor is used by all currently supported LDAP operations.
*
@@ -732,6 +737,22 @@
}
/**
+ * {@inheritDoc}
+ */
+ public String getControlOID() {
+ return controlOID;
+ }
+
+ /**
+ * Set the the controlOID value to the specified oid string.
+ *
+ * @param oid The control oid string.
+ */
+ protected void setControlOID(String oid) {
+ this.controlOID=oid;
+ }
+
+ /**
* {@inheritDoc}
*/
public EnumEvalResult hasAuthenticationMethod(EnumAuthMethod authMethod,
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
index e321013..c03b0d7 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
@@ -37,7 +37,7 @@
import static org.opends.server.messages.AciMessages.*;
import static org.opends.server.messages.MessageHandler.getMessage;
import static org.opends.server.schema.SchemaConstants.SYNTAX_DN_OID;
-import static org.opends.server.util.ServerConstants.OID_GET_EFFECTIVE_RIGHTS;
+import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
import static org.opends.server.util.StaticUtils.toLowerCase;
@@ -53,7 +53,7 @@
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.types.*;
import org.opends.server.workflowelement.localbackend.*;
-
+import org.opends.server.controls.GetEffectiveRights;
/**
@@ -1153,32 +1153,37 @@
return ret;
}
- //TODO Check access to control, issue #452.
- /**
- * Called when a proxied authorization control was decoded. Currently used
- * to save the current authorization entry in an operation attachment, but
- * eventually will be used to check access to the actual control.
- * @param operation The operation to save the attachment to.
- * @param entry The new authorization entry.
- * @return True if the control is allowed access.
- */
- public boolean isProxiedAuthAllowed(Operation operation, Entry entry) {
- operation.setAttachment(ORIG_AUTH_ENTRY, operation.getAuthorizationEntry());
- return true;
- }
/**
- * Called when a geteffectiverights request control was decoded. Currently
- * used to save the control in the specified operation's attachment list.
- * Eventually will be used to check access to the actual control.
- * @param operation The operation to save the attachment to.
- * @param c The request control to save.
- * @return True if the control is allowed access.
+ * {@inheritDoc}
*/
- public boolean isGetEffectiveRightsAllowed(SearchOperation operation,
- Control c) {
- operation.setAttachment(OID_GET_EFFECTIVE_RIGHTS, c);
- return true;
+ @Override
+ public boolean isAllowed(DN entryDN, Operation op, Control control) {
+ boolean ret;
+ if(!(ret=skipAccessCheck(op))) {
+ Entry e = new Entry(entryDN, null, null, null);
+ AciLDAPOperationContainer operationContainer =
+ new AciLDAPOperationContainer(op, e, control.getOID());
+ ret=accessAllowed(operationContainer);
+ }
+ if(control.getOID().equals(OID_PROXIED_AUTH_V2) ||
+ control.getOID().equals(OID_PROXIED_AUTH_V1))
+ op.setAttachment(ORIG_AUTH_ENTRY, op.getAuthorizationEntry());
+ else if(control.getOID().equals(OID_GET_EFFECTIVE_RIGHTS)) {
+ try {
+ GetEffectiveRights getEffectiveRightsControl =
+ GetEffectiveRights.decodeControl(control);
+ op.setAttachment(OID_GET_EFFECTIVE_RIGHTS, getEffectiveRightsControl);
+ } catch (LDAPException le) {
+ int msgID=MSGID_ACI_SYNTAX_DECODE_EFFECTIVERIGHTS_FAIL;
+ String message = getMessage(msgID, le.getMessage());
+ logError(ErrorLogCategory.ACCESS_CONTROL,
+ ErrorLogSeverity.INFORMATIONAL,
+ message, msgID);
+ ret=false;
+ }
+ }
+ return ret;
}
//Not planned to be implemented methods.
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciLDAPOperationContainer.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciLDAPOperationContainer.java
index b980c79..a417b61 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciLDAPOperationContainer.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciLDAPOperationContainer.java
@@ -30,10 +30,9 @@
import java.util.List;
import org.opends.server.core.*;
-import org.opends.server.types.Modification;
-import org.opends.server.types.SearchResultEntry;
-import org.opends.server.types.Entry;
+import org.opends.server.types.*;
import org.opends.server.workflowelement.localbackend.*;
+import static org.opends.server.authorization.dseecompat.Aci.ACI_READ;
/**
* The AciLDAPOperationContainer is an AciContainer
@@ -65,6 +64,18 @@
}
/**
+ * Constructor interface for control evaluation.
+ *
+ * @param operation The operation to evaluate.
+ * @param e An entry built especially for control evaluation.
+ * @param oid The control's oid string.
+ */
+ public AciLDAPOperationContainer(Operation operation, Entry e, String oid) {
+ super(operation, (ACI_READ), e );
+ setControlOID(oid);
+ }
+
+ /**
* Constructor interface for the add operation.
* @param operation The add operation to evaluate.
* @param rights The rights of an add operation.
@@ -81,8 +92,7 @@
* @param rights The rights of a delete operation.
*/
public AciLDAPOperationContainer(LocalBackendDeleteOperation operation,
- int rights)
- {
+ int rights) {
super(operation, rights, operation.getEntryToDelete());
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargetMatchContext.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargetMatchContext.java
index 33f4db1..d0a5f1c 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargetMatchContext.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargetMatchContext.java
@@ -118,6 +118,13 @@
*/
public int getRights();
+ /**
+ * Return the oid string of the control being evaluated.
+ *
+ * @return The oid string of the control being evaluated.
+ */
+ public String getControlOID();
+
/**
* Checks if the container's rights has the specified rights.
* @param rights The rights to check for.
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java
index ca0a049..e55aca6 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java
@@ -71,6 +71,11 @@
*/
private TargAttrFilters targAttrFilters=null;
+ /**
+ * The ACI syntax has a targetcontrol keyword.
+ */
+ private TargetControl targetControl=null;
+
/*
* The number of regular expression group positions in a valid ACI target
* expression.
@@ -139,16 +144,19 @@
* @param targetFilter The ACI targetfilter keyword if any.
* @param targetScope The ACI targetscope keyword if any.
* @param targAttrFilters The ACI targAttrFilters keyword if any.
+ * @param targetControl The ACI targetControl keyword if any.
*/
private AciTargets(Target targetEntry, TargetAttr targetAttr,
TargetFilter targetFilter,
SearchScope targetScope,
- TargAttrFilters targAttrFilters) {
+ TargAttrFilters targAttrFilters,
+ TargetControl targetControl) {
this.target=targetEntry;
this.targetAttr=targetAttr;
this.targetScope=targetScope;
this.targetFilter=targetFilter;
this.targAttrFilters=targAttrFilters;
+ this.targetControl=targetControl;
}
/**
@@ -194,6 +202,16 @@
public TargAttrFilters getTargAttrFilters() {
return targAttrFilters;
}
+
+ /**
+ * Return the class representing the ACI targetcontrol keyword. May be
+ * null.
+ * @return The targetcontrol information.
+ */
+ public TargetControl getTargetControl() {
+ return targetControl;
+ }
+
/**
* Decode an ACI's target part of the syntax from the string provided.
* @param input String representing an ACI target part of syntax.
@@ -207,6 +225,7 @@
TargetAttr targetAttr=null;
TargetFilter targetFilter=null;
TargAttrFilters targAttrFilters=null;
+ TargetControl targetControl=null;
SearchScope targetScope=SearchScope.WHOLE_SUBTREE;
Pattern targetPattern = Pattern.compile(targetRegex);
Matcher targetMatcher = targetPattern.matcher(input);
@@ -252,6 +271,22 @@
}
break;
}
+ case KEYWORD_TARGETCONTROL:
+ {
+ if (targetControl == null){
+ targetControl =
+ TargetControl.decode(targetOperator, expression);
+ }
+ else
+ {
+ int msgID =
+ MSGID_ACI_SYNTAX_INVALID_TARGET_DUPLICATE_KEYWORDS;
+ String message =
+ getMessage(msgID, "targetcontrol", input);
+ throw new AciException(msgID, message);
+ }
+ break;
+ }
case KEYWORD_TARGETATTR:
{
if (targetAttr == null){
@@ -318,7 +353,7 @@
}
}
return new AciTargets(target, targetAttr, targetFilter,
- targetScope, targAttrFilters);
+ targetScope, targAttrFilters, targetControl);
}
/**
@@ -365,6 +400,23 @@
}
/**
+ * Check an ACI's targetcontrol against a target match context.
+ *
+ * @param aci The ACI to match the targetcontrol against.
+ * @param matchCtx The target match context containing the information
+ * needed to perform the target match.
+ * @return True if the targetcontrol matched the target context.
+ */
+ public static boolean isTargetControlApplicable(Aci aci,
+ AciTargetMatchContext matchCtx) {
+ boolean ret=true;
+ TargetControl targetControl=aci.getTargets().getTargetControl();
+ if(targetControl != null)
+ ret=targetControl.isApplicable(matchCtx);
+ return ret;
+ }
+
+ /**
* Check an ACI's targattrfilters against a target match context.
* @param aci The ACI to match the targattrfilters against.
* @param matchCtx The target match context containing the information
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/EnumTargetKeyword.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/EnumTargetKeyword.java
index e58fe0b..e22c5fd 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/EnumTargetKeyword.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/EnumTargetKeyword.java
@@ -56,7 +56,12 @@
* This enumeration is returned when the target keyword is
* "targattrfilters".
*/
- KEYWORD_TARGATTRFILTERS ("targattrfilters");
+ KEYWORD_TARGATTRFILTERS ("targattrfilters"),
+ /**
+ * This enumeration is returned when the target keyword is
+ * "targetcontrol".
+ */
+ KEYWORD_TARGETCONTROL ("targetcontrol");
/*
* The target keyword name.
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/TargetAttr.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/TargetAttr.java
index c28633e..9ea4fa9 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/TargetAttr.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/TargetAttr.java
@@ -59,10 +59,10 @@
*/
private HashSet<AttributeType> attributes = new HashSet<AttributeType>();
- /**
- * HashSet of the operational attribute types parsed by the constructor.
- */
- private HashSet<AttributeType> opAttributes = new HashSet<AttributeType>();
+ /**
+ * HashSet of the operational attribute types parsed by the constructor.
+ */
+ private HashSet<AttributeType> opAttributes = new HashSet<AttributeType>();
/*
* Regular expression that matches one or more ATTR_NAME's separated by
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/TargetControl.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/TargetControl.java
new file mode 100644
index 0000000..9510888
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/TargetControl.java
@@ -0,0 +1,101 @@
+/*
+ * 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
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+
+package org.opends.server.authorization.dseecompat;
+
+import static org.opends.server.messages.AciMessages.*;
+import java.util.HashSet;
+
+/**
+ * This class represents an ACI's targetcontrol keyword.
+ */
+
+public class TargetControl {
+
+ /*
+ * HashSet of OID strings parsed from the decode.
+ */
+ private HashSet<String> controlOIDS = new HashSet<String>();
+
+ /*
+ * Enumeration representing the targetcontrol operator.
+ */
+
+ private EnumTargetOperator op = EnumTargetOperator.EQUALITY;
+
+ /**
+ * Creates a class that can be used to evaluate a targetcontrol.
+ *
+ * @param op The operator of the targetfilter expression (=, !=).
+ * @param controlOIDS Set of control OIDS to use in the evaluation (may
+ * contain wild-card '*').
+ */
+ private TargetControl(EnumTargetOperator op, HashSet<String> controlOIDS) {
+ this.controlOIDS=controlOIDS;
+ this.op=op;
+ }
+
+ /**
+ * Decode an targetcontrol expression string.
+ *
+ * @param operator An enumeration representing the operator type.
+ * @param expr A string representing the targetcontrol expression.
+ * @return A class representing the targetcontrol expression that can be
+ * used to evaluate an ACI.
+ *
+ * @throws AciException If the specified expression string is invalid.
+ */
+ public static TargetControl decode(EnumTargetOperator operator, String expr)
+ throws AciException {
+ HashSet<String> controlOIDs =
+ Aci.decodeOID(expr,MSGID_ACI_SYNTAX_INVALID_TARGETCONTROL_EXPRESSION);
+ return new TargetControl(operator, controlOIDs);
+ }
+
+ /**
+ * Check if a targetcontrol is applicable based on the provided target match
+ * context.
+ *
+ * @param matchCtx The target match context to use in the check.
+ * @return True if the targetcontrol is applicable based on the context.
+ */
+ public boolean isApplicable(AciTargetMatchContext matchCtx) {
+ if(matchCtx.getControlOID() == null)
+ return false;
+ boolean ret = false;
+ for(String oid : controlOIDS)
+ if(oid.equals("*") || matchCtx.getControlOID().equals(oid)) {
+ ret=true;
+ break;
+ }
+ if(op.equals(EnumTargetOperator.NOT_EQUALITY))
+ ret = !ret;
+ return ret;
+ }
+}
+
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/DefaultAccessControlHandler.java b/opendj-sdk/opends/src/server/org/opends/server/core/DefaultAccessControlHandler.java
index 46aec3a..1980fd6 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/DefaultAccessControlHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/DefaultAccessControlHandler.java
@@ -100,7 +100,6 @@
}
-
/**
* {@inheritDoc}
*/
@@ -160,6 +159,17 @@
* {@inheritDoc}
*/
@Override
+ public boolean isAllowed(DN dn, Operation op, Control control)
+ {
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public boolean isAllowed(LocalBackendModifyDNOperation modifyDNOperation)
{
return true;
@@ -189,7 +199,6 @@
}
-
/**
* {@inheritDoc}
*/
@@ -213,27 +222,5 @@
return true;
}
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isProxiedAuthAllowed(Operation operation, Entry entry)
- {
- return true;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isGetEffectiveRightsAllowed(SearchOperation operation,
- Control c)
- {
- return true;
- }
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java b/opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java
index 3b5b432..6955d0e 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java
@@ -60,6 +60,7 @@
import org.opends.server.types.DebugLogLevel;
import static org.opends.server.messages.CoreMessages.*;
import static org.opends.server.messages.MessageHandler.*;
+import static org.opends.server.messages.MessageHandler.getMessage;
import static org.opends.server.util.ServerConstants.*;
@@ -487,6 +488,15 @@
{
for (Control c : requestControls)
{
+ if (!AccessControlConfigManager.getInstance().
+ getAccessControlHandler().
+ isAllowed(this.getAuthorizationDN(), this, c)) {
+ setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+ int msgID = MSGID_CONTROL_INSUFFICIENT_ACCESS_RIGHTS;
+ appendErrorMessage(getMessage(msgID, c.getOID()));
+ skipPostOperation=true;
+ break extendedProcessing;
+ }
if (! c.isCritical())
{
// The control isn't critical, so we don't care if it's supported
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/AciMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/AciMessages.java
index 1b79d7d..da777e4 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/AciMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/AciMessages.java
@@ -913,7 +913,48 @@
public static final int MSGID_ACI_SYNTAX_INVALID_NETMASK =
CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 90;
+
/**
+ * The message ID for the message that will be used if an "aci" attribute
+ * type value parse failed because a targetcontrol keyword expression
+ * did not parse. This takes one argument, which is the targetcontrol
+ * expression from the ACI.
+ */
+
+ public static final int MSGID_ACI_SYNTAX_INVALID_TARGETCONTROL_EXPRESSION =
+ CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 91;
+
+ /**
+ * The message ID for the message that will be used if an "aci" attribute
+ * type value cannot be parsed because numeric OID contained an
+ * illegal character. This takes three arguments, which are the provided
+ * value, the illegal character, and the position of that character.
+ */
+ public static final int
+ MSGID_ACI_SYNTAX_ILLEGAL_CHAR_IN_NUMERIC_OID =
+ CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 92;
+
+
+ /**
+ * The message ID for the message that will be used if an "aci" attribute
+ * type value cannot be parsed because the OID contained two
+ * consecutive periods. This takes two arguments, which are the provided
+ * value and the position of the second period.
+ */
+ public static final int
+ MSGID_ACI_SYNTAX_DOUBLE_PERIOD_IN_NUMERIC_OID =
+ CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 93;
+
+ /**
+ * The message ID for the message that will be used the ACI handler cannot
+ * decode an geteffectiverights control. This takes one argument, the
+ * message from the decode exception.
+ */
+ public static final int
+ MSGID_ACI_SYNTAX_DECODE_EFFECTIVERIGHTS_FAIL =
+ CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 94;
+
+ /**
* Associates a set of generic messages with the message IDs defined in
* this class.
*/
@@ -1435,5 +1476,30 @@
"IP address expression failed to parse because the " +
"netmask part of the expression \"%s\" has an invalid value");
+
+ registerMessage(MSGID_ACI_SYNTAX_INVALID_TARGETCONTROL_EXPRESSION,
+ "The provided Access Control Instruction (ACI) " +
+ "targetcontrol expression value \"%s\" is invalid. A valid " +
+ "targetcontrol keyword expression value requires one or more " +
+ "valid control OID strings in the following format: " +
+ "oid [|| oid1] ... [|| oidn]");
+
+ registerMessage(MSGID_ACI_SYNTAX_ILLEGAL_CHAR_IN_NUMERIC_OID,
+ "The provided Access Control Instruction (ACI) " +
+ "targetcontrol OID value \"%s\" could not be parsed " +
+ " because the value contained an illegal character %s " +
+ "at position %d");
+
+ registerMessage(MSGID_ACI_SYNTAX_DOUBLE_PERIOD_IN_NUMERIC_OID,
+ "The provided Access Control Instruction (ACI) " +
+ "targetcontrol OID value \"%s\" could not be parsed " +
+ " because the numeric OID " +
+ "contained two consecutive periods at position %d");
+
+ registerMessage(MSGID_ACI_SYNTAX_DECODE_EFFECTIVERIGHTS_FAIL,
+ "The access control check failed because a" +
+ " geteffectiverights control could not be" +
+ " decoded because of the following reason: \"%s\"");
+
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java
index 1c0331c..aa3b15f 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java
@@ -6084,13 +6084,12 @@
/**
- * The message ID for the message that will be used if a search
- * operation cannot be processed due to insufficient access rights caused
- * by an access control check on the geteffectiverights control. This message
- * takes a single argument, the name of the search operation's base entry.
+ * The message ID for the message that will be used if a request control
+ * cannot be used due to insufficient access rights. This message takes a
+ * single argument, which is the OID string of the control being used.
*/
public static final
- int MSGID_SEARCH_EFFECTIVERIGHTS_INSUFFICIENT_ACCESS_RIGHTS =
+ int MSGID_CONTROL_INSUFFICIENT_ACCESS_RIGHTS =
CATEGORY_MASK_CORE | SEVERITY_MASK_SEVERE_ERROR | 611;
@@ -8348,8 +8347,9 @@
"The entry %s cannot be modified due to insufficient access rights");
registerMessage(MSGID_SEARCH_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS,
"The entry %s cannot be searched due to insufficient access rights");
- registerMessage(MSGID_SEARCH_EFFECTIVERIGHTS_INSUFFICIENT_ACCESS_RIGHTS,
- "The entry %s cannot be searched due to insufficient access rights");
+ registerMessage(MSGID_CONTROL_INSUFFICIENT_ACCESS_RIGHTS,
+ "The request control with Object Identifier (OID) \"%s\" cannot be" +
+ " used due to insufficient access rights");
registerMessage(MSGID_BIND_OPERATION_INSECURE_SIMPLE_BIND,
"Rejecting a simple bind request for user %s because the " +
"password policy requires secure authentication");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
index adc3cd7..22db5f0 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
@@ -10484,7 +10484,7 @@
"ERROR: No configuration changes were specified");
registerMessage(MSGID_CONFIGDS_PORT_ALREADY_SPECIFIED,
"ERROR: You have specified the value %s for different " +
- "ports.");
+ "ports");
registerMessage(MSGID_CONFIGDS_WROTE_UPDATED_CONFIG,
"Successfully wrote the updated Directory Server " +
"configuration");
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
index ee3a804..5c7790c 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -56,7 +56,6 @@
import org.opends.server.api.plugin.PostOperationPluginResult;
import org.opends.server.api.plugin.PreOperationPluginResult;
import org.opends.server.controls.AuthorizationIdentityResponseControl;
-import org.opends.server.controls.GetEffectiveRights;
import org.opends.server.controls.LDAPAssertionRequestControl;
import org.opends.server.controls.LDAPPostReadRequestControl;
import org.opends.server.controls.LDAPPostReadResponseControl;
@@ -214,7 +213,7 @@
/**
* Perform a local modify operation against the local backend.
*
- * @param operation - The operation to perform
+ * @param localOp - The operation to perform
*/
private void processLocalModify(LocalBackendModifyOperation localOp)
{
@@ -392,6 +391,17 @@
Control c = requestControls.get(i);
String oid = c.getOID();
+ if (!AccessControlConfigManager.getInstance().
+ getAccessControlHandler().
+ isAllowed(entryDN, localOp, c))
+ {
+ localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+ int msgID = MSGID_CONTROL_INSUFFICIENT_ACCESS_RIGHTS;
+ localOp.appendErrorMessage(getMessage(msgID, oid));
+ skipPostOperation = true;
+ break modifyProcessing;
+ }
+
if (oid.equals(OID_LDAP_ASSERTION))
{
LDAPAssertionRequestControl assertControl;
@@ -459,7 +469,7 @@
}
else if (oid.equals(OID_LDAP_READENTRY_PREREAD))
{
- if (c instanceof LDAPAssertionRequestControl)
+ if (c instanceof LDAPPreReadRequestControl)
{
preReadRequest = (LDAPPreReadRequestControl) c;
}
@@ -486,7 +496,7 @@
}
else if (oid.equals(OID_LDAP_READENTRY_POSTREAD))
{
- if (c instanceof LDAPAssertionRequestControl)
+ if (c instanceof LDAPPostReadRequestControl)
{
postReadRequest = (LDAPPostReadRequestControl) c;
}
@@ -569,19 +579,6 @@
break modifyProcessing;
}
-
- if (AccessControlConfigManager.getInstance().
- getAccessControlHandler().isProxiedAuthAllowed(localOp,
- authorizationEntry) == false) {
- localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_MODIFY_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- localOp.appendErrorMessage(getMessage(msgID,
- String.valueOf(entryDN)));
-
- skipPostOperation = true;
- break modifyProcessing;
- }
localOp.setAuthorizationEntry(authorizationEntry);
if (authorizationEntry == null)
{
@@ -650,18 +647,6 @@
break modifyProcessing;
}
- if (AccessControlConfigManager.getInstance().
- getAccessControlHandler().isProxiedAuthAllowed(localOp,
- authorizationEntry) == false) {
- localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_MODIFY_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- localOp.appendErrorMessage(getMessage(msgID,
- String.valueOf(entryDN)));
-
- skipPostOperation = true;
- break modifyProcessing;
- }
localOp.setAuthorizationEntry(authorizationEntry);
if (authorizationEntry == null)
{
@@ -2545,6 +2530,17 @@
Control c = requestControls.get(i);
String oid = c.getOID();
+ if (!AccessControlConfigManager.getInstance().
+ getAccessControlHandler().
+ isAllowed(baseDN, localOp, c))
+ {
+ localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+ int msgID = MSGID_CONTROL_INSUFFICIENT_ACCESS_RIGHTS;
+ localOp.appendErrorMessage(getMessage(msgID, oid));
+ skipPostOperation = true;
+ break searchProcessing;
+ }
+
if (oid.equals(OID_LDAP_ASSERTION))
{
LDAPAssertionRequestControl assertControl;
@@ -2696,18 +2692,6 @@
break searchProcessing;
}
- if (AccessControlConfigManager.getInstance().
- getAccessControlHandler().isProxiedAuthAllowed(localOp,
- authorizationEntry) == false) {
- localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_SEARCH_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- localOp.appendErrorMessage(getMessage(msgID,
- String.valueOf(baseDN)));
-
- skipPostOperation = true;
- break searchProcessing;
- }
localOp.setAuthorizationEntry(authorizationEntry);
if (authorizationEntry == null)
{
@@ -2777,18 +2761,6 @@
break searchProcessing;
}
- if (AccessControlConfigManager.getInstance().
- getAccessControlHandler().isProxiedAuthAllowed(localOp,
- authorizationEntry) == false) {
- localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_SEARCH_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- localOp.appendErrorMessage(getMessage(msgID,
- String.valueOf(baseDN)));
-
- skipPostOperation = true;
- break searchProcessing;
- }
localOp.setAuthorizationEntry(authorizationEntry);
if (authorizationEntry == null)
{
@@ -2884,48 +2856,6 @@
{
localOp.setVirtualAttributesOnly(true);
}
- else if(oid.equals(OID_GET_EFFECTIVE_RIGHTS))
- {
- GetEffectiveRights effectiveRightsControl;
- if (c instanceof GetEffectiveRights)
- {
- effectiveRightsControl = (GetEffectiveRights) c;
- }
- else
- {
- try
- {
- effectiveRightsControl = GetEffectiveRights.decodeControl(c);
- }
- catch (LDAPException le)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, le);
- }
-
- localOp.setResultCode(ResultCode.valueOf(le.getResultCode()));
- localOp.appendErrorMessage(le.getMessage());
-
- break searchProcessing;
- }
- }
-
- if (!AccessControlConfigManager.getInstance()
- .getAccessControlHandler().
- isGetEffectiveRightsAllowed(localOp,
- effectiveRightsControl)) {
- localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
- int msgID =
- MSGID_SEARCH_EFFECTIVERIGHTS_INSUFFICIENT_ACCESS_RIGHTS;
- localOp.appendErrorMessage(getMessage(msgID,
- String.valueOf(baseDN)));
-
- skipPostOperation = true;
- break searchProcessing;
- }
- }
-
// NYI -- Add support for additional controls.
else if (c.isCritical())
{
@@ -3151,7 +3081,7 @@
/**
* Perform a local bind operation against a local backend.
*
- * @param operation - The operation to perform
+ * @param localOp - The operation to perform
*/
private void processLocalBind(LocalBackendBindOperation localOp)
{
@@ -3241,6 +3171,16 @@
Control c = requestControls.get(i);
String oid = c.getOID();
+ if (!AccessControlConfigManager.getInstance().
+ getAccessControlHandler(). isAllowed(bindDN, localOp, c))
+ {
+ localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+ int msgID = MSGID_CONTROL_INSUFFICIENT_ACCESS_RIGHTS;
+ localOp.appendErrorMessage(getMessage(msgID, oid));
+ skipPostOperation = true;
+ break bindProcessing;
+ }
+
if (oid.equals(OID_AUTHZID_REQUEST))
{
returnAuthzID = true;
@@ -4560,7 +4500,7 @@
/**
* Perform a local add operation against a local backend.
*
- * @param operation - The operation to perform
+ * @param localOp - The operation to perform
*/
private void processLocalAdd(LocalBackendAddOperation localOp)
{
@@ -5298,6 +5238,16 @@
Control c = requestControls.get(i);
String oid = c.getOID();
+ if (!AccessControlConfigManager.getInstance().
+ getAccessControlHandler().isAllowed(parentDN, localOp, c))
+ {
+ localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+ int msgID = MSGID_CONTROL_INSUFFICIENT_ACCESS_RIGHTS;
+ localOp.appendErrorMessage(getMessage(msgID, oid));
+ skipPostOperation = true;
+ break addProcessing;
+ }
+
if (oid.equals(OID_LDAP_ASSERTION))
{
LDAPAssertionRequestControl assertControl;
@@ -5365,7 +5315,7 @@
}
else if (oid.equals(OID_LDAP_READENTRY_POSTREAD))
{
- if (c instanceof LDAPAssertionRequestControl)
+ if (c instanceof LDAPPostReadRequestControl)
{
postReadRequest = (LDAPPostReadRequestControl) c;
}
@@ -5448,18 +5398,6 @@
break addProcessing;
}
- if (AccessControlConfigManager.getInstance()
- .getAccessControlHandler().isProxiedAuthAllowed(localOp,
- authorizationEntry) == false) {
- localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_ADD_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- localOp.appendErrorMessage(getMessage(msgID,
- String.valueOf(entryDN)));
-
- skipPostOperation = true;
- break addProcessing;
- }
localOp.setAuthorizationEntry(authorizationEntry);
if (authorizationEntry == null)
{
@@ -5528,18 +5466,6 @@
break addProcessing;
}
- if (AccessControlConfigManager.getInstance()
- .getAccessControlHandler().isProxiedAuthAllowed(localOp,
- authorizationEntry) == false) {
- localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_ADD_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- localOp.appendErrorMessage(getMessage(msgID,
- String.valueOf(entryDN)));
-
- skipPostOperation = true;
- break addProcessing;
- }
localOp.setAuthorizationEntry(authorizationEntry);
if (authorizationEntry == null)
{
@@ -5945,7 +5871,7 @@
/**
* Performs a local delete operation against a local backend.
*
- * @param operation the operation to perform
+ * @param localOp the operation to perform
*/
private void processLocalDelete(LocalBackendDeleteOperation localOp)
{
@@ -6095,6 +6021,16 @@
Control c = requestControls.get(i);
String oid = c.getOID();
+ if (!AccessControlConfigManager.getInstance().
+ getAccessControlHandler().isAllowed(entryDN, localOp, c))
+ {
+ localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+ int msgID = MSGID_CONTROL_INSUFFICIENT_ACCESS_RIGHTS;
+ localOp.appendErrorMessage(getMessage(msgID, oid));
+ skipPostOperation = true;
+ break deleteProcessing;
+ }
+
if (oid.equals(OID_LDAP_ASSERTION))
{
LDAPAssertionRequestControl assertControl;
@@ -6162,7 +6098,7 @@
}
else if (oid.equals(OID_LDAP_READENTRY_PREREAD))
{
- if (c instanceof LDAPAssertionRequestControl)
+ if (c instanceof LDAPPreReadRequestControl)
{
preReadRequest = (LDAPPreReadRequestControl) c;
}
@@ -6245,18 +6181,6 @@
break deleteProcessing;
}
- if (AccessControlConfigManager.getInstance()
- .getAccessControlHandler().isProxiedAuthAllowed(localOp,
- authorizationEntry) == false) {
- localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_DELETE_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- localOp.appendErrorMessage(
- getMessage(msgID, String.valueOf(entryDN)));
-
- skipPostOperation = true;
- break deleteProcessing;
- }
localOp.setAuthorizationEntry(authorizationEntry);
if (authorizationEntry == null)
{
@@ -6325,18 +6249,6 @@
break deleteProcessing;
}
- if (AccessControlConfigManager.getInstance()
- .getAccessControlHandler().isProxiedAuthAllowed(localOp,
- authorizationEntry) == false) {
- localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_DELETE_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- localOp.appendErrorMessage(
- getMessage(msgID, String.valueOf(entryDN)));
-
- skipPostOperation = true;
- break deleteProcessing;
- }
localOp.setAuthorizationEntry(authorizationEntry);
if (authorizationEntry == null)
{
@@ -6755,7 +6667,7 @@
/**
* Perform a local compare operation against a local backend.
*
- * @param operation - The operation to perform
+ * @param localOp - The operation to perform
*/
private void processLocalCompare(LocalBackendCompareOperation localOp)
{
@@ -6896,6 +6808,17 @@
Control c = requestControls.get(i);
String oid = c.getOID();
+ if (!AccessControlConfigManager.getInstance().
+ getAccessControlHandler().
+ isAllowed(entryDN, localOp, c))
+ {
+ localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+ int msgID = MSGID_CONTROL_INSUFFICIENT_ACCESS_RIGHTS;
+ localOp.appendErrorMessage(getMessage(msgID, oid));
+ skipPostOperation = true;
+ break compareProcessing;
+ }
+
if (oid.equals(OID_LDAP_ASSERTION))
{
LDAPAssertionRequestControl assertControl;
@@ -7015,18 +6938,6 @@
break compareProcessing;
}
- if (AccessControlConfigManager.getInstance()
- .getAccessControlHandler().isProxiedAuthAllowed(localOp,
- authorizationEntry) == false) {
- localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_COMPARE_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- localOp.appendErrorMessage(
- getMessage(msgID, String.valueOf(entryDN)));
-
- skipPostOperation = true;
- break compareProcessing;
- }
localOp.setAuthorizationEntry(authorizationEntry);
if (authorizationEntry == null)
{
@@ -7095,18 +7006,6 @@
break compareProcessing;
}
- if (AccessControlConfigManager.getInstance()
- .getAccessControlHandler().isProxiedAuthAllowed(localOp,
- authorizationEntry) == false) {
- localOp.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_COMPARE_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- localOp.appendErrorMessage(
- getMessage(msgID, String.valueOf(entryDN)));
-
- skipPostOperation = true;
- break compareProcessing;
- }
localOp.setAuthorizationEntry(authorizationEntry);
if (authorizationEntry == null)
{
@@ -7323,7 +7222,7 @@
/**
* Perform a local moddn operation against the local backend.
*
- * @param operation - The operation to perform
+ * @param op - The operation to perform
*/
private void processLocalModifyDN(LocalBackendModifyDNOperation op)
{
@@ -7606,6 +7505,16 @@
Control c = requestControls.get(i);
String oid = c.getOID();
+ if (!AccessControlConfigManager.getInstance().
+ getAccessControlHandler().isAllowed(entryDN, op, c))
+ {
+ op.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+ int msgID = MSGID_CONTROL_INSUFFICIENT_ACCESS_RIGHTS;
+ op.appendErrorMessage(getMessage(msgID, oid));
+ skipPostOperation = true;
+ break modifyDNProcessing;
+ }
+
if (oid.equals(OID_LDAP_ASSERTION))
{
LDAPAssertionRequestControl assertControl;
@@ -7671,7 +7580,7 @@
}
else if (oid.equals(OID_LDAP_READENTRY_PREREAD))
{
- if (c instanceof LDAPAssertionRequestControl)
+ if (c instanceof LDAPPreReadRequestControl)
{
preReadRequest = (LDAPPreReadRequestControl) c;
}
@@ -7698,7 +7607,7 @@
}
else if (oid.equals(OID_LDAP_READENTRY_POSTREAD))
{
- if (c instanceof LDAPAssertionRequestControl)
+ if (c instanceof LDAPPostReadRequestControl)
{
postReadRequest = (LDAPPostReadRequestControl) c;
}
@@ -7780,18 +7689,6 @@
break modifyDNProcessing;
}
- if (AccessControlConfigManager.getInstance()
- .getAccessControlHandler().isProxiedAuthAllowed(op,
- authorizationEntry) == false) {
- op.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_MODDN_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- op.appendErrorMessage(getMessage(msgID,
- String.valueOf(entryDN)));
-
- skipPostOperation = true;
- break modifyDNProcessing;
- }
op.setAuthorizationEntry(authorizationEntry);
if (authorizationEntry == null)
{
@@ -7858,19 +7755,6 @@
break modifyDNProcessing;
}
- if (AccessControlConfigManager.getInstance()
- .getAccessControlHandler().isProxiedAuthAllowed(op,
- authorizationEntry) == false) {
- op.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_MODDN_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- op.appendErrorMessage(getMessage(msgID,
- String.valueOf(entryDN)));
-
- skipPostOperation = true;
- break modifyDNProcessing;
- }
-
op.setAuthorizationEntry(authorizationEntry);
if (authorizationEntry == null)
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java
index d516143..c588e5c 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java
@@ -31,6 +31,8 @@
import org.opends.server.TestCaseUtils;
import org.opends.server.tools.LDAPModify;
import org.opends.server.tools.LDAPSearch;
+import org.opends.server.tools.LDAPDelete;
+import org.opends.server.tools.LDAPPasswordModify;
import static org.opends.server.util.ServerConstants.EOL;
import org.testng.annotations.Test;
import org.testng.Assert;
@@ -48,14 +50,86 @@
public static final String ACCESS_HANDLER_DN =
"cn=Access Control Handler,cn=config";
- private static ByteArrayOutputStream oStream = new ByteArrayOutputStream();
- private static ThreadLocal<Map<String,File>> tempLdifFile =
+ //GLOBAL ACIs
+
+ protected final static String G_READ_ACI =
+ "(targetattr!=\"userPassword||authPassword\")" +
+ "(version 3.0; acl \"Anonymous read access\";" +
+ "allow (read,search,compare) userdn=\"ldap:///anyone\";)";
+
+ protected final static String G_SELF_MOD =
+ "(targetattr=\"*\")(version 3.0; acl \"Self entry modification\";" +
+ "allow (write) userdn=\"ldap:///self\";)";
+
+ protected final static String G_SCHEMA =
+ "(target=\"ldap:///cn=schema\")(targetscope=\"base\")" +
+ "(targetattr=\"attributeTypes||dITContentRules||dITStructureRules||" +
+ "ldapSyntaxes||matchingRules||matchingRuleUse||nameForms||" +
+ "objectClasses\")" +
+ "(version 3.0; acl \"User-Visible Schema Operational Attributes\";" +
+ "allow (read,search,compare) userdn=\"ldap:///anyone\";)";
+
+ protected final static String G_DSE =
+ "(target=\"ldap:///\")(targetscope=\"base\")" +
+ "(targetattr=\"namingContexts||supportedAuthPasswordSchemes||" +
+ "supportedControl||supportedExtension||supportedFeatures||" +
+ "supportedSASLMechanisms||vendorName||vendorVersion\")" +
+ "(version 3.0; acl \"User-Visible Root DSE Operational Attributes\"; " +
+ "allow (read,search,compare) userdn=\"ldap:///anyone\";)";
+
+ protected final static String G_USER_OPS =
+ "(targetattr=\"createTimestamp||creatorsName||modifiersName||" +
+ "modifyTimestamp||entryDN||entryUUID||subschemaSubentry\")" +
+ "(version 3.0; acl \"User-Visible Operational Attributes\"; " +
+ "allow (read,search,compare) userdn=\"ldap:///anyone\";)";
+
+ protected final static String G_CONTROL =
+ "(targetcontrol = \"*\")" +
+ "(version 3.0; acl \"Control\"; " +
+ "allow (read) userdn=\"ldap:///anyone\";)";
+
+ private static final ByteArrayOutputStream oStream = new ByteArrayOutputStream();
+ private static final ThreadLocal<Map<String,File>> tempLdifFile =
new ThreadLocal<Map<String,File>>();
+
+ protected String pwdModify(String bindDn, String bindPassword,
+ String newPassword, String noOpControl,
+ String pwdPolicyControl, int rc) {
+
+ ArrayList<String> argList=new ArrayList<String>(20);
+ 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);
+ argList.add("-c");
+ argList.add(bindPassword);
+ argList.add("-n");
+ argList.add(newPassword);
+ if(noOpControl != null) {
+ argList.add("-J");
+ argList.add(noOpControl);
+ }
+ if(pwdPolicyControl != null) {
+ argList.add("-J");
+ argList.add(pwdPolicyControl);
+ }
+ String[] args = new String[argList.size()];
+ oStream.reset();
+ int ret=
+ LDAPPasswordModify.mainPasswordModify(argList.toArray(args),
+ false, oStream, oStream);
+ Assert.assertEquals(rc, ret, "Returned error: " + oStream.toString());
+ return oStream.toString();
+ }
+
protected String LDAPSearchCtrl(String bindDn, String bindPassword,
String proxyDN, String controlStr,
- String base, String filter, String attr)
- throws Exception {
+ String base, String filter, String attr) {
ArrayList<String> argList=new ArrayList<String>(20);
argList.add("-h");
argList.add("127.0.0.1");
@@ -90,10 +164,29 @@
return oStream.toString();
}
+ protected String
+ LDAPSearchParams(String bindDn, String bindPassword,
+ String proxyDN, String authzid,
+ String[] attrList,
+ String base, String filter ,String attr,
+ boolean pwdPolicy, boolean reportAuthzID,
+ int rc) {
+ return _LDAPSearchParams(bindDn, bindPassword, proxyDN, authzid, attrList,
+ base, filter, attr, pwdPolicy, reportAuthzID, rc);
+ }
+
protected String LDAPSearchParams(String bindDn, String bindPassword,
+ String proxyDN, String authzid,
+ String[] attrList,
+ String base, String filter ,String attr) {
+ return _LDAPSearchParams(bindDn, bindPassword, proxyDN, authzid, attrList,
+ base, filter, attr, false, false, 0);
+ }
+
+ private String _LDAPSearchParams(String bindDn, String bindPassword,
String proxyDN, String authzid, String[] attrList,
- String base, String filter ,String attr)
- throws Exception {
+ String base, String filter ,String attr,
+ boolean pwdPolicy, boolean reportAuthzID, int rc) {
ArrayList<String> argList=new ArrayList<String>(20);
argList.add("-h");
argList.add("127.0.0.1");
@@ -118,6 +211,12 @@
argList.add(a);
}
}
+ if(pwdPolicy) {
+ argList.add("--usePasswordPolicyControl");
+ }
+ if(reportAuthzID) {
+ argList.add("-E");
+ }
argList.add("-b");
argList.add(base);
argList.add("-s");
@@ -130,11 +229,59 @@
oStream.reset();
int retVal =
LDAPSearch.mainSearch(argList.toArray(args), false, oStream, oStream);
- Assert.assertEquals(0, retVal, "Returned error: " + oStream.toString());
+ Assert.assertEquals(rc, retVal, "Returned error: " + oStream.toString());
return oStream.toString();
}
+ protected void LDIFAdd(String ldif, String bindDn, String bindPassword,
+ String controlStr, int rc) throws Exception {
+ _LDIFModify(ldif, bindDn, bindPassword, controlStr, true, rc);
+ }
+
+ protected void LDIFModify(String ldif, String bindDn, String bindPassword,
+ String controlStr, int rc) throws Exception {
+ _LDIFModify(ldif, bindDn, bindPassword, controlStr, false, rc);
+ }
+
protected void LDIFModify(String ldif, String bindDn, String bindPassword)
+ throws Exception {
+ _LDIFModify(ldif, bindDn, bindPassword, null, false, -1);
+ }
+
+ protected void LDIFDelete(String dn, String bindDn, String bindPassword,
+ String controlStr, int rc) {
+ _LDIFDelete(dn, bindDn, bindPassword, controlStr, rc);
+ }
+
+ private void _LDIFDelete(String dn, String bindDn, String bindPassword,
+ String controlStr, int rc) {
+ ArrayList<String> argList=new ArrayList<String>(20);
+ 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(controlStr != null) {
+ argList.add("-J");
+ argList.add(controlStr);
+ }
+ argList.add(dn);
+ String[] args = new String[argList.size()];
+ ldapDelete(argList.toArray(args), rc);
+ }
+
+ private void ldapDelete(String[] args, int rc) {
+ oStream.reset();
+ int retVal = LDAPDelete.mainDelete(args, false, oStream, oStream);
+ Assert.assertEquals(rc, retVal, "Returned error: " + oStream.toString());
+ }
+
+
+ private void _LDIFModify(String ldif, String bindDn, String bindPassword,
+ String controlStr, boolean add, int rc)
throws Exception {
File tempFile = getTemporaryLdifFile();
TestCaseUtils.writeFile(tempFile, ldif);
@@ -147,19 +294,27 @@
argList.add(bindDn);
argList.add("-w");
argList.add(bindPassword);
+ if(controlStr != null) {
+ argList.add("-J");
+ argList.add(controlStr);
+ }
+ if(add) {
+ argList.add("-a");
+ }
argList.add("-f");
argList.add(tempFile.getAbsolutePath());
String[] args = new String[argList.size()];
- ldapModify(argList.toArray(args));
+ ldapModify(argList.toArray(args), rc);
}
- protected void ldapModify(String[] args) {
+ private void ldapModify(String[] args, int rc) {
oStream.reset();
- LDAPModify.mainModify(args, false, oStream, oStream);
+ int retVal =LDAPModify.mainModify(args, false, oStream, oStream);
+ if(rc != -1)
+ Assert.assertEquals(rc, retVal, "Returned error: " + oStream.toString());
}
- protected void deleteAttrFromEntry(String dn, String attr)
- throws Exception {
+ protected void deleteAttrFromEntry(String dn, String attr) throws Exception {
StringBuilder ldif = new StringBuilder();
ldif.append(TestCaseUtils.makeLdif(
"dn: " + dn,
@@ -168,6 +323,20 @@
LDIFModify(ldif.toString(), DIR_MGR_DN, PWD);
}
+ protected static String makeModDNLDIF(String dn, String newRDN,
+ String deleteOldRDN,
+ String newSuperior ) {
+ StringBuilder ldif = new StringBuilder();
+ ldif.append("dn: ").append(dn).append(EOL);
+ ldif.append("changetype: modrdn").append(EOL);
+ ldif.append("newrdn: ").append(newRDN).append(EOL);
+ ldif.append("deleteoldrdn: ").append(deleteOldRDN).append(EOL);
+ if(newSuperior != null)
+ ldif.append("newsuperior: ").append(newSuperior).append(EOL);
+ ldif.append(EOL);
+ return ldif.toString();
+ }
+
protected static String makeDelLDIF(String attr, String dn, String... acis) {
StringBuilder ldif = new StringBuilder();
ldif.append("dn: ").append(dn).append(EOL);
@@ -179,6 +348,16 @@
return ldif.toString();
}
+ protected static String
+ makeAddEntryLDIF(String dn, String ... lines) {
+ StringBuilder ldif = new StringBuilder();
+ ldif.append("dn: ").append(dn).append(EOL);
+ ldif.append("changetype: add").append(EOL);
+ for(String l : lines)
+ ldif.append(l).append(EOL);
+ ldif.append(EOL);
+ return ldif.toString();
+ }
protected static String makeAddLDIF(String attr, String dn, String... acis) {
StringBuilder ldif = new StringBuilder();
@@ -191,7 +370,7 @@
return ldif.toString();
}
- protected File getTemporaryLdifFile() throws IOException {
+ private File getTemporaryLdifFile() throws IOException {
Map<String,File> tempFilesForThisThread = tempLdifFile.get();
if (tempFilesForThisThread == null) {
tempFilesForThisThread = new HashMap<String,File>();
@@ -313,7 +492,7 @@
}
protected HashMap<String, String>
- getAttrMap(String resultString) throws Exception {
+ getAttrMap(String resultString) {
StringReader r=new StringReader(resultString);
BufferedReader br=new BufferedReader(r);
HashMap<String, String> attrMap = new HashMap<String,String>();
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTests.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTests.java
index e28169b..6c2f536 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTests.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTests.java
@@ -38,6 +38,7 @@
import org.opends.server.util.LDIFReader;
import org.opends.server.util.LDIFWriter;
import static org.opends.server.config.ConfigConstants.*;
+import static org.opends.server.util.ServerConstants.*;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
@@ -307,6 +308,12 @@
//The ACIs for the proxy tests.
+
+ private static final String ALLOW_PROXY_CONTROL_TO_LEVEL_1=
+ buildAciValue("name", "allow proxy control", "targetcontrol",
+ OID_PROXIED_AUTH_V2, "allow(read)",
+ BIND_RULE_USERDN_LEVEL_1);
+
private static final String ALLOW_PROXY_TO_IMPORT_MGR_NEW =
buildAciValue("name", "allow proxy import new mgr new tree", "target",
MGR_NEW_DN_URL, "allow(import)", BIND_RULE_USERDN_PROXY);
@@ -1050,22 +1057,46 @@
GLOBAL_ALLOW_MONITOR_TO_ADMIN_ACI,
GLOBAL_ALLOW_BASE_DN_TO_LEVEL_1_ACI);
- //Global defauls
-private static final String GLOBAL_ANONYMOUS_READ_ACI =
- buildGlobalAciValue("name", "Anonymous read access", "targetattr!=",
- "userPassword||authPassword",
- "allow(read, search, compare)", BIND_RULE_USERDN_ANYONE);
+ //Global defaults
+ private static final String GLOBAL_ANONYMOUS_READ_ACI =
+ buildGlobalAciValue("name", "Anonymous read access", "targetattr!=",
+ "userPassword||authPassword",
+ "allow(read, search, compare)", BIND_RULE_USERDN_ANYONE);
-private static final String GLOBAL_SELF_WRITE_ACI =
- buildGlobalAciValue("name", "Self entry modification", "targetattr",
- "*",
- "allow(write)", BIND_RULE_USERDN_SELF);
+ private static final String GLOBAL_SELF_WRITE_ACI =
+ buildGlobalAciValue("name", "Self entry modification", "targetattr",
+ "*",
+ "allow(write)", BIND_RULE_USERDN_SELF);
+ private static final String GLOBAL_SCHEMA_ACI =
+ buildGlobalAciValue("name", "User-Visible Schema Operational Attributes",
+ "target", "ldap:///cn=schema", "targetscope", "base",
+ "targetattr",
+ "attributeTypes||dITContentRules||dITStructureRules||ldapSyntaxes||matchingRules||matchingRuleUse||nameForms||objectClasses",
+ "allow(read, search, compare)", BIND_RULE_USERDN_ANYONE);
-private static final String GLOBAL_DEFAULT_ACIS =
+ private static final String GLOBAL_DSE_ACI = buildGlobalAciValue(
+ "name","User-Visible Root DSE Operational Attributes",
+ "target", "ldap:///", "targetscope", "base",
+ "targetattr",
+ "namingContexts||supportedAuthPasswordSchemes||supportedControl||supportedExtension||supportedFeatures||supportedSASLMechanisms||vendorName||vendorVersion",
+ "allow(read, search, compare)",BIND_RULE_USERDN_ANYONE);
+
+ private static final String GLOBAL_USER_OP_ATTRS_ACI = buildGlobalAciValue(
+ "name", "User-Visible Operational Attributes", "targetattr",
+ "createTimestamp||creatorsName||modifiersName||modifyTimestamp||entryDN||entryUUID||subschemaSubentry",
+ "allow(read, search, compare)", BIND_RULE_USERDN_ANYONE);
+
+ private static final String GLOBAL_CONTROL_ACI = buildGlobalAciValue(
+ "name", "Control", "targetcontrol", "*",
+ "allow(read)", BIND_RULE_USERDN_ANYONE);
+
+ private static final String GLOBAL_DEFAULT_ACIS =
makeAttrAddAciLdif(ATTR_AUTHZ_GLOBAL_ACI,ACCESS_HANDLER_DN,
GLOBAL_ANONYMOUS_READ_ACI,
- GLOBAL_SELF_WRITE_ACI);
+ GLOBAL_SELF_WRITE_ACI, GLOBAL_SCHEMA_ACI,
+ GLOBAL_DSE_ACI, GLOBAL_USER_OP_ATTRS_ACI,
+ GLOBAL_CONTROL_ACI);
//ACI used to test LDAP compare.
private static final
@@ -1102,6 +1133,10 @@
private static final String ACI_PROXY_IMPORT_MGR_NEW =
makeAddAciLdif(OU_BASE_DN, ALLOW_PROXY_TO_IMPORT_MGR_NEW);
+
+private static final String ACI_PROXY_CONTROL_LEVEL_1 =
+ makeAddAciLdif(OU_BASE_DN, ALLOW_PROXY_CONTROL_TO_LEVEL_1);
+
private static final String ACI_PROXY_IMPORT_MGR =
makeAddAciLdif(OU_BASE_DN, ALLOW_PROXY_TO_IMPORT_MGR);
@@ -1769,6 +1804,7 @@
try {
addEntries(BASIC_LDIF__GROUP_SEARCH_TESTS, DIR_MGR_DN, DIR_MGR_PW);
modEntries(ACI_PROXY_IMPORT_MGR, DIR_MGR_DN, DIR_MGR_PW);
+ modEntries(ACI_PROXY_CONTROL_LEVEL_1, DIR_MGR_DN, DIR_MGR_PW);
modEntries(ACI_PROXY_IMPORT_MGR_NEW, DIR_MGR_DN, DIR_MGR_PW);
modEntries(ACI_PROXY_EXPORT_MGR, DIR_MGR_DN, DIR_MGR_PW);
modEntries(ACI_PROXY_EXPORT_MGR_NEW, DIR_MGR_DN, DIR_MGR_PW);
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AlternateRootDN.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AlternateRootDN.java
index 4fa4562..b6e40c1 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AlternateRootDN.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AlternateRootDN.java
@@ -32,6 +32,7 @@
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import org.testng.annotations.AfterClass;
import org.testng.Assert;
import org.opends.server.TestCaseUtils;
import static org.opends.server.config.ConfigConstants.*;
@@ -55,11 +56,17 @@
"(version 3.0; acl \"proxy" + user3 + "\";" +
"allow (proxy) userdn=\"ldap:///" + user3 + "\";)";
+ //Need an ACI to allow proxy control
+ String controlACI = "(targetcontrol=\"" + OID_PROXIED_AUTH_V2 + "\")" +
+ "(version 3.0; acl \"control\";" +
+ "allow(read) userdn=\"ldap:///" + user3 + "\";)";
+
private static final
String rootDNACI= "(targetattr=\"" + ATTR_USER_PASSWORD + "\")" +
"(version 3.0; acl \"pwd search, read " + rootDN + "\";" +
"allow(read, search) userdn=\"ldap:///" + rootDN + "\";)";
+
@BeforeClass
public void setupClass() throws Exception {
TestCaseUtils.startServer();
@@ -68,6 +75,13 @@
addRootEntry();
}
+ @AfterClass
+ public void tearDown() throws Exception {
+ String aciLdif=makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN,
+ G_READ_ACI, G_SELF_MOD, G_SCHEMA, G_DSE, G_USER_OPS, G_CONTROL);
+ LDIFModify(aciLdif, DIR_MGR_DN, PWD);
+ }
+
/**
* This test uses an ACI allowing access to the userPassword attribute, based
@@ -117,7 +131,7 @@
*/
@Test()
public void testAlternateProxyDNs() throws Exception {
- String aciLdif=makeAddLDIF("aci", user1, rootDNACI, proxyACI);
+ String aciLdif=makeAddLDIF("aci", user1, rootDNACI, proxyACI, controlACI);
LDIFModify(aciLdif, DIR_MGR_DN, PWD);
String adminDNResults =
LDAPSearchParams(user3, PWD, adminDN, null, null,
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/GetEffectiveRightsTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/GetEffectiveRightsTestCase.java
index 2d5af24..73cd2dd 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/GetEffectiveRightsTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/GetEffectiveRightsTestCase.java
@@ -30,10 +30,12 @@
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.AfterClass;
import static org.opends.server.config.ConfigConstants.*;
import org.testng.Assert;
import org.opends.server.TestCaseUtils;
import static org.opends.server.util.ServerConstants.OID_GET_EFFECTIVE_RIGHTS;
+
import java.util.HashMap;
public class GetEffectiveRightsTestCase extends AciTestCase {
@@ -86,6 +88,12 @@
"selfwrite_add:1,selfwrite_delete:1,proxy:0";
//ACI needed to search/read aciRights attribute.
+
+ //Need an ACI to allow proxy control
+ String controlACI = "(targetcontrol=\"" + OID_GET_EFFECTIVE_RIGHTS + "\")" +
+ "(version 3.0; acl \"control\";" +
+ "allow(read) userdn=\"ldap:///anyone\";)";
+
private static final
String aclRightsAci = "(targetattr=\"aclRights\")" +
"(version 3.0;acl \"aclRights access\";" +
@@ -160,10 +168,17 @@
addEntries();
}
- @BeforeMethod
- public void removeAcis() throws Exception {
+ @AfterClass
+ public void tearDown() throws Exception {
+ String aciLdif=makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN,
+ G_READ_ACI, G_SELF_MOD, G_SCHEMA, G_DSE, G_USER_OPS, G_CONTROL);
+ LDIFModify(aciLdif, DIR_MGR_DN, PWD);
+ }
+
+ @BeforeMethod
+ public void removeAcis() throws Exception {
deleteAttrFromEntry("ou=People,o=test", "aci");
- }
+ }
/**
* Test entry level using the -g param and anonymous dn as the authzid.
@@ -172,7 +187,8 @@
*/
@Test()
public void testAnonEntryLevelParams() throws Exception {
- String aciLdif=makeAddLDIF("aci", "ou=People,o=test", readSearchAnonAci);
+ String aciLdif=makeAddLDIF("aci", "ou=People,o=test", readSearchAnonAci,
+ controlACI);
LDIFModify(aciLdif, DIR_MGR_DN, PWD);
String userResults =
LDAPSearchParams(DIR_MGR_DN, PWD, null, "dn:", null,
@@ -190,7 +206,8 @@
*/
@Test()
public void testSuEntryLevelParams() throws Exception {
- String aciLdif=makeAddLDIF("aci", "ou=People,o=test", aclRightsAci);
+ String aciLdif=makeAddLDIF("aci", "ou=People,o=test", aclRightsAci,
+ controlACI);
LDIFModify(aciLdif, DIR_MGR_DN, PWD);
aciLdif=makeAddLDIF("aci", "ou=People,o=test", readSearchAci);
LDIFModify(aciLdif, DIR_MGR_DN, PWD);
@@ -242,7 +259,8 @@
*/
@Test()
public void testSuEntryLevelCtrl() throws Exception {
- String aciLdif=makeAddLDIF("aci", "ou=People,o=test", aclRightsAci);
+ String aciLdif=makeAddLDIF("aci", "ou=People,o=test", aclRightsAci,
+ controlACI);
LDIFModify(aciLdif, DIR_MGR_DN, PWD);
aciLdif=makeAddLDIF("aci", "ou=People,o=test", readSearchAci);
LDIFModify(aciLdif, DIR_MGR_DN, PWD);
@@ -294,6 +312,8 @@
*/
@Test()
public void testBypassEntryLevelCtrl() throws Exception {
+ String aciLdif=makeAddLDIF("aci", "ou=People,o=test", controlACI);
+ LDIFModify(aciLdif, DIR_MGR_DN, PWD);
String userResults =
LDAPSearchCtrl(DIR_MGR_DN, PWD, null, OID_GET_EFFECTIVE_RIGHTS,
base, filter, "aclRights");
@@ -311,7 +331,8 @@
*/
@Test()
public void testSuAttrLevelParams() throws Exception {
- String aciLdif=makeAddLDIF("aci", "ou=People,o=test", aclRightsAci);
+ String aciLdif=makeAddLDIF("aci", "ou=People,o=test", aclRightsAci,
+ controlACI);
LDIFModify(aciLdif, DIR_MGR_DN, PWD);
aciLdif=makeAddLDIF("aci", "ou=People,o=test", readSearchAci);
LDIFModify(aciLdif, DIR_MGR_DN, PWD);
@@ -337,7 +358,8 @@
*/
@Test()
public void testSuAttrLevelParams2() throws Exception {
- String aciLdif=makeAddLDIF("aci", "ou=People,o=test", aclRightsAci);
+ String aciLdif=makeAddLDIF("aci", "ou=People,o=test", aclRightsAci,
+ controlACI);
LDIFModify(aciLdif, DIR_MGR_DN, PWD);
aciLdif=makeAddLDIF("aci", "ou=People,o=test", readSearchAci);
LDIFModify(aciLdif, DIR_MGR_DN, PWD);
@@ -369,7 +391,8 @@
*/
@Test()
public void testSuAttrLevelParams3() throws Exception {
- String aciLdif=makeAddLDIF("aci", "ou=People,o=test", aclRightsAci);
+ String aciLdif=makeAddLDIF("aci", "ou=People,o=test", aclRightsAci,
+ controlACI);
LDIFModify(aciLdif, DIR_MGR_DN, PWD);
aciLdif=makeAddLDIF("aci", "ou=People,o=test", readSearchAci);
LDIFModify(aciLdif, DIR_MGR_DN, PWD);
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java
index ae2e545..e8969e4 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java
@@ -29,6 +29,7 @@
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import org.testng.annotations.AfterClass;
import org.testng.Assert;
import org.opends.server.TestCaseUtils;
import static org.opends.server.config.ConfigConstants.*;
@@ -125,6 +126,14 @@
addEntries();
}
+ @AfterClass
+ public void tearDown() throws Exception {
+ String aciLdif=makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN,
+ G_READ_ACI, G_SELF_MOD, G_SCHEMA, G_DSE, G_USER_OPS, G_CONTROL);
+ LDIFModify(aciLdif, DIR_MGR_DN, PWD);
+ }
+
+
/**
* Test targetattr behavior using userattr bind rule.
*
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetControlTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetControlTestCase.java
new file mode 100644
index 0000000..81e47c4
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetControlTestCase.java
@@ -0,0 +1,342 @@
+/*
+ * 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
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+
+package org.opends.server.authorization.dseecompat;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.AfterClass;
+import org.opends.server.TestCaseUtils;
+import org.opends.server.protocols.ldap.LDAPResultCode;
+import static org.opends.server.util.ServerConstants.*;
+import static org.opends.server.config.ConfigConstants.ATTR_AUTHZ_GLOBAL_ACI;
+
+/**
+ * Unit test to test the targetcontrol ACI keyword.
+ */
+public class TargetControlTestCase extends AciTestCase {
+
+ private static final String superUser="uid=superuser,ou=admins,o=test";
+ private static final String level3User="uid=user.3,ou=People,o=test";
+ private static final String newPWD="newPWD";
+
+
+ private static final String level1User="uid=user.1,ou=People,o=test";
+ private static final String base="uid=user.3,ou=People,o=test";
+ private static final String newRDN = "uid=user.3x";
+ private static final String newSup="ou=new,o=test";
+ private static final String newDN="uid=user.4," + base;
+
+ private static final String peopleBase="ou=People,o=test";
+ private static final String adminBase="ou=Admins,o=test";
+ private static final String newPeopleDN="uid=user.4," + peopleBase;
+ private static final String newAdminDN="uid=user.4," + adminBase;
+
+
+ @BeforeClass
+ public void setupClass() throws Exception {
+ TestCaseUtils.startServer();
+ deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
+ addEntries();
+ }
+
+ @AfterClass
+ public void tearDown() throws Exception {
+ String aciLdif=makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN,
+ G_READ_ACI, G_SELF_MOD, G_SCHEMA, G_DSE, G_USER_OPS, G_CONTROL);
+ LDIFModify(aciLdif, DIR_MGR_DN, PWD);
+ }
+
+ private static final String[] newEntry = new String[] {
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: john.doe",
+ "givenName: John",
+ "sn: Doe",
+ "cn: John Doe",
+ "mail: john.doe@example.com",
+ "userPassword: password",
+ };
+
+ //Valid targetcontrol statements. Not the complete ACI.
+ @DataProvider(name = "validStatements")
+ public Object[][] valids() {
+ return new Object[][] {
+ {"1.3.6.1.4.1.42.2.27.8.5.1"},
+ {"2.16.840.1.113730.3.4.18"},
+ {"*"},
+ };
+ }
+
+ //Invalid targetcontrol statements. Not the complete ACI.
+ @DataProvider(name = "invalidStatements")
+ public Object[][] invalids() {
+ return new Object[][] {
+ {"1.3.6.1.4.1.42.2.27..8.5.1"},
+ {"2.16.840.1.113730.3.XXX.18"},
+ {"2.16.840.1.113730.*.4.18"},
+ {"2.16.840,1.113730.3.4.18"},
+ {"+"},
+ };
+ }
+
+ private static final
+ String ALLOW_ALL = "(targetattr=\"*\")" +
+ "(version 3.0;acl \"aclRights access\";" +
+ "allow (all) " +
+ "userdn=\"ldap:///self\";)";
+
+ private static final
+ String aclRightsAci = "(targetattr=\"aclRights\")" +
+ "(version 3.0;acl \"aclRights access\";" +
+ "allow (search, read) " +
+ "userdn=\"ldap:///uid=superuser,ou=admins,o=test\";)";
+
+ //Disallow all controls with wild-card.
+ private static final
+ String controlNotWC = "(targetcontrol!=\"" + "*" + "\")" +
+ "(version 3.0; acl \"control\";" +
+ "allow(read) userdn=\"ldap:///" + superUser + "\";)";
+
+ //Allow all controls with wild-card.
+ private static final
+ String controlWC = "(targetcontrol=\"" + "*" + "\")" +
+ "(version 3.0; acl \"control\";" +
+ "allow(read) userdn=\"ldap:///" + superUser + "\";)";
+
+ //People branch can do any control but geteffectiverights assertion control.
+ private static final
+ String controlPeople = "(targetcontrol!=\"" +
+ OID_GET_EFFECTIVE_RIGHTS + "\")" +
+ "(target=\"ldap:///" + peopleBase + "\")" +
+ "(version 3.0; acl \"control\";" +
+ "allow(read) userdn=\"ldap:///" + "anyone" + "\";)";
+
+ //Admin branch can only do geteffectiverights control.
+ private static final
+ String controlAdmin = "(targetcontrol=\"" + OID_GET_EFFECTIVE_RIGHTS + "\")" +
+ "(target=\"ldap:///" + adminBase + "\")" +
+ "(version 3.0; acl \"control\";" +
+ "allow(read) userdn=\"ldap:///" + "anyone" + "\";)";
+
+ //Allow either reportauthzID or passwordpolicy controls. Used in the
+ //bind tests.
+ private static final
+ String pwdControls =
+ "(targetcontrol=\"" + OID_AUTHZID_REQUEST + "||" +
+ OID_PASSWORD_POLICY_CONTROL + "\")" +
+ "(version 3.0; acl \"control\";" +
+ "allow(read) userdn=\"ldap:///" + "anyone" + "\";)";
+
+
+ //Allow either no-op or passwordpolicy controls. Used in the
+ //ext op tests.
+ private static final
+ String extOpControls =
+ "(targetcontrol=\"" + OID_LDAP_NOOP_OPENLDAP_ASSIGNED + "||" +
+ OID_PASSWORD_POLICY_CONTROL + "\")" +
+ "(version 3.0; acl \"control\";" +
+ "allow(read) userdn=\"ldap:///" + "anyone" + "\";)";
+
+
+ /**
+ * Test valid targetcontrol statements.
+ *
+ * @param statement The targetcontrol statement to attempt to decode.
+ * @throws AciException If an unexpected result happens.
+ */
+ @Test(dataProvider = "validStatements")
+ public void testValidStatements(String statement) throws AciException {
+ TargetControl.decode(EnumTargetOperator.EQUALITY, statement);
+ }
+
+ /**
+ * Test invalid targetcontrol statements.
+ *
+ * @param statement The targetcontrol statement to attempt to decode.
+ * @throws Exception If an unexpected result happens.
+ */
+ @Test(expectedExceptions= AciException.class, dataProvider="invalidStatements")
+ public void testInvalidStatements(String statement) throws Exception {
+ try {
+ TargetControl.decode(EnumTargetOperator.EQUALITY,statement);
+ } catch (AciException e) {
+ throw e;
+ } catch (Exception e) {
+ System.out.println(
+ "Invalid targetcontrol <" + statement +
+ "> threw wrong exception type.");
+ throw e;
+ }
+ throw new RuntimeException(
+ "Invalid targetcontrol <" + statement +
+ "> did not throw an exception.");
+ }
+
+ /**
+ * Test access to extended op controls (no-op and userPasswordPolicy).
+ *
+ * @throws Exception If an unexpected result is returned.
+ */
+ @Test()
+ public void testExtendOpControls() throws Exception {
+ String pwdLdifs =
+ makeAddLDIF("aci", peopleBase, extOpControls, ALLOW_ALL);
+ LDIFModify(pwdLdifs, DIR_MGR_DN, PWD);
+ String noOpCtrlStr=OID_LDAP_NOOP_OPENLDAP_ASSIGNED + ":true";
+ //This pwd change should return no-op since the no-op control is
+ //specified and it is allowed for authorization dn.
+ pwdModify(level3User, PWD, newPWD, noOpCtrlStr, null,
+ LDAPResultCode.NO_OPERATION);
+ //This pwd change should fail even though the no-op is specified, since
+ //since the no-op control is not allowed for this authorization dn.
+ pwdModify(superUser, PWD, newPWD, noOpCtrlStr, null,
+ LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+ deleteAttrFromEntry(peopleBase, "aci");
+ }
+
+ /**
+ * Test access to bind controls (reportAuthzID and usePasswordPolicy).
+ *
+ * @throws Exception If an unexpected result is returned.
+ */
+ @Test()
+ public void testBindControl() throws Exception {
+ String pwdLdifs =
+ makeAddLDIF("aci", peopleBase, pwdControls, ALLOW_ALL);
+ LDIFModify(pwdLdifs, DIR_MGR_DN, PWD);
+ //The bind operation control access is based on the bind DN so this
+ //should succeed since both pwd policy and authzID control are allowed on
+ //ou=people, o=test suffix.
+ LDAPSearchParams(level3User, PWD, null, null, null,
+ superUser, filter, "aclRights mail description", true,
+ false, 0);
+ LDAPSearchParams(level3User, PWD, null, null, null,
+ superUser, filter, "aclRights mail description", true,
+ true, 0);
+ //This should fail since the both controls are not allowed for the
+ //ou=admins, o=test suffix.
+ LDAPSearchParams(superUser, PWD, null, null, null,
+ superUser, filter, "aclRights mail description", true,
+ true, LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+ deleteAttrFromEntry(peopleBase, "aci");
+ }
+
+ /**
+ * Test target from global ACI level. Two global ACIs are added, one allowing
+ * all controls except geteffective rights to the ou=people, o=test
+ * suffix. The other ACI only allows the geteffectiverights control on
+ * the ou=admin, o=test suffix. Comments in method should explain more
+ * what operations and controls are attempted.
+ *
+ * @throws Exception If an unexpected result happens.
+ */
+ @Test()
+ public void testGlobalTargets() throws Exception {
+ String globalControlAcis=
+ makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN,
+ controlAdmin, controlPeople);
+ LDIFModify(globalControlAcis, DIR_MGR_DN, PWD);
+ //Fails because geteffectiverights control not allowed on
+ //ou=people, o=test
+ LDAPSearchParams(level3User, PWD, null,
+ "dn: " + level1User, null,
+ level1User, filter, "aclRights mail description",
+ false, false, LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+ //Ok because geteffectiverights control is allowed on
+ //ou=admin, o=test
+ LDAPSearchParams(level3User, PWD, null,
+ "dn: " + level1User, null,
+ superUser, filter, "aclRights mail description",
+ false, false, 0);
+ String controlStr=OID_LDAP_ASSERTION + ":true:junk";
+ //Test add to ou=people, o=test with assertion control,
+ //should get protocol error since this control is allowed but value is
+ //junk.
+ String addEntryLDIF=makeAddEntryLDIF(newPeopleDN, newEntry);
+ LDIFAdd(addEntryLDIF, superUser, PWD, controlStr,
+ LDAPResultCode.PROTOCOL_ERROR);
+ //Test add to ou=admin, o=test with assertion control,
+ //should get access denied since this control is not allowed.
+ String addEntryLDIF1=makeAddEntryLDIF(newAdminDN, newEntry);
+ LDIFAdd(addEntryLDIF1, superUser, PWD, controlStr,
+ LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+ deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
+ }
+
+
+ /**
+ * Test wildcard access. First test "targetcontrol != *"
+ * expression. Should all be access denied. Remove that ACI and add
+ * "targetcontrol = *" expression. Use assertion control with bad filter,
+ * all should return protocol error (modify, add, delete, modifyDN). Search
+ * with geteffectiverights should succeed.
+ *
+ * @throws Exception If an unexpected result happens.
+ */
+ @Test()
+ public void testWildCard() throws Exception {
+
+ String aciDeny=makeAddLDIF("aci", base, controlNotWC);
+ String aciRight=makeAddLDIF("aci", base, aclRightsAci);
+ LDIFModify(aciDeny, DIR_MGR_DN, PWD);
+ LDAPSearchParams(superUser, PWD, null,
+ "dn: " + superUser, null,
+ base, filter, "aclRights mail description", false, false,
+ LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+ LDIFModify(aciRight, superUser, PWD, OID_LDAP_READENTRY_PREREAD,
+ LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS);
+ deleteAttrFromEntry (base, "aci");
+ String aciAllow=makeAddLDIF("aci", base, controlWC, ALLOW_ALL);
+ LDIFModify(aciAllow, DIR_MGR_DN, PWD);
+ //Search with geteffectiverights control.
+ LDAPSearchParams(superUser, PWD, null,
+ "dn: " + superUser, null,
+ base, filter, "aclRights mail description");
+ String controlStr=OID_LDAP_ASSERTION + ":true:junk";
+ //Attempt modify. Protocol error means we passed access control
+ LDIFModify(aciRight, superUser, PWD, controlStr ,
+ LDAPResultCode.PROTOCOL_ERROR);
+ //Attempt add, protocol error means we passed access control
+ String addEntryLDIF=makeAddEntryLDIF(newDN, newEntry);
+ LDIFAdd(addEntryLDIF, superUser, PWD, controlStr,
+ LDAPResultCode.PROTOCOL_ERROR);
+ //Attempt delete. Protocol error means we passed access control.
+ LDIFDelete(base, superUser, PWD, controlStr,
+ LDAPResultCode.PROTOCOL_ERROR);
+ String modDNLDIF=makeModDNLDIF(base, newRDN , "0", newSup);
+ //Attempt modify DN. Protocol error means we passed access control.
+ LDIFModify(modDNLDIF, superUser, PWD, controlStr ,
+ LDAPResultCode.PROTOCOL_ERROR);
+ deleteAttrFromEntry(base, "aci");
+ }
+}
+
--
Gitblit v1.10.0