001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.server.core.authz.support; 021 022 023import java.util.Collection; 024import java.util.Iterator; 025 026import org.apache.directory.api.ldap.aci.ACITuple; 027import org.apache.directory.api.ldap.aci.ProtectedItem; 028import org.apache.directory.api.ldap.aci.protectedItem.AllAttributeValuesItem; 029import org.apache.directory.api.ldap.aci.protectedItem.AttributeTypeItem; 030import org.apache.directory.api.ldap.aci.protectedItem.AttributeValueItem; 031import org.apache.directory.api.ldap.aci.protectedItem.ClassesItem; 032import org.apache.directory.api.ldap.aci.protectedItem.MaxImmSubItem; 033import org.apache.directory.api.ldap.aci.protectedItem.MaxValueCountElem; 034import org.apache.directory.api.ldap.aci.protectedItem.MaxValueCountItem; 035import org.apache.directory.api.ldap.aci.protectedItem.RangeOfValuesItem; 036import org.apache.directory.api.ldap.aci.protectedItem.RestrictedByElem; 037import org.apache.directory.api.ldap.aci.protectedItem.RestrictedByItem; 038import org.apache.directory.api.ldap.aci.protectedItem.SelfValueItem; 039import org.apache.directory.api.ldap.model.constants.SchemaConstants; 040import org.apache.directory.api.ldap.model.entry.Attribute; 041import org.apache.directory.api.ldap.model.entry.Entry; 042import org.apache.directory.api.ldap.model.entry.Value; 043import org.apache.directory.api.ldap.model.exception.LdapException; 044import org.apache.directory.api.ldap.model.name.Dn; 045import org.apache.directory.api.ldap.model.schema.AttributeType; 046import org.apache.directory.api.ldap.model.schema.SchemaManager; 047import org.apache.directory.server.core.api.event.Evaluator; 048import org.apache.directory.server.core.api.subtree.RefinementEvaluator; 049import org.apache.directory.server.i18n.I18n; 050 051 052/** 053 * An {@link ACITupleFilter} that discards all tuples whose {@link ProtectedItem}s 054 * are not related with the operation. (18.8.3.2, X.501) 055 * 056 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 057 */ 058public class RelatedProtectedItemFilter implements ACITupleFilter 059{ 060 private final RefinementEvaluator refinementEvaluator; 061 private final Evaluator entryEvaluator; 062 private final SchemaManager schemaManager; 063 064 065 public RelatedProtectedItemFilter( RefinementEvaluator refinementEvaluator, Evaluator entryEvaluator, 066 SchemaManager schemaManager ) 067 { 068 this.refinementEvaluator = refinementEvaluator; 069 this.entryEvaluator = entryEvaluator; 070 this.schemaManager = schemaManager; 071 } 072 073 074 /** 075 * {@inheritDoc} 076 */ 077 @Override 078 public Collection<ACITuple> filter( AciContext aciContext, OperationScope scope, Entry userEntry ) 079 throws LdapException 080 { 081 if ( aciContext.getAciTuples().isEmpty() ) 082 { 083 return aciContext.getAciTuples(); 084 } 085 086 for ( Iterator<ACITuple> i = aciContext.getAciTuples().iterator(); i.hasNext(); ) 087 { 088 ACITuple tuple = i.next(); 089 090 if ( !isRelated( tuple, scope, aciContext.getUserDn(), aciContext.getEntryDn(), 091 aciContext.getAttributeType(), aciContext.getAttrValue(), aciContext.getEntry() ) ) 092 { 093 i.remove(); 094 } 095 } 096 097 return aciContext.getAciTuples(); 098 } 099 100 101 private boolean isRelated( ACITuple tuple, OperationScope scope, Dn userName, Dn entryName, 102 AttributeType attributeType, Value attrValue, Entry entry ) throws LdapException, InternalError 103 { 104 String oid = null; 105 106 if ( attributeType != null ) 107 { 108 oid = attributeType.getOid(); 109 } 110 111 for ( ProtectedItem item : tuple.getProtectedItems() ) 112 { 113 if ( item == ProtectedItem.ENTRY ) 114 { 115 if ( scope != OperationScope.ENTRY ) 116 { 117 continue; 118 } 119 120 return true; 121 } 122 else if ( ( item == ProtectedItem.ALL_USER_ATTRIBUTE_TYPES ) 123 || ( item == ProtectedItem.ALL_USER_ATTRIBUTE_TYPES_AND_VALUES ) ) 124 { 125 if ( scope != OperationScope.ATTRIBUTE_TYPE && scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE ) 126 { 127 continue; 128 } 129 130 return true; 131 } 132 else if ( item instanceof AllAttributeValuesItem ) 133 { 134 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE ) 135 { 136 continue; 137 } 138 139 AllAttributeValuesItem aav = ( AllAttributeValuesItem ) item; 140 141 for ( Iterator<AttributeType> iterator = aav.iterator(); iterator.hasNext(); ) 142 { 143 AttributeType attr = iterator.next(); 144 145 if ( oid.equals( attr.getOid() ) ) 146 { 147 return true; 148 } 149 } 150 } 151 else if ( item instanceof AttributeTypeItem ) 152 { 153 if ( scope != OperationScope.ATTRIBUTE_TYPE ) 154 { 155 continue; 156 } 157 158 AttributeTypeItem at = ( AttributeTypeItem ) item; 159 160 for ( Iterator<AttributeType> iterator = at.iterator(); iterator.hasNext(); ) 161 { 162 AttributeType attr = iterator.next(); 163 164 if ( oid.equals( attr.getOid() ) ) 165 { 166 return true; 167 } 168 } 169 } 170 else if ( item instanceof AttributeValueItem ) 171 { 172 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE ) 173 { 174 continue; 175 } 176 177 AttributeValueItem av = ( AttributeValueItem ) item; 178 179 for ( Iterator<Attribute> j = av.iterator(); j.hasNext(); ) 180 { 181 Attribute entryAttribute = j.next(); 182 183 AttributeType attr = entryAttribute.getAttributeType(); 184 String attrOid; 185 186 if ( attr != null ) 187 { 188 attrOid = entryAttribute.getAttributeType().getOid(); 189 } 190 else 191 { 192 attr = schemaManager.lookupAttributeTypeRegistry( entryAttribute.getId() ); 193 attrOid = attr.getOid(); 194 entryAttribute.apply( attr ); 195 } 196 197 if ( oid.equals( attrOid ) && entryAttribute.contains( attrValue ) ) 198 { 199 return true; 200 } 201 } 202 } 203 else if ( item instanceof ClassesItem ) 204 { 205 ClassesItem refinement = ( ClassesItem ) item; 206 207 if ( refinementEvaluator 208 .evaluate( refinement.getClasses(), entry.get( SchemaConstants.OBJECT_CLASS_AT ) ) ) 209 { 210 return true; 211 } 212 } 213 else if ( item instanceof MaxImmSubItem ) 214 { 215 return true; 216 } 217 else if ( item instanceof MaxValueCountItem ) 218 { 219 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE ) 220 { 221 continue; 222 } 223 224 MaxValueCountItem mvc = ( MaxValueCountItem ) item; 225 226 for ( Iterator<MaxValueCountElem> j = mvc.iterator(); j.hasNext(); ) 227 { 228 MaxValueCountElem mvcItem = j.next(); 229 230 if ( oid.equals( mvcItem.getAttributeType().getOid() ) ) 231 { 232 return true; 233 } 234 } 235 } 236 else if ( item instanceof RangeOfValuesItem ) 237 { 238 RangeOfValuesItem rov = ( RangeOfValuesItem ) item; 239 240 if ( entryEvaluator.evaluate( rov.getRefinement(), entryName, entry ) ) 241 { 242 return true; 243 } 244 } 245 else if ( item instanceof RestrictedByItem ) 246 { 247 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE ) 248 { 249 continue; 250 } 251 252 RestrictedByItem rb = ( RestrictedByItem ) item; 253 254 for ( Iterator<RestrictedByElem> j = rb.iterator(); j.hasNext(); ) 255 { 256 RestrictedByElem rbItem = j.next(); 257 258 if ( oid.equals( rbItem.getAttributeType().getOid() ) ) 259 { 260 return true; 261 } 262 } 263 } 264 else if ( item instanceof SelfValueItem ) 265 { 266 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE && scope != OperationScope.ATTRIBUTE_TYPE ) 267 { 268 continue; 269 } 270 271 SelfValueItem sv = ( SelfValueItem ) item; 272 273 for ( Iterator<AttributeType> iterator = sv.iterator(); iterator.hasNext(); ) 274 { 275 AttributeType attr = iterator.next(); 276 277 if ( oid.equals( attr.getOid() ) ) 278 { 279 Attribute entryAttribute = entry.get( oid ); 280 281 if ( ( entryAttribute != null ) && entryAttribute.contains( userName.getNormName() ) ) 282 { 283 return true; 284 } 285 } 286 } 287 } 288 else 289 { 290 throw new InternalError( I18n.err( I18n.ERR_232, item.getClass().getName() ) ); 291 } 292 } 293 294 return false; 295 } 296}