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 legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2008 Sun Microsystems, Inc. 025 * Portions Copyright 2014-2015 ForgeRock AS 026 */ 027package org.opends.server.authorization.dseecompat; 028 029import java.util.regex.Pattern; 030 031import org.opends.server.types.DN; 032import org.opends.server.types.DirectoryException; 033import org.opends.server.types.LDAPURL; 034 035import static org.opends.messages.AccessControlMessages.*; 036import static org.opends.server.authorization.dseecompat.Aci.*; 037 038/** 039 * A class representing an ACI target keyword. 040 */ 041public 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; 052 053 /** 054 * The target DN from the URL or null if it was a wild-card pattern. 055 */ 056 private DN urlDN; 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; 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 (!NULL_LDAP_URL.equals(target) && !Pattern.matches(LDAP_URL, target)) { 086 throw new AciException(WARN_ACI_SYNTAX_INVALID_TARGETKEYWORD_EXPRESSION.get(target)); 087 } 088 LDAPURL targetURL = LDAPURL.decode(target, false); 089 if (targetURL.getRawBaseDN().contains("*")) { 090 this.isPattern=true; 091 patternDN = PatternDN.decodeSuffix(targetURL.getRawBaseDN()); 092 } else { 093 urlDN=targetURL.getBaseDN(); 094 if(!urlDN.isDescendantOf(aciDN)) { 095 throw new AciException(WARN_ACI_SYNTAX_TARGET_DN_NOT_DESCENDENTOF.get(urlDN, aciDN)); 096 } 097 } 098 } 099 catch (DirectoryException e){ 100 throw new AciException(WARN_ACI_SYNTAX_INVALID_TARGETKEYWORD_EXPRESSION.get(target)); 101 } 102 } 103 104 /** 105 * Decode an expression string representing a target keyword expression. 106 * @param operator An enumeration of the operation of this target. 107 * @param expr A string representation of the target. 108 * @param aciDN The DN of the ACI entry used for a descendant check. 109 * @return A Target class representing this target. 110 * @throws AciException If the expression string is invalid. 111 */ 112 public static Target decode(EnumTargetOperator operator, 113 String expr, DN aciDN) 114 throws AciException { 115 return new Target(operator, expr, aciDN); 116 } 117 118 /** 119 * Returns the operator of this expression. 120 * @return An enumeration of the operation value. 121 */ 122 public EnumTargetOperator getOperator() { 123 return operator; 124 } 125 126 /** 127 * Returns the URL DN of the expression. 128 * @return A DN of the URL or null if the URL contained a DN pattern. 129 */ 130 public DN getDN() { 131 return urlDN; 132 } 133 134 /** 135 * Returns boolean if a pattern was seen during parsing. 136 * @return True if the URL contained a DN pattern. 137 */ 138 public boolean isPattern() { 139 return isPattern; 140 } 141 142 /** 143 * This method tries to match a pattern against a DN. 144 * @param dn The DN to try an match. 145 * @return True if the pattern matches. 146 */ 147 public boolean matchesPattern(DN dn) { 148 return patternDN.matchesDN(dn); 149 } 150}