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 */
020 package org.apache.directory.server.core.authz.support;
021
022
023 import java.util.Collection;
024 import java.util.Iterator;
025
026 import javax.naming.NamingException;
027 import javax.naming.directory.Attribute;
028
029 import org.apache.directory.server.core.event.Evaluator;
030 import org.apache.directory.server.core.interceptor.context.OperationContext;
031 import org.apache.directory.server.core.subtree.RefinementEvaluator;
032 import org.apache.directory.server.i18n.I18n;
033 import org.apache.directory.shared.ldap.aci.ACITuple;
034 import org.apache.directory.shared.ldap.aci.MicroOperation;
035 import org.apache.directory.shared.ldap.aci.ProtectedItem;
036 import org.apache.directory.shared.ldap.aci.ProtectedItem.MaxValueCountItem;
037 import org.apache.directory.shared.ldap.aci.ProtectedItem.RestrictedByItem;
038 import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
039 import org.apache.directory.shared.ldap.constants.SchemaConstants;
040 import org.apache.directory.shared.ldap.entry.EntryAttribute;
041 import org.apache.directory.shared.ldap.entry.ServerEntry;
042 import org.apache.directory.shared.ldap.entry.Value;
043 import org.apache.directory.shared.ldap.exception.LdapException;
044 import org.apache.directory.shared.ldap.name.DN;
045 import org.apache.directory.shared.ldap.schema.AttributeType;
046 import org.apache.directory.shared.ldap.schema.SchemaManager;
047 import org.apache.directory.shared.ldap.schema.registries.OidRegistry;
048 import org.apache.directory.shared.ldap.util.AttributeUtils;
049
050
051 /**
052 * An {@link ACITupleFilter} that discards all tuples whose {@link ProtectedItem}s
053 * are not related with the operation. (18.8.3.2, X.501)
054 *
055 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
056 * @version $Rev: 927146 $, $Date: 2010-03-24 20:39:54 +0200 (Wed, 24 Mar 2010) $
057 */
058 public 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 OidRegistry oidRegistry, SchemaManager schemaManager )
067 {
068 this.refinementEvaluator = refinementEvaluator;
069 this.entryEvaluator = entryEvaluator;
070 this.schemaManager = schemaManager;
071 }
072
073
074 public Collection<ACITuple> filter(
075 SchemaManager schemaManager,
076 Collection<ACITuple> tuples,
077 OperationScope scope,
078 OperationContext opContext,
079 Collection<DN> userGroupNames,
080 DN userName,
081 ServerEntry userEntry,
082 AuthenticationLevel authenticationLevel,
083 DN entryName,
084 String attrId,
085 Value<?> attrValue,
086 ServerEntry entry,
087 Collection<MicroOperation> microOperations,
088 ServerEntry entryView )
089 throws LdapException, NamingException
090 {
091 if ( tuples.size() == 0 )
092 {
093 return tuples;
094 }
095
096 for ( Iterator<ACITuple> i = tuples.iterator(); i.hasNext(); )
097 {
098 ACITuple tuple = i.next();
099
100 if ( !isRelated( tuple, scope, userName, entryName, attrId, attrValue, entry ) )
101 {
102 i.remove();
103 }
104 }
105
106 return tuples;
107 }
108
109
110 private boolean isRelated( ACITuple tuple, OperationScope scope, DN userName, DN entryName, String attrId,
111 Value<?> attrValue, ServerEntry entry ) throws LdapException, NamingException, InternalError
112 {
113 String oid = null;
114
115 if ( attrId != null )
116 {
117 oid = schemaManager.getAttributeTypeRegistry().getOidByName( attrId );
118 }
119
120 for ( ProtectedItem item : tuple.getProtectedItems() )
121 {
122 if ( item == ProtectedItem.ENTRY )
123 {
124 if ( scope == OperationScope.ENTRY )
125 {
126 return true;
127 }
128 }
129 else if ( item == ProtectedItem.ALL_USER_ATTRIBUTE_TYPES )
130 {
131 if ( scope != OperationScope.ATTRIBUTE_TYPE && scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE )
132 {
133 continue;
134 }
135
136 return true;
137 }
138 else if ( item == ProtectedItem.ALL_USER_ATTRIBUTE_TYPES_AND_VALUES )
139 {
140 if ( scope != OperationScope.ATTRIBUTE_TYPE && scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE )
141 {
142 continue;
143 }
144
145 return true;
146 }
147 else if ( item instanceof ProtectedItem.AllAttributeValues )
148 {
149 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE )
150 {
151 continue;
152 }
153
154 ProtectedItem.AllAttributeValues aav = ( ProtectedItem.AllAttributeValues ) item;
155
156 for ( Iterator<String> j = aav.iterator(); j.hasNext(); )
157 {
158 if ( oid.equals( schemaManager.getAttributeTypeRegistry().getOidByName( j.next() ) ) )
159 {
160 return true;
161 }
162 }
163 }
164 else if ( item instanceof ProtectedItem.AttributeType )
165 {
166 if ( scope != OperationScope.ATTRIBUTE_TYPE )
167 {
168 continue;
169 }
170
171 ProtectedItem.AttributeType at = ( ProtectedItem.AttributeType ) item;
172
173 for ( Iterator<String> j = at.iterator(); j.hasNext(); )
174 {
175 if ( oid.equals( schemaManager.getAttributeTypeRegistry().getOidByName( j.next() ) ) )
176 {
177 return true;
178 }
179 }
180 }
181 else if ( item instanceof ProtectedItem.AttributeValue )
182 {
183 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE )
184 {
185 continue;
186 }
187
188 ProtectedItem.AttributeValue av = ( ProtectedItem.AttributeValue ) item;
189 for ( Iterator<Attribute> j = av.iterator(); j.hasNext(); )
190 {
191 Attribute attr = j.next();
192 String attrOid = schemaManager.getAttributeTypeRegistry().getOidByName( attr.getID() );
193 AttributeType attrType = schemaManager.lookupAttributeTypeRegistry( attrOid );
194
195 if ( oid.equals( attrOid ) && AttributeUtils.containsValue( attr, attrValue, attrType ) )
196 {
197 return true;
198 }
199 }
200 }
201 else if ( item instanceof ProtectedItem.Classes )
202 {
203 ProtectedItem.Classes c = ( ProtectedItem.Classes ) item;
204 if ( refinementEvaluator.evaluate( c.getClasses(), entry.get( SchemaConstants.OBJECT_CLASS_AT ) ) )
205 {
206 return true;
207 }
208 }
209 else if ( item instanceof ProtectedItem.MaxImmSub )
210 {
211 return true;
212 }
213 else if ( item instanceof ProtectedItem.MaxValueCount )
214 {
215 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE )
216 {
217 continue;
218 }
219
220 ProtectedItem.MaxValueCount mvc = ( ProtectedItem.MaxValueCount ) item;
221 for ( Iterator<MaxValueCountItem> j = mvc.iterator(); j.hasNext(); )
222 {
223 MaxValueCountItem mvcItem = j.next();
224
225 if ( oid.equals( schemaManager.getAttributeTypeRegistry().getOidByName( mvcItem.getAttributeType() ) ) )
226 {
227 return true;
228 }
229 }
230 }
231 else if ( item instanceof ProtectedItem.RangeOfValues )
232 {
233 ProtectedItem.RangeOfValues rov = ( ProtectedItem.RangeOfValues ) item;
234
235 if ( entryEvaluator.evaluate( rov.getFilter(), entryName.getNormName(), entry ) )
236 {
237 return true;
238 }
239 }
240 else if ( item instanceof ProtectedItem.RestrictedBy )
241 {
242 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE )
243 {
244 continue;
245 }
246
247 ProtectedItem.RestrictedBy rb = ( ProtectedItem.RestrictedBy ) item;
248 for ( Iterator<RestrictedByItem> j = rb.iterator(); j.hasNext(); )
249 {
250 RestrictedByItem rbItem = j.next();
251 if ( oid.equals( schemaManager.getAttributeTypeRegistry().getOidByName( rbItem.getAttributeType() ) ) )
252 {
253 return true;
254 }
255 }
256 }
257 else if ( item instanceof ProtectedItem.SelfValue )
258 {
259 if ( scope != OperationScope.ATTRIBUTE_TYPE_AND_VALUE && scope != OperationScope.ATTRIBUTE_TYPE )
260 {
261 continue;
262 }
263
264 ProtectedItem.SelfValue sv = ( ProtectedItem.SelfValue ) item;
265 for ( Iterator<String> j = sv.iterator(); j.hasNext(); )
266 {
267 String svItem = j.next();
268
269 if ( oid.equals( schemaManager.getAttributeTypeRegistry().getOidByName( svItem ) ) )
270 {
271 EntryAttribute attr = entry.get( oid );
272
273 if ( ( attr != null ) &&
274 ( ( attr.contains( userName.getNormName() ) ||
275 ( attr.contains( userName.getName() ) ) ) ) )
276 {
277 return true;
278 }
279 }
280 }
281 }
282 else
283 {
284 throw new InternalError( I18n.err( I18n.ERR_232, item.getClass().getName() ) );
285 }
286 }
287
288 return false;
289 }
290 }