Add new ACI keyword "extop" that can be used to enforce access
based on the OID of an extended operation. For example, a new global
access extended operation rule is also being added:
ds-cfg-global-aci:
(extop="1.3.6.1.4.1.26027.1.6.1 || 1.3.6.1.4.1.4203.1.11.1 || 1.3.6.1.4.1.1466.20037 || 1.3.6.1.4.1.4203.1.11.3")
(version 3.0; acl "Anonymous extended operation access"; allow(read) userdn="ldap:///anyone";)
which allows anonymous access to the following extended operations:
- StartTLS 1.3.6.1.4.1.1466.20037
- password policy state 1.3.6.1.4.1.26027.1.6.1
- password modify 1.3.6.1.4.1.4203.1.11.1
- Who Am I 1.3.6.1.4.1.4203.1.11.3
A wildcard can also be specified:
aci: (extop="*")(version 3.0; acl "Anonymous extended operation access"; allow(read) userdn="ldap:///anyone";)
Issue #443.
2 files added
18 files modified
| | |
| | | objectClass: top |
| | | objectClass: ds-cfg-access-control-handler |
| | | objectClass: ds-cfg-dseecompat-access-control-handler |
| | | ds-cfg-global-aci: (extop="1.3.6.1.4.1.26027.1.6.1 || 1.3.6.1.4.1.4203.1.11.1 || 1.3.6.1.4.1.1466.20037 || 1.3.6.1.4.1.4203.1.11.3") (version 3.0; acl "Anonymous extended operation access"; allow(read) userdn="ldap:///anyone";) |
| | | 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: (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";) |
| | |
| | | public static final int TARGATTRFILTERS_DELETE = 0x2000; |
| | | |
| | | /** |
| | | * Used by the control evaluation access check. |
| | | */ |
| | | public static final int ACI_CONTROL = 0x4000; |
| | | |
| | | /** |
| | | * Used by the extended operation access check. |
| | | */ |
| | | public static final int ACI_EXT_OP = 0x8000; |
| | | |
| | | /** |
| | | * ACI_ATTR_STAR_MATCHED is the flag set when the evaluation reason of a |
| | | * AciHandler.maysend ACI_READ access evaluation was the result of an |
| | | * ACI targetattr all attributes expression (targetattr="*") target match. |
| | |
| | | |
| | | /** |
| | | * Test if the given ACI is applicable using the target match information |
| | | * provided. The ACI target can have four keywords at this time: |
| | | * provided. The ACI target can have seven keywords at this time: |
| | | * |
| | | * These two base decision on the resource entry DN: |
| | | * |
| | | * 1. target - checked in isTargetApplicable. |
| | | * 2. targetscope - checked in isTargetApplicable. |
| | | * |
| | | * These three base decision on resource entry attributes: |
| | | * |
| | | * 3. targetfilter - checked in isTargetFilterApplicable. |
| | | * 4. targetattr - checked in isTargetAttrApplicable. |
| | | * 5. targattrfilters - checked in isTargAttrFiltersApplicable. |
| | | * |
| | | * One and two are checked for match first. If they return true, then |
| | | * three is checked. Lastly four is checked. |
| | | * These two base decisions on a resource entry built by the ACI handler |
| | | * that only contains a DN: |
| | | * 6. targetcontrol - check in isTargetControlApplicable. |
| | | * 7. extop - check in isExtOpApplicable. |
| | | * |
| | | * Six and seven are specific to the check being done: targetcontrol when a |
| | | * control is being evaluated and extop when an extended operation is |
| | | * evaluated. None of the attribute based keywords should be checked |
| | | * when a control or extended op is being evaluated, because one |
| | | * of those attribute keywords rule might incorrectly make an ACI |
| | | * applicable that shouldn't be. This can happen by erroneously basing |
| | | * their decision on the ACI handler generated stub resource entry. For |
| | | * example, a "(targetattr != userpassword)" rule would match the generated |
| | | * stub resource entry, even though a control or extended op might be |
| | | * denied. |
| | | * |
| | | * What is allowed is the target and targetscope keywords, since the DN is |
| | | * known, so they are checked along with the correct method for the access |
| | | * check (isTargetControlApplicable for control and |
| | | * isTExtOpApplicable for extended operations). See comments in code |
| | | * where these checks are done. |
| | | * |
| | | * @param aci The ACI to test. |
| | | * @param matchCtx The target matching context containing all the info |
| | |
| | | */ |
| | | public static boolean |
| | | isApplicable(Aci aci, AciTargetMatchContext matchCtx) { |
| | | int ctxRights=matchCtx.getRights(); |
| | | //First check if the ACI and context have similar rights. |
| | | if(matchCtx.hasRights(ACI_EXT_OP)) { |
| | | //Extended operation is being evaluated. |
| | | return AciTargets.isTargetApplicable(aci, matchCtx) && |
| | | AciTargets.isExtOpApplicable(aci, matchCtx); |
| | | } else if(matchCtx.hasRights(ACI_CONTROL)) { |
| | | //Control is being evaluated. |
| | | return AciTargets.isTargetApplicable(aci, matchCtx) && |
| | | AciTargets.isTargetControlApplicable(aci, matchCtx); |
| | | } else { |
| | | int ctxRights = matchCtx.getRights(); |
| | | //First check if the ACI and context have similar rights. |
| | | if(!aci.hasRights(ctxRights)) { |
| | | //TODO This check might be able to be removed further testing |
| | | // is needed. |
| | | if(!(aci.hasRights(ACI_SEARCH| ACI_READ) && |
| | | matchCtx.hasRights(ACI_SEARCH | ACI_READ))) |
| | | return false; |
| | | if(!(aci.hasRights(ACI_SEARCH| ACI_READ) && |
| | | matchCtx.hasRights(ACI_SEARCH | ACI_READ))) |
| | | return false; |
| | | } |
| | | return AciTargets.isTargetApplicable(aci, matchCtx) && |
| | | AciTargets.isTargetControlApplicable(aci, matchCtx) && |
| | | AciTargets.isTargetFilterApplicable(aci, matchCtx) && |
| | | AciTargets.isTargAttrFiltersApplicable(aci, matchCtx) && |
| | | AciTargets.isTargetAttrApplicable(aci, matchCtx); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | private int evalAllAttributes=0; |
| | | |
| | | /* |
| | | * String used to hold a control OID string. |
| | | */ |
| | | * String used to hold a control OID string. |
| | | */ |
| | | private String controlOID; |
| | | |
| | | /* |
| | | * String used to hold an extended operation OID string. |
| | | */ |
| | | private String extOpOID; |
| | | |
| | | /** |
| | | * This constructor is used by all currently supported LDAP operations. |
| | | * |
| | |
| | | return controlOID; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String getExtOpOID() { |
| | | return extOpOID; |
| | | } |
| | | |
| | | /** |
| | | * Set the the controlOID value to the specified oid string. |
| | | * |
| | |
| | | this.controlOID=oid; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Set the extended operation OID value to the specified oid string. |
| | | * |
| | | * @param oid The extended operation oid string. |
| | | */ |
| | | protected void setExtOpOID(String oid) { |
| | | this.extOpOID=oid; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | |
| | | if(!(ret=skipAccessCheck(op))) { |
| | | Entry e = new Entry(entryDN, null, null, null); |
| | | AciLDAPOperationContainer operationContainer = |
| | | new AciLDAPOperationContainer(op, e, control.getOID()); |
| | | new AciLDAPOperationContainer(op, e, control, |
| | | (ACI_READ | ACI_CONTROL)); |
| | | ret=accessAllowed(operationContainer); |
| | | } |
| | | if(control.getOID().equals(OID_PROXIED_AUTH_V2) || |
| | |
| | | return ret; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isAllowed(ExtendedOperation operation) { |
| | | boolean ret; |
| | | if(!(ret=skipAccessCheck(operation))) { |
| | | Entry e = new Entry(operation.getAuthorizationDN(), null, null, null); |
| | | AciLDAPOperationContainer operationContainer = |
| | | new AciLDAPOperationContainer(operation, e, (ACI_READ | ACI_EXT_OP)); |
| | | ret=accessAllowed(operationContainer); |
| | | } |
| | | if(operation.getRequestOID().equals(OID_PROXIED_AUTH_V2) || |
| | | operation.getRequestOID().equals(OID_PROXIED_AUTH_V1)) |
| | | operation. |
| | | setAttachment(ORIG_AUTH_ENTRY, operation.getAuthorizationEntry()); |
| | | return ret; |
| | | } |
| | | |
| | | |
| | | //Not planned to be implemented methods. |
| | | |
| | | /** |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isAllowed(ExtendedOperation extendedOperation) { |
| | | //Not planned to be implemented. |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isAllowed(LocalBackendSearchOperation searchOperation) { |
| | | //Not planned to be implemented. |
| | | return true; |
| | |
| | | import org.opends.server.core.*; |
| | | 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 |
| | |
| | | } |
| | | |
| | | /** |
| | | * Constructor interface for control evaluation. |
| | | * Constructor interface for evaluation of a control. |
| | | * |
| | | * @param operation The operation to evaluate. |
| | | * @param e An entry built especially for control evaluation. |
| | | * @param oid The control's oid string. |
| | | * @param operation The operation to use in the evaluation. |
| | | * @param e An entry built especially for evaluation. |
| | | * @param c The control to evaluate. |
| | | * @param rights The rights of a control. |
| | | */ |
| | | public AciLDAPOperationContainer(Operation operation, Entry e, String oid) { |
| | | super(operation, (ACI_READ), e ); |
| | | setControlOID(oid); |
| | | public AciLDAPOperationContainer(Operation operation, Entry e, Control c, |
| | | int rights) { |
| | | super(operation, rights, e ); |
| | | setControlOID(c.getOID()); |
| | | } |
| | | |
| | | /** |
| | | * Constructor interface for evaluation of the extended operation. |
| | | * |
| | | * @param operation The extended operation to evaluate. |
| | | * @param e An entry built especially for evaluation. |
| | | * @param rights The rights of a extended operation. |
| | | */ |
| | | public AciLDAPOperationContainer(ExtendedOperation operation, Entry e, |
| | | int rights) { |
| | | super(operation, rights, e ); |
| | | setExtOpOID(operation.getRequestOID()); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | public int getRights(); |
| | | |
| | | /** |
| | | * Return the oid string of the control being evaluated. |
| | | * |
| | | * @return The oid string of the control being evaluated. |
| | | */ |
| | | public String getControlOID(); |
| | | /** |
| | | * Return the OID (Object Identifier) string of the control being evaluated. |
| | | * |
| | | * @return The OID string of the control being evaluated. |
| | | */ |
| | | public String getControlOID(); |
| | | |
| | | |
| | | /** |
| | | * Return The OID (Object Identifier) string of the extended operation being |
| | | * evaluated. |
| | | * |
| | | * @return The OID string of the extended operation being evaluated. |
| | | */ |
| | | public String getExtOpOID(); |
| | | |
| | | /** |
| | | * Checks if the container's rights has the specified rights. |
| | |
| | | * of an ACI before the ACI body and specifies the entry, attributes, or set |
| | | * of entries and attributes which the ACI controls access. |
| | | * |
| | | * The five supported ACI target keywords are: target, targetattr, |
| | | * targetscope, targetfilter and targattrfilters. |
| | | * The supported ACI target keywords are: target, targetattr, |
| | | * targetscope, targetfilter, targattrfilters, targetcontrol and extop. |
| | | */ |
| | | public class AciTargets { |
| | | |
| | |
| | | */ |
| | | private TargetControl targetControl=null; |
| | | |
| | | /** |
| | | * The ACI syntax has a extop keyword. |
| | | */ |
| | | private ExtOp extOp=null; |
| | | |
| | | /* |
| | | * The number of regular expression group positions in a valid ACI target |
| | | * expression. |
| | |
| | | |
| | | /** |
| | | * Creates an ACI target from the specified arguments. All of these |
| | | * may be null -- the ACI has no targets an will use defaults. |
| | | * @param targetEntry The ACI target keyword if any. |
| | | * @param targetAttr The ACI targetattr keyword if any. |
| | | * @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. |
| | | * may be null. If the ACI has no targets defaults will be used. |
| | | * |
| | | * @param targetEntry The ACI target keyword class. |
| | | * @param targetAttr The ACI targetattr keyword class. |
| | | * @param targetFilter The ACI targetfilter keyword class. |
| | | * @param targetScope The ACI targetscope keyword class. |
| | | * @param targAttrFilters The ACI targAttrFilters keyword class. |
| | | * @param targetControl The ACI targetControl keyword class. |
| | | * @param extOp The ACI extop keyword class. |
| | | */ |
| | | private AciTargets(Target targetEntry, TargetAttr targetAttr, |
| | | TargetFilter targetFilter, |
| | | SearchScope targetScope, |
| | | TargAttrFilters targAttrFilters, |
| | | TargetControl targetControl) { |
| | | TargetControl targetControl, |
| | | ExtOp extOp) { |
| | | this.target=targetEntry; |
| | | this.targetAttr=targetAttr; |
| | | this.targetScope=targetScope; |
| | | this.targetFilter=targetFilter; |
| | | this.targAttrFilters=targAttrFilters; |
| | | this.targetControl=targetControl; |
| | | this.extOp=extOp; |
| | | } |
| | | |
| | | /** |
| | |
| | | return targetControl; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Return the class representing the ACI extop keyword. May be |
| | | * null. |
| | | * @return The extop information. |
| | | */ |
| | | public ExtOp getExtOp() { |
| | | return extOp; |
| | | } |
| | | |
| | | /** |
| | | * Decode an ACI's target part of the syntax from the string provided. |
| | | * @param input String representing an ACI target part of syntax. |
| | |
| | | TargetFilter targetFilter=null; |
| | | TargAttrFilters targAttrFilters=null; |
| | | TargetControl targetControl=null; |
| | | ExtOp extOp=null; |
| | | SearchScope targetScope=SearchScope.WHOLE_SUBTREE; |
| | | Pattern targetPattern = Pattern.compile(targetRegex); |
| | | Matcher targetMatcher = targetPattern.matcher(input); |
| | |
| | | } |
| | | case KEYWORD_TARGETCONTROL: |
| | | { |
| | | if (targetControl == null){ |
| | | targetControl = |
| | | TargetControl.decode(targetOperator, expression); |
| | | } |
| | | else |
| | | { |
| | | int msgID = |
| | | if (targetControl == null){ |
| | | targetControl = |
| | | TargetControl.decode(targetOperator, expression); |
| | | } |
| | | else |
| | | { |
| | | int msgID = |
| | | MSGID_ACI_SYNTAX_INVALID_TARGET_DUPLICATE_KEYWORDS; |
| | | String message = |
| | | String message = |
| | | getMessage(msgID, "targetcontrol", input); |
| | | throw new AciException(msgID, message); |
| | | } |
| | | break; |
| | | throw new AciException(msgID, message); |
| | | } |
| | | break; |
| | | } |
| | | case KEYWORD_EXTOP: |
| | | { |
| | | if (extOp == null){ |
| | | extOp = ExtOp.decode(targetOperator, expression); |
| | | } |
| | | else |
| | | { |
| | | int msgID = |
| | | MSGID_ACI_SYNTAX_INVALID_TARGET_DUPLICATE_KEYWORDS; |
| | | String message = |
| | | getMessage(msgID, "extop", input); |
| | | throw new AciException(msgID, message); |
| | | } |
| | | break; |
| | | } |
| | | case KEYWORD_TARGETATTR: |
| | | { |
| | |
| | | } |
| | | } |
| | | return new AciTargets(target, targetAttr, targetFilter, |
| | | targetScope, targAttrFilters, targetControl); |
| | | targetScope, targAttrFilters, targetControl, |
| | | extOp); |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * Checks an ACI's targetfilter information against a target match |
| | | * Checks an ACI's targetfilter rule information against a target match |
| | | * context. |
| | | * @param aci The ACI to try an match the targetfilter of. |
| | | * @param matchCtx The target match context containing information needed |
| | | * to perform a target match. |
| | | * @return True if the targetfilter matched the target context. |
| | | * @return True if the targetfilter rule matched the target context. |
| | | */ |
| | | public static boolean isTargetFilterApplicable(Aci aci, |
| | | AciTargetMatchContext matchCtx) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Check an ACI's targetcontrol against a target match context. |
| | | * Check an ACI's targetcontrol rule 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. |
| | | * @return True if the targetcontrol rule matched the target context. |
| | | */ |
| | | public static boolean isTargetControlApplicable(Aci aci, |
| | | AciTargetMatchContext matchCtx) { |
| | | boolean ret=true; |
| | | boolean ret=false; |
| | | TargetControl targetControl=aci.getTargets().getTargetControl(); |
| | | if(targetControl != null) |
| | | ret=targetControl.isApplicable(matchCtx); |
| | |
| | | } |
| | | |
| | | /** |
| | | * Check an ACI's targattrfilters against a target match context. |
| | | * Check an ACI's extop rule against a target match context. |
| | | * |
| | | * @param aci The ACI to match the extop rule against. |
| | | * @param matchCtx The target match context containing the information |
| | | * needed to perform the target match. |
| | | * @return True if the extop rule matched the target context. |
| | | */ |
| | | public static boolean isExtOpApplicable(Aci aci, |
| | | AciTargetMatchContext matchCtx) { |
| | | boolean ret=false; |
| | | ExtOp extOp=aci.getTargets().getExtOp(); |
| | | if(extOp != null) |
| | | ret=extOp.isApplicable(matchCtx); |
| | | return ret; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Check an ACI's targattrfilters rule against a target match context. |
| | | * |
| | | * @param aci The ACI to match the targattrfilters against. |
| | | * @param matchCtx The target match context containing the information |
| | | * needed to perform the target match. |
| | | * @return True if the targattrfilters matched the target context. |
| | | * @return True if the targattrfilters rule matched the target context. |
| | | */ |
| | | public static boolean isTargAttrFiltersApplicable(Aci aci, |
| | | AciTargetMatchContext matchCtx) { |
| | |
| | | * of method calls over local variables. |
| | | */ |
| | | /** |
| | | * Checks an provided ACI's targetattr information against a target match |
| | | * Checks an provided ACI's targetattr rule against a target match |
| | | * context. |
| | | * |
| | | * @param aci The ACI to evaluate. |
| | | * @param targetMatchCtx The target match context to check the ACI against. |
| | | * @return True if the targetattr matched the target context. |
| | |
| | | * This enumeration is returned when the target keyword is |
| | | * "targetcontrol". |
| | | */ |
| | | KEYWORD_TARGETCONTROL ("targetcontrol"); |
| | | KEYWORD_TARGETCONTROL ("targetcontrol"), |
| | | /** |
| | | * This enumeration is returned when the target keyword is |
| | | * "extop". |
| | | */ |
| | | KEYWORD_EXTOP ("extop"); |
| | | |
| | | /* |
| | | * The target keyword name. |
| New file |
| | |
| | | /* |
| | | * 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 extop keyword rule. |
| | | */ |
| | | |
| | | public class ExtOp { |
| | | |
| | | |
| | | /* |
| | | * HashSet of OID strings parsed from the decode. |
| | | */ |
| | | private HashSet<String> extOpOIDs = new HashSet<String>(); |
| | | |
| | | /* |
| | | * Enumeration representing the extop operator. |
| | | */ |
| | | |
| | | private EnumTargetOperator op = EnumTargetOperator.EQUALITY; |
| | | |
| | | /** |
| | | * Creates a class that can be used to evaluate a extop rule. |
| | | * |
| | | * @param op The operator of the extop expression (=, !=). |
| | | * @param extOpOIDs Set of extended operation OIDS to use in the evaluation |
| | | * (wild-card '*' allowed). |
| | | */ |
| | | private ExtOp(EnumTargetOperator op, HashSet<String> extOpOIDs) { |
| | | this.extOpOIDs=extOpOIDs; |
| | | this.op=op; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Decode an extop expression string. |
| | | * |
| | | * @param operator An enumeration representing the operator type. |
| | | * @param expr A string representing the extop expression. |
| | | * @return A class representing the extop expression that can be |
| | | * used to evaluate an ACI. |
| | | * |
| | | * @throws AciException If the specified expression string is invalid. |
| | | */ |
| | | public static ExtOp decode(EnumTargetOperator operator, String expr) |
| | | throws AciException { |
| | | HashSet<String> extOpOIDs = |
| | | Aci.decodeOID(expr,MSGID_ACI_SYNTAX_INVALID_TARGEXTOP_EXPRESSION); |
| | | return new ExtOp(operator, extOpOIDs); |
| | | } |
| | | |
| | | /** |
| | | * Check if a extop is applicable based on the provided target match |
| | | * context. |
| | | * |
| | | * @param matchCtx The target match context to use in the check. |
| | | * @return True if the extop is applicable based on the context. |
| | | */ |
| | | public boolean isApplicable(AciTargetMatchContext matchCtx) { |
| | | if(matchCtx.getExtOpOID() == null) |
| | | return false; |
| | | boolean ret = false; |
| | | for(String oid : extOpOIDs) |
| | | if(oid.equals("*") || matchCtx.getExtOpOID().equals(oid)) { |
| | | ret=true; |
| | | break; |
| | | } |
| | | if(op.equals(EnumTargetOperator.NOT_EQUALITY)) |
| | | ret = !ret; |
| | | return ret; |
| | | } |
| | | |
| | | } |
| | |
| | | /** |
| | | * Creates a class that can be used to evaluate a targetcontrol. |
| | | * |
| | | * @param op The operator of the targetfilter expression (=, !=). |
| | | * @param op The operator of the targetcontrol expression (=, !=). |
| | | * @param controlOIDS Set of control OIDS to use in the evaluation (may |
| | | * contain wild-card '*'). |
| | | */ |
| | |
| | | MSGID_ACI_SYNTAX_DECODE_EFFECTIVERIGHTS_FAIL = |
| | | CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 94; |
| | | |
| | | /** |
| | | * The message ID for the message that will be used if an "aci" attribute |
| | | * type value parse failed because an extop keyword expression |
| | | * did not parse. This takes one argument, which is the extop |
| | | * expression from the ACI. |
| | | */ |
| | | |
| | | public static final int MSGID_ACI_SYNTAX_INVALID_TARGEXTOP_EXPRESSION = |
| | | CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 95; |
| | | |
| | | /** |
| | | * Associates a set of generic messages with the message IDs defined in |
| | | * this class. |
| | |
| | | " geteffectiverights control could not be" + |
| | | " decoded because of the following reason: \"%s\""); |
| | | |
| | | registerMessage(MSGID_ACI_SYNTAX_INVALID_TARGEXTOP_EXPRESSION, |
| | | "The provided Access Control Instruction (ACI) " + |
| | | "extop expression value \"%s\" is invalid. A valid " + |
| | | "extop keyword expression value requires one or more " + |
| | | "valid extended operation request OID strings in the following" + |
| | | " format: oid [|| oid1] ... [|| oidn]"); |
| | | |
| | | } |
| | | } |
| | |
| | | replace: ds-cfg-trust-manager-provider-dn |
| | | ds-cfg-trust-manager-provider-dn: cn=JKS,cn=Trust Manager Providers,cn=config |
| | | |
| | | dn: cn=Access Control Handler,cn=config |
| | | changeType: modify |
| | | add: ds-cfg-global-aci |
| | | ds-cfg-global-aci: (targetcontrol="*") (version 3.0; acl "Anonymous control access"; allow(read) userdn="ldap:///anyone";) |
| | | ds-cfg-global-aci: (extop="*") (version 3.0; acl "Anonymous extended op access"; allow(read) userdn="ldap:///anyone";) |
| | | |
| | | dn: cn=JMX Connection Handler,cn=Connection Handlers,cn=config |
| | | changeType: modify |
| | | replace: ds-cfg-listen-port |
| | |
| | | |
| | | protected final static String G_CONTROL = |
| | | "(targetcontrol = \"*\")" + |
| | | "(version 3.0; acl \"Control\"; " + |
| | | "(version 3.0; acl \"Anonymous control access\"; " + |
| | | "allow (read) userdn=\"ldap:///anyone\";)"; |
| | | |
| | | protected final static String E_EXTEND_OP = |
| | | "(extop = \"*\")" + |
| | | "(version 3.0; acl \"Anonymous extend op access\"; " + |
| | | "allow (read) userdn=\"ldap:///anyone\";)"; |
| | | |
| | | private static final ByteArrayOutputStream oStream = new ByteArrayOutputStream(); |
| | |
| | | "uid: user.3", |
| | | "givenName: User 3", |
| | | "sn: 3", |
| | | "mail: user.3@test", |
| | | "description: user.3 description", |
| | | "cn: User 3", |
| | | "l: Austin", |
| | | "l: Austin", |
| | | "userPassword: password", |
| | | "ds-privilege-name: proxied-auth", |
| | | "", |
| | | "dn: uid=user.4,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: user.4", |
| | | "givenName: User 4", |
| | | "sn: 4", |
| | | "cn: User 4", |
| | | "l: ft worth", |
| | | "userPassword: password", |
| | | "", |
| | | "dn: uid=user.5,ou=People,o=test", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: user.5", |
| | | "givenName: User 5", |
| | | "sn: 5", |
| | | "mail: user.5@test", |
| | | "description: user.5 description", |
| | | "cn: User 5", |
| | | "l: waco", |
| | | "userPassword: password", |
| | | "ds-privilege-name: proxied-auth"); |
| | | } |
| | |
| | | "allow(write)", BIND_RULE_USERDN_SELF); |
| | | |
| | | private static final String GLOBAL_SCHEMA_ACI = |
| | | buildGlobalAciValue("name", "User-Visible Schema Operational Attributes", |
| | | buildGlobalAciValue("name", |
| | | "User-Visible Schema Operational Attributes", |
| | | "target", "ldap:///cn=schema", "targetscope", "base", |
| | | "targetattr", |
| | | "attributeTypes||dITContentRules||dITStructureRules||ldapSyntaxes||matchingRules||matchingRuleUse||nameForms||objectClasses", |
| | | "attributeTypes||dITContentRules||dITStructureRules||" + |
| | | "ldapSyntaxes||matchingRules||matchingRuleUse||nameForms||" + |
| | | "objectClasses", |
| | | "allow(read, search, compare)", BIND_RULE_USERDN_ANYONE); |
| | | |
| | | 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", |
| | | "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", |
| | | "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", "*", |
| | | "name", "Anonymous control access", "targetcontrol", |
| | | "*", |
| | | "allow(read)", BIND_RULE_USERDN_ANYONE); |
| | | |
| | | private static final String GLOBAL_EXT_OP_ACI = buildGlobalAciValue( |
| | | "name", "Anonymous extend op access", "extop", |
| | | "*", |
| | | "allow(read)", BIND_RULE_USERDN_ANYONE); |
| | | |
| | | private static final String GLOBAL_DEFAULT_ACIS = |
| | |
| | | GLOBAL_ANONYMOUS_READ_ACI, |
| | | GLOBAL_SELF_WRITE_ACI, GLOBAL_SCHEMA_ACI, |
| | | GLOBAL_DSE_ACI, GLOBAL_USER_OP_ATTRS_ACI, |
| | | GLOBAL_CONTROL_ACI); |
| | | GLOBAL_CONTROL_ACI, GLOBAL_EXT_OP_ACI); |
| | | |
| | | //ACI used to test LDAP compare. |
| | | private static final |
| | |
| | | String aciField = aciFields[i]; |
| | | String aciValue = aciFields[i+1]; |
| | | |
| | | if (aciField.startsWith("targ")) { |
| | | if (aciField.startsWith("targ") || aciField.equals("extop")) { |
| | | if (!aciField.endsWith("=")) { // We allow = or more importantly != to be included with the target |
| | | aciField += "="; |
| | | } |
| | |
| | | String permission = aciFields[i]; |
| | | String bindRule = aciFields[i+1]; |
| | | |
| | | if (!permission.startsWith("targ") && !permission.equals("name")) { |
| | | if (!permission.startsWith("targ") && !permission.equals("extop") && |
| | | !permission.equals("name")) { |
| | | aci.append(EOL + " " + permission + " " + bindRule + ";"); |
| | | } |
| | | } |
| | |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.Test; |
| | | import org.testng.annotations.AfterClass; |
| | | import org.testng.annotations.BeforeMethod; |
| | | import org.testng.Assert; |
| | | import org.opends.server.TestCaseUtils; |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | |
| | | @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); |
| | | G_READ_ACI, G_SELF_MOD, G_SCHEMA, G_DSE, G_USER_OPS, G_CONTROL, |
| | | E_EXTEND_OP); |
| | | LDIFModify(aciLdif, DIR_MGR_DN, PWD); |
| | | } |
| | | |
| | | |
| | | @BeforeMethod |
| | | public void clearBackend() throws Exception { |
| | | deleteAttrFromEntry(user1, "aci"); |
| | | deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI); |
| | | } |
| | | |
| | | /** |
| | | * This test uses an ACI allowing access to the userPassword attribute, based |
| | | * on one of the alternate bind DNs of a root entry. The root entry does not |
| New file |
| | |
| | | /* |
| | | * 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.*; |
| | | import org.testng.annotations.Test; |
| | | 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.*; |
| | | |
| | | /** |
| | | * Unit test to test the extop ACI keyword. |
| | | */ |
| | | |
| | | public class ExtOpTestCase extends AciTestCase { |
| | | |
| | | private static final String superUser="uid=superuser,ou=admins,o=test"; |
| | | private static final String level5User="uid=user.5,ou=People,o=test"; |
| | | private static final String level4User="uid=user.4,ou=People,o=test"; |
| | | private static final String level3User="uid=user.3,ou=People,o=test"; |
| | | private static final String level2User="uid=user.2,ou=People,o=test"; |
| | | private static final String level1User="uid=user.1,ou=People,o=test"; |
| | | private static final String newPWD="newPWD"; |
| | | private static final String peopleBase="ou=People,o=test"; |
| | | private static final String adminBase="ou=Admins,o=test"; |
| | | |
| | | //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 only password modify extended op. |
| | | private static final |
| | | String extOp = |
| | | "(extop=\"" + OID_PASSWORD_MODIFY_REQUEST + "\")" + |
| | | "(version 3.0; acl \"extended op\";" + |
| | | "allow(read) userdn=\"ldap:///" + "anyone" + "\";)"; |
| | | |
| | | |
| | | //Allow all extended ops based on extop = *. |
| | | private static final |
| | | String extOpWC = |
| | | "(extop=\"" + "*" + "\")" + |
| | | "(version 3.0; acl \"extended op WC\";" + |
| | | "allow(read) userdn=\"ldap:///" + "anyone" + "\";)"; |
| | | |
| | | |
| | | //Dis-allow all extended ops based on extop != *" |
| | | private static final |
| | | String extOpNotWC = |
| | | "(extop!=\"" + "*" + "\")" + |
| | | "(version 3.0; acl \"extended op no wc\";" + |
| | | "allow(read) userdn=\"ldap:///" + "anyone" + "\";)"; |
| | | |
| | | |
| | | //Allow all attributes to be modified - so the password can be changed. |
| | | private static final |
| | | String ALLOW_ALL = "(targetattr=\"*\")" + |
| | | "(version 3.0;acl \"all access\";" + |
| | | "allow (all) " + |
| | | "userdn=\"ldap:///self\";)"; |
| | | |
| | | //Allow pwd modify to people branch. |
| | | private static final |
| | | String extOpPeople = "(extop=\"" + |
| | | OID_PASSWORD_MODIFY_REQUEST + "\")" + |
| | | "(target=\"ldap:///" + peopleBase + "\")" + |
| | | "(version 3.0; acl \"extended op\";" + |
| | | "allow(read) userdn=\"ldap:///" + "anyone" + "\";)"; |
| | | |
| | | //Dis-allow pwd modify to admin branch. |
| | | private static final |
| | | String extOpAdmin = |
| | | "(extop!=\"" + OID_PASSWORD_MODIFY_REQUEST + "\")" + |
| | | "(target=\"ldap:///" + adminBase + "\")" + |
| | | "(version 3.0; acl \"extended op\";" + |
| | | "allow(read) userdn=\"ldap:///" + "anyone" + "\";)"; |
| | | |
| | | //Test for side effect -- targetattr rule gives access to denied extended |
| | | //op. |
| | | private static final |
| | | String complicated = |
| | | "(extop = \"1.2.3.4\")" + |
| | | "(targetattr != \"userpassword\")" + |
| | | "(version 3.0; acl \"extended op\";" + |
| | | "allow(all) userdn=\"ldap:///" + "anyone" + "\";)"; |
| | | |
| | | @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, |
| | | E_EXTEND_OP); |
| | | LDIFModify(aciLdif, DIR_MGR_DN, PWD); |
| | | } |
| | | |
| | | @BeforeMethod |
| | | public void clearBackend() throws Exception { |
| | | deleteAttrFromEntry(peopleBase, "aci"); |
| | | deleteAttrFromEntry(adminBase, "aci"); |
| | | deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI); |
| | | } |
| | | |
| | | /** |
| | | * Test access to extended op using wildcard. |
| | | * |
| | | * @throws Exception If an unexpected result is returned. |
| | | */ |
| | | @Test() |
| | | public void testExtendOpPwdWC() throws Exception { |
| | | String pwdLdifs = |
| | | makeAddLDIF("aci", peopleBase, pwdControls, extOpWC, ALLOW_ALL); |
| | | LDIFModify(pwdLdifs, DIR_MGR_DN, PWD); |
| | | String pwdLdifs1 = |
| | | makeAddLDIF("aci", adminBase, pwdControls, ALLOW_ALL); |
| | | LDIFModify(pwdLdifs1, DIR_MGR_DN, PWD); |
| | | //Pass the people branch has access to all extended op using wild-card. |
| | | pwdModify(level1User, PWD, newPWD, null, null, 0); |
| | | //Fail the admin branch has no access to the extended op. |
| | | pwdModify(superUser, PWD, newPWD, null, null, |
| | | LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS); |
| | | deleteAttrFromEntry(peopleBase, "aci"); |
| | | deleteAttrFromEntry(adminBase, "aci"); |
| | | } |
| | | |
| | | /** |
| | | * Test denied access to extended operation based on a extop rule |
| | | * deny all using a wild-card. |
| | | * |
| | | * @throws Exception If an unexpected result is returned. |
| | | */ |
| | | @Test() |
| | | public void testExtendOpPwdNotWC() throws Exception { |
| | | String pwdLdifs = |
| | | makeAddLDIF("aci", peopleBase, pwdControls, extOpNotWC, ALLOW_ALL); |
| | | LDIFModify(pwdLdifs, DIR_MGR_DN, PWD); |
| | | pwdModify(level5User, PWD, newPWD, null, null, |
| | | LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS); |
| | | deleteAttrFromEntry(peopleBase, "aci"); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Test access to extended op using one ACI to allow access to the |
| | | * extended op and another ACI to allow the pwd change.. |
| | | * |
| | | * @throws Exception If an unexpected result is returned. |
| | | */ |
| | | @Test() |
| | | public void testExtendOpPwd() throws Exception { |
| | | String pwdLdifs = |
| | | makeAddLDIF("aci", peopleBase, pwdControls, extOp, ALLOW_ALL); |
| | | LDIFModify(pwdLdifs, DIR_MGR_DN, PWD); |
| | | pwdModify(level3User, PWD, newPWD, null, null, 0); |
| | | deleteAttrFromEntry(peopleBase, "aci"); |
| | | } |
| | | |
| | | /** |
| | | * Test access to disallowed extended op based on a targetattr rule allowing |
| | | * access. |
| | | * |
| | | * @throws Exception If an unexpected result is returned. |
| | | */ |
| | | |
| | | @Test() |
| | | public void testTargetattrSideEffect() throws Exception { |
| | | String pwdLdifs = |
| | | makeAddLDIF("aci", peopleBase, complicated); |
| | | LDIFModify(pwdLdifs, DIR_MGR_DN, PWD); |
| | | //Fail because pwd not an allowed extended operation. |
| | | pwdModify(level4User, PWD, newPWD, null, null, |
| | | LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS); |
| | | deleteAttrFromEntry(peopleBase, "aci"); |
| | | } |
| | | |
| | | /** |
| | | * Test access to pwd changes using global ACIs with target statements giving |
| | | * access to different parts of the DIT. |
| | | * |
| | | * @throws Exception If an unexpected result is returned. |
| | | */ |
| | | public void testGlobalTargets() throws Exception { |
| | | String globalControlAcis= |
| | | makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN, |
| | | extOpAdmin, extOpPeople); |
| | | LDIFModify(globalControlAcis, DIR_MGR_DN, PWD); |
| | | String pwdLdifs = |
| | | makeAddLDIF("aci", peopleBase, pwdControls, ALLOW_ALL); |
| | | LDIFModify(pwdLdifs, DIR_MGR_DN, PWD); |
| | | String pwdLdifs1 = |
| | | makeAddLDIF("aci", adminBase, pwdControls, ALLOW_ALL); |
| | | LDIFModify(pwdLdifs1, DIR_MGR_DN, PWD); |
| | | //Succeed because ACI gives access to people branch. |
| | | pwdModify(level2User, PWD, newPWD, null, null, 0); |
| | | //Fail because ACI doesn't give access to admin branch. |
| | | pwdModify(superUser, PWD, newPWD, null, null, |
| | | LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS); |
| | | deleteAttrFromEntry(peopleBase, "aci"); |
| | | deleteAttrFromEntry(adminBase, "aci"); |
| | | deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI); |
| | | } |
| | | |
| | | } |
| | |
| | | @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); |
| | | G_READ_ACI, G_SELF_MOD, G_SCHEMA, G_DSE, G_USER_OPS, G_CONTROL, |
| | | E_EXTEND_OP); |
| | | LDIFModify(aciLdif, DIR_MGR_DN, PWD); |
| | | } |
| | | |
| | |
| | | |
| | | package org.opends.server.authorization.dseecompat; |
| | | |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.Test; |
| | | import org.testng.annotations.DataProvider; |
| | | import java.net.InetAddress; |
| | |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.Test; |
| | | import org.testng.annotations.AfterClass; |
| | | import org.testng.annotations.BeforeMethod; |
| | | import org.testng.Assert; |
| | | import org.opends.server.TestCaseUtils; |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | |
| | | @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); |
| | | G_READ_ACI, G_SELF_MOD, G_SCHEMA, G_DSE, G_USER_OPS, G_CONTROL, |
| | | E_EXTEND_OP); |
| | | LDIFModify(aciLdif, DIR_MGR_DN, PWD); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Test targetattr behavior using userattr bind rule. |
| | | * |
| | |
| | | |
| | | import org.testng.annotations.DataProvider; |
| | | import org.testng.annotations.Test; |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.AfterClass; |
| | | import org.testng.annotations.*; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.protocols.ldap.LDAPResultCode; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | |
| | | |
| | | 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 level4User="uid=user.4,ou=People,o=test"; |
| | | private static final String newPWD="newPWD"; |
| | | |
| | | |
| | |
| | | |
| | | 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; |
| | | private static final String newPeopleDN="uid=user.6," + peopleBase; |
| | | private static final String newAdminDN="uid=user.6," + adminBase; |
| | | |
| | | |
| | | @BeforeClass |
| | |
| | | @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); |
| | | G_READ_ACI, G_SELF_MOD, G_SCHEMA, G_DSE, G_USER_OPS, G_CONTROL, |
| | | E_EXTEND_OP); |
| | | LDIFModify(aciLdif, DIR_MGR_DN, PWD); |
| | | } |
| | | |
| | | |
| | | @BeforeMethod |
| | | public void clearBackend() throws Exception { |
| | | deleteAttrFromEntry(peopleBase, "aci"); |
| | | deleteAttrFromEntry(base, "aci"); |
| | | deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI); |
| | | } |
| | | |
| | | private static final String[] newEntry = new String[] { |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | |
| | | "(version 3.0; acl \"control\";" + |
| | | "allow(read) userdn=\"ldap:///" + "anyone" + "\";)"; |
| | | |
| | | //Allow all to extended op. |
| | | private static final |
| | | String extOpAll = |
| | | "(extop=\"" + "*" + "\")" + |
| | | "(version 3.0; acl \"control\";" + |
| | | "allow(read) userdn=\"ldap:///" + "anyone" + "\";)"; |
| | | |
| | | //Only allow access to the password policy control. Used to test if the |
| | | //targetattr rule will give access erroneously. |
| | | private static final |
| | | String complicated = |
| | | "(targetcontrol=\"" + OID_PASSWORD_POLICY_CONTROL + "\")" + |
| | | "(targetattr != \"userpassword\")" + |
| | | "(version 3.0; acl \"control\";" + |
| | | "allow(all) userdn=\"ldap:///" + "anyone" + "\";)"; |
| | | |
| | | /** |
| | | * Test valid targetcontrol statements. |
| | |
| | | } |
| | | |
| | | /** |
| | | * Test access to disallowed control based on a targetattr rule allowing |
| | | * access. |
| | | * |
| | | * @throws Exception If an unexpected result is returned. |
| | | */ |
| | | |
| | | @Test() |
| | | public void testTargetattrSideEffect() throws Exception { |
| | | String pwdLdifs = |
| | | makeAddLDIF("aci", peopleBase, complicated); |
| | | LDIFModify(pwdLdifs, DIR_MGR_DN, PWD); |
| | | String noOpCtrlStr=OID_LDAP_NOOP_OPENLDAP_ASSIGNED + ":true"; |
| | | //This should fail beacause this ACI only allows acces to the |
| | | //password policy control. |
| | | pwdModify(level4User, PWD, newPWD, noOpCtrlStr, null, |
| | | LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS); |
| | | deleteAttrFromEntry(peopleBase, "aci"); |
| | | } |
| | | |
| | | /** |
| | | * Test access to extended op controls (no-op and userPasswordPolicy). |
| | | * |
| | | * @throws Exception If an unexpected result is returned. |
| | | */ |
| | | @Test() |
| | | @Test() |
| | | public void testExtendOpControls() throws Exception { |
| | | String pwdLdifs = |
| | | makeAddLDIF("aci", peopleBase, extOpControls, ALLOW_ALL); |
| | | makeAddLDIF("aci", peopleBase, extOpControls, extOpAll, 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 |
| | |
| | | * |
| | | * @throws Exception If an unexpected result is returned. |
| | | */ |
| | | @Test() |
| | | @Test() |
| | | public void testBindControl() throws Exception { |
| | | String pwdLdifs = |
| | | makeAddLDIF("aci", peopleBase, pwdControls, ALLOW_ALL); |
| | |
| | | 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 |