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.jndi;
21
22
23 import org.apache.directory.server.core.CoreSession;
24 import org.apache.directory.server.core.DefaultCoreSession;
25 import org.apache.directory.server.core.DirectoryService;
26 import org.apache.directory.server.core.authn.LdapPrincipal;
27 import org.apache.directory.shared.ldap.entry.EntryAttribute;
28 import org.apache.directory.server.core.entry.ClonedServerEntry;
29 import org.apache.directory.server.core.entry.ServerEntry;
30 import org.apache.directory.server.core.entry.ServerEntryUtils;
31 import org.apache.directory.server.core.event.DirectoryListener;
32 import org.apache.directory.server.core.event.NotificationCriteria;
33 import org.apache.directory.server.core.filtering.EntryFilteringCursor;
34 import org.apache.directory.server.core.interceptor.context.AddOperationContext;
35 import org.apache.directory.server.core.interceptor.context.BindOperationContext;
36 import org.apache.directory.server.core.interceptor.context.DeleteOperationContext;
37 import org.apache.directory.server.core.interceptor.context.EntryOperationContext;
38 import org.apache.directory.server.core.interceptor.context.GetRootDSEOperationContext;
39 import org.apache.directory.server.core.interceptor.context.ListOperationContext;
40 import org.apache.directory.server.core.interceptor.context.LookupOperationContext;
41 import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
42 import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext;
43 import org.apache.directory.server.core.interceptor.context.MoveOperationContext;
44 import org.apache.directory.server.core.interceptor.context.RenameOperationContext;
45 import org.apache.directory.server.core.interceptor.context.SearchOperationContext;
46 import org.apache.directory.shared.ldap.constants.JndiPropertyConstants;
47 import org.apache.directory.shared.ldap.constants.SchemaConstants;
48 import org.apache.directory.shared.ldap.entry.Modification;
49 import org.apache.directory.shared.ldap.exception.LdapNoPermissionException;
50 import org.apache.directory.shared.ldap.exception.LdapSchemaViolationException;
51 import org.apache.directory.shared.ldap.filter.ExprNode;
52 import org.apache.directory.shared.ldap.filter.PresenceNode;
53 import org.apache.directory.shared.ldap.filter.SearchScope;
54 import org.apache.directory.shared.ldap.message.AliasDerefMode;
55 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
56 import org.apache.directory.shared.ldap.name.AttributeTypeAndValue;
57 import org.apache.directory.shared.ldap.name.LdapDN;
58 import org.apache.directory.shared.ldap.name.Rdn;
59 import org.apache.directory.shared.ldap.util.AttributeUtils;
60 import org.apache.directory.shared.ldap.util.StringTools;
61
62 import javax.naming.Context;
63 import javax.naming.InvalidNameException;
64 import javax.naming.Name;
65 import javax.naming.NameNotFoundException;
66 import javax.naming.NameParser;
67 import javax.naming.NamingEnumeration;
68 import javax.naming.NamingException;
69 import javax.naming.Reference;
70 import javax.naming.Referenceable;
71 import javax.naming.directory.DirContext;
72 import javax.naming.directory.SearchControls;
73 import javax.naming.event.EventContext;
74 import javax.naming.event.NamingListener;
75 import javax.naming.ldap.Control;
76 import javax.naming.spi.DirStateFactory;
77 import javax.naming.spi.DirectoryManager;
78 import java.io.Serializable;
79 import java.util.HashMap;
80 import java.util.Hashtable;
81 import java.util.List;
82 import java.util.Map;
83
84
85
86
87
88
89
90
91 public abstract class ServerContext implements EventContext
92 {
93
94 public static final String DELETE_OLD_RDN_PROP = JndiPropertyConstants.JNDI_LDAP_DELETE_RDN;
95
96
97 protected static final Control[] EMPTY_CONTROLS = new Control[0];
98
99
100 private final DirectoryService service;
101
102
103 private final Hashtable<String, Object> env;
104
105
106 private final LdapDN dn;
107
108
109 private final Map<NamingListener,DirectoryListener> listeners =
110 new HashMap<NamingListener,DirectoryListener>();
111
112
113 protected Control[] requestControls = EMPTY_CONTROLS;
114
115
116 protected Control[] responseControls = EMPTY_CONTROLS;
117
118
119 protected Control[] connectControls = EMPTY_CONTROLS;
120
121 private final CoreSession session;
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 @SuppressWarnings(value = { "unchecked" })
144 protected ServerContext( DirectoryService service, Hashtable<String, Object> env ) throws Exception
145 {
146 this.service = service;
147
148 this.env = env;
149
150 LdapJndiProperties props = LdapJndiProperties.getLdapJndiProperties( this.env );
151 dn = props.getProviderDn();
152
153
154
155
156
157 BindOperationContext opContext = doBindOperation( props.getBindDn(), props.getCredentials(),
158 props.getSaslMechanism(), props.getSaslAuthId() );
159
160 session = opContext.getSession();
161
162 if ( ! service.getOperationManager().hasEntry( new EntryOperationContext( session, dn ) ) )
163 {
164 throw new NameNotFoundException( dn + " does not exist" );
165 }
166 }
167
168
169
170
171
172
173
174
175
176
177
178
179 public ServerContext( DirectoryService service, LdapPrincipal principal, Name dn ) throws Exception
180 {
181 this.service = service;
182 this.dn = ( LdapDN ) dn.clone();
183
184 this.env = new Hashtable<String, Object>();
185 this.env.put( PROVIDER_URL, dn.toString() );
186 this.env.put( DirectoryService.JNDI_KEY, service );
187 session = new DefaultCoreSession( principal, service );
188
189 if ( ! service.getOperationManager().hasEntry( new EntryOperationContext( session, ( LdapDN ) dn ) ) )
190 {
191 throw new NameNotFoundException( dn + " does not exist" );
192 }
193 }
194
195
196 public ServerContext( DirectoryService service, CoreSession session, Name dn ) throws Exception
197 {
198 this.service = service;
199 this.dn = ( LdapDN ) dn.clone();
200 this.env = new Hashtable<String, Object>();
201 this.env.put( PROVIDER_URL, dn.toString() );
202 this.env.put( DirectoryService.JNDI_KEY, service );
203 this.session = session;
204
205 if ( ! service.getOperationManager().hasEntry( new EntryOperationContext( session, ( LdapDN ) dn ) ) )
206 {
207 throw new NameNotFoundException( dn + " does not exist" );
208 }
209 }
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227 protected void doAddOperation( LdapDN target, ServerEntry entry ) throws Exception
228 {
229
230 AddOperationContext opCtx = new AddOperationContext( session, entry );
231
232 opCtx.addRequestControls( requestControls );
233
234
235 service.getOperationManager().add( opCtx );
236
237
238 requestControls = EMPTY_CONTROLS;
239 responseControls = opCtx.getResponseControls();
240 }
241
242
243
244
245
246
247 protected void doDeleteOperation( LdapDN target ) throws Exception
248 {
249
250 DeleteOperationContext opCtx = new DeleteOperationContext( session, target );
251 opCtx.addRequestControls( requestControls );
252
253
254 service.getOperationManager().delete( opCtx );
255
256
257 requestControls = EMPTY_CONTROLS;
258 responseControls = opCtx.getResponseControls();
259 }
260
261
262
263
264
265
266
267
268
269
270 protected EntryFilteringCursor doSearchOperation( LdapDN dn, AliasDerefMode aliasDerefMode,
271 ExprNode filter, SearchControls searchControls ) throws Exception
272 {
273
274 SearchOperationContext opCtx = new SearchOperationContext( session, dn, aliasDerefMode, filter,
275 searchControls );
276 opCtx.addRequestControls( requestControls );
277
278
279 EntryFilteringCursor results = service.getOperationManager().search( opCtx );
280
281
282 requestControls = EMPTY_CONTROLS;
283 responseControls = opCtx.getResponseControls();
284
285 return results;
286 }
287
288
289
290
291
292 protected EntryFilteringCursor doListOperation( LdapDN target ) throws Exception
293 {
294
295 ListOperationContext opCtx = new ListOperationContext( session, target );
296 opCtx.addRequestControls( requestControls );
297
298
299 EntryFilteringCursor results = service.getOperationManager().list( opCtx );
300
301
302 requestControls = EMPTY_CONTROLS;
303 responseControls = opCtx.getResponseControls();
304
305 return results;
306 }
307
308
309 protected ServerEntry doGetRootDSEOperation( LdapDN target ) throws Exception
310 {
311 GetRootDSEOperationContext opCtx = new GetRootDSEOperationContext( session, target );
312 opCtx.addRequestControls( requestControls );
313
314
315
316 return service.getOperationManager().getRootDSE( opCtx );
317 }
318
319
320
321
322
323 protected ServerEntry doLookupOperation( LdapDN target ) throws Exception
324 {
325
326 LookupOperationContext opCtx;
327
328
329 opCtx = new LookupOperationContext( session, target );
330 opCtx.addRequestControls( requestControls );
331 ServerEntry serverEntry = service.getOperationManager().lookup( opCtx );
332
333
334 requestControls = EMPTY_CONTROLS;
335 responseControls = opCtx.getResponseControls();
336 return serverEntry;
337 }
338
339
340
341
342
343 protected ServerEntry doLookupOperation( LdapDN target, String[] attrIds ) throws Exception
344 {
345
346 LookupOperationContext opCtx;
347
348
349 opCtx = new LookupOperationContext( session, target, attrIds );
350 opCtx.addRequestControls( requestControls );
351 ClonedServerEntry serverEntry = service.getOperationManager().lookup( opCtx );
352
353
354 requestControls = EMPTY_CONTROLS;
355 responseControls = opCtx.getResponseControls();
356
357
358 if ( ( opCtx.getAttrsId() != null ) && ( opCtx.getAttrsId().size() != 0 ) )
359 {
360 if ( ( serverEntry.get( SchemaConstants.OBJECT_CLASS_AT ) != null )
361 && ( serverEntry.get( SchemaConstants.OBJECT_CLASS_AT ).size() == 0 ) )
362 {
363 serverEntry.removeAttributes( SchemaConstants.OBJECT_CLASS_AT );
364 }
365 }
366
367 return serverEntry;
368 }
369
370
371
372
373
374 protected BindOperationContext doBindOperation( LdapDN bindDn, byte[] credentials, String saslMechanism,
375 String saslAuthId ) throws Exception
376 {
377
378 BindOperationContext opCtx = new BindOperationContext( null );
379 opCtx.setDn( bindDn );
380 opCtx.setCredentials( credentials );
381 opCtx.setSaslMechanism( saslMechanism );
382 opCtx.setSaslAuthId( saslAuthId );
383 opCtx.addRequestControls( requestControls );
384
385
386 service.getOperationManager().bind( opCtx );
387
388
389 requestControls = EMPTY_CONTROLS;
390 responseControls = opCtx.getResponseControls();
391 return opCtx;
392 }
393
394
395
396
397
398 protected void doMoveAndRenameOperation( LdapDN oldDn, LdapDN parent, String newRdn, boolean delOldDn )
399 throws Exception
400 {
401
402 MoveAndRenameOperationContext opCtx = new MoveAndRenameOperationContext( session, oldDn, parent, new Rdn(
403 newRdn ), delOldDn );
404 opCtx.addRequestControls( requestControls );
405
406
407 service.getOperationManager().moveAndRename( opCtx );
408
409
410 requestControls = EMPTY_CONTROLS;
411 responseControls = opCtx.getResponseControls();
412 }
413
414
415
416
417
418 protected void doModifyOperation( LdapDN dn, List<Modification> modifications ) throws Exception
419 {
420
421 ModifyOperationContext opCtx = new ModifyOperationContext( session, dn, modifications );
422 opCtx.addRequestControls( requestControls );
423
424
425 service.getOperationManager().modify( opCtx );
426
427
428 requestControls = EMPTY_CONTROLS;
429 responseControls = opCtx.getResponseControls();
430 }
431
432
433
434
435
436 protected void doMove( LdapDN oldDn, LdapDN target ) throws Exception
437 {
438
439 MoveOperationContext opCtx = new MoveOperationContext( session, oldDn, target );
440 opCtx.addRequestControls( requestControls );
441
442
443 service.getOperationManager().move( opCtx );
444
445
446 requestControls = EMPTY_CONTROLS;
447 responseControls = opCtx.getResponseControls();
448 }
449
450
451
452
453
454 protected void doRename( LdapDN oldDn, String newRdn, boolean delOldRdn ) throws Exception
455 {
456
457 RenameOperationContext opCtx = new RenameOperationContext( session, oldDn, new Rdn( newRdn ), delOldRdn );
458 opCtx.addRequestControls( requestControls );
459
460
461 service.getOperationManager().rename( opCtx );
462
463
464 requestControls = EMPTY_CONTROLS;
465 responseControls = opCtx.getResponseControls();
466 }
467
468
469 public CoreSession getSession()
470 {
471 return session;
472 }
473
474
475 public DirectoryService getDirectoryService()
476 {
477 return service;
478 }
479
480
481
482
483
484
485
486
487
488
489
490
491 public abstract ServerContext getRootContext() throws NamingException;
492
493
494
495
496
497
498
499 public DirectoryService getService()
500 {
501 return service;
502 }
503
504
505
506
507
508
509
510
511
512
513
514
515 protected Name getDn()
516 {
517 return dn;
518 }
519
520
521
522
523
524
525
526
527
528 public void close() throws NamingException
529 {
530 for ( DirectoryListener listener : listeners.values() )
531 {
532 try
533 {
534 service.getEventService().removeListener( listener );
535 }
536 catch ( Exception e )
537 {
538 JndiUtils.wrap( e );
539 }
540 }
541
542 listeners.clear();
543 }
544
545
546
547
548
549 public String getNameInNamespace() throws NamingException
550 {
551 return dn.getUpName();
552 }
553
554
555
556
557
558 public Hashtable<String, Object> getEnvironment()
559 {
560 return env;
561 }
562
563
564
565
566
567
568 public Object addToEnvironment( String propName, Object propVal ) throws NamingException
569 {
570 return env.put( propName, propVal );
571 }
572
573
574
575
576
577 public Object removeFromEnvironment( String propName ) throws NamingException
578 {
579 return env.remove( propName );
580 }
581
582
583
584
585
586 public Context createSubcontext( String name ) throws NamingException
587 {
588 return createSubcontext( new LdapDN( name ) );
589 }
590
591
592
593
594
595 public Context createSubcontext( Name name ) throws NamingException
596 {
597 LdapDN target = buildTarget( name );
598 ServerEntry serverEntry = service.newEntry( target );
599 serverEntry.add( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, JavaLdapSupport.JCONTAINER_ATTR );
600
601
602 Rdn rdn = target.getRdn();
603
604 if ( rdn != null )
605 {
606 if ( SchemaConstants.CN_AT.equals( rdn.getNormType() ) )
607 {
608 serverEntry.put( rdn.getUpType(), ( String ) rdn.getUpValue() );
609 }
610 else
611 {
612
613 throw new LdapSchemaViolationException( name
614 + " does not contains the mandatory 'cn' attribute for JavaContainer ObjectClass!",
615 ResultCodeEnum.OBJECT_CLASS_VIOLATION );
616 }
617 }
618 else
619 {
620
621 throw new LdapSchemaViolationException( name
622 + " does not contains the mandatory 'cn' attribute for JavaContainer ObjectClass!",
623 ResultCodeEnum.OBJECT_CLASS_VIOLATION );
624 }
625
626
627
628
629
630
631
632
633 try
634 {
635 doAddOperation( target, serverEntry );
636 }
637 catch ( Exception e )
638 {
639 JndiUtils.wrap( e );
640 }
641
642 ServerLdapContext ctx = null;
643
644 try
645 {
646 ctx = new ServerLdapContext( service, session.getEffectivePrincipal(), target );
647 }
648 catch ( Exception e )
649 {
650 JndiUtils.wrap( e );
651 }
652
653 return ctx;
654 }
655
656
657
658
659
660 public void destroySubcontext( String name ) throws NamingException
661 {
662 destroySubcontext( new LdapDN( name ) );
663 }
664
665
666
667
668
669 public void destroySubcontext( Name name ) throws NamingException
670 {
671 LdapDN target = buildTarget( name );
672
673 if ( target.size() == 0 )
674 {
675 throw new LdapNoPermissionException( "can't delete the rootDSE" );
676 }
677
678 try
679 {
680 doDeleteOperation( target );
681 }
682 catch ( Exception e )
683 {
684 JndiUtils.wrap( e );
685 }
686 }
687
688
689
690
691
692 public void bind( String name, Object obj ) throws NamingException
693 {
694 bind( new LdapDN( name ), obj );
695 }
696
697
698 private void injectRdnAttributeValues( LdapDN target, ServerEntry serverEntry ) throws NamingException
699 {
700
701 Rdn rdn = target.getRdn( target.size() - 1 );
702
703 if ( rdn.size() == 1 )
704 {
705 serverEntry.put( rdn.getUpType(), ( String ) rdn.getValue() );
706 }
707 else
708 {
709 for ( AttributeTypeAndValue atav : rdn )
710 {
711 serverEntry.put( atav.getUpType(), ( String ) atav.getNormValue() );
712 }
713 }
714 }
715
716
717
718
719
720 public void bind( Name name, Object obj ) throws NamingException
721 {
722
723 DirStateFactory.Result res = DirectoryManager.getStateToBind( obj, name, this, env, null );
724
725 LdapDN target = buildTarget( name );
726
727
728 ServerEntry outServerEntry = ServerEntryUtils.toServerEntry( AttributeUtils.toCaseInsensitive( res
729 .getAttributes() ), target, service.getRegistries() );
730
731 if ( outServerEntry != null )
732 {
733 try
734 {
735 doAddOperation( target, outServerEntry );
736 }
737 catch ( Exception e )
738 {
739 JndiUtils.wrap( e );
740 }
741 return;
742 }
743
744 if ( obj instanceof ServerEntry )
745 {
746 try
747 {
748 doAddOperation( target, ( ServerEntry ) obj );
749 }
750 catch ( Exception e )
751 {
752 JndiUtils.wrap( e );
753 }
754 }
755
756 else if ( obj instanceof Referenceable )
757 {
758 throw new NamingException( "Do not know how to store Referenceables yet!" );
759 }
760
761 else if ( obj instanceof Reference )
762 {
763
764 throw new NamingException( "Do not know how to store References yet!" );
765 }
766 else if ( obj instanceof Serializable )
767 {
768
769 ServerEntry serverEntry = service.newEntry( target );
770
771 if ( ( outServerEntry != null ) && ( outServerEntry.size() > 0 ) )
772 {
773 for ( EntryAttribute serverAttribute : outServerEntry )
774 {
775 serverEntry.put( serverAttribute );
776 }
777 }
778
779
780 injectRdnAttributeValues( target, serverEntry );
781
782
783 JavaLdapSupport.serialize( serverEntry, obj, service.getRegistries() );
784 try
785 {
786 doAddOperation( target, serverEntry );
787 }
788 catch ( Exception e )
789 {
790 JndiUtils.wrap( e );
791 }
792 }
793 else if ( obj instanceof DirContext )
794 {
795
796 ServerEntry serverEntry = ServerEntryUtils.toServerEntry( ( ( DirContext ) obj ).getAttributes( "" ),
797 target, service.getRegistries() );
798
799 if ( ( outServerEntry != null ) && ( outServerEntry.size() > 0 ) )
800 {
801 for ( EntryAttribute serverAttribute : outServerEntry )
802 {
803 serverEntry.put( serverAttribute );
804 }
805 }
806
807 injectRdnAttributeValues( target, serverEntry );
808 try
809 {
810 doAddOperation( target, serverEntry );
811 }
812 catch ( Exception e )
813 {
814 JndiUtils.wrap( e );
815 }
816 }
817 else
818 {
819 throw new NamingException( "Can't find a way to bind: " + obj );
820 }
821 }
822
823
824
825
826
827 public void rename( String oldName, String newName ) throws NamingException
828 {
829 rename( new LdapDN( oldName ), new LdapDN( newName ) );
830 }
831
832
833
834
835
836 public void rename( Name oldName, Name newName ) throws NamingException
837 {
838 LdapDN oldDn = buildTarget( oldName );
839 LdapDN newDn = buildTarget( newName );
840
841 if ( oldDn.size() == 0 )
842 {
843 throw new LdapNoPermissionException( "can't rename the rootDSE" );
844 }
845
846
847 LdapDN oldBase = ( LdapDN ) oldName.clone();
848 oldBase.remove( oldName.size() - 1 );
849 LdapDN newBase = ( LdapDN ) newName.clone();
850 newBase.remove( newName.size() - 1 );
851
852 String newRdn = newName.get( newName.size() - 1 );
853 String oldRdn = oldName.get( oldName.size() - 1 );
854 boolean delOldRdn = true;
855
856
857
858
859
860 if ( null != env.get( DELETE_OLD_RDN_PROP ) )
861 {
862 String delOldRdnStr = ( String ) env.get( DELETE_OLD_RDN_PROP );
863 delOldRdn = !delOldRdnStr.equalsIgnoreCase( "false" ) && !delOldRdnStr.equalsIgnoreCase( "no" )
864 && !delOldRdnStr.equals( "0" );
865 }
866
867
868
869
870
871
872
873
874
875 if ( ( oldName.size() == newName.size() ) && oldBase.equals( newBase ) )
876 {
877 try
878 {
879 doRename( oldDn, newRdn, delOldRdn );
880 }
881 catch ( Exception e )
882 {
883 JndiUtils.wrap( e );
884 }
885 }
886 else
887 {
888 LdapDN target = ( LdapDN ) newDn.clone();
889 target.remove( newDn.size() - 1 );
890
891 if ( newRdn.equalsIgnoreCase( oldRdn ) )
892 {
893 try
894 {
895 doMove( oldDn, target );
896 }
897 catch ( Exception e )
898 {
899 JndiUtils.wrap( e );
900 }
901 }
902 else
903 {
904 try
905 {
906 doMoveAndRenameOperation( oldDn, target, newRdn, delOldRdn );
907 }
908 catch ( Exception e )
909 {
910 JndiUtils.wrap( e );
911 }
912 }
913 }
914 }
915
916
917
918
919
920 public void rebind( String name, Object obj ) throws NamingException
921 {
922 rebind( new LdapDN( name ), obj );
923 }
924
925
926
927
928
929 public void rebind( Name name, Object obj ) throws NamingException
930 {
931 LdapDN target = buildTarget( name );
932
933 try
934 {
935 if ( service.getOperationManager().hasEntry( new EntryOperationContext( session, target ) ) )
936 {
937 doDeleteOperation( target );
938 }
939 }
940 catch ( Exception e )
941 {
942 JndiUtils.wrap( e );
943 }
944
945 bind( name, obj );
946 }
947
948
949
950
951
952 public void unbind( String name ) throws NamingException
953 {
954 unbind( new LdapDN( name ) );
955 }
956
957
958
959
960
961 public void unbind( Name name ) throws NamingException
962 {
963 try
964 {
965 doDeleteOperation( buildTarget( name ) );
966 }
967 catch ( Exception e )
968 {
969 JndiUtils.wrap( e );
970 }
971 }
972
973
974
975
976
977 public Object lookup( String name ) throws NamingException
978 {
979 if ( StringTools.isEmpty( name ) )
980 {
981 return lookup( LdapDN.EMPTY_LDAPDN );
982 }
983 else
984 {
985 return lookup( new LdapDN( name ) );
986 }
987 }
988
989
990
991
992
993 public Object lookup( Name name ) throws NamingException
994 {
995 Object obj;
996 LdapDN target = buildTarget( name );
997
998 ServerEntry serverEntry = null;
999
1000 try
1001 {
1002 if ( name.size() == 0 )
1003 {
1004 serverEntry = doGetRootDSEOperation( target );
1005 }
1006 else
1007 {
1008 serverEntry = doLookupOperation( target );
1009 }
1010 }
1011 catch ( Exception e )
1012 {
1013 JndiUtils.wrap( e );
1014 }
1015
1016 try
1017 {
1018 obj = DirectoryManager.getObjectInstance( null, name, this, env,
1019 ServerEntryUtils.toBasicAttributes( serverEntry ) );
1020 }
1021 catch ( Exception e )
1022 {
1023 String msg = "Failed to create an object for " + target;
1024 msg += " using object factories within the context's environment.";
1025 NamingException ne = new NamingException( msg );
1026 ne.setRootCause( e );
1027 throw ne;
1028 }
1029
1030 if ( obj != null )
1031 {
1032 return obj;
1033 }
1034
1035
1036 if ( serverEntry.get( JavaLdapSupport.JCLASSNAME_ATTR ) != null )
1037 {
1038
1039 return JavaLdapSupport.deserialize( serverEntry );
1040 }
1041
1042
1043 ServerLdapContext ctx = null;
1044
1045 try
1046 {
1047 ctx = new ServerLdapContext( service, session.getEffectivePrincipal(), target );
1048 }
1049 catch ( Exception e )
1050 {
1051 JndiUtils.wrap( e );
1052 }
1053
1054 return ctx;
1055 }
1056
1057
1058
1059
1060
1061 public Object lookupLink( String name ) throws NamingException
1062 {
1063 throw new UnsupportedOperationException();
1064 }
1065
1066
1067
1068
1069
1070 public Object lookupLink( Name name ) throws NamingException
1071 {
1072 throw new UnsupportedOperationException();
1073 }
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084 public NameParser getNameParser( String name ) throws NamingException
1085 {
1086 return new NameParser()
1087 {
1088 public Name parse( String name ) throws NamingException
1089 {
1090 return new LdapDN( name );
1091 }
1092 };
1093 }
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104 public NameParser getNameParser( Name name ) throws NamingException
1105 {
1106 return new NameParser()
1107 {
1108 public Name parse( String name ) throws NamingException
1109 {
1110 return new LdapDN( name );
1111 }
1112 };
1113 }
1114
1115
1116
1117
1118
1119 @SuppressWarnings(value =
1120 { "unchecked" })
1121 public NamingEnumeration list( String name ) throws NamingException
1122 {
1123 return list( new LdapDN( name ) );
1124 }
1125
1126
1127
1128
1129
1130 @SuppressWarnings(value =
1131 { "unchecked" })
1132 public NamingEnumeration list( Name name ) throws NamingException
1133 {
1134 try
1135 {
1136 return new NamingEnumerationAdapter( doListOperation( buildTarget( name ) ) );
1137 }
1138 catch ( Exception e )
1139 {
1140 JndiUtils.wrap( e );
1141 return null;
1142 }
1143 }
1144
1145
1146
1147
1148
1149 @SuppressWarnings(value =
1150 { "unchecked" })
1151 public NamingEnumeration listBindings( String name ) throws NamingException
1152 {
1153 return listBindings( new LdapDN( name ) );
1154 }
1155
1156
1157
1158
1159
1160 @SuppressWarnings(value =
1161 { "unchecked" })
1162 public NamingEnumeration listBindings( Name name ) throws NamingException
1163 {
1164
1165 LdapDN base = buildTarget( name );
1166 PresenceNode filter = new PresenceNode( SchemaConstants.OBJECT_CLASS_AT );
1167 SearchControls ctls = new SearchControls();
1168 ctls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
1169 AliasDerefMode aliasDerefMode = AliasDerefMode.getEnum( getEnvironment() );
1170 try
1171 {
1172 return new NamingEnumerationAdapter( doSearchOperation( base, aliasDerefMode, filter, ctls ) );
1173 }
1174 catch ( Exception e )
1175 {
1176 JndiUtils.wrap( e );
1177 return null;
1178 }
1179 }
1180
1181
1182
1183
1184
1185 public String composeName( String name, String prefix ) throws NamingException
1186 {
1187 return composeName( new LdapDN( name ), new LdapDN( prefix ) ).toString();
1188 }
1189
1190
1191
1192
1193
1194
1195 public Name composeName( Name name, Name prefix ) throws NamingException
1196 {
1197
1198 if ( prefix == null || prefix.size() == 0 )
1199 {
1200 return name;
1201 }
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219 Name fqn = buildTarget( name );
1220 String head = prefix.get( 0 );
1221
1222
1223 while ( fqn.size() > 0 )
1224 {
1225
1226 if ( fqn.get( 0 ).equalsIgnoreCase( head ) )
1227 {
1228 return fqn;
1229 }
1230 else
1231
1232 {
1233 fqn.remove( 0 );
1234 }
1235 }
1236
1237 String msg = "The prefix '" + prefix + "' is not an ancestor of this ";
1238 msg += "entry '" + dn + "'";
1239 throw new NamingException( msg );
1240 }
1241
1242
1243
1244
1245
1246
1247 public void addNamingListener( Name name, int scope, NamingListener namingListener ) throws NamingException
1248 {
1249 ExprNode filter = new PresenceNode( SchemaConstants.OBJECT_CLASS_AT );
1250
1251 try
1252 {
1253 DirectoryListener listener = new EventListenerAdapter( ( ServerLdapContext ) this, namingListener );
1254 NotificationCriteria criteria = new NotificationCriteria();
1255 criteria.setFilter( filter );
1256 criteria.setScope( SearchScope.getSearchScope( scope ) );
1257 criteria.setAliasDerefMode( AliasDerefMode.getEnum( env ) );
1258 criteria.setBase( buildTarget( name ) );
1259
1260 service.getEventService().addListener( listener );
1261 listeners.put( namingListener, listener );
1262 }
1263 catch ( Exception e )
1264 {
1265 JndiUtils.wrap( e );
1266 }
1267 }
1268
1269
1270 public void addNamingListener( String name, int scope, NamingListener namingListener ) throws NamingException
1271 {
1272 addNamingListener( new LdapDN( name ), scope, namingListener );
1273 }
1274
1275
1276 public void removeNamingListener( NamingListener namingListener ) throws NamingException
1277 {
1278 try
1279 {
1280 DirectoryListener listener = listeners.remove( namingListener );
1281
1282 if ( listener != null )
1283 {
1284 service.getEventService().removeListener( listener );
1285 }
1286 }
1287 catch ( Exception e )
1288 {
1289 JndiUtils.wrap( e );
1290 }
1291 }
1292
1293
1294 public boolean targetMustExist() throws NamingException
1295 {
1296 return false;
1297 }
1298
1299
1300
1301
1302
1303
1304
1305 protected Map<NamingListener, DirectoryListener> getListeners()
1306 {
1307 return listeners;
1308 }
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324 LdapDN buildTarget( Name relativeName ) throws InvalidNameException
1325 {
1326 LdapDN target = ( LdapDN ) dn.clone();
1327
1328
1329 target.addAllNormalized( target.size(), relativeName );
1330 return target;
1331 }
1332 }