1 17 package org.apache.ldap.server.jndi; 18 19 20 import org.apache.ldap.common.exception.LdapAuthenticationNotSupportedException; 21 import org.apache.ldap.common.exception.LdapConfigurationException; 22 import org.apache.ldap.common.exception.LdapNoPermissionException; 23 import org.apache.ldap.common.message.LockableAttributesImpl; 24 import org.apache.ldap.common.message.ResultCodeEnum; 25 import org.apache.ldap.common.name.LdapName; 26 import org.apache.ldap.common.schema.AttributeType; 27 import org.apache.ldap.common.schema.Normalizer; 28 import org.apache.ldap.common.util.DateUtils; 29 import org.apache.ldap.common.util.StringTools; 30 import org.apache.ldap.server.*; 31 import org.apache.ldap.server.db.*; 32 import org.apache.ldap.server.db.jdbm.JdbmDatabase; 33 import org.apache.ldap.server.interceptor.InterceptorChain; 34 import org.apache.ldap.server.interceptor.InterceptorConfigBuilder; 35 import org.apache.ldap.server.interceptor.InterceptorContext; 36 import org.apache.ldap.server.schema.AttributeTypeRegistry; 37 import org.apache.ldap.server.schema.GlobalRegistries; 38 import org.apache.ldap.server.schema.MatchingRuleRegistry; 39 import org.apache.ldap.server.schema.OidRegistry; 40 import org.apache.ldap.server.schema.bootstrap.BootstrapRegistries; 41 import org.apache.ldap.server.schema.bootstrap.BootstrapSchemaLoader; 42 43 import javax.naming.Context ; 44 import javax.naming.Name ; 45 import javax.naming.NamingException ; 46 import javax.naming.directory.Attributes ; 47 import javax.naming.directory.Attribute ; 48 import javax.naming.spi.InitialContextFactory ; 49 import java.io.File ; 50 import java.lang.reflect.Constructor ; 51 import java.util.ArrayList ; 52 import java.util.Hashtable ; 53 import java.util.List ; 54 55 56 72 public class CoreContextFactory implements InitialContextFactory 73 { 74 78 79 80 private static final String TYPE = Context.SECURITY_AUTHENTICATION; 81 82 83 private static final String CREDS = Context.SECURITY_CREDENTIALS; 84 85 86 protected static final String PRINCIPAL = Context.SECURITY_PRINCIPAL; 87 88 89 protected static final String ADMIN = SystemPartition.ADMIN_PRINCIPAL; 90 91 92 protected static final Name ADMIN_NAME = SystemPartition.getAdminDn(); 93 94 95 public static final String DEFAULT_WKDIR = "server-work"; 96 97 98 protected static final String [] DEFAULT_SCHEMAS = new String [] 99 { 100 "org.apache.ldap.server.schema.bootstrap.CoreSchema", 101 "org.apache.ldap.server.schema.bootstrap.CosineSchema", 102 "org.apache.ldap.server.schema.bootstrap.ApacheSchema", 103 "org.apache.ldap.server.schema.bootstrap.InetorgpersonSchema", 104 "org.apache.ldap.server.schema.bootstrap.JavaSchema", 105 "org.apache.ldap.server.schema.bootstrap.SystemSchema" 106 }; 107 108 112 113 protected JndiProvider provider = null; 114 115 116 protected Hashtable initialEnv; 117 118 119 protected SystemPartition system; 120 121 122 protected GlobalRegistries globalRegistries; 123 124 125 protected RootNexus nexus; 126 127 128 protected boolean createMode; 129 130 131 134 public CoreContextFactory() 135 { 136 JndiProvider.setProviderOn( this ); 137 } 138 139 140 145 void setProvider( JndiProvider provider ) 146 { 147 this.provider = provider; 148 } 149 150 151 public Context getInitialContext( Hashtable env ) throws NamingException 152 { 153 env = ( Hashtable ) env.clone(); 154 155 Context ctx = null; 156 157 if ( env.containsKey( EnvKeys.SHUTDOWN ) ) 158 { 159 if ( this.provider == null ) 160 { 161 return new DeadContext(); 162 } 163 164 try 165 { 166 this.provider.shutdown(); 167 } 168 catch ( Throwable t ) 169 { 170 t.printStackTrace(); 171 } 172 finally 173 { 174 ctx = new DeadContext(); 175 176 provider = null; 177 178 initialEnv = null; 179 } 180 181 return ctx; 182 } 183 184 if ( env.containsKey( EnvKeys.SYNC ) ) 185 { 186 provider.sync(); 187 188 return provider.getLdapContext( env ); 189 } 190 191 checkSecuritySettings( env ); 192 193 if ( isAnonymous( env ) ) 194 { 195 env.put( PRINCIPAL, "" ); 196 } 197 198 if ( null == provider ) 200 { 201 if ( isAnonymous( env ) && env.containsKey( EnvKeys.DISABLE_ANONYMOUS ) ) 204 { 205 throw new LdapNoPermissionException( "cannot bind as anonymous " 206 + "on startup while disabling anonymous binds w/ property: " 207 + EnvKeys.DISABLE_ANONYMOUS ); 208 } 209 210 this.initialEnv = env; 211 212 initialize(); 213 214 createMode = createBootstrapEntries(); 215 216 222 223 if ( createMode && env.containsKey( EnvKeys.TEST_ENTRIES ) ) 224 { 225 ArrayList list = ( ArrayList ) initialEnv.get( EnvKeys.TEST_ENTRIES ); 226 227 if ( list != null ) 228 { 229 for ( int ii = 0; ii < list.size(); ii++ ) 230 { 231 Attributes attributes = ( Attributes ) list.get( ii ); 232 233 attributes.put( "creatorsName", ADMIN ); 234 235 attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() ); 236 237 Attribute dn = attributes.remove( "dn" ); 238 239 nexus.add( ( String ) dn.get(), new LdapName( ( String ) dn.get() ), attributes ); 240 } 241 } 242 } 243 } 244 245 ctx = ( ServerContext ) provider.getLdapContext( env ); 246 247 return ctx; 248 } 249 250 251 256 protected void checkSecuritySettings( Hashtable env ) throws NamingException 257 { 258 if ( env.containsKey( TYPE ) && env.get( TYPE ) != null ) 259 { 260 264 if ( env.get( TYPE ).equals( "simple" ) ) 265 { 266 if ( !env.containsKey( CREDS ) ) 267 { 268 throw new LdapConfigurationException( "missing required " 269 + CREDS + " property for simple authentication" ); 270 } 271 272 if ( !env.containsKey( PRINCIPAL ) ) 273 { 274 throw new LdapConfigurationException( "missing required " 275 + PRINCIPAL + " property for simple authentication" ); 276 } 277 } 278 282 else if ( env.get( TYPE ).equals( "none" ) ) 283 { 284 if ( env.containsKey( CREDS ) ) 285 { 286 throw new LdapConfigurationException( "ambiguous bind " 287 + "settings encountered where bind is anonymous yet " 288 + CREDS + " property is set" ); 289 } 290 if ( env.containsKey( PRINCIPAL ) ) 291 { 292 throw new LdapConfigurationException( "ambiguous bind " 293 + "settings encountered where bind is anonymous yet " 294 + PRINCIPAL + " property is set" ); 295 } 296 } 297 301 else 302 { 303 throw new LdapAuthenticationNotSupportedException( ResultCodeEnum.AUTHMETHODNOTSUPPORTED ); 304 } 305 } 306 else if ( env.containsKey( CREDS ) ) 307 { 308 if ( !env.containsKey( PRINCIPAL ) ) 309 { 310 throw new LdapConfigurationException( "credentials provided " 311 + "without principal name property: " + PRINCIPAL ); 312 } 313 } 314 } 315 316 317 322 protected boolean isAnonymous( Hashtable env ) 323 { 324 325 if ( env.containsKey( TYPE ) && env.get( TYPE ) != null ) 326 { 327 if ( env.get( TYPE ).equals( "none" ) ) 328 { 329 return true; 330 } 331 332 return false; 333 } 334 335 if ( env.containsKey( CREDS ) ) 336 { 337 return false; 338 } 339 340 return true; 341 } 342 343 344 351 private boolean createBootstrapEntries() throws NamingException 352 { 353 boolean isFirstStart = false; 354 355 359 362 if ( nexus.hasEntry( ADMIN_NAME ) ) 363 { 364 isFirstStart = false; 365 } 366 else 367 { 368 isFirstStart = true; 369 370 Attributes attributes = new LockableAttributesImpl(); 371 372 attributes.put( "objectClass", "top" ); 373 374 attributes.put( "objectClass", "person" ); 375 376 attributes.put( "objectClass", "organizationalPerson" ); 377 378 attributes.put( "objectClass", "inetOrgPerson" ); 379 380 attributes.put( "uid", SystemPartition.ADMIN_UID ); 381 382 attributes.put( "userPassword", SystemPartition.ADMIN_PW ); 383 384 attributes.put( "displayName", "Directory Superuser" ); 385 386 attributes.put( "creatorsName", ADMIN ); 387 388 attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() ); 389 390 attributes.put( "displayName", "Directory Superuser" ); 391 392 nexus.add( ADMIN, ADMIN_NAME, attributes ); 393 } 394 395 399 if ( nexus.hasEntry( new LdapName( "ou=users,ou=system" ) ) ) 400 { 401 isFirstStart = false; 402 } 403 else 404 { 405 isFirstStart = true; 406 407 Attributes attributes = new LockableAttributesImpl(); 408 409 attributes.put( "objectClass", "top" ); 410 411 attributes.put( "objectClass", "organizationalUnit" ); 412 413 attributes.put( "ou", "users" ); 414 415 attributes.put( "creatorsName", ADMIN ); 416 417 attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() ); 418 419 nexus.add( "ou=users,ou=system", new LdapName( "ou=users,ou=system" ), attributes ); 420 } 421 422 426 if ( nexus.hasEntry( new LdapName( "ou=groups,ou=system" ) ) ) 427 { 428 isFirstStart = false; 429 } 430 else 431 { 432 isFirstStart = true; 433 434 Attributes attributes = new LockableAttributesImpl(); 435 436 attributes.put( "objectClass", "top" ); 437 438 attributes.put( "objectClass", "organizationalUnit" ); 439 440 attributes.put( "ou", "groups" ); 441 442 attributes.put( "creatorsName", ADMIN ); 443 444 attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() ); 445 446 nexus.add( "ou=groups,ou=system", new LdapName( "ou=groups,ou=system" ), attributes ); 447 } 448 449 453 if ( nexus.hasEntry( new LdapName( "prefNodeName=sysPrefRoot,ou=system" ) ) ) 454 { 455 isFirstStart = false; 456 } 457 else 458 { 459 isFirstStart = true; 460 461 Attributes attributes = new LockableAttributesImpl(); 462 463 attributes.put( "objectClass", "top" ); 464 465 attributes.put( "objectClass", "prefNode" ); 466 467 attributes.put( "objectClass", "extensibleObject" ); 468 469 attributes.put( "prefNodeName", "sysPrefRoot" ); 470 471 attributes.put( "creatorsName", ADMIN ); 472 473 attributes.put( "createTimestamp", DateUtils.getGeneralizedTime() ); 474 475 LdapName dn = new LdapName( "prefNodeName=sysPrefRoot,ou=system" ); 476 477 nexus.add( "prefNodeName=sysPrefRoot,ou=system", dn, attributes ); 478 } 479 480 return isFirstStart; 481 } 482 483 484 489 protected void initialize() throws NamingException 490 { 491 495 BootstrapRegistries bootstrapRegistries = new BootstrapRegistries(); 496 497 BootstrapSchemaLoader loader = new BootstrapSchemaLoader(); 498 499 String [] schemas = DEFAULT_SCHEMAS; 500 501 if ( initialEnv.containsKey( EnvKeys.SCHEMAS ) ) 502 { 503 String schemaList = ( String ) initialEnv.get( EnvKeys.SCHEMAS ); 504 505 schemaList = StringTools.deepTrim( schemaList ); 506 507 schemas = schemaList.split( " " ); 508 509 for ( int ii = 0; ii < schemas.length; ii++ ) 510 { 511 schemas[ii] = schemas[ii].trim(); 512 } 513 } 514 515 loader.load( schemas, bootstrapRegistries ); 516 517 List errors = bootstrapRegistries.checkRefInteg(); 518 519 if ( !errors.isEmpty() ) 520 { 521 NamingException e = new NamingException (); 522 523 e.setRootCause( ( Throwable ) errors.get( 0 ) ); 524 525 throw e; 526 } 527 528 532 String wkdir = DEFAULT_WKDIR; 533 534 if ( initialEnv.containsKey( EnvKeys.WKDIR ) ) 535 { 536 wkdir = ( ( String ) initialEnv.get( EnvKeys.WKDIR ) ).trim(); 537 } 538 539 File wkdirFile = new File ( wkdir ); 540 541 if ( wkdirFile.isAbsolute() ) 542 { 543 if ( !wkdirFile.exists() ) 544 { 545 throw new NamingException ( "working directory " + wkdir + " does not exist" ); 546 } 547 } 548 else 549 { 550 File current = new File ( "." ); 551 552 mkdirs( current.getAbsolutePath(), wkdir ); 553 } 554 555 LdapName suffix = new LdapName(); 556 557 suffix.add( SystemPartition.SUFFIX ); 558 559 Database db = new JdbmDatabase( suffix, suffix, wkdir ); 560 561 AttributeTypeRegistry attributeTypeRegistry; 562 563 attributeTypeRegistry = bootstrapRegistries .getAttributeTypeRegistry(); 564 565 OidRegistry oidRegistry; 566 567 oidRegistry = bootstrapRegistries.getOidRegistry(); 568 569 ExpressionEvaluator evaluator; 570 571 evaluator = new ExpressionEvaluator( db, oidRegistry, attributeTypeRegistry ); 572 573 ExpressionEnumerator enumerator; 574 575 enumerator = new ExpressionEnumerator( db, attributeTypeRegistry, evaluator ); 576 577 SearchEngine eng = new DefaultSearchEngine( db, evaluator, enumerator ); 578 579 AttributeType[] attributes = new AttributeType[] 580 { 581 attributeTypeRegistry.lookup( SystemPartition.ALIAS_OID ), 582 583 attributeTypeRegistry.lookup( SystemPartition.EXISTANCE_OID ), 584 585 attributeTypeRegistry.lookup( SystemPartition.HIERARCHY_OID ), 586 587 attributeTypeRegistry.lookup( SystemPartition.NDN_OID ), 588 589 attributeTypeRegistry.lookup( SystemPartition.ONEALIAS_OID ), 590 591 attributeTypeRegistry.lookup( SystemPartition.SUBALIAS_OID ), 592 593 attributeTypeRegistry.lookup( SystemPartition.UPDN_OID ) 594 }; 595 596 system = new SystemPartition( db, eng, attributes ); 597 598 globalRegistries = new GlobalRegistries( system, bootstrapRegistries ); 599 600 nexus = new RootNexus( system, new LockableAttributesImpl() ); 601 602 provider = new JndiProvider( nexus ); 603 604 InterceptorChain interceptor = ( InterceptorChain ) initialEnv.get( EnvKeys.INTERCEPTORS ); 608 609 if( interceptor == null ) 610 { 611 613 interceptor = InterceptorChain.newDefaultChain(); 614 } 615 616 interceptor.init( new InterceptorContext( initialEnv, system, globalRegistries, nexus, 617 InterceptorConfigBuilder.build( initialEnv, EnvKeys.INTERCEPTORS ) ) ); 618 619 provider.setInterceptor( interceptor ); 620 621 if ( initialEnv.get( EnvKeys.PARTITIONS ) != null ) 623 { 624 startUpAppPartitions( wkdir ); 625 } 626 } 627 628 636 protected void startUpAppPartitions( String eveWkdir ) throws NamingException 637 { 638 OidRegistry oidRegistry = globalRegistries.getOidRegistry(); 639 640 AttributeTypeRegistry attributeTypeRegistry; 641 642 attributeTypeRegistry = globalRegistries.getAttributeTypeRegistry(); 643 644 MatchingRuleRegistry reg = globalRegistries.getMatchingRuleRegistry(); 645 646 ContextPartitionConfig[] configs = null; 648 649 configs = PartitionConfigBuilder.getContextPartitionConfigs( initialEnv ); 650 651 for ( int ii = 0; ii < configs.length; ii++ ) 652 { 653 657 String wkdir = eveWkdir + File.separator + configs[ii].getId(); 658 659 mkdirs( eveWkdir, configs[ii].getId() ); 660 661 665 Name upSuffix = new LdapName( configs[ii].getSuffix() ); 666 667 Normalizer dnNorm = reg.lookup( "distinguishedNameMatch" ) .getNormalizer(); 668 669 Name normSuffix = new LdapName( ( String ) dnNorm.normalize( configs[ii].getSuffix() ) ); 670 671 Database db = new JdbmDatabase( upSuffix, normSuffix, wkdir ); 672 673 677 ExpressionEvaluator evaluator; 678 679 evaluator = new ExpressionEvaluator( db, oidRegistry, attributeTypeRegistry ); 680 681 ExpressionEnumerator enumerator; 682 683 enumerator = new ExpressionEnumerator( db, attributeTypeRegistry, evaluator ); 684 685 SearchEngine eng = new DefaultSearchEngine( db, evaluator, enumerator ); 686 687 691 ArrayList attributeTypeList = new ArrayList (); 692 693 attributeTypeList.add( attributeTypeRegistry.lookup( SystemPartition.ALIAS_OID ) ); 694 695 attributeTypeList.add( attributeTypeRegistry.lookup( SystemPartition.EXISTANCE_OID ) ); 696 697 attributeTypeList.add( attributeTypeRegistry.lookup( SystemPartition.HIERARCHY_OID ) ); 698 699 attributeTypeList.add( attributeTypeRegistry.lookup( SystemPartition.NDN_OID ) ); 700 701 attributeTypeList.add( attributeTypeRegistry.lookup( SystemPartition.ONEALIAS_OID ) ); 702 703 attributeTypeList.add( attributeTypeRegistry.lookup( SystemPartition.SUBALIAS_OID ) ); 704 705 attributeTypeList.add( attributeTypeRegistry.lookup( SystemPartition.UPDN_OID ) ); 706 707 711 for ( int jj = 0; jj < configs[ii].getIndices().length; jj++ ) 712 { 713 attributeTypeList.add( attributeTypeRegistry 714 .lookup( configs[ii].getIndices()[jj] ) ); 715 } 716 717 721 AttributeType[] indexTypes = ( AttributeType[] ) attributeTypeList 722 .toArray( new AttributeType[attributeTypeList.size()] ); 723 724 String partitionClass = configs[ii].getPartitionClass(); 725 726 String properties = configs[ii].getProperties(); 727 728 ContextPartition partition = null; 729 730 if ( partitionClass == null ) 731 { 732 partition = new ApplicationPartition( upSuffix, normSuffix, db, eng, indexTypes ); 734 735 } 736 else 737 { 738 try 740 { 741 Class clazz = Class.forName( partitionClass ); 742 743 Constructor constructor = clazz.getConstructor( 744 new Class [] { Name.class, Name.class, String .class } ); 745 746 partition = ( ContextPartition ) constructor.newInstance( 747 new Object [] { upSuffix, normSuffix, properties } ); 748 } 749 catch ( Exception e ) 750 { 751 e.printStackTrace(); 752 } 753 } 754 755 if ( partition != null ) 756 { 757 nexus.register( partition ); 758 } 759 760 764 partition.add( configs[ii].getSuffix(), normSuffix, configs[ii].getAttributes() ); 765 } 766 } 767 768 769 776 protected boolean mkdirs( String base, String path ) 777 { 778 String [] comps = path.split( "/" ); 779 780 File file = new File ( base ); 781 782 if ( !file.exists() ) 783 { 784 file.mkdirs(); 785 } 786 787 for ( int ii = 0; ii < comps.length; ii++ ) 788 { 789 file = new File ( file, comps[ii] ); 790 791 if ( !file.exists() ) 792 { 793 file.mkdirs(); 794 } 795 } 796 797 return file.exists(); 798 } 799 } 800 | Popular Tags |