| | |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011 ForgeRock AS |
| | | * Portions Copyright 2011-2013 ForgeRock AS |
| | | */ |
| | | |
| | | package org.opends.server.authorization.dseecompat; |
| | | |
| | | import org.opends.server.protocols.ldap.LDAPClientConnection; |
| | | import org.opends.server.types.*; |
| | | import org.opends.server.api.ClientConnection; |
| | | import org.opends.server.api.Group; |
| | | import org.opends.server.core.AddOperationBasis; |
| | | import org.opends.server.core.SearchOperation; |
| | | import org.opends.server.types.Operation; |
| | | import java.net.InetAddress; |
| | | import java.security.cert.Certificate; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.HashMap; |
| | | |
| | | import static org.opends.server.authorization.dseecompat.Aci.*; |
| | | import static org.opends.server.authorization.dseecompat.AciHandler.*; |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | |
| | | import java.net.InetAddress; |
| | | import java.security.cert.Certificate; |
| | | import java.util.HashMap; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | |
| | | import org.opends.server.api.ClientConnection; |
| | | import org.opends.server.api.Group; |
| | | import org.opends.server.controls.GetEffectiveRightsRequestControl; |
| | | import static org.opends.server.util.ServerConstants.OID_GET_EFFECTIVE_RIGHTS; |
| | | import org.opends.server.core.AddOperation; |
| | | import org.opends.server.core.SearchOperation; |
| | | import org.opends.server.protocols.ldap.LDAPClientConnection; |
| | | import org.opends.server.types.*; |
| | | |
| | | /** |
| | | * The AciContainer class contains all of the needed information to perform |
| | |
| | | public abstract class AciContainer |
| | | implements AciTargetMatchContext, AciEvalContext { |
| | | |
| | | /* |
| | | /** |
| | | * The allow and deny lists. |
| | | */ |
| | | private LinkedList<Aci> denyList, allowList; |
| | | |
| | | /* |
| | | /** |
| | | * The attribute type in the resource entry currently being evaluated. |
| | | */ |
| | | private AttributeType attributeType; |
| | | |
| | | /* |
| | | /** |
| | | * The attribute type value in the resource entry currently being |
| | | * evaluated. |
| | | */ |
| | | private AttributeValue attributeValue; |
| | | |
| | | /* |
| | | /** |
| | | * True if this is the first attribute type in the resource entry being |
| | | * evaluated. |
| | | */ |
| | | private boolean isFirst = false; |
| | | |
| | | /* |
| | | /** |
| | | * True if an entry test rule was seen during target matching of an ACI |
| | | * entry. A entry test rule is an ACI with targetattrs target keyword. |
| | | */ |
| | | private boolean isEntryTestRule = false; |
| | | |
| | | /* |
| | | /** |
| | | * True if the evaluation of an ACI is from the deny list. |
| | | */ |
| | | private boolean isDenyEval; |
| | | |
| | | /* |
| | | /** |
| | | * True if the evaluation is a result of an LDAP add operation. |
| | | */ |
| | | private boolean isAddOp=false; |
| | | |
| | | /* |
| | | /** |
| | | * The right mask to use in the evaluation of the LDAP operation. |
| | | */ |
| | | private int rightsMask; |
| | | |
| | | /* |
| | | /** |
| | | * The entry being evaluated (resource entry). |
| | | */ |
| | | private Entry resourceEntry; |
| | | |
| | | /* |
| | | /** |
| | | * The client connection information. |
| | | */ |
| | | private final ClientConnection clientConnection; |
| | | |
| | | /* |
| | | /** |
| | | * The operation being evaluated. |
| | | */ |
| | | private final Operation operation; |
| | | |
| | | /* |
| | | /** |
| | | * True if a targattrfilters match was found. |
| | | */ |
| | | private boolean targAttrFiltersMatch=false; |
| | | |
| | | /* |
| | | /** |
| | | * The authorization entry currently being evaluated. If proxied |
| | | * authorization is being used and the handler is doing a proxy access |
| | | * check, then this entry will switched to the original authorization entry |
| | |
| | | */ |
| | | private Entry authorizationEntry; |
| | | |
| | | /* |
| | | /** |
| | | * Used to save the current authorization entry when the authorization |
| | | * entry is switched during a proxy access check. |
| | | */ |
| | | private final Entry saveAuthorizationEntry; |
| | | |
| | | /* |
| | | /** |
| | | * This entry is only used if proxied authorization is being used. It is |
| | | * the original authorization entry before the proxied authorization change. |
| | | */ |
| | | private Entry origAuthorizationEntry=null; |
| | | |
| | | /* |
| | | /** |
| | | * True if proxied authorization is being used. |
| | | */ |
| | | private boolean proxiedAuthorization=false; |
| | | |
| | | /* |
| | | /** |
| | | * Used by proxied authorization processing. True if the entry has already |
| | | * been processed by an access proxy check. Some operations might perform |
| | | * several access checks on the same entry (modify DN), this |
| | |
| | | */ |
| | | private boolean seenEntry=false; |
| | | |
| | | /* |
| | | /** |
| | | * True if geteffectiverights evaluation is in progress. |
| | | */ |
| | | private boolean isGetEffectiveRightsEval=false; |
| | | |
| | | /* |
| | | /** |
| | | * True if the operation has a geteffectiverights control. |
| | | */ |
| | | private boolean hasGetEffectiveRightsControl=false; |
| | | |
| | | /* |
| | | /** |
| | | * The geteffectiverights authzID in DN format. |
| | | */ |
| | | private DN authzid=null; |
| | | |
| | | /* |
| | | /** |
| | | * True if the authZid should be used as the client DN, only used in |
| | | * geteffectiverights evaluation. |
| | | */ |
| | | private boolean useAuthzid=false; |
| | | |
| | | /* |
| | | /** |
| | | * The list of specific attributes to get rights for, in addition to |
| | | * any attributes requested in the search. |
| | | */ |
| | | private List<AttributeType> specificAttrs=null; |
| | | |
| | | /* |
| | | /** |
| | | * Table of ACIs that have targattrfilter keywords that matched. Used |
| | | * in geteffectiverights attributeLevel write evaluation. |
| | | */ |
| | | private final HashMap<Aci,Aci> targAttrFilterAcis=new HashMap<Aci, Aci>(); |
| | | |
| | | /* |
| | | /** |
| | | * The name of a ACI that decided an evaluation and contained a |
| | | * targattrfilter keyword. Used in geteffectiverights attributeLevel |
| | | * write evaluation. |
| | | */ |
| | | private String targAttrFiltersAciName=null; |
| | | |
| | | /* |
| | | /** |
| | | * Value that is used to store the allow/deny result of a deciding ACI |
| | | * containing a targattrfilter keyword. Used in geteffectiverights |
| | | * attributeLevel write evaluation. |
| | | */ |
| | | private int targAttrMatch=0; |
| | | |
| | | /* |
| | | /** |
| | | * The ACI that decided the last evaluation. Used in geteffectiverights |
| | | * loginfo processing. |
| | | */ |
| | | private Aci decidingAci=null; |
| | | |
| | | /* |
| | | /** |
| | | * The reason the last evaluation decision was made. Used both |
| | | * in geteffectiverights loginfo processing and attributeLevel write |
| | | * evaluation. |
| | | */ |
| | | private EnumEvalReason evalReason=null; |
| | | |
| | | /* |
| | | /** |
| | | * A summary string holding the last evaluation information in textual |
| | | * format. Used in geteffectiverights loginfo processing. |
| | | */ |
| | | private String summaryString=null; |
| | | |
| | | /* |
| | | /** |
| | | * Flag used to determine if ACI all attributes target matched. |
| | | */ |
| | | private int evalAllAttributes=0; |
| | | |
| | | /* |
| | | /** |
| | | * String used to hold a control OID string. |
| | | */ |
| | | private String controlOID; |
| | | |
| | | /* |
| | | /** |
| | | * String used to hold an extended operation OID string. |
| | | */ |
| | | private String extOpOID; |
| | | |
| | | /* |
| | | /** |
| | | * AuthenticationInfo class to use. |
| | | */ |
| | | private AuthenticationInfo authInfo; |
| | |
| | | this.resourceEntry=entry; |
| | | this.operation=operation; |
| | | this.clientConnection=operation.getClientConnection(); |
| | | if(operation instanceof AddOperationBasis) |
| | | this.isAddOp=true; |
| | | this.isAddOp = operation instanceof AddOperation; |
| | | this.authInfo = clientConnection.getAuthenticationInfo(); |
| | | |
| | | //If the proxied authorization control was processed, then the operation |
| | | //will contain an attachment containing the original authorization entry. |
| | | this.origAuthorizationEntry = |
| | | (Entry) operation.getAttachment(ORIG_AUTH_ENTRY); |
| | | if(origAuthorizationEntry != null) |
| | | this.proxiedAuthorization=true; |
| | | this.proxiedAuthorization = origAuthorizationEntry != null; |
| | | this.authorizationEntry=operation.getAuthorizationEntry(); |
| | | |
| | | //The ACI_READ right at constructor time can only be the result of the |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isProxiedAuthorization() { |
| | | return this.proxiedAuthorization; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isGetEffectiveRightsEval() { |
| | | return this.isGetEffectiveRightsEval; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void addTargAttrFiltersMatchAci(Aci aci) { |
| | | this.targAttrFilterAcis.put(aci, aci); |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean hasTargAttrFiltersMatchAci(Aci aci) { |
| | | return this.targAttrFilterAcis.containsKey(aci); |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isTargAttrFilterMatchAciEmpty() { |
| | | return this.targAttrFilterAcis.isEmpty(); |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setTargAttrFiltersAciName(String name) { |
| | | this.targAttrFiltersAciName=name; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String getTargAttrFiltersAciName() { |
| | | return this.targAttrFiltersAciName; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setTargAttrFiltersMatchOp(int flag) { |
| | | this.targAttrMatch |= flag; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean hasTargAttrFiltersMatchOp(int flag) { |
| | | return (this.targAttrMatch & flag) != 0; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setDecidingAci(Aci aci) { |
| | | this.decidingAci=aci; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String getDecidingAciName() { |
| | | if(this.decidingAci != null) |
| | | return this.decidingAci.getName(); |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setEvalReason(EnumEvalReason reason) { |
| | | this.evalReason=reason; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public EnumEvalReason getEvalReason() { |
| | | return this.evalReason; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setEvalSummary(String summary) { |
| | | this.summaryString=summary; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String getEvalSummary() { |
| | | @Override |
| | | public String getEvalSummary() { |
| | | return this.summaryString; |
| | | } |
| | | |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setDenyList(LinkedList<Aci> denys) { |
| | | denyList=denys; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setAllowList(LinkedList<Aci> allows) { |
| | | allowList=allows; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public AttributeType getCurrentAttributeType() { |
| | | return attributeType; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public AttributeValue getCurrentAttributeValue() { |
| | | return attributeValue; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setCurrentAttributeType(AttributeType type) { |
| | | attributeType=type; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setCurrentAttributeValue(AttributeValue value) { |
| | | attributeValue=value; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isFirstAttribute() { |
| | | return isFirst; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setIsFirstAttribute(boolean val) { |
| | | isFirst=val; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean hasEntryTestRule() { |
| | | return isEntryTestRule; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setEntryTestRule(boolean val) { |
| | | isEntryTestRule=val; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Entry getResourceEntry() { |
| | | return resourceEntry; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Entry getClientEntry() { |
| | | return this.authorizationEntry; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public LinkedList<Aci> getDenyList() { |
| | | return denyList; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public LinkedList<Aci> getAllowList() { |
| | | return allowList; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isDenyEval() { |
| | | return isDenyEval; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isAnonymousUser() { |
| | | return !authInfo.isAuthenticated(); |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setDenyEval(boolean val) { |
| | | isDenyEval = val; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public DN getClientDN() { |
| | | if(this.useAuthzid) |
| | | return this.authzid; |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public DN getResourceDN() { |
| | | return resourceEntry.getDN(); |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean hasRights(int rights) { |
| | | return (this.rightsMask & rights) != 0; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public int getRights() { |
| | | return this.rightsMask; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setRights(int rights) { |
| | | this.rightsMask=rights; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String getHostName() { |
| | | return clientConnection.getRemoteAddress().getCanonicalHostName(); |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public InetAddress getRemoteAddress() { |
| | | return clientConnection.getRemoteAddress(); |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isAddOperation() { |
| | | return isAddOp; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setTargAttrFiltersMatch(boolean v) { |
| | | this.targAttrFiltersMatch=v; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean getTargAttrFiltersMatch() { |
| | | return targAttrFiltersMatch; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String getControlOID() { |
| | | return controlOID; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String getExtOpOID() { |
| | | return extOpOID; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public EnumEvalResult hasAuthenticationMethod(EnumAuthMethod authMethod, |
| | | String saslMech) { |
| | | EnumEvalResult matched=EnumEvalResult.FALSE; |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isMemberOf(Group<?> group) { |
| | | boolean ret; |
| | | try { |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String rightToString() { |
| | | if(hasRights(ACI_SEARCH)) |
| | | return "search"; |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setEvalUserAttributes(int v) { |
| | | if(operation instanceof SearchOperation && (rightsMask == ACI_READ)) { |
| | | if(v == ACI_FOUND_USER_ATTR_RULE) { |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void setEvalOpAttributes(int v) { |
| | | if(operation instanceof SearchOperation && (rightsMask == ACI_READ)) { |
| | | if(v == ACI_FOUND_OP_ATTR_RULE) { |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean hasEvalUserAttributes() { |
| | | return (evalAllAttributes & ACI_FOUND_USER_ATTR_RULE) == |
| | | ACI_FOUND_USER_ATTR_RULE; |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean hasEvalOpAttributes() { |
| | | return (evalAllAttributes & ACI_FOUND_OP_ATTR_RULE) == |
| | | ACI_FOUND_OP_ATTR_RULE; |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void clearEvalAttributes(int v) { |
| | | if(v == 0) |
| | | evalAllAttributes=0; |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public int getCurrentSSF() { |
| | | return clientConnection.getSSF(); |
| | | } |