1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.core.exception;
21
22
23 import org.apache.commons.collections4.map.LRUMap;
24 import org.apache.directory.api.ldap.model.constants.SchemaConstants;
25 import org.apache.directory.api.ldap.model.entry.Attribute;
26 import org.apache.directory.api.ldap.model.entry.Entry;
27 import org.apache.directory.api.ldap.model.entry.Value;
28 import org.apache.directory.api.ldap.model.exception.LdapAliasException;
29 import org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException;
30 import org.apache.directory.api.ldap.model.exception.LdapException;
31 import org.apache.directory.api.ldap.model.exception.LdapNoSuchObjectException;
32 import org.apache.directory.api.ldap.model.exception.LdapUnwillingToPerformException;
33 import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
34 import org.apache.directory.api.ldap.model.name.Dn;
35 import org.apache.directory.server.core.api.CoreSession;
36 import org.apache.directory.server.core.api.DirectoryService;
37 import org.apache.directory.server.core.api.InterceptorEnum;
38 import org.apache.directory.server.core.api.entry.ClonedServerEntry;
39 import org.apache.directory.server.core.api.interceptor.BaseInterceptor;
40 import org.apache.directory.server.core.api.interceptor.Interceptor;
41 import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
42 import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext;
43 import org.apache.directory.server.core.api.interceptor.context.HasEntryOperationContext;
44 import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
45 import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext;
46 import org.apache.directory.server.core.api.interceptor.context.MoveAndRenameOperationContext;
47 import org.apache.directory.server.core.api.interceptor.context.MoveOperationContext;
48 import org.apache.directory.server.core.api.interceptor.context.OperationContext;
49 import org.apache.directory.server.core.api.interceptor.context.RenameOperationContext;
50 import org.apache.directory.server.core.api.partition.Partition;
51 import org.apache.directory.server.core.api.partition.PartitionNexus;
52 import org.apache.directory.server.i18n.I18n;
53
54
55
56
57
58
59
60
61
62
63 public class ExceptionInterceptor extends BaseInterceptor
64 {
65 private PartitionNexus nexus;
66 private Dn subschemSubentryDn;
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 private final LRUMap notAliasCache = new LRUMap( DEFAULT_CACHE_SIZE );
87
88
89 private static final int DEFAULT_CACHE_SIZE = 100;
90
91
92
93
94
95 public ExceptionInterceptor()
96 {
97 super( InterceptorEnum.EXCEPTION_INTERCEPTOR );
98 }
99
100
101
102
103
104 @Override
105 public void init( DirectoryService directoryService ) throws LdapException
106 {
107 super.init( directoryService );
108 nexus = directoryService.getPartitionNexus();
109 Value attr = nexus.getRootDseValue( directoryService.getAtProvider().getSubschemaSubentry() );
110 subschemSubentryDn = dnFactory.create( attr.getString() );
111 }
112
113
114
115
116
117
118 @Override
119 public void add( AddOperationContext addContext ) throws LdapException
120 {
121 Dn name = addContext.getDn();
122
123 if ( subschemSubentryDn.equals( name ) )
124 {
125 throw new LdapEntryAlreadyExistsException( I18n.err( I18n.ERR_249 ) );
126 }
127
128 Dn suffix = nexus.getSuffixDn( name );
129
130
131 if ( suffix.equals( name ) )
132 {
133 next( addContext );
134 return;
135 }
136
137 Dn parentDn = name.getParent();
138
139
140 boolean notAnAlias;
141
142 synchronized ( notAliasCache )
143 {
144 notAnAlias = notAliasCache.containsKey( parentDn.getNormName() );
145 }
146
147 if ( !notAnAlias )
148 {
149
150
151 Entry attrs;
152
153 try
154 {
155 CoreSession session = addContext.getSession();
156 LookupOperationContexttor/context/LookupOperationContext.html#LookupOperationContext">LookupOperationContext lookupContext = new LookupOperationContext( session, parentDn,
157 SchemaConstants.ALL_ATTRIBUTES_ARRAY );
158 lookupContext.setPartition( addContext.getPartition() );
159 lookupContext.setTransaction( addContext.getTransaction() );
160
161 attrs = directoryService.getPartitionNexus().lookup( lookupContext );
162 }
163 catch ( Exception e )
164 {
165 throw new LdapNoSuchObjectException( I18n.err( I18n.ERR_251_PARENT_NOT_FOUND, parentDn.getName() ) );
166 }
167
168 Attribute objectClass = ( ( ClonedServerEntry ) attrs ).getOriginalEntry().get(
169 directoryService.getAtProvider().getObjectClass() );
170
171 if ( objectClass.contains( SchemaConstants.ALIAS_OC ) )
172 {
173 String msg = I18n.err( I18n.ERR_252_ALIAS_WITH_CHILD_NOT_ALLOWED, name.getName(), parentDn.getName() );
174 throw new LdapAliasException( msg );
175 }
176 else
177 {
178 synchronized ( notAliasCache )
179 {
180 notAliasCache.put( parentDn.getNormName(), parentDn );
181 }
182 }
183 }
184
185 next( addContext );
186 }
187
188
189
190
191
192
193 @Override
194 public void delete( DeleteOperationContext deleteContext ) throws LdapException
195 {
196 Dn dn = deleteContext.getDn();
197
198 if ( dn.equals( subschemSubentryDn ) )
199 {
200 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err( I18n.ERR_253,
201 subschemSubentryDn ) );
202 }
203
204 next( deleteContext );
205
206
207 synchronized ( notAliasCache )
208 {
209 if ( notAliasCache.containsKey( dn.getNormName() ) )
210 {
211 notAliasCache.remove( dn.getNormName() );
212 }
213 }
214 }
215
216
217
218
219
220 @Override
221 public void modify( ModifyOperationContext modifyContext ) throws LdapException
222 {
223
224 String msg = "Attempt to modify non-existant entry: ";
225
226
227
228 if ( modifyContext.getDn().equals( subschemSubentryDn ) )
229 {
230 next( modifyContext );
231 return;
232 }
233
234
235
236 assertHasEntry( modifyContext, msg );
237
238
239
240
241
242
243 synchronized ( notAliasCache )
244 {
245 if ( notAliasCache.containsKey( modifyContext.getDn().getNormName() ) )
246 {
247 notAliasCache.remove( modifyContext.getDn().getNormName() );
248 }
249 }
250
251 next( modifyContext );
252 }
253
254
255
256
257
258 @Override
259 public void move( MoveOperationContext moveContext ) throws LdapException
260 {
261 Dn oriChildName = moveContext.getDn();
262
263 if ( oriChildName.equals( subschemSubentryDn ) )
264 {
265 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err( I18n.ERR_258,
266 subschemSubentryDn, subschemSubentryDn ) );
267 }
268
269 next( moveContext );
270
271
272 synchronized ( notAliasCache )
273 {
274 if ( notAliasCache.containsKey( oriChildName.getNormName() ) )
275 {
276 notAliasCache.remove( oriChildName.getNormName() );
277 }
278 }
279 }
280
281
282
283
284
285 @Override
286 public void moveAndRename( MoveAndRenameOperationContext moveAndRenameContext ) throws LdapException
287 {
288 Dn oldDn = moveAndRenameContext.getDn();
289
290
291 if ( oldDn.getNormName().equals( subschemSubentryDn.getNormName() ) )
292 {
293 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err( I18n.ERR_258,
294 subschemSubentryDn, subschemSubentryDn ) );
295 }
296
297
298 synchronized ( notAliasCache )
299 {
300 if ( notAliasCache.containsKey( oldDn.getNormName() ) )
301 {
302 notAliasCache.remove( oldDn.getNormName() );
303 }
304 }
305
306 next( moveAndRenameContext );
307 }
308
309
310
311
312
313 @Override
314 public void rename( RenameOperationContext renameContext ) throws LdapException
315 {
316 Dn dn = renameContext.getDn();
317
318 if ( dn.equals( subschemSubentryDn ) )
319 {
320 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err( I18n.ERR_255,
321 subschemSubentryDn, subschemSubentryDn ) );
322 }
323
324
325 Dn newDn = renameContext.getNewDn();
326
327 HasEntryOperationContextcontext/HasEntryOperationContext.html#HasEntryOperationContext">HasEntryOperationContext hasEntryContext = new HasEntryOperationContext( renameContext.getSession(), newDn );
328 hasEntryContext.setPartition( renameContext.getPartition() );
329 hasEntryContext.setTransaction( renameContext.getTransaction() );
330
331 if ( nexus.hasEntry( hasEntryContext ) )
332 {
333
334
335
336 if ( !newDn.equals( dn ) )
337 {
338 throw new LdapEntryAlreadyExistsException( I18n.err( I18n.ERR_250_ENTRY_ALREADY_EXISTS, newDn.getName() ) );
339 }
340 }
341
342
343 synchronized ( notAliasCache )
344 {
345 if ( notAliasCache.containsKey( dn.getNormName() ) )
346 {
347 notAliasCache.remove( dn.getNormName() );
348 }
349 }
350
351 next( renameContext );
352 }
353
354
355
356
357
358
359
360
361
362
363 private void assertHasEntry( OperationContext opContext, String msg ) throws LdapException
364 {
365 Dn dn = opContext.getDn();
366
367 if ( subschemSubentryDn.equals( dn ) )
368 {
369 return;
370 }
371
372 if ( opContext.getEntry() == null )
373 {
374 LdapNoSuchObjectException e;
375
376 if ( msg != null )
377 {
378 e = new LdapNoSuchObjectException( msg + dn.getName() );
379 }
380 else
381 {
382 e = new LdapNoSuchObjectException( dn.getName() );
383 }
384
385 throw e;
386 }
387 }
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421 }