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