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.referral;
21
22
23 import javax.naming.Context;
24
25 import org.apache.directory.api.ldap.model.constants.SchemaConstants;
26 import org.apache.directory.api.ldap.model.entry.Attribute;
27 import org.apache.directory.api.ldap.model.entry.Entry;
28 import org.apache.directory.api.ldap.model.entry.Value;
29 import org.apache.directory.api.ldap.model.exception.LdapException;
30 import org.apache.directory.api.ldap.model.exception.LdapURLEncodingException;
31 import org.apache.directory.api.ldap.model.message.SearchScope;
32 import org.apache.directory.api.ldap.model.name.Dn;
33 import org.apache.directory.api.ldap.model.url.LdapUrl;
34 import org.apache.directory.api.util.Strings;
35 import org.apache.directory.server.core.api.DirectoryService;
36 import org.apache.directory.server.core.api.InterceptorEnum;
37 import org.apache.directory.server.core.api.ReferralManager;
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.context.AddOperationContext;
41 import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext;
42 import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
43 import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext;
44 import org.apache.directory.server.core.api.interceptor.context.MoveAndRenameOperationContext;
45 import org.apache.directory.server.core.api.interceptor.context.MoveOperationContext;
46 import org.apache.directory.server.core.api.interceptor.context.RenameOperationContext;
47 import org.apache.directory.server.core.api.partition.PartitionNexus;
48 import org.apache.directory.server.core.shared.ReferralManagerImpl;
49 import org.apache.directory.server.i18n.I18n;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53
54
55
56
57
58
59
60
61 public class ReferralInterceptor extends BaseInterceptor
62 {
63 private static final Logger LOG = LoggerFactory.getLogger( ReferralInterceptor.class );
64
65 private PartitionNexus nexus;
66
67
68 private ReferralManager referralManager;
69
70
71 private Dn subschemaSubentryDn;
72
73
74
75
76
77 public ReferralInterceptor()
78 {
79 super( InterceptorEnum.REFERRAL_INTERCEPTOR );
80 }
81
82
83 private static void checkRefAttributeValue( Value value ) throws LdapException
84 {
85 String refVal = value.getString();
86
87 LdapUrl ldapUrl = new LdapUrl( refVal );
88
89
90
91
92
93
94
95
96 if ( ldapUrl.getScope() != SearchScope.OBJECT )
97 {
98
99
100
101 String message = I18n.err( I18n.ERR_36 );
102 LOG.error( message );
103 throw new LdapException( message );
104 }
105
106 if ( !Strings.isEmpty( ldapUrl.getFilter() ) )
107 {
108 String message = I18n.err( I18n.ERR_37 );
109 LOG.error( message );
110 throw new LdapException( message );
111 }
112
113 if ( ( ldapUrl.getAttributes() != null ) && !ldapUrl.getAttributes().isEmpty() )
114 {
115 String message = I18n.err( I18n.ERR_38 );
116 LOG.error( message );
117 throw new LdapException( message );
118 }
119
120 if ( ( ldapUrl.getExtensions() != null ) && !ldapUrl.getExtensions().isEmpty() )
121 {
122 String message = I18n.err( I18n.ERR_39 );
123 LOG.error( message );
124 throw new LdapException( message );
125 }
126
127 if ( ( ldapUrl.getExtensions() != null ) && !ldapUrl.getExtensions().isEmpty() )
128 {
129 String message = I18n.err( I18n.ERR_40 );
130 LOG.error( message );
131 throw new LdapException( message );
132 }
133
134 Dn dn = ldapUrl.getDn();
135
136 if ( ( dn == null ) || dn.isEmpty() )
137 {
138 String message = I18n.err( I18n.ERR_41 );
139 LOG.error( message );
140 throw new LdapException( message );
141 }
142 }
143
144
145
146 @SuppressWarnings("PMD.EmptyCatchBlock")
147 private boolean isReferral( Entry entry ) throws LdapException
148 {
149
150
151
152 if ( entry == null )
153 {
154 return false;
155 }
156
157 if ( !entry.contains( directoryService.getAtProvider().getObjectClass(), SchemaConstants.REFERRAL_OC ) )
158 {
159 return false;
160 }
161 else
162 {
163
164
165
166
167 Attribute refAttr = entry.get( SchemaConstants.REF_AT );
168
169 if ( refAttr == null )
170 {
171
172 String message = I18n.err( I18n.ERR_42 );
173 LOG.error( message );
174 throw new LdapException( message );
175 }
176
177 for ( Value value : refAttr )
178 {
179 try
180 {
181 checkRefAttributeValue( value );
182 }
183 catch ( LdapURLEncodingException luee )
184 {
185
186
187 }
188 }
189
190 return true;
191 }
192 }
193
194
195 @Override
196 public void init( DirectoryService directoryService ) throws LdapException
197 {
198 super.init( directoryService );
199
200 nexus = directoryService.getPartitionNexus();
201
202
203 referralManager = new ReferralManagerImpl( directoryService );
204 directoryService.setReferralManager( referralManager );
205
206 Value subschemaSubentry = nexus.getRootDseValue( directoryService.getAtProvider().getSubschemaSubentry() );
207 subschemaSubentryDn = dnFactory.create( subschemaSubentry.getString() );
208 }
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231 @Override
232 public void add( AddOperationContext addContext ) throws LdapException
233 {
234 Entry entry = addContext.getEntry();
235
236
237 boolean isReferral = isReferral( entry );
238
239
240 next( addContext );
241
242
243 if ( isReferral )
244 {
245
246 referralManager.lockWrite();
247
248 try
249 {
250 referralManager.addReferral( entry );
251 }
252 finally
253 {
254 referralManager.unlock();
255 }
256 }
257 }
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276 @Override
277 public void delete( DeleteOperationContext deleteContext ) throws LdapException
278 {
279
280 next( deleteContext );
281
282 Entry entry = deleteContext.getEntry();
283
284
285
286 if ( ( entry != null ) && isReferral( entry ) )
287 {
288
289 referralManager.lockWrite();
290
291 try
292 {
293 referralManager.removeReferral( entry );
294 }
295 finally
296 {
297 referralManager.unlock();
298 }
299 }
300 }
301
302
303
304
305
306 @Override
307 public void modify( ModifyOperationContext modifyContext ) throws LdapException
308 {
309 Dn dn = modifyContext.getDn();
310
311
312 next( modifyContext );
313
314
315
316 if ( dn.isEmpty() || dn.equals( subschemaSubentryDn ) )
317 {
318
319 return;
320 }
321
322
323
324
325
326
327 LookupOperationContext lookupContext =
328 new LookupOperationContext( modifyContext.getSession(), dn, SchemaConstants.ALL_ATTRIBUTES_ARRAY );
329 lookupContext.setPartition( modifyContext.getPartition() );
330 lookupContext.setTransaction( modifyContext.getTransaction() );
331
332 Entry newEntry = nexus.lookup( lookupContext );
333
334
335
336
337 if ( newEntry != null )
338 {
339 referralManager.lockWrite();
340
341 try
342 {
343 if ( referralManager.isReferral( newEntry.getDn() ) )
344 {
345 referralManager.removeReferral( modifyContext.getEntry() );
346 referralManager.addReferral( newEntry );
347 }
348 }
349 finally
350 {
351 referralManager.unlock();
352 }
353 }
354 }
355
356
357
358
359
360 @Override
361 public void move( MoveOperationContext moveContext ) throws LdapException
362 {
363
364 boolean isReferral = isReferral( moveContext.getOriginalEntry() );
365
366 next( moveContext );
367
368 if ( isReferral )
369 {
370
371 referralManager.lockWrite();
372
373 try
374 {
375 referralManager.addReferral( moveContext.getModifiedEntry() );
376 referralManager.removeReferral( moveContext.getOriginalEntry() );
377 }
378 finally
379 {
380 referralManager.unlock();
381 }
382 }
383 }
384
385
386
387
388
389 @Override
390 public void moveAndRename( MoveAndRenameOperationContext moveAndRenameContext ) throws LdapException
391 {
392
393 boolean isReferral = isReferral( moveAndRenameContext.getOriginalEntry() );
394
395 next( moveAndRenameContext );
396
397 if ( isReferral )
398 {
399
400 Entry newEntry = moveAndRenameContext.getModifiedEntry();
401
402 referralManager.lockWrite();
403
404 try
405 {
406 referralManager.addReferral( newEntry );
407 referralManager.removeReferral( moveAndRenameContext.getOriginalEntry() );
408 }
409 finally
410 {
411 referralManager.unlock();
412 }
413 }
414 }
415
416
417
418
419
420 @Override
421 public void rename( RenameOperationContext renameContext ) throws LdapException
422 {
423
424 boolean isReferral = isReferral( renameContext.getOriginalEntry() );
425
426 next( renameContext );
427
428 if ( isReferral )
429 {
430
431 LookupOperationContexttor/context/LookupOperationContext.html#LookupOperationContext">LookupOperationContext lookupContext = new LookupOperationContext( renameContext.getSession(),
432 renameContext.getNewDn(), SchemaConstants.ALL_ATTRIBUTES_ARRAY );
433 lookupContext.setPartition( renameContext.getPartition() );
434 lookupContext.setTransaction( renameContext.getTransaction() );
435
436 Entry newEntry = nexus.lookup( lookupContext );
437
438 referralManager.lockWrite();
439
440 try
441 {
442 referralManager.addReferral( newEntry );
443 referralManager.removeReferral( ( ( ClonedServerEntry ) renameContext.getEntry() ).getOriginalEntry() );
444 }
445 finally
446 {
447 referralManager.unlock();
448 }
449 }
450 }
451 }