001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2008 Sun Microsystems, Inc.
026 */
027
028 package org.opends.server.authorization.dseecompat;
029 import org.opends.messages.Message;
030
031 import static org.opends.messages.AccessControlMessages.*;
032 import static org.opends.server.authorization.dseecompat.Aci.*;
033 import java.util.regex.Pattern;
034 import org.opends.server.types.DN;
035 import org.opends.server.types.DirectoryException;
036 import org.opends.server.types.LDAPURL;
037
038 /**
039 * A class representing an ACI target keyword.
040 */
041 public class Target
042 {
043 /**
044 * Enumeration representing the target operator.
045 */
046 private EnumTargetOperator operator = EnumTargetOperator.EQUALITY;
047
048 /**
049 * True if the URL contained a DN wild-card pattern.
050 */
051 private boolean isPattern=false;
052
053 /**
054 * The target DN from the URL or null if it was a wild-card pattern.
055 */
056 private DN urlDN=null;
057
058 /**
059 * The pattern matcher for a wild-card pattern or null if the URL
060 * contained an ordinary DN.
061 */
062 private PatternDN patternDN =null;
063
064 /*
065 * TODO Save aciDN parameter and use it in matchesPattern re-write.
066 *
067 * Should the aciDN argument provided to the constructor be stored so that
068 * it can be used in the matchesPattern() method? The DN should only be
069 * considered a potential match if it is at or below the entry containing
070 * the ACI.
071 *
072 */
073 /**
074 * This constructor parses the target string.
075 * @param operator An enumeration of the operation of this target.
076 * @param target A string representation of the target.
077 * @param aciDN The dn of the ACI entry used for a descendant check.
078 * @throws AciException If the target string is invalid.
079 */
080 private Target(EnumTargetOperator operator, String target, DN aciDN)
081 throws AciException {
082 this.operator = operator;
083 try {
084 //The NULL_LDAP_URL corresponds to the root DSE.
085 if((!target.equals(NULL_LDAP_URL)) &&
086 (!Pattern.matches(LDAP_URL, target))) {
087 Message message =
088 WARN_ACI_SYNTAX_INVALID_TARGETKEYWORD_EXPRESSION.get(target);
089 throw new AciException(message);
090 }
091 LDAPURL targetURL = LDAPURL.decode(target, false);
092 if(targetURL.getRawBaseDN().indexOf("*") != -1) {
093 this.isPattern=true;
094 patternDN = PatternDN.decodeSuffix(targetURL.getRawBaseDN());
095 } else {
096 urlDN=targetURL.getBaseDN();
097 if(!urlDN.isDescendantOf(aciDN)) {
098 Message message = WARN_ACI_SYNTAX_TARGET_DN_NOT_DESCENDENTOF.
099 get(urlDN.toNormalizedString(),
100 aciDN.toNormalizedString());
101 throw new AciException(message);
102 }
103 }
104 }
105 catch (DirectoryException e){
106 Message message =
107 WARN_ACI_SYNTAX_INVALID_TARGETKEYWORD_EXPRESSION.get(target);
108 throw new AciException(message);
109 }
110 }
111
112 /**
113 * Decode an expression string representing a target keyword expression.
114 * @param operator An enumeration of the operation of this target.
115 * @param expr A string representation of the target.
116 * @param aciDN The DN of the ACI entry used for a descendant check.
117 * @return A Target class representing this target.
118 * @throws AciException If the expression string is invalid.
119 */
120 public static Target decode(EnumTargetOperator operator,
121 String expr, DN aciDN)
122 throws AciException {
123 return new Target(operator, expr, aciDN);
124 }
125
126 /**
127 * Returns the operator of this expression.
128 * @return An enumeration of the operation value.
129 */
130 public EnumTargetOperator getOperator() {
131 return operator;
132 }
133
134 /**
135 * Returns the URL DN of the expression.
136 * @return A DN of the URL or null if the URL contained a DN pattern.
137 */
138 public DN getDN() {
139 return urlDN;
140 }
141
142 /**
143 * Returns boolean if a pattern was seen during parsing.
144 * @return True if the URL contained a DN pattern.
145 */
146 public boolean isPattern() {
147 return isPattern;
148 }
149
150 /**
151 * This method tries to match a pattern against a DN.
152 * @param dn The DN to try an match.
153 * @return True if the pattern matches.
154 */
155 public boolean matchesPattern(DN dn) {
156 return patternDN.matchesDN(dn);
157 }
158 }