From b6a7d650413cf42003ffae4910e3197d14e889be Mon Sep 17 00:00:00 2001
From: Jean-Noël Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Tue, 19 Apr 2016 16:15:40 +0000
Subject: [PATCH] Code cleanup in ACIs
---
opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternDN.java | 500 +++++++++++++++--------------------
opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciTargets.java | 187 ++++--------
opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternRDN.java | 97 +++---
3 files changed, 328 insertions(+), 456 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciTargets.java b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciTargets.java
index 6fb83ed..065caa5 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciTargets.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciTargets.java
@@ -18,14 +18,15 @@
import static org.opends.messages.AccessControlMessages.*;
import static org.opends.server.authorization.dseecompat.Aci.*;
+import static org.opends.server.authorization.dseecompat.EnumTargetOperator.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.forgerock.i18n.LocalizableMessage;
-import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.SearchScope;
+import org.forgerock.opendj.ldap.schema.AttributeType;
/**
* This class represents target part of an ACI's syntax. This is the part
@@ -36,66 +37,31 @@
* targetscope, targetfilter, targattrfilters, targetcontrol and extop.
*/
public class AciTargets {
-
- /**
- * ACI syntax has a target keyword.
- */
+ /** ACI syntax has a target keyword. */
private Target target;
-
- /**
- * ACI syntax has a targetscope keyword.
- */
+ /** ACI syntax has a targetscope keyword. */
private SearchScope targetScope = SearchScope.WHOLE_SUBTREE;
-
- /**
- * ACI syntax has a targetattr keyword.
- */
+ /** ACI syntax has a targetattr keyword. */
private TargetAttr targetAttr;
-
- /**
- * ACI syntax has a targetfilter keyword.
- */
+ /** ACI syntax has a targetfilter keyword. */
private TargetFilter targetFilter;
-
- /**
- * ACI syntax has a targattrtfilters keyword.
- */
+ /** ACI syntax has a targattrtfilters keyword. */
private TargAttrFilters targAttrFilters;
-
- /**
- * The ACI syntax has a targetcontrol keyword.
- */
+ /** The ACI syntax has a targetcontrol keyword. */
private TargetControl targetControl;
-
- /**
- * The ACI syntax has a extop keyword.
- */
+ /** The ACI syntax has a extop keyword. */
private ExtOp extOp;
- /**
- * The number of regular expression group positions in a valid ACI target
- * expression.
- */
+ /** The number of regular expression group positions in a valid ACI target expression. */
private static final int targetElementCount = 3;
-
- /**
- * Regular expression group position of a target keyword.
- */
+ /** Regular expression group position of a target keyword. */
private static final int targetKeywordPos = 1;
-
- /**
- * Regular expression group position of a target operator enumeration.
- */
+ /** Regular expression group position of a target operator enumeration. */
private static final int targetOperatorPos = 2;
-
- /**
- * Regular expression group position of a target expression statement.
- */
+ /** Regular expression group position of a target expression statement. */
private static final int targetExpressionPos = 3;
- /**
- * Regular expression used to match a single target rule.
- */
+ /** Regular expression used to match a single target rule. */
private static final String targetRegex =
OPEN_PAREN + ZERO_OR_MORE_WHITESPACE + WORD_GROUP +
ZERO_OR_MORE_WHITESPACE + "(!?=)" + ZERO_OR_MORE_WHITESPACE +
@@ -463,7 +429,6 @@
*/
public static boolean isTargAttrFiltersApplicable(Aci aci,
AciTargetMatchContext matchCtx) {
- boolean ret=true;
TargAttrFilters targAttrFilters=aci.getTargets().getTargAttrFilters();
if(targAttrFilters != null) {
if((matchCtx.hasRights(ACI_ADD) &&
@@ -471,17 +436,17 @@
(matchCtx.hasRights(ACI_DELETE) &&
targAttrFilters.hasMask(TARGATTRFILTERS_DELETE)))
{
- ret=targAttrFilters.isApplicableAddDel(matchCtx);
+ return targAttrFilters.isApplicableAddDel(matchCtx);
}
else if((matchCtx.hasRights(ACI_WRITE_ADD) &&
targAttrFilters.hasMask(TARGATTRFILTERS_ADD)) ||
(matchCtx.hasRights(ACI_WRITE_DELETE) &&
targAttrFilters.hasMask(TARGATTRFILTERS_DELETE)))
{
- ret=targAttrFilters.isApplicableMod(matchCtx, aci);
+ return targAttrFilters.isApplicableMod(matchCtx, aci);
}
}
- return ret;
+ return true;
}
/*
@@ -574,8 +539,7 @@
* @param entryDN The DN to use in this evaluation.
* @return True if the ACI matched the target and DN.
*/
- public static boolean isTargetApplicable(Aci aci,
- AciTargets targets, DN entryDN) {
+ public static boolean isTargetApplicable(Aci aci, AciTargets targets, DN entryDN) {
DN targetDN=aci.getDN();
/*
* Scoping of the ACI uses either the DN of the entry
@@ -583,82 +547,63 @@
* contains a simple target DN and a equality operator, that
* simple target DN is used as the target DN.
*/
- if(targets.getTarget() != null && !targets.getTarget().isPattern()) {
- EnumTargetOperator op=targets.getTarget().getOperator();
- if(op != EnumTargetOperator.NOT_EQUALITY)
- {
- targetDN=targets.getTarget().getDN();
- }
+ Target target = targets.getTarget();
+ if(target != null && !target.isPattern() && target.getOperator() != NOT_EQUALITY)
+ {
+ targetDN=target.getDN();
}
- //Check if the scope is correct.
- switch(targets.getTargetScope().asEnum()) {
- case BASE_OBJECT:
- if(!targetDN.equals(entryDN))
- {
- return false;
- }
- break;
- case SINGLE_LEVEL:
- /*
- * We use the standard definition of single level to mean the
- * immediate children only -- not the target entry itself.
- * Sun CR 6535035 has been raised on DSEE:
- * Non-standard interpretation of onelevel in ACI targetScope.
- */
- if(!targetDN.equals(entryDN.parent()))
- {
- return false;
- }
- break;
- case WHOLE_SUBTREE:
- if(!entryDN.isSubordinateOrEqualTo(targetDN))
- {
- return false;
- }
- break;
- case SUBORDINATES:
- if (entryDN.size() <= targetDN.size() ||
- !entryDN.isSubordinateOrEqualTo(targetDN)) {
- return false;
- }
- break;
- default:
+ if (!isInScopeOf(entryDN, targetDN, targets.getTargetScope()))
+ {
+ return false;
+ }
+
+ if (target != null)
+ {
+ /*
+ * For inequality checks, scope was tested against the entry containing the ACI.
+ * If operator is inequality, check that it doesn't match the target DN.
+ */
+ if (!target.isPattern()
+ && target.getOperator() == NOT_EQUALITY
+ && entryDN.isSubordinateOrEqualTo(target.getDN()))
+ {
return false;
- }
- /*
- * The entry is in scope. For inequality checks, scope was tested
- * against the entry containing the ACI. If operator is inequality,
- * check that it doesn't match the target DN.
- */
- if(targets.getTarget() != null &&
- !targets.getTarget().isPattern()) {
- EnumTargetOperator op=targets.getTarget().getOperator();
- if(op == EnumTargetOperator.NOT_EQUALITY) {
- DN tmpDN=targets.getTarget().getDN();
- if(entryDN.isSubordinateOrEqualTo(tmpDN))
- {
- return false;
- }
- }
- }
- /*
- * There is a pattern, need to match the substring filter
- * created when the ACI was decoded. If inequality flip the
- * result.
- */
- if(targets.getTarget() != null &&
- targets.getTarget().isPattern()) {
- final boolean ret = targets.getTarget().matchesPattern(entryDN);
- EnumTargetOperator op=targets.getTarget().getOperator();
- if(op == EnumTargetOperator.NOT_EQUALITY)
- {
+ }
+ /*
+ * There is a pattern, need to match the substring filter
+ * created when the ACI was decoded. If inequality flip the result.
+ */
+ if(target.isPattern()) {
+ final boolean ret = target.matchesPattern(entryDN);
+ if (target.getOperator() == NOT_EQUALITY) {
return !ret;
}
return ret;
+ }
}
return true;
}
+ private static boolean isInScopeOf(DN entryDN, DN targetDN, SearchScope scope) {
+ switch(scope.asEnum()) {
+ case BASE_OBJECT:
+ return targetDN.equals(entryDN);
+ case SINGLE_LEVEL:
+ /*
+ * We use the standard definition of single level to mean the
+ * immediate children only -- not the target entry itself.
+ * Sun CR 6535035 has been raised on DSEE:
+ * Non-standard interpretation of onelevel in ACI targetScope.
+ */
+ return targetDN.equals(entryDN.parent());
+ case WHOLE_SUBTREE:
+ return entryDN.isSubordinateOrEqualTo(targetDN);
+ case SUBORDINATES:
+ return entryDN.size() > targetDN.size() && entryDN.isSubordinateOrEqualTo(targetDN);
+ default:
+ return false;
+ }
+ }
/**
* The method is used to try and determine if a targetAttr expression that
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternDN.java b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternDN.java
index da12b45..52cf514 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternDN.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternDN.java
@@ -22,14 +22,16 @@
import static org.opends.server.util.StaticUtils.*;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.ldap.ByteString;
+import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.util.Reject;
-import org.forgerock.opendj.ldap.DN;
import org.opends.server.types.DirectoryException;
/**
@@ -59,20 +61,18 @@
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
/**
- * If the pattern did not include any Multiple-Whole-RDN wildcards, then
- * this is the sequence of RDN patterns in the DN pattern. Otherwise it
- * is null.
+ * If the pattern did not include any Multiple-Whole-RDN wildcards, then this
+ * is the sequence of RDN patterns in the DN pattern. Otherwise it is null.
*/
- PatternRDN[] equality;
-
+ private PatternRDN[] equality;
/**
* If the pattern included any Multiple-Whole-RDN wildcards, then these
* are the RDN pattern sequences that appear between those wildcards.
*/
- PatternRDN[] subInitial;
- List<PatternRDN[]> subAnyElements;
- PatternRDN[] subFinal;
+ private PatternRDN[] subInitial;
+ private List<PatternRDN[]> subAnyElements;
+ private PatternRDN[] subFinal;
/**
@@ -82,14 +82,14 @@
* suffix pattern but the pattern started with a Multiple-Whole-RDN wildcard
* (one or more RDN components allowed before matching elements).
*/
- boolean isSuffix;
+ private boolean isSuffix;
/**
* Create a DN pattern that does not include any Multiple-Whole-RDN wildcards.
* @param equality The sequence of RDN patterns making up the DN pattern.
*/
- private PatternDN(PatternRDN[] equality)
+ private PatternDN(PatternRDN... equality)
{
this.equality = equality;
}
@@ -122,109 +122,109 @@
*/
public boolean matchesDN(DN dn)
{
- if (equality != null)
+ return equality != null ? equalityMatchDN(dn) : substringMatchDN(dn);
+ }
+
+ private boolean equalityMatchDN(DN dn)
+ {
+ // There are no Multiple-Whole-RDN wildcards in the pattern.
+ if (equality.length != dn.size())
{
- // There are no Multiple-Whole-RDN wildcards in the pattern.
- if (equality.length != dn.size())
+ return false;
+ }
+
+ for (int i = 0; i < dn.size(); i++)
+ {
+ if (!equality[i].matchesRDN(dn.rdn(i)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private boolean substringMatchDN(DN dn)
+ {
+ // There are Multiple-Whole-RDN wildcards in the pattern.
+ int valueLength = dn.size();
+
+ int pos = 0;
+ if (subInitial != null)
+ {
+ int initialLength = subInitial.length;
+ if (initialLength > valueLength)
{
return false;
}
- for (int i = 0; i < dn.size(); i++)
+ for (; pos < initialLength; pos++)
{
- if (!equality[i].matchesRDN(dn.rdn(i)))
+ if (!subInitial[pos].matchesRDN(dn.rdn(pos)))
{
return false;
}
}
-
- return true;
+ pos++;
}
else
{
- // There are Multiple-Whole-RDN wildcards in the pattern.
- int valueLength = dn.size();
-
- int pos = 0;
- if (subInitial != null)
+ if (!isSuffix)
{
- int initialLength = subInitial.length;
- if (initialLength > valueLength)
- {
- return false;
- }
-
- for (; pos < initialLength; pos++)
- {
- if (!subInitial[pos].matchesRDN(dn.rdn(pos)))
- {
- return false;
- }
- }
pos++;
}
- else
+ }
+
+
+ if (subAnyElements != null && ! subAnyElements.isEmpty())
+ {
+ for (PatternRDN[] element : subAnyElements)
{
- if (!isSuffix)
+ int anyLength = element.length;
+
+ int end = valueLength - anyLength;
+ boolean match = false;
+ for (; pos < end; pos++)
{
- pos++;
- }
- }
-
-
- if (subAnyElements != null && ! subAnyElements.isEmpty())
- {
- for (PatternRDN[] element : subAnyElements)
- {
- int anyLength = element.length;
-
- int end = valueLength - anyLength;
- boolean match = false;
- for (; pos < end; pos++)
+ if (element[0].matchesRDN(dn.rdn(pos)))
{
- if (element[0].matchesRDN(dn.rdn(pos)))
+ if (subMatch(dn, pos, element, anyLength))
{
- if (subMatch(dn, pos, element, anyLength))
- {
- match = true;
- break;
- }
+ match = true;
+ break;
}
}
-
- if (match)
- {
- pos += anyLength + 1;
- }
- else
- {
- return false;
- }
}
- }
-
- if (subFinal != null)
- {
- int finalLength = subFinal.length;
-
- if (valueLength - finalLength < pos)
+ if (!match)
{
return false;
}
+ pos += anyLength + 1;
+ }
+ }
- pos = valueLength - finalLength;
- for (int i=0; i < finalLength; i++,pos++)
- {
- if (!subFinal[i].matchesRDN(dn.rdn(pos)))
- {
- return false;
- }
- }
+
+ if (subFinal != null)
+ {
+ int finalLength = subFinal.length;
+
+ if (valueLength - finalLength < pos)
+ {
+ return false;
}
- return pos <= valueLength;
+ pos = valueLength - finalLength;
+ for (int i=0; i < finalLength; i++,pos++)
+ {
+ if (!subFinal[i].matchesRDN(dn.rdn(pos)))
+ {
+ return false;
+ }
+ }
}
+
+ return pos <= valueLength;
}
private boolean subMatch(DN dn, int pos, PatternRDN[] element, int length)
@@ -246,8 +246,7 @@
* is not valid.
* @return A new DN pattern matcher.
*/
- public static PatternDN decodeSuffix(String pattern)
- throws DirectoryException
+ public static PatternDN decodeSuffix(String pattern) throws DirectoryException
{
// Parse the user supplied pattern.
PatternDN patternDN = decode(pattern);
@@ -281,22 +280,21 @@
* is not valid.
* @return A new DN pattern matcher.
*/
- public static PatternDN decode(String dnString)
- throws DirectoryException
+ public static PatternDN decode(String dnString) throws DirectoryException
{
- ArrayList<PatternRDN> rdnComponents = new ArrayList<>();
- ArrayList<Integer> doubleWildPos = new ArrayList<>();
+ List<PatternRDN> rdnComponents = new ArrayList<>();
+ List<Integer> doubleWildPos = new ArrayList<>();
// A null or empty DN is acceptable.
if (dnString == null)
{
- return new PatternDN(new PatternRDN[0]);
+ return new PatternDN();
}
int length = dnString.length();
if (length == 0)
{
- return new PatternDN(new PatternRDN[0]);
+ return new PatternDN();
}
@@ -311,12 +309,9 @@
{
// This means that the DN was completely comprised of spaces
// and therefore should be considered the same as a null or empty DN.
- return new PatternDN(new PatternRDN[0]);
+ return new PatternDN();
}
- else
- {
- c = dnString.charAt(pos);
- }
+ c = dnString.charAt(pos);
}
// We know that it's not an empty DN, so we can do the real
@@ -430,14 +425,14 @@
// RDN component and return the DN.
if (pos >= length)
{
- ArrayList<ByteString> arrayList = newArrayList(ByteString.empty());
- rdnComponents.add(new PatternRDN(name, arrayList, dnString));
+ List<ByteString> valuePattern = newArrayList(ByteString.empty());
+ rdnComponents.add(new PatternRDN(name, valuePattern, dnString));
break;
}
// Parse the value for this RDN component.
- ArrayList<ByteString> parsedValue = new ArrayList<>();
+ List<ByteString> parsedValue = new ArrayList<>();
pos = parseValuePattern(dnString, pos, parsedValue);
@@ -518,15 +513,10 @@
// This means that we hit the end of the value before
// finding a '='. This is illegal because there is no
// attribute-value separator.
- LocalizableMessage message =
- ERR_ATTR_SYNTAX_DN_END_WITH_ATTR_NAME.get(dnString, name);
throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ ERR_ATTR_SYNTAX_DN_END_WITH_ATTR_NAME.get(dnString, name));
}
- else
- {
- c = dnString.charAt(pos);
- }
+ c = dnString.charAt(pos);
}
@@ -539,8 +529,7 @@
else
{
LocalizableMessage message = ERR_ATTR_SYNTAX_DN_NO_EQUAL.get(dnString, name, c);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
}
@@ -558,8 +547,8 @@
// the RDN component and return the DN.
if (pos >= length)
{
- ArrayList<ByteString> arrayList = newArrayList(ByteString.empty());
- rdn.addValue(name, arrayList, dnString);
+ List<ByteString> valuePattern = newArrayList(ByteString.empty());
+ rdn.addValue(name, valuePattern, dnString);
rdnComponents.add(rdn);
break;
}
@@ -611,51 +600,46 @@
if (doubleWildPos.isEmpty())
{
- PatternRDN[] patterns = new PatternRDN[rdnComponents.size()];
- patterns = rdnComponents.toArray(patterns);
- return new PatternDN(patterns);
+ return new PatternDN(rdnComponents.toArray(new PatternRDN[rdnComponents.size()]));
}
- else
+
+ PatternRDN[] subInitial = null;
+ PatternRDN[] subFinal = null;
+ List<PatternRDN[]> subAnyElements = new ArrayList<>();
+
+ int i = 0;
+ int numComponents = rdnComponents.size();
+
+ int to = doubleWildPos.get(i);
+ if (to != 0)
{
- PatternRDN[] subInitial = null;
- PatternRDN[] subFinal = null;
- List<PatternRDN[]> subAnyElements = new ArrayList<>();
-
- int i = 0;
- int numComponents = rdnComponents.size();
-
- int to = doubleWildPos.get(i);
- if (to != 0)
- {
- // Initial piece.
- subInitial = new PatternRDN[to];
- subInitial = rdnComponents.subList(0, to).toArray(subInitial);
- }
-
- int from;
- for (; i < doubleWildPos.size() - 1; i++)
- {
- from = doubleWildPos.get(i);
- to = doubleWildPos.get(i+1);
- PatternRDN[] subAny = new PatternRDN[to-from];
- subAny = rdnComponents.subList(from, to).toArray(subAny);
- subAnyElements.add(subAny);
- }
-
- if (i < doubleWildPos.size())
- {
- from = doubleWildPos.get(i);
- if (from != numComponents)
- {
- // Final piece.
- subFinal = new PatternRDN[numComponents-from];
- subFinal = rdnComponents.subList(from, numComponents).
- toArray(subFinal);
- }
- }
-
- return new PatternDN(subInitial, subAnyElements, subFinal);
+ // Initial piece.
+ subInitial = new PatternRDN[to];
+ subInitial = rdnComponents.subList(0, to).toArray(subInitial);
}
+
+ int from;
+ for (; i < doubleWildPos.size() - 1; i++)
+ {
+ from = doubleWildPos.get(i);
+ to = doubleWildPos.get(i + 1);
+ PatternRDN[] subAny = new PatternRDN[to - from];
+ subAny = rdnComponents.subList(from, to).toArray(subAny);
+ subAnyElements.add(subAny);
+ }
+
+ if (i < doubleWildPos.size())
+ {
+ from = doubleWildPos.get(i);
+ if (from != numComponents)
+ {
+ // Final piece.
+ subFinal = new PatternRDN[numComponents - from];
+ subFinal = rdnComponents.subList(from, numComponents).toArray(subFinal);
+ }
+ }
+
+ return new PatternDN(subInitial, subAnyElements, subFinal);
}
@@ -697,8 +681,7 @@
// therefore the last non-space character of the DN must
// have been a comma. This is not acceptable.
LocalizableMessage message = ERR_ATTR_SYNTAX_DN_END_WITH_COMMA.get(dnString);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
}
}
}
@@ -731,10 +714,7 @@
case ')':
// None of these are allowed in an attribute name or any
// character immediately following it.
- LocalizableMessage message =
- ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR.get(dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw illegalCharacter(dnString, pos, c);
case '*':
@@ -743,12 +723,7 @@
break;
case '+':
- // None of these are allowed in an attribute name or any
- // character immediately following it.
- message =
- ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR.get(dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw illegalCharacter(dnString, pos, c);
case ',':
@@ -759,17 +734,12 @@
case '-':
// This will be allowed as long as it isn't the first
// character in the attribute name.
- if (attributeName.length() > 0)
+ if (attributeName.length() == 0)
{
- attributeName.append(c);
+ LocalizableMessage message = ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_INITIAL_DASH.get(dnString);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
}
- else
- {
- message =
- ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_INITIAL_DASH.get(dnString);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
- }
+ attributeName.append(c);
break;
@@ -783,12 +753,7 @@
case '/':
- // This is not allowed in an attribute name or any character
- // immediately following it.
- message =
- ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR.get(dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw illegalCharacter(dnString, pos, c);
case '0':
@@ -811,12 +776,7 @@
case ':':
- // Not allowed in an attribute name or any
- // character immediately following it.
- message =
- ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR.get(dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw illegalCharacter(dnString, pos, c);
case ';': // NOTE: attribute options are not allowed in a DN.
@@ -825,12 +785,7 @@
break;
case '<':
- // None of these are allowed in an attribute name or any
- // character immediately following it.
- message =
- ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR.get(dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw illegalCharacter(dnString, pos, c);
case '=':
@@ -842,12 +797,7 @@
case '>':
case '?':
case '@':
- // None of these are allowed in an attribute name or any
- // character immediately following it.
- message =
- ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR.get(dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw illegalCharacter(dnString, pos, c);
case 'A':
@@ -885,12 +835,7 @@
case '\\':
case ']':
case '^':
- // None of these are allowed in an attribute name or any
- // character immediately following it.
- message =
- ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR.get(dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw illegalCharacter(dnString, pos, c);
case '_':
@@ -899,12 +844,7 @@
case '`':
- // This is not allowed in an attribute name or any character
- // immediately following it.
- message =
- ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR.get(dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw illegalCharacter(dnString, pos, c);
case 'a':
@@ -941,10 +881,7 @@
default:
// This is not allowed in an attribute name or any character
// immediately following it.
- message =
- ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR.get(dnString, c, pos);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw illegalCharacter(dnString, pos, c);
}
@@ -964,8 +901,7 @@
if (attributeName.length() == 0)
{
LocalizableMessage message = ERR_ATTR_SYNTAX_DN_ATTR_NO_NAME.get(dnString);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
}
else if (checkForOID)
{
@@ -1045,6 +981,12 @@
return pos;
}
+ private static DirectoryException illegalCharacter(String dnString, int pos, char c)
+ {
+ return new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
+ ERR_ATTR_SYNTAX_DN_ATTR_ILLEGAL_CHAR.get(dnString, c, pos));
+ }
+
/**
* Parses the attribute value pattern from the provided DN pattern
@@ -1067,7 +1009,7 @@
* provided DN string.
*/
private static int parseValuePattern(String dnString, int pos,
- ArrayList<ByteString> attributeValues)
+ List<ByteString> attributeValues)
throws DirectoryException
{
// All leading spaces have already been stripped so we can start
@@ -1089,8 +1031,7 @@
if (pos+2 > length)
{
LocalizableMessage message = ERR_ATTR_SYNTAX_DN_HEX_VALUE_TOO_SHORT.get(dnString);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
}
for (int i=0; i < 2; i++)
@@ -1102,10 +1043,8 @@
}
else
{
- LocalizableMessage message =
- ERR_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT.get(dnString, c);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ LocalizableMessage message = ERR_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT.get(dnString, c);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
}
}
@@ -1129,18 +1068,14 @@
}
else
{
- LocalizableMessage message =
- ERR_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT.get(dnString, c);
- throw new DirectoryException(
- ResultCode.INVALID_DN_SYNTAX, message);
+ LocalizableMessage message = ERR_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT.get(dnString, c);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
}
}
else
{
- LocalizableMessage message =
- ERR_ATTR_SYNTAX_DN_HEX_VALUE_TOO_SHORT.get(dnString);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ LocalizableMessage message = ERR_ATTR_SYNTAX_DN_HEX_VALUE_TOO_SHORT.get(dnString);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
}
}
else if (c == ' ' || c == ',' || c == ';')
@@ -1151,10 +1086,8 @@
}
else
{
- LocalizableMessage message =
- ERR_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT.get(dnString, c);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ LocalizableMessage message = ERR_ATTR_SYNTAX_DN_INVALID_HEX_DIGIT.get(dnString, c);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
}
}
@@ -1181,8 +1114,7 @@
// should continue until the corresponding closing quotation mark.
else if (c == '"')
{
- // Keep reading until we find an unescaped closing quotation
- // mark.
+ // Keep reading until we find an unescaped closing quotation mark.
boolean escaped = false;
StringBuilder valueString = new StringBuilder();
while (true)
@@ -1192,8 +1124,7 @@
// We hit the end of the DN before the closing quote.
// That's an error.
LocalizableMessage message = ERR_ATTR_SYNTAX_DN_UNMATCHED_QUOTE.get(dnString);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
}
c = dnString.charAt(pos++);
@@ -1251,15 +1182,13 @@
}
- // Keep reading until we find an unescaped comma or plus sign or
- // the end of the DN.
+ // Keep reading until we find an unescaped comma or plus sign or the end of the DN.
while (true)
{
if (pos >= length)
{
- // This is the end of the DN and therefore the end of the
- // value. If there are any hex characters, then we need to
- // deal with them accordingly.
+ // This is the end of the DN and therefore the end of the value.
+ // If there are any hex characters, then we need to deal with them accordingly.
appendHexChars(dnString, valueString, hexChars);
break;
}
@@ -1267,44 +1196,31 @@
c = dnString.charAt(pos++);
if (escaped)
{
- // The previous character was an escape, so we'll take this
- // one. However, this could be a hex digit, and if that's
+ // The previous character was an escape, so we'll take this one.
+ // However, this could be a hex digit, and if that's
// the case then the escape would actually be in front of
- // two hex digits that should be treated as a special
- // character.
+ // two hex digits that should be treated as a special character.
if (isHexDigit(c))
{
- // It is a hexadecimal digit, so the next digit must be
- // one too. However, this could be just one in a series
- // of escaped hex pairs that is used in a string
- // containing one or more multi-byte UTF-8 characters so
- // we can't just treat this byte in isolation. Collect
- // all the bytes together and make sure to take care of
- // these hex bytes before appending anything else to the
- // value.
+ // It is a hexadecimal digit, so the next digit must be one too.
+ // However, this could be just one in a series of escaped hex pairs
+ // that is used in a string containing one or more multi-byte UTF-8
+ // characters so we can't just treat this byte in isolation.
+ // Collect all the bytes together and make sure to take care of
+ // these hex bytes before appending anything else to the value.
if (pos >= length)
{
- LocalizableMessage message =
- ERR_ATTR_SYNTAX_DN_ESCAPED_HEX_VALUE_INVALID.get(dnString);
- throw new DirectoryException(
- ResultCode.INVALID_DN_SYNTAX, message);
+ LocalizableMessage message = ERR_ATTR_SYNTAX_DN_ESCAPED_HEX_VALUE_INVALID.get(dnString);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
}
- else
+ char c2 = dnString.charAt(pos++);
+ if (!isHexDigit(c2))
{
- char c2 = dnString.charAt(pos++);
- if (isHexDigit(c2))
- {
- hexChars.append(c);
- hexChars.append(c2);
- }
- else
- {
- LocalizableMessage message =
- ERR_ATTR_SYNTAX_DN_ESCAPED_HEX_VALUE_INVALID.get(dnString);
- throw new DirectoryException(
- ResultCode.INVALID_DN_SYNTAX, message);
- }
+ LocalizableMessage message = ERR_ATTR_SYNTAX_DN_ESCAPED_HEX_VALUE_INVALID.get(dnString);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
}
+ hexChars.append(c);
+ hexChars.append(c2);
}
else
{
@@ -1337,8 +1253,7 @@
{
LocalizableMessage message =
WARN_PATTERN_DN_CONSECUTIVE_WILDCARDS_IN_VALUE.get(dnString);
- throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX,
- message);
+ throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
}
attributeValues.add(ByteString.valueOfUtf8(valueString));
valueString = new StringBuilder();
@@ -1360,15 +1275,12 @@
int lastPos = valueString.length() - 1;
while (lastPos > 0)
{
- if (valueString.charAt(lastPos) == ' ')
- {
- valueString.delete(lastPos, lastPos+1);
- lastPos--;
- }
- else
+ if (valueString.charAt(lastPos) != ' ')
{
break;
}
+ valueString.delete(lastPos, lastPos + 1);
+ lastPos--;
}
}
@@ -1413,4 +1325,30 @@
ERR_ATTR_SYNTAX_DN_ATTR_VALUE_DECODE_FAILURE.get(dnString, e));
}
}
+
+ @Override
+ public String toString()
+ {
+ if (this.equality != null)
+ {
+ return getClass().getSimpleName() + "(equality=" + Arrays.toString(equality) + ")";
+ }
+ StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append("(substring:");
+ if (subInitial!=null) {
+ sb.append(" subInitial=").append(Arrays.toString(subInitial));
+ }
+ sb.append(", subAnyElements=[");
+ final Iterator<PatternRDN[]> iterator = subAnyElements.iterator();
+ if (iterator.hasNext()) {
+ sb.append(Arrays.toString(iterator.next()));
+
+ while (iterator.hasNext()) {
+ sb.append(", ");
+ sb.append(Arrays.toString(iterator.next()));
+ }
+ }
+ sb.append("]");
+ sb.append(", subFinal=").append(Arrays.toString(subFinal)).append(")");
+ return sb.toString();
+ }
}
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternRDN.java b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternRDN.java
index 2411ab9..75a1d51 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternRDN.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/PatternRDN.java
@@ -19,10 +19,9 @@
import static org.opends.messages.AccessControlMessages.*;
import static org.opends.server.util.CollectionUtils.*;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
-import java.util.Set;
import java.util.TreeMap;
import org.forgerock.i18n.LocalizableMessage;
@@ -30,6 +29,7 @@
import org.forgerock.opendj.ldap.AVA;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
+import org.forgerock.opendj.ldap.RDN;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.forgerock.opendj.ldap.schema.MatchingRule;
@@ -37,7 +37,6 @@
import org.opends.server.types.Attribute;
import org.opends.server.types.Attributes;
import org.opends.server.types.DirectoryException;
-import org.forgerock.opendj.ldap.RDN;
/**
* This class is used to match RDN patterns containing wildcards in either
@@ -61,10 +60,7 @@
* a list of one element A. The value "*A*" is represented as a list
* of three elements "", A and "".
*/
- private ArrayList<ArrayList<ByteString>> valuePatterns;
- /** The number of attribute-value pairs in this RDN pattern. */
- private int numValues;
-
+ private List<List<ByteString>> valuePatterns;
/**
* Create a new RDN pattern composed of a single attribute-value pair.
@@ -73,7 +69,7 @@
* @param dnString The DN pattern containing the attribute-value pair.
* @throws DirectoryException If the attribute-value pair is not valid.
*/
- public PatternRDN(String type, ArrayList<ByteString> valuePattern, String dnString)
+ public PatternRDN(String type, List<ByteString> valuePattern, String dnString)
throws DirectoryException
{
// Only Whole-Type wildcards permitted.
@@ -89,7 +85,6 @@
hasTypeWildcard = true;
}
- numValues = 1;
typePatterns = new String[] { type };
valuePatterns = newArrayList(valuePattern);
}
@@ -105,9 +100,7 @@
* this RDN, or <CODE>false</CODE> if it was not (e.g., it
* was already present).
*/
- public boolean addValue(String type, ArrayList<ByteString> valuePattern,
- String dnString)
- throws DirectoryException
+ public boolean addValue(String type, List<ByteString> valuePattern, String dnString) throws DirectoryException
{
// No type wildcards permitted in multi-valued patterns.
if (hasTypeWildcard || type.contains("*"))
@@ -117,13 +110,9 @@
throw new DirectoryException(ResultCode.INVALID_DN_SYNTAX, message);
}
- numValues++;
-
- String[] newTypes = new String[numValues];
- System.arraycopy(typePatterns, 0, newTypes, 0,
- typePatterns.length);
- newTypes[typePatterns.length] = type;
- typePatterns = newTypes;
+ int oldLength = typePatterns.length;
+ typePatterns = Arrays.copyOf(typePatterns, oldLength + 1);
+ typePatterns[oldLength] = type;
valuePatterns.add(valuePattern);
@@ -140,7 +129,7 @@
*/
public int getNumValues()
{
- return numValues;
+ return typePatterns.length;
}
@@ -164,40 +153,27 @@
return false;
}
- AVA firstAVA = rdn.getFirstAVA();
- AttributeType thatType = firstAVA.getAttributeType();
+ AVA ava = rdn.getFirstAVA();
if (!typePatterns[0].equals("*"))
{
AttributeType thisType = DirectoryServer.getAttributeType(typePatterns[0]);
- if (thisType.isPlaceHolder() || !thisType.equals(thatType))
+ if (thisType.isPlaceHolder() || !thisType.equals(ava.getAttributeType()))
{
return false;
}
}
- return matchValuePattern(valuePatterns.get(0), thatType, firstAVA.getAttributeValue());
+ return matchValuePattern(valuePatterns.get(0), ava);
}
- if (hasTypeWildcard)
- {
- return false;
- }
-
- if (numValues != rdn.size())
+ if (hasTypeWildcard || typePatterns.length != rdn.size())
{
return false;
}
// Sort the attribute-value pairs by attribute type.
- TreeMap<String,ArrayList<ByteString>> patternMap = new TreeMap<>();
- TreeMap<String, ByteString> rdnMap = new TreeMap<>();
-
- for (AVA ava : rdn)
- {
- rdnMap.put(ava.getAttributeType().getNameOrOID(), ava.getAttributeValue());
- }
-
- for (int i = 0; i < numValues; i++)
+ TreeMap<String, List<ByteString>> patternMap = new TreeMap<>();
+ for (int i = 0; i < typePatterns.length; i++)
{
AttributeType type = DirectoryServer.getAttributeType(typePatterns[i]);
if (type.isPlaceHolder())
@@ -207,18 +183,12 @@
patternMap.put(type.getNameOrOID(), valuePatterns.get(i));
}
- Set<String> patternKeys = patternMap.keySet();
- Set<String> rdnKeys = rdnMap.keySet();
- Iterator<String> patternKeyIter = patternKeys.iterator();
- for (String rdnKey : rdnKeys)
+ Iterator<String> patternKeyIter = patternMap.keySet().iterator();
+ for (AVA ava : rdn)
{
- if (!rdnKey.equals(patternKeyIter.next()))
- {
- return false;
- }
-
- AttributeType rdnAttrType = DirectoryServer.getAttributeType(rdnKey);
- if (!matchValuePattern(patternMap.get(rdnKey), rdnAttrType, rdnMap.get(rdnKey)))
+ String rdnKey = ava.getAttributeType().getNameOrOID();
+ if (!rdnKey.equals(patternKeyIter.next())
+ || !matchValuePattern(patternMap.get(rdnKey), ava))
{
return false;
}
@@ -227,7 +197,6 @@
return true;
}
-
/**
* Determine whether a value pattern matches a given attribute-value pair.
* @param pattern The value pattern where each element of the list is a
@@ -236,15 +205,15 @@
* @param value The value of the attribute-value pair.
* @return true if the value pattern matches the attribute-value pair.
*/
- private boolean matchValuePattern(List<ByteString> pattern,
- AttributeType type,
- ByteString value)
+ private boolean matchValuePattern(List<ByteString> pattern, AVA ava)
{
if (pattern == null)
{
return true;
}
+ final AttributeType type = ava.getAttributeType();
+ ByteString value = ava.getAttributeValue();
try
{
if (pattern.size() == 1)
@@ -288,4 +257,24 @@
}
}
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append("(");
+ for (int i = 0; i < typePatterns.length; i++)
+ {
+ sb.append(typePatterns[i]).append("=");
+ List<ByteString> patterns = valuePatterns.get(i);
+ if (patterns.size() == 1)
+ {
+ sb.append(patterns.get(0));
+ }
+ else
+ {
+ sb.append(patterns);
+ }
+ }
+ sb.append(")");
+ return sb.toString();
+ }
}
--
Gitblit v1.10.0