/* Copyright (c) 2001 - 2013 OpenPlans - www.openplans.org. All rights reserved. * This code is licensed under the GPL 2.0 license, available at the root * application directory. * * This code was derived from * http://svn.apache.org/repos/asf/directory/documentation/samples/trunk/embedded-sample/. Which * falls under the following license. * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.acme; import java.io.File; import java.util.HashSet; import java.util.List; import org.apache.directory.server.constants.ServerDNConstants; import org.apache.directory.server.core.DefaultDirectoryService; import org.apache.directory.server.core.DirectoryService; import org.apache.directory.server.core.entry.ClonedServerEntry; import org.apache.directory.server.core.filtering.EntryFilteringCursor; import org.apache.directory.server.core.partition.Partition; import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex; import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition; import org.apache.directory.server.core.partition.ldif.LdifPartition; import org.apache.directory.server.core.schema.SchemaPartition; import org.apache.directory.server.ldap.LdapServer; import org.apache.directory.server.ldap.handlers.BindHandler; import org.apache.directory.server.protocol.shared.transport.TcpTransport; import org.apache.directory.server.xdbm.Index; import org.apache.directory.shared.ldap.entry.Entry; import org.apache.directory.shared.ldap.entry.ServerEntry; import org.apache.directory.shared.ldap.exception.LdapException; import org.apache.directory.shared.ldap.filter.FilterParser; import org.apache.directory.shared.ldap.filter.SearchScope; import org.apache.directory.shared.ldap.message.AliasDerefMode; import org.apache.directory.shared.ldap.name.DN; import org.apache.directory.shared.ldap.schema.SchemaManager; import org.apache.directory.shared.ldap.schema.ldif.extractor.SchemaLdifExtractor; import org.apache.directory.shared.ldap.schema.ldif.extractor.impl.DefaultSchemaLdifExtractor; import org.apache.directory.shared.ldap.schema.loader.ldif.LdifSchemaLoader; import org.apache.directory.shared.ldap.schema.manager.impl.DefaultSchemaManager; import org.apache.directory.shared.ldap.schema.registries.SchemaLoader; import com.sun.tools.javac.comp.Enter; import static java.lang.String.format; /** * A simple example exposing how to embed Apache Directory Server version 1.5.7 * into an application. * */ public class Ldap { private static final int LDAP_PORT = 10389; /** The directory service */ private DirectoryService service; /** The LDAP server */ private LdapServer server; /** * Add a new partition to the server * * @param partitionId The partition Id * @param partitionDn The partition DN * @return The newly added partition * @throws Exception If the partition can't be added */ private Partition addPartition( String partitionId, String partitionDn ) throws Exception { // Create a new partition named 'foo'. JdbmPartition partition = new JdbmPartition(); partition.setId( partitionId ); partition.setPartitionDir( new File( service.getWorkingDirectory(), partitionId ) ); partition.setSuffix( partitionDn ); service.addPartition( partition ); return partition; } /** * Add a new set of index on the given attributes * * @param partition The partition on which we want to add index * @param attrs The list of attributes to index */ private void addIndex( Partition partition, String... attrs ) { // Index some attributes on the apache partition HashSet<Index<?, ServerEntry, Long>> indexedAttributes = new HashSet<Index<?, ServerEntry, Long>>(); for ( String attribute : attrs ) { indexedAttributes.add( new JdbmIndex<String, ServerEntry>( attribute ) ); } ( ( JdbmPartition ) partition ).setIndexedAttributes( indexedAttributes ); } /** * initialize the schema manager and add the schema partition to diectory service * * @throws Exception if the schema LDIF files are not found on the classpath */ private void initSchemaPartition() throws Exception { SchemaPartition schemaPartition = service.getSchemaService().getSchemaPartition(); // Init the LdifPartition LdifPartition ldifPartition = new LdifPartition(); String workingDirectory = service.getWorkingDirectory().getPath(); ldifPartition.setWorkingDirectory( workingDirectory + "/schema" ); // Extract the schema on disk (a brand new one) and load the registries File schemaRepository = new File( workingDirectory, "schema" ); SchemaLdifExtractor extractor = new DefaultSchemaLdifExtractor( new File( workingDirectory ) ); extractor.extractOrCopy( true ); schemaPartition.setWrappedPartition( ldifPartition ); SchemaLoader loader = new LdifSchemaLoader( schemaRepository ); SchemaManager schemaManager = new DefaultSchemaManager( loader ); service.setSchemaManager( schemaManager ); // We have to load the schema now, otherwise we won't be able // to initialize the Partitions, as we won't be able to parse // and normalize their suffix DN schemaManager.loadAllEnabled(); schemaPartition.setSchemaManager( schemaManager ); List<Throwable> errors = schemaManager.getErrors(); if ( errors.size() != 0 ) { throw new Exception( "Schema load failed : " + errors ); } } /** * Initialize the server. It creates the partition, adds the index, and * injects the context entries for the created partitions. * * @param workDir the directory to be used for storing the data * @throws Exception if there were some problems while initializing the system */ private void initDirectoryService( File workDir ) throws Exception { // Initialize the LDAP service service = new DefaultDirectoryService(); service.setWorkingDirectory( workDir ); // first load the schema initSchemaPartition(); // then the system partition // this is a MANDATORY partition Partition systemPartition = addPartition( "system", ServerDNConstants.SYSTEM_DN ); service.setSystemPartition( systemPartition ); // Disable the ChangeLog system service.getChangeLog().setEnabled( false ); service.setDenormalizeOpAttrsEnabled( true ); // Now we can create as many partitions as we need Partition acmePartition = addPartition("acme", "dc=acme,dc=org"); // Index some attributes on the apache partition //addIndex( apachePartition, "objectClass", "ou", "uid" ); addIndex( acmePartition, "objectClass", "ou", "uid" ); // And start the service service.startup(); // Inject the foo root entry if it does not already exist try { service.getAdminSession().lookup( acmePartition.getSuffixDn() ); } catch ( LdapException lnnfe ) { DN dnBar = new DN( "dc=acme,dc=org" ); ServerEntry entryBar = service.newEntry( dnBar ); entryBar.add( "objectClass", "dcObject", "organization"); entryBar.add( "o", "acme" ); entryBar.add( "dc", "acme" ); service.getAdminSession().add( entryBar ); } // add the people and groups entries DN peopleDn = new DN("ou=people,dc=acme,dc=org"); if (!service.getAdminSession().exists(peopleDn)) { ServerEntry e = service.newEntry(peopleDn); e.add("objectClass", "organizationalUnit"); e.add("ou", "people"); service.getAdminSession().add(e); } DN groupsDn = new DN("ou=groups,dc=acme,dc=org"); if (!service.getAdminSession().exists(groupsDn)) { ServerEntry e = service.newEntry(groupsDn); e.add("objectClass", "organizationalUnit"); e.add("ou", "groups"); service.getAdminSession().add(e); } //add some users addUser("bob", "Bob", "secret"); addUser("alice", "Alice", "foobar"); addUser("bill", "Bill", "hello"); //add some groups addGroup("user", "bob", "alice"); addGroup("admin", "bill"); } private void addGroup(String groupname, String... users) throws Exception { DN dn = new DN(format("cn=%s,ou=groups,dc=acme,dc=org", groupname)); if (!service.getAdminSession().exists(dn)) { ServerEntry e = service.newEntry(dn); e.add("objectClass", "groupOfNames"); e.add("cn", groupname); for (String user : users) { e.add("member", format("uid=%s,ou=people,dc=acme,dc=org", user)); } service.getAdminSession().add(e); } } private void addUser(String username, String displayName, String passwd) throws Exception { DN dn = new DN(format("uid=%s,ou=people,dc=acme,dc=org", username)); if (!service.getAdminSession().exists(dn)) { ServerEntry e = service.newEntry(dn); e.add("objectClass", "person", "inetOrgPerson"); e.add("uid", username); e.add("givenName", displayName); e.add("sn", displayName); e.add("cn", displayName); e.add("displayName", displayName); e.add("userPassword", passwd.getBytes()); service.getAdminSession().add(e); } } /** * Creates a new instance of EmbeddedADS. It initializes the directory service. * * @throws Exception If something went wrong */ public Ldap( File workDir ) throws Exception { initDirectoryService( workDir ); } /** * starts the LdapServer * * @throws Exception */ public void startServer() throws Exception { server = new LdapServer(); server.setBindHandler(new BindHandler()); server.setTransports( new TcpTransport( LDAP_PORT ) ); server.setDirectoryService( service ); server.start(); } /** * Main class. * * @param args Not used. */ public static void main( String[] args ) { try { File workDir = new File( System.getProperty( "java.io.tmpdir" ) + "/server-work" ); workDir.mkdirs(); // Create the server Ldap ldap = new Ldap( workDir ); System.out.println("Directory contents:"); EntryFilteringCursor cursor = ldap.service.getAdminSession().search(new DN("ou=people,dc=acme,dc=org"), SearchScope.SUBTREE, FilterParser.parse("(objectClass=*)"), AliasDerefMode.NEVER_DEREF_ALIASES, null); for (ClonedServerEntry e : cursor) { String indent = " "; if (e.hasObjectClass("person")) { indent += " "; } System.out.println(indent + e.getDn()); } cursor.close(); cursor = ldap.service.getAdminSession().search(new DN("ou=groups,dc=acme,dc=org"), SearchScope.SUBTREE, FilterParser.parse("(objectClass=*)"), AliasDerefMode.NEVER_DEREF_ALIASES, null); for (ClonedServerEntry e : cursor) { String indent = " "; if (e.hasObjectClass("groupOfNames")) { indent += " "; } System.out.println(" " + e.getDn()); if (e.hasObjectClass("groupOfNames")) { System.out.print(e.get("member")); } } System.out.println(); System.out.println("Server running on port " + LDAP_PORT); ldap.startServer(); } catch ( Exception e ) { // Ok, we have something wrong going on ... e.printStackTrace(); } } }