ApacheDS Guide

143
ApacheDS Advanced User Guide v1.5.8-SNAPSHOT

Transcript of ApacheDS Guide

Page 1: ApacheDS Guide

ApacheDS Advanced UserGuide v1.5.8-SNAPSHOT

Page 2: ApacheDS Guide

Draft Draft

© 2003-20102

The Apache Software Foundation Privacy Policy

ApacheDS Advanced User Guide v1.5.8-SNAPSHOTCopyright © 2003-2010 The Apache Software Foundation

Licensed to the Apache Software Foundation (ASF) under oneor more contributor license agreements. See the NOTICE filedistributed with this work for additional informationregarding copyright ownership. The ASF licenses this fileto you under the Apache License, Version 2.0 (the"License"); you may not use this file except in compliancewith 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 ANYKIND, either express or implied. See the License for thespecific language governing permissions and limitationsunder the License.

Page 3: ApacheDS Guide

Draft Draft

© 2003-2010iii

The Apache Software Foundation Privacy Policy

Table of ContentsWork in progress ......................................................................................................... xi1. Community .............................................................................................................. 1

1.1. Reporting Bugs .............................................................................................. 11.1.1. Introduction ......................................................................................... 11.1.2. Creating a testcase project: using the apacheds-archetype-testcase .................. 11.1.3. Installing the apacheds-archetype-testcase ................................................. 11.1.4. Invoking (running) the archetype: generating the testcase project ................... 1

1.1.4.1. For IDEA ................................................................................. 21.1.4.2. For Eclipse ............................................................................... 31.1.4.3. For Netbeans ............................................................................. 3

1.1.5. Note about version ............................................................................... 31.1.6. Why a Maven Archetype for Testing? ...................................................... 3

1.2. Building trunks ............................................................................................... 31.2.1. Project Hierarchy ................................................................................. 41.2.2. Prerequisites for building ....................................................................... 4

1.2.2.1. Maven ..................................................................................... 41.2.2.2. JDK 5 ...................................................................................... 4

1.2.3. Getting the code ................................................................................... 41.2.4. Building the trunks ............................................................................... 5

1.2.4.1. Enabling Snapshot Repositories .................................................... 51.2.4.2. Building the trunks .................................................................. 6

1.2.5. Building the installers ........................................................................... 61.2.6. Starting the server without installation ...................................................... 61.2.7. Integration test ..................................................................................... 61.2.8. Eclipse ............................................................................................... 7

1.2.8.1. Building eclipse files .................................................................. 71.2.8.2. Maven settings .......................................................................... 71.2.8.3. Eclipse hints ............................................................................. 71.2.8.4. Eclipse plugins .......................................................................... 71.2.8.5. Coding standards ....................................................................... 7

1.3. Contributing ................................................................................................... 72. Architecture .............................................................................................................. 8

2.1. Architectural Overview .................................................................................... 82.1.1. Partitions ............................................................................................ 8

2.2. Interceptors .................................................................................................... 82.2.1. What is it? .......................................................................................... 82.2.2. How does it work? ............................................................................... 82.2.3. JNDI Implementation ............................................................................ 82.2.4. The nexus proxy object ......................................................................... 92.2.5. Operation handling within interceptors .................................................... 102.2.6. Bind Operation ................................................................................... 112.2.7. Normalization interceptor ..................................................................... 112.2.8. Authentication interceptor .................................................................... 122.2.9. Add operation .................................................................................... 12

2.3. The Administrative Model .............................................................................. 122.3.1. Introduction ....................................................................................... 122.3.2. What exactly are subentries? ................................................................. 132.3.3. Administrative Areas, Entries and Points ................................................. 132.3.4. How are administrative areas defined? .................................................... 142.3.5. Subentries under an IAA or an AAA ...................................................... 152.3.6. Base parameter ................................................................................... 152.3.7. Chop parameters ................................................................................. 15

2.3.7.1. chopBefore and chopAfter ......................................................... 152.3.7.2. minimum and maximum ............................................................ 15

2.3.8. Specification filter parameter ................................................................ 16

Page 4: ApacheDS Guide

Draft ApacheDS Advanced UserGuide v1.5.8-SNAPSHOT

Draft

© 2003-2010iv

The Apache Software Foundation Privacy Policy

2.3.9. Subentry types in ApacheDS ................................................................. 162.3.10. How to specify a subentry's subtreeSpecification ..................................... 162.3.11. Future Possibilities ............................................................................ 182.3.12. Conclusions ..................................................................................... 18

2.4. Supported RFCs ............................................................................................ 183. Authentication & Authorization .................................................................................. 25

3.1. SASL Authentication to ApacheDS .................................................................. 253.1.1. Introduction ....................................................................................... 253.1.2. Architecture ....................................................................................... 253.1.3. CRAM-MD5 ...................................................................................... 253.1.4. DIGEST-MD5 .................................................................................... 253.1.5. GSSAPI ............................................................................................ 263.1.6. Anonymous queries ............................................................................. 263.1.7. SASL queries ..................................................................................... 263.1.8. Resources .......................................................................................... 26

3.2. HOWTO do SASL GSSAPI Authentication to ApacheDS ..................................... 273.2.1. Introduction ....................................................................................... 273.2.2. Getting Started ................................................................................... 27

3.3. Start TLS with ApacheDS .............................................................................. 313.3.1. Introduction ....................................................................................... 313.3.2. Testing LDAP binds with TLS .............................................................. 313.3.3. Resources .......................................................................................... 31

3.4. Writing a custom authenticator ........................................................................ 313.4.1. Using custom authenticators ................................................................. 31

3.5. Authorization ................................................................................................ 323.5.1. Enabling Basic Access Controls ............................................................ 323.5.2. Types of ACI (Access Control Information) ............................................. 33

3.5.2.1. Entry ACI ............................................................................... 333.5.2.2. Prescriptive ACI ...................................................................... 333.5.2.3. Subentry ACI .......................................................................... 33

3.5.3. Some Simple Examples ....................................................................... 333.5.3.1. ACI Trails .............................................................................. 34

3.5.4. ACAreas ........................................................................................... 343.5.4.1. Introduction ............................................................................. 343.5.4.2. Creating Access Control Specific Areas (ACSA) ............................ 34

3.5.4.2.1. Adding an 'administrativeRole' Attribute ............................. 343.5.4.3. Creating an Access Control Inner Administrative Area ..................... 353.5.4.4. Access Control Subentries .......................................................... 35

3.5.5. AllowSelfPasswordModify ................................................................... 353.5.5.1. Commentary ............................................................................ 36

3.5.6. EnableSearchForAllUsers ..................................................................... 363.5.6.1. Enable Authenticated Users to Browse and Read Entries in aSubtree .............................................................................................. 36

3.5.6.1.1. Check for insufficientAccessRights for Normal Users ............ 363.5.6.1.2. Partition and Access Control Area Setup ............................. 363.5.6.1.3. Adding the Subentry ....................................................... 363.5.6.1.4. ACIItem Description ...................................................... 37

3.5.7. UserClasses ....................................................................................... 393.5.7.1. What are User Classes? ............................................................. 393.5.7.2. Simple User Classes ................................................................. 393.5.7.3. User Class: userGroup ............................................................... 393.5.7.4. User Class: subtree ................................................................... 40

3.5.8. Combining Multiple UserClass Specification Mechanisms .......................... 404. Attributes, Entries & Schemas ................................................................................... 41

4.1. Add your first elements to the schema .............................................................. 414.1.1. Motivation ......................................................................................... 414.1.2. Browsing the schema of ApacheDS ........................................................ 414.1.3. Which OIDs should you use? ................................................................ 43

Page 5: ApacheDS Guide

Draft ApacheDS Advanced UserGuide v1.5.8-SNAPSHOT

Draft

© 2003-2010v

The Apache Software Foundation Privacy Policy

4.1.3.1. Some OID background information .............................................. 434.1.3.2. OIDs in the example ................................................................. 444.1.3.3. OIDs for your own custom schema elements .................................. 44

4.1.4. A simple example ............................................................................... 444.1.4.1. attribute type numberOfGuns ...................................................... 444.1.4.2. object class ship ....................................................................... 45

4.1.5. Using Apache Directory Studio Schema Editor to load the new schemaelements .................................................................................................... 454.1.6. Using LDIF to load schema elements in RFC 4512 format .......................... 484.1.7. Using JNDI to add the schema elements programmatically .......................... 48

4.1.7.1. Some simple Java programs ....................................................... 484.1.8. Using JNDI to add schema elements in RFC 4512 format programmatically................................................................................................................. 494.1.9. Resources .......................................................................................... 50

4.2. Collective Attributes ...................................................................................... 504.2.1. Introduction ....................................................................................... 50

4.2.1.1. Use Case ................................................................................ 504.2.2. Setting up a Collective Attribute Administration Area (AA) ........................ 51

4.2.2.1. Example ................................................................................. 514.2.3. Collective Attribute Types .................................................................... 52

5. Embedding ApacheDS .............................................................................................. 555.1. Embedding ApacheDS into an application ......................................................... 55

5.1.1. Setting up the environment ................................................................... 555.1.2. Creating the application ....................................................................... 555.1.3. Initializing the server ........................................................................... 565.1.4. Building the sample ............................................................................ 585.1.5. Running the sample ............................................................................ 58

5.2. Using ApacheDS for unit tests ......................................................................... 595.2.1. First steps .......................................................................................... 595.2.2. Creating a blank test ........................................................................... 59

5.2.2.1. Test description ........................................................................ 625.2.2.1.1. Annotations .................................................................. 625.2.2.1.2. Server startup ................................................................ 635.2.2.1.3. Writing your own test using JNDI ..................................... 635.2.2.1.4. Writing your own tests using the Netscape API .................... 63

5.2.3. Creating our own partition .................................................................... 645.2.4. Adding some data into the partition ........................................................ 655.2.5. Cleanup the code ................................................................................ 665.2.6. Searching for entries ........................................................................... 675.2.7. Adding your own schema ..................................................................... 685.2.8. Conclusion ........................................................................................ 685.2.9. Resources .......................................................................................... 69

5.3. Embedding ApacheDS as a Web Application ..................................................... 695.3.1. Solution Outline ................................................................................. 69

5.3.1.1. A Servlet Context Listener to start and stop ApacheDS .................... 695.3.1.2. A client within ......................................................................... 70

5.3.2. Step 1: The web component which starts and stops the server ...................... 705.3.2.1. Deployment descriptor .............................................................. 72

5.3.3. Packaging and Deploying the WebApp ................................................... 725.3.3.1. Creating the WebApp using the ApacheDS Maven Archetype ........... 725.3.3.2. Run on embedded Jetty ............................................................. 735.3.3.3. Deploying on Apache Tomcat ..................................................... 735.3.3.4. Connecting to ApacheDS from the outside .................................... 735.3.3.5. Other Web Application Servers ................................................... 76

5.3.4. Step 2: Adding functionality: A servlet which displays the Root DSE ............ 776. Protocol Providers ................................................................................................... 80

6.1. Protocol Providers ......................................................................................... 806.1.1. Apache Directory Protocol Providers ...................................................... 80

Page 6: ApacheDS Guide

Draft ApacheDS Advanced UserGuide v1.5.8-SNAPSHOT

Draft

© 2003-2010vi

The Apache Software Foundation Privacy Policy

6.1.2. Service Configuration .......................................................................... 806.1.3. Changes from 1.5 to 1.5.1 .................................................................... 806.1.4. Protocol Providers ............................................................................... 80

6.2. Common Parameters for Configuration .............................................................. 816.2.1. Changes to Configuration ..................................................................... 81

6.2.1.1. Changes to LDAP configuration in 1.5.1 ....................................... 826.2.1.2. Changes to the other protocols in 1.5.1 ......................................... 82

6.2.2. Configuration Parameters Reference ....................................................... 826.2.2.1. Environment parameters ............................................................ 826.2.2.2. Protocol providers .................................................................... 83

6.2.2.2.1. Parameters common to all protocol providers ....................... 836.2.2.2.2. LDAP-Specific Configuration Parameters ........................... 856.2.2.2.3. Kerberos-Specific Configuration Parameters ........................ 876.2.2.2.4. Change Password-Specific Configuration Parameters ............ 876.2.2.2.5. NTP-Specific configuration parameters .............................. 886.2.2.2.6. DHCP-Specific configuration parameters ............................ 88

6.2.2.3. Server Startup Configuration ...................................................... 886.2.2.3.1. Replication ................................................................... 88

6.2.2.4. Partition Configuration .............................................................. 896.3. LDAP Protocol Provider ................................................................................. 89

6.3.1. Before .............................................................................................. 896.3.2. After ................................................................................................ 896.3.3. Common Service Configuration Parameters ............................................. 906.3.4. LDAP-Specific Configuration Parameters ................................................ 916.3.5. More Information ............................................................................... 92

6.4. Kerberos Protocol Provider ............................................................................. 926.4.1. Introduction ....................................................................................... 926.4.2. More Information ............................................................................... 936.4.3. Resources .......................................................................................... 93

6.4.3.1. Kerberos Articles ..................................................................... 936.4.3.2. Microsoft Interoperability .......................................................... 936.4.3.3. Standards ................................................................................ 93

6.4.4. Kerberos Protocol Configuration ............................................................ 936.4.4.1. Before .................................................................................... 936.4.4.2. After ...................................................................................... 946.4.4.3. Common Service Configuration Parameters ................................... 946.4.4.4. Kerberos-Specific Configuration Parameters .................................. 956.4.4.5. More Information ..................................................................... 95

6.4.5. Kerberos and Unlimited Strength Policy .................................................. 966.4.5.1. Introduction ............................................................................. 966.4.5.2. Installation .............................................................................. 96

6.4.6. Kerberos in ApacheDS 1.5.5 ................................................................. 966.4.6.1. Overview ................................................................................ 976.4.6.2. Activate Kerberos ..................................................................... 976.4.6.3. Optional: Logging .................................................................... 976.4.6.4. Restart the Server ..................................................................... 976.4.6.5. Load User Data ........................................................................ 986.4.6.6. Authenticate using kinit (Unix/Linux) .......................................... 986.4.6.7. Authenticate using Apache Directory Studio .................................. 99

6.5. Change Password Protocol Provider .................................................................. 996.5.1. Introduction ....................................................................................... 996.5.2. Changing Passwords with Windows 2003 .............................................. 100

6.5.2.1. Configure the Windows 2003 workstation to use an Apache ChangePassword server ................................................................................. 1006.5.2.2. Change a password using Windows Security ................................ 1006.5.2.3. Or change a password using the Command Prompt ........................ 101

6.5.3. Change Password Configuration ........................................................... 1016.5.3.1. Before .................................................................................. 101

Page 7: ApacheDS Guide

Draft ApacheDS Advanced UserGuide v1.5.8-SNAPSHOT

Draft

© 2003-2010vii

The Apache Software Foundation Privacy Policy

6.5.3.2. After .................................................................................... 1016.5.3.3. Common Service Configuration Parameters ................................. 1026.5.3.4. Change Password-Specific Configuration Parameters ..................... 1036.5.3.5. More Information ................................................................... 103

6.5.4. Change Password in ApacheDS 1.5.5 .................................................... 1036.5.4.1. Activating the Change Password Server ...................................... 103

6.6. DNS Protocol Provider ................................................................................. 1046.6.1. Introduction ..................................................................................... 104

6.6.1.1. Basic Testing ......................................................................... 1046.6.1.2. ApacheDS schema for storing DNS zones in LDAP ....................... 104

6.6.1.2.1. Abstract objectClass used to build all DNS recordobjectclasses ............................................................................. 1046.6.1.2.2. Address (A) record ....................................................... 1056.6.1.2.3. Pointer (PTR) record ..................................................... 1056.6.1.2.4. Name Server (NS) record ............................................... 1056.6.1.2.5. Start Of Authority (SOA) record ..................................... 105

6.6.1.3. Configuring DNS Zones .......................................................... 1066.6.1.3.1. The STRUCTURAL 'dcObject' objectClass ....................... 1066.6.1.3.2. The AUXILIARY 'domain' objectClass ............................ 107

6.6.2. DNS Best Practices ........................................................................... 1076.6.2.1. DNS Testing Tool .................................................................. 107

6.6.3. Notes .............................................................................................. 1076.6.3.1. A Zone is a Pruned Subtree ...................................................... 1076.6.3.2. Sender Permitted From ............................................................ 1086.6.3.3. Secret Key Transaction Authentication for DNS (TSIG) ................. 108

6.6.4. DNS Protocol Configuration ............................................................... 1086.6.4.1. Common Service Configuration Parameters ................................. 1086.6.4.2. More Information ................................................................... 109

6.7. NTP Protocol Provider ................................................................................. 1096.7.1. Introduction ..................................................................................... 1096.7.2. Basic Testing ................................................................................... 1106.7.3. Resources ........................................................................................ 110

6.7.3.1. SNTP RFC's .......................................................................... 1106.7.4. NTP Protocol Configuration ................................................................ 110

6.7.4.1. Common Service Configuration Parameters ................................. 1106.7.4.2. More Information ................................................................... 111

6.8. DHCP Protocol Provider ............................................................................... 1116.8.1. Introduction ..................................................................................... 111

6.8.1.1. DHCP Notes .......................................................................... 1126.8.2. More Information .............................................................................. 112

7. Extending the server ............................................................................................... 1137.1. How to write a simple custom partition for ApacheDS ........................................ 113

7.1.1. What exactly is a partition? ................................................................. 1137.1.2. Hello world. A minimal partition ......................................................... 113

7.1.2.1. The sources ........................................................................... 1147.1.2.2. Implementing the class HelloWorldPartition ................................. 1147.1.2.3. Using the partition .................................................................. 115

7.1.2.3.1. Embedded mode .......................................................... 1157.1.2.3.2. Adding it to a server.xml file .......................................... 116

7.1.2.4. Verification ........................................................................... 1167.1.3. To be continued ................................................................................ 117

7.2. Implementing a simple custom Interceptor ....................................................... 1177.2.1. What exactly is an interceptor? ............................................................ 1187.2.2. Password hash. A simple interceptor ..................................................... 118

7.2.2.1. The sources ........................................................................... 1197.2.2.2. Implementing the class PasswordHashInterceptor .......................... 1197.2.2.3. Using the interceptor ............................................................... 120

7.2.2.3.1. Adding it to a standard server installation (server.xml) ......... 120

Page 8: ApacheDS Guide

Draft ApacheDS Advanced UserGuide v1.5.8-SNAPSHOT

Draft

© 2003-2010viii

The Apache Software Foundation Privacy Policy

7.2.2.3.2. Embedded mode .......................................................... 1217.2.2.4. Verification ........................................................................... 1227.2.2.5. Limitations of the example ....................................................... 123

7.2.3. Further reading ................................................................................. 1248. Partitioning & Replication ....................................................................................... 125

8.1. Referrals .................................................................................................... 1258.2. Replication ................................................................................................. 125

9. Triggers & Stored Procedures .................................................................................. 1269.1. Stored Procedures ........................................................................................ 126

9.1.1. What are Stored Procedures in LDAP? .................................................. 1269.1.1.1. Java as the Native SP Language ................................................ 1269.1.1.2. Storing Classes within the DIT .................................................. 1269.1.1.3. Code Security and Class Conflicts ............................................. 1269.1.1.4. Searching and Search Order for Classes ...................................... 1279.1.1.5. Stored Procedure Call Specification ............................................ 1279.1.1.6. Stored Procedure Execution Request Value .................................. 127

9.1.1.6.1. BER .......................................................................... 1279.1.1.6.2. The State Machine ........................................................ 127

9.1.1.7. Explanations .......................................................................... 1289.1.1.8. Security ................................................................................ 128

9.2. LDAP Triggers ........................................................................................... 1289.2.1. Introduction ..................................................................................... 1289.2.2. Trigger Specification ......................................................................... 1289.2.3. Action Time for Triggers .................................................................... 1299.2.4. Trigger Events: LDAP Operations ........................................................ 1299.2.5. Triggered Actions: LDAP Stored Procedures .......................................... 1299.2.6. Planned New Features for Triggers ....................................................... 129

10. Tuning ................................................................................................................ 13010.1. Performance Tuning ................................................................................... 130

10.1.1. Balancing Cache w/ Heap Memory Indexing Attributes .......................... 130Index ....................................................................................................................... 132

Page 9: ApacheDS Guide

Draft Draft

© 2003-2010ix

The Apache Software Foundation Privacy Policy

List of Figures2.1. Interceptors .......................................................................................................... 102.2. Interceptor chaining ............................................................................................... 114.1. Schema Browser Person ......................................................................................... 424.2. Schema Browser Tree ............................................................................................ 434.3. Schemas view ....................................................................................................... 464.4. Schemas view with loaded schemas .......................................................................... 464.5. Schema browser ship ............................................................................................. 474.6. Entry editor with ship ............................................................................................ 474.7. SubEntry ............................................................................................................. 525.1. ApacheDS as a Web Application ............................................................................. 705.2. Tomcat Manager App in Browser ............................................................................ 735.3. New LDAP Connection Directory Studio 1 ................................................................ 745.4. New LDAP Connection Directory Studio 2 ................................................................ 755.5. Properties New LDAP Connection Directory Studio .................................................... 765.6. WebSphere Admin Console .................................................................................... 775.7. RootDSE Servlet in a Browser ................................................................................ 796.1. The activated keyDerivationInterceptor automatically creates the krb5Key attributes ........... 986.2. Authenticate using Apache Directory Studio .............................................................. 996.3. Windows Security ............................................................................................... 1006.4. Windows Change Password ................................................................................... 1016.5. ........................................................................................................................ 1067.1. Hello World UML ............................................................................................... 1147.2. Hello World LDAP Browser ................................................................................. 1167.3. Hello World Entry Editor ...................................................................................... 1177.4. PasswordHash Interceptor UML ............................................................................. 1197.5. PasswordHash Interceptor PasswordEditor ............................................................... 1227.6. PasswordHash Interceptor ModificationLog .............................................................. 1237.7. PasswordHash Interceptor EntryEditor ..................................................................... 123

Page 10: ApacheDS Guide

Draft Draft

© 2003-2010x

The Apache Software Foundation Privacy Policy

List of Tables2.1. Nexus Proxy Object ................................................................................................ 92.2. Administrative areas .............................................................................................. 142.3. LDAP related RFCs ............................................................................................... 193.1. SASL QoP levels .................................................................................................. 283.2. To be named ........................................................................................................ 303.3. ACI Trails ........................................................................................................... 343.4. Access Control Subentries ...................................................................................... 353.5. ACIItem fields ...................................................................................................... 373.6. Simple User Classes .............................................................................................. 395.1. Test Annotations ................................................................................................... 626.1. Protocol Providers ................................................................................................. 806.2. Environment parameters ......................................................................................... 836.3. Parameters common to all protocol providers ............................................................. 836.4. Parameters common to all protocol providers 1 ........................................................... 846.5. LDAP-Specific Configuration Parameters 1 ............................................................... 866.6. LDAP-Specific Configuration Parameters 2 ............................................................... 866.7. Kerberos-Specific Configuration Parameters ............................................................... 876.8. Change Password-Specific Configuration Parameters ................................................... 876.9. NTP-Specific configuration parameters ..................................................................... 886.10. Replication Startup Configuration ........................................................................... 896.11. Common Service Configuration Parameters .............................................................. 906.12. LDAP-Specific Configuration Parameters ................................................................ 916.13. Common Service Configuration Parameters .............................................................. 946.14. Kerberos-Specific Configuration Parameters ............................................................. 956.15. Download the unlimited strength policy JAR files ..................................................... 966.16. Extract the unlimited strength policy JAR files .......................................................... 966.17. Install the unlimited strength policy JAR files ........................................................... 966.18. Common Service Configuration Parameters ............................................................ 1026.19. Change Password-Specific Configuration Parameters ................................................ 1036.20. Abstract objectClass used to build all DNS record objectclasses .................................. 1046.21. Address (A) record ............................................................................................. 1056.22. Pointer (PTR) record .......................................................................................... 1056.23. Name Server (NS) record .................................................................................... 1056.24. Start Of Authority (SOA) record ........................................................................... 1056.25. Common Service Configuration Parameters ............................................................ 1086.26. Common Service Configuration Parameters ............................................................ 110

Page 11: ApacheDS Guide

Draft Draft

© 2003-2010xi

The Apache Software Foundation Privacy Policy

Work in progressUnfortunately the Basic User's Guide for ApacheDS 1.5 is not finished yet. We have started to moveand revise the content, things you find here are work in progress but should be valid for ApacheDS1.5.5. In the meantime you can have a look at the ApacheDS 1.0 Basic User's Guide, which is currentlymore complete.

Page 12: ApacheDS Guide

Draft Draft

© 2003-20101

The Apache Software Foundation Privacy Policy

Chapter 1. Community

1.1. Reporting BugsThis site was updated for ApacheDS 1.5.5.

1.1.1. IntroductionSo you found a bug in ApacheDS. Don't worry this is a good thing! We can fix it really fast but needyour help. There are different degrees to your ability to help out. Some of you have developer skillsso you might be able to write a test case that pin points that bug. If you can do this we will prioritizeyour bug report above all others. Yes we will put your bug to the top most important fixes that shouldbe fixed first. But if you can't do this and your bug is serious then we're prioritize it ahead of othersanyway.

This wiki page shows you how you can help us to help you!!!

1.1.2. Creating a testcase project: using the apacheds-archetype-testcase

We've created a simple archetype for you to rapidly create a Maven project that fires up ApacheDSin embedded mode within a JUnit testcase. This test case will start up ApacheDS as a server on anyavailable port above 1024 on your machine. You can then use JNDI or the Netscape LDAP API (moreAPIs to come) going over the wire on that port above 1024. You can also use the ApacheDS core APIto access the data directly.

So you can write client code in your test case immediately. Just add your code, tar gzip the project,and attach it to your JIRA issue on the ApacheDS JIRA here:

https://issues.apache.org/jira/browse/DIRSERVER

We'll prioritize your bug higher than others and probably fix it rapidly because the problem is isolatedthanks to your testcase submission. We will in fact strip out your testcase and add it to our suite of testcases to make sure ApacheDS always passes this integration test you've provided.

1.1.3. Installing the apacheds-archetype-testcaseTo use the archetype you'll need to check it out and install it. Here's how you can do that for theleading edge of 1.5.5:

svn co http://svn.apache.org/repos/asf/directory/samples/trunk/apacheds-archetype-testcasecd apacheds-archetype-testcasemvn install

This will install the archetype onto your local repository. Now you can invoke the archetype.

1.1.4. Invoking (running) the archetype: generating thetestcase project

Once you checkout the archetype plugin and install it you can use it like so to generate a foo-testproject:

Page 13: ApacheDS Guide

Draft Community Draft

© 2003-20102

The Apache Software Foundation Privacy Policy

mvn archetype:generate -DarchetypeGroupId=org.apache.directory.samples \ -DarchetypeArtifactId=apacheds-archetype-testcase \ -DarchetypeVersion=1.5.5-SNAPSHOT \ -DgroupId=com.acme -DartifactId=foo-test -Dpackage=com.acme

This will generate the default test case project with the following tree structure:

~/foo-test$ tree.|-- pom.xml`-- src |-- main | `-- java | `-- com | `-- acme | `-- Dummy.java `-- test |-- java | `-- com | `-- acme | |-- AdvancedTest.java | |-- AdvancedTestApacheDsFactory.java | `-- MinimalTest.java `-- resources |-- log4j.properties |-- sevenSeas_data.ldif `-- sevenSeas_schema.ldif

10 directories, 8 files

• Dummy.java - this is just a placeholder file to make sure that Maven works properly.

• MinimalTest - a minimal ApacheDS Integration Test. It contains two test methods to demonstrateusage of JNDI and the ApacheDS core API. Add your own test method here.

• AdvancedTest - an advanced ApacheDS Integration Test in case you need a special configurationfor your test. It demonstrates how to add a new partition, how to enable LDAPS, how to enable adisabled schema, how to inject a custom schema, and how to inject custom test data.

• AdvancedTestApacheDsFactory - configures ApacheDS for the advanced test

• pom.xml - the Maven Project Object Model (POM) for your new testcase project (can remain as is).

• log4j.properties - Log4j configuration file that controls ApacheDS logging for your convenience;edit this file to control logging output.

• sevenSeas_data.ldif - sample custom test data used by the advanced test.

• sevenSeas_schema.ldif - sample custom schema used by the advanced test.

Once you do this you can cd into foo-test and just build and test it for fun to see what happens. Thiswill build, and test the sample test cases (they should pass) that comes packaged with the project youjust created. CD into foo-test and run the following command:

mvn test

Now you can customize the MinimalTest.java or AdvancedTest.java file to isolate your bug. Open theclasses with your favorite editor and goto town. However if you want to pull this project into your IDEand edit it there you can use Maven's IDEA, Eclipse and Netbeans integration to create IDE projectdescriptors for them. Then you can import this project into your IDE. Here's how:

1.1.4.1. For IDEA

mvn idea:idea

Page 14: ApacheDS Guide

Draft Community Draft

© 2003-20103

The Apache Software Foundation Privacy Policy

1.1.4.2. For Eclipse

mvn eclipse:eclipse

1.1.4.3. For Netbeans

See this page: http://maven.apache.org/guides/mini/guide-ide-netbeans/guide-ide-netbeans.html

mvn eclipse:eclipse

1.1.5. Note about versionNote that this archetype is specific for ApacheDS 1.5.5.

1.1.6. Why a Maven Archetype for Testing?1. Easy and fast to start integration testing ApacheDS.

2. We (developers of ApacheDS) can use it ourselves.

3. We want users of ApacheDS to help us help them.

4. Users need to customize a project with perhaps additional dependencies.

5. Users can add many test cases to the project.

6. Tests isolating custom bugs can be incorporated into our community test suite for ApacheDS.

1.2. Building trunksThis page give some information about the layout of Apache DS 1.5 trunks, and try to explain howit is built.

• Section 1.2.1, “Project Hierarchy”

• Section 1.2.2, “Prerequisites for building”

• Section 1.2.2.1, “Maven”

• Section 1.2.2.2, “JDK 5”

• Section 1.2.3, “Getting the code”

• Section 1.2.4, “Building the trunks”

• Section 1.2.4.1, “Enabling Snapshot Repositories”

• Section 1.2.4.2, “ Building the trunks ”

• Section 1.2.5, “Building the installers”

• Section 1.2.6, “Starting the server without installation”

• Section 1.2.7, “Integration test”

• Section 1.2.8, “Eclipse”

• Section 1.2.8.1, “Building eclipse files”

Page 15: ApacheDS Guide

Draft Community Draft

© 2003-20104

The Apache Software Foundation Privacy Policy

• Section 1.2.8.2, “Maven settings”

• Section 1.2.8.3, “Eclipse hints”

• Section 1.2.8.4, “Eclipse plugins”

• Section 1.2.8.5, “Coding standards”

1.2.1. Project HierarchyThe actual project hierarchy is the following (as of 1.5.5-SNAPSHOT) :

This hierarchy represent the projects being built.

1.2.2. Prerequisites for buildingYou must have installed Maven 2.0.9 and have a JDK 5 installed on your computer. A workinginternet connection is also mandatory.

If the build hangs or you get an out of memory exception please increase the heap space:

• For Linux:

MAVEN_OPTS="-Xmx256m" mvn clean install

• For Windows:

SET MAVEN_OPTS="-Xmx256m"mvn clean install

1.2.2.1. Maven

Download [http://maven.apache.org/download.html] and install Maven 2.0.9. (ATTENTION !!! DoNOT use an older version of Maven )

Add a MAVEN_HOME environment variable and add MAVEN_HOME/bin to your system path:

On a Linux box you could add the following to the .bashrc file (.bashrc is a file you'll find in yourhome directory)

...export MAVEN_HOME=/opt/maven-2.0.9export PATH=$JAVA_HOME:$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH...

Windows users, use Control Panel -> System -> Advanced -> Environment Variables

1.2.2.2. JDK 5

1.2.3. Getting the codeTo download the sources, you must have installed a Subversion client.

With readonly access :

svn co http://svn.apache.org/repos/asf/directory/apacheds/trunk-with-dependencies/ apacheds-trunk

Page 16: ApacheDS Guide

Draft Community Draft

© 2003-20105

The Apache Software Foundation Privacy Policy

With read/write access (for committers only) :

svn co https://svn.apache.org/repos/asf/directory/apacheds/trunk-with-dependencies/ apacheds-trunk

1.2.4. Building the trunks

1.2.4.1. Enabling Snapshot Repositories

The following information is only needed if one want to setup its own maven repo. There isno need to define a settings.xml file for generic usage.

Before building the trunks, you must configure Maven 2 to use the snapshot repository forApache. Snapshot repositories are typically configured per user at ~/.m2/settings.xml. Thefollowing example, added to your settings.xml, will add a profile for the Apache snapshotrepository.

<settings> <profiles> ... <profile> <id>apache</id> <repositories> <repository> <id>apache.org</id> <name>Maven Snapshots</name> <url>http://people.apache.org/repo/m2-snapshot-repository</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>apache.org</id> <name>Maven Plugin Snapshots</name> <url>http://people.apache.org/repo/m2-snapshot-repository</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories> </profile> ... </profiles></settings>

You may either specify the profile at the command-line, each time you use 'mvn', or you may configurethe profile to always be active.

To use a profile at the command-line:

# mvn -Papache [options] [<goal(s)>] [<phase(s)>]

To specify the 'apache' profile to always be active:

<settings> ... <activeProfiles> <activeProfile>apache</activeProfile> </activeProfiles>

Page 17: ApacheDS Guide

Draft Community Draft

© 2003-20106

The Apache Software Foundation Privacy Policy

...</settings>

1.2.4.2. Building the trunks

Now, we can compile the project.

The command is simple :

cd apacheds-trunkmvn clean install

You must make sure you build the shared, installers, and daemon project modules in additionto the apacheds module to prevent problems with stale Maven SNAPSHOT jars in the snapshotrepository from causing compilation errors. This can be guaranteed by performing all Mavenoperations above in the top directory that you checked out: the apacheds-trunk directory.

A lot of plugins will be downloaded. If you are curious, you can then look at .m2/repository to seewhat has been downloaded on this step. Building should finish with these lines:

[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESSFUL[INFO] ------------------------------------------------------------------------[INFO] Total time: 8 minutes 30 seconds[INFO] Finished at: Mon Oct 30 23:32:41 CET 2006[INFO] Final Memory: 18M/32M[INFO] ------------------------------------------------------------------------

1.2.5. Building the installersBuilding the installers is a two phase process :

cd apacheds-trunkmvn installcd installers/apachedsmvn -Pserver-installer install

That's it, the jars will be find in target/images/apacheds-1.5.?SNAPSHOT <XXXXXX>-setup.jarwhere XXXXXX is your local system and ? is the feature release minor number for the 1.5 branch.

1.2.6. Starting the server without installationThe directory apacheds-trunk/installers/apacheds-noarch contains a script for Linux (apacheds.sh) andone for Windows (apacheds.bat) which can be used for starting the server without the need to installit first (as non-root-user on Linux and non-Windows-service on Windows).

Linux:

cd apacheds-trunk/installers/apacheds-noarch./apacheds.sh

1.2.7. Integration testTo run integration tests, just use the following command :

cd apacheds-trunkmvn -Dintegration test

Page 18: ApacheDS Guide

Draft Community Draft

© 2003-20107

The Apache Software Foundation Privacy Policy

1.2.8. Eclipse

1.2.8.1. Building eclipse files

To build the .project and .classpath files for eclipse, type the following commands :

cd apacheds-trunkmvn clean installmvn eclipse:eclipsecd apacheds/bootstrap-partitionmvn clean install

(The last command is necessary because eclipse:eclipse purge the target directory, and we need somegenerated files which has been removed. This is why we do another *mvn clean install* in the boostrap-partition module then import all the existing project which has been created.

1.2.8.2. Maven settings

Don't forget to declare a classpath variable named M2_REPO, pointing to ~/.m2/repository, otherwisemany links to existing jars will be broken.

You can declare new variables in Eclipse in -> Preferences... and selecting -> Build Path ->Classpath Variables

1.2.8.3. Eclipse hints

Add an eclipse-apacheDS.sh file in your eclipse root directory, to allow eclipse to get more memory(e.g. 750MB)

You may also declare a specific workspace when launching eclipse. I have created a workspace-apacheDS directory in my HOME directory, where all the ApacheDS project is built when I useEclipse.

<eclipse_root>/eclipse -data $HOME/workspace-apacheDS -vm java -vmargs -Xmx750M

Launch eclipse :

<eclipse_root>/eclipse-apacheDS.sh

1.2.8.4. Eclipse plugins

1.2.8.5. Coding standards

The coding standards including an eclipse code formatting profile is available here [http://directory.apache.org/apacheds/DIRxDEV/coding-standards.html] .

1.3. Contributing

Page 19: ApacheDS Guide

Draft Draft

© 2003-20108

The Apache Software Foundation Privacy Policy

Chapter 2. Architecture2.1. Architectural Overview

2.1.1. PartitionsA partition is a physically distinct store for a subset of the entries contained within a DSA (DirectoryServer/Service Agent A.K.A the LDAP server). The entries of a partition all share the samesuffix which is the distinguished name of the namingContext from which the stored entries in thepartition are hung from the DIT. A partition can be implemented using any storage mechanismor can even be backed in memory. The default storage mechanism for a partition is JDBM. Theaddition of such a partition is described in the Basic User's Guide [http://directory.apache.org/apacheds/1.5/apacheds-v15-basic-users-guide.html] . A partition with a different storage mechanismsimply has to implement the Partition interface and by doing so can be mounted in the server at it'ssuffix/namingContext (described here [http://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=DIRxSRVx11&title=6.1.%20Implementing%20an%20alternative%20Backend&linkCreation=true&fromPageId=55216] ).

The server can have any number of partitions (with any implementation) attached to variousnamingContexts which are published by the RootDSE (empty string dn "") using the namingContextsoperational attribute. So if you want to see the partitions served by the server you can query theRootDSE for this information.

2.2. Interceptors

2.2.1. What is it?The mechanism is a means for injecting and isolating orthogonal services into calls against the nexus.The nexus is the hub used to route calls to partitions to perform CRUD operations upon entries.By injecting these services at this level, partition implementators need not duplicate fuctionality.Services such as authentication, authorization, schema checking, normalization, operational attributemaintenance and more are introduced using Interceptors. By using interceptors, partition implementorsneed not be concerned with these aspects and can focus on raw CRUD operations against their backingstores what ever they may be.

2.2.2. How does it work?Before we talk more about interceptors we must quickly cover the JNDI provider implementationsince it is somewhat related.

2.2.3. JNDI ImplementationThe JNDI implementation is composed of a set of JNDI Context implementations, a ContextFactoryimplementation and a set of helper classes.

• DeadContext

• JavaLdapSupport

• ServerContext

• ServerDirContext

• ServerLdapContext

Page 20: ApacheDS Guide

Draft Architecture Draft

© 2003-20109

The Apache Software Foundation Privacy Policy

• AbstractContextFactory

• CoreContextFactory

• ServerDirObjectFactory

• ServerDirStateFactory

Every JNDI Context implementation in the provider holds a dedicated reference to a nexus proxyobject. This proxy contains all the operations that the nexus contains . The proxy object is at the heartof the mechanism. We will disuss it more after covering the rest of the JNDI provider.

Calls made against JNDI Contexts take relative names as arguments. These names are relative to thedistinguished name of the JNDI Context. Within the Context implementations these relative namesare transformed into absolute distinguished names. The transformed names are used to make callsagainst the proxy.

Additional processing may occur before or after a call is made by a context on its proxy to manageJNDI provider specific functions. One such example is the handling of Java objects for serializationand the use of object and state factories.

2.2.4. The nexus proxy objectAs mentioned above, each Context that is created has a nexus proxy. The proxy maintains a handleon the context as well.

Table 2.1. Nexus Proxy Object

The primary job of the proxy is to injectInterceptor based services. It does so byinvoking a chain of Interceptors managed bythe system. Interceptors mirror the methods thatare intercepted on the nexus interface. Whenan intercepted method is invoked on the proxy,the proxy pushes an Invocation object on tothe InvocationStack associated with the currentexecuting Thread. The proxy then calls the samemethod on a chain of Interceptors. The results ofthe call are returned after the InvocationStack ispopped.

The InvocationStack is used to track the callsbeing intercepted. Invocation objects pushed ontothe stack track the context making the call tothe proxy, the name of the intercepted calland its arguments. A stack is used because inthe case of Triggers, stored procedures may beinvoked which operate against the DIT usingJNDI. These JNDI calls will also be intercepted.Their Invocation object will be stacked on top ofthe Invocation which raised the Trigger. This wayidentities and context of operations can be trackedand used by the Trigger management system toprevent runnaway cascades or to limit the cascadedepth. There are other areas besides just triggerswhere this stack will serve a purpose.

The InterceptorChain is a container ofInterceptors which has the same or analogous

The following picture describe the Interceptorsmechanisms :

Page 21: ApacheDS Guide

Draft Architecture Draft

© 2003-201010

The Apache Software Foundation Privacy Policy

methods as do Interceptors. These are for theinterceptable methods. A call against the chaininvokes the first Interceptor which then usuallyinvokes the next interceptor in the chain. AnInterceptor need not call the next interceptorhowever. It can raise an exception before makingthe call to the next interceptor or it can completelybypass the rest of the chain by just returningbefore calling the next Interceptor. Interceptorscan preprocess the arguments, or perform othertasks before they invoke the next Interceptor.They can also catch exceptions raised by otherdownstream interceptors and respond to themto handle errors. Finally they can perform postprocessing operations on the results of returnedvalues from downstream Interceptors.

One might ask when is the call made againstthe actual nexus. This happens using a specialInterceptor which resides at the end of the chain.It actually makes the call against the nexus andreturns the results.

Interceptors can be seen as Servlet Filters :they can be added, removed, bypassedeither by configuration or, for embededservers, on the fly.

Figure 2.1. Interceptors

2.2.5. Operation handling within interceptors

Each operation is associated with a method in each interceptors, even if it does nothing else thancalling the next interceptor.

The base idea is to allow pre and post actions to be executed before and after the call of the nextinterceptors :

Page 22: ApacheDS Guide

Draft Architecture Draft

© 2003-201011

The Apache Software Foundation Privacy Policy

Figure 2.2. Interceptor chaining

Each interceptor process the pre action, call the next interceptor, wait for the response, execute thepost action, and returns. We have to implement this chain of interceptors in a way which allows usto add new interceptors, or new pre or post actions, without having to modify the existing code ormechanism.

2.2.6. Bind OperationThe Bind operation call the interceptor chain in the PartitionNexusProxy class, where we can founda bind method :

public void bind( LdapDN bindDn, byte[] credentials, List mechanisms, String saslAuthId, Collection bypass ) throws NamingException { ... this.configuration.getInterceptorChain().bind( bindDn, credentials, mechanisms, saslAuthId ); ... }

this will call the first configured interceptor from a chain which is declared in the configuration fileserver.xml . The first interceptor is the NormalizationService .

The information which are passed are :

• The DN used to bind

• The password (credentials)

• The list of supported mechanisms

• The SASL authent

We will often use only the two first elements.

2.2.7. Normalization interceptorThis interceptor will just normalize the DN used to bind. If the DN is invalid, an exception will bethrown.

It is the first interceptor in the chain because as we will manupulate the DN through all interceptors,it is important that we normalize it as soon as possible.

The normalized DN will be stored in an special form, usefull for internal comparizons. This operationcan be costly, but as the DN has already been parsed, this is quite efficient.

Page 23: ApacheDS Guide

Draft Architecture Draft

© 2003-201012

The Apache Software Foundation Privacy Policy

We can call the next interceptor :

2.2.8. Authentication interceptorWe must check that this bind request is valid, that is the DN and the associated password are knownby the server. We have two cases :

1. The user have already been authenticated

2. This is the first time this user try to bind

What we call user is the DN of a known entry stored in the server.

In the first case, we will have to search the password in the backend, and this will be a lookup operation,which will be applied through another chain of interceptors.

Let's assume we are in the second case, because if we are in the first case, we will have to ask thebackend about the entry which DN is equal to the one we received, to get its associated password, thuscallaing a specific chain of interceptors ( FINAL_INTERCEPTOR ).

The password is compared using the given mechanism (which should be simple on a new server), andif it matches, we create a principal object which will be stored in the connection context for futureusage.

We are done with the bind operation.

2.2.9. Add operationAn add operation is more complex. What we need to do is to check if the current user has enoughright to add an entry, and that the entry can be added.

A new entry is a composition of three elements :

• A partition name

• A path from this partition

• An entry name

For instance, when adding an entry which DN is cn=acme, ou=users, ou=system , we will have :

• Partition = ""ou=system"

• Path = "ou=users, ou=system"

• Entry name = "cn=acme"

The two first elements must exist in the base. We can't add an entry in an not existing partition, andwe can't add an entry which path is not existing.

2.3. The Administrative Model2.3.1. Introduction

Subentries are used for managing the administration of different aspects of the directory. LDAP hasjust recently formalized the notion of subentires in RFC 3672 [http://www.faqs.org/rfcs/rfc3672.html]. Subentries have existed within X.500 Directories for years with clear specifications for administeringcollective attributes, schema, and access controls. With the exception of managing collective attributesLDAP has no equivalent yet for administering these aspects. However with RFC 3672, LDAP is onits way towards adopting and adapting these mechanisms from X.500 Directories. It is only a matterof time.

Page 24: ApacheDS Guide

Draft Architecture Draft

© 2003-201013

The Apache Software Foundation Privacy Policy

For this reason we intend to remain ahead of the curve by implementing these aspects of administrationusing Subentries and Administrative Areas similar to X.500 Directories.

2.3.2. What exactly are subentries?To explain this properly we're going to need to discuss a couple other things like administrative areas(AA) and administrative points (AP) within the directory. However for the impatient here's a quickattempt to describe what subentries are:

Subentries are hidden leaf entries (which cannot have children). These entries immediately subordinateto an administrative point (AP) within the directory. They are used to specify administrativeinformation for a part of the Directory Information Tree (DIT). Subentries can contain administrativeinformation for aspects of access control, schema administration, and collective attributes (and otherswhich have not been defined in any specification yet).

2.3.3. Administrative Areas, Entries and PointsFirst some definitions as provided by X.501:

• 11.1.1 administrative area: A subtree of the DIT considered from the perspective of administration.

• 11.1.2 administrative entry: An entry located at an administrative point.

• 11.1.3 administrative point: The root vertex of an administrative area.

• 11.1.5 autonomous administrative area: A subtree of the DIT whose entries are all administered bythe same Administrative Authority. Autonomous administrative areas are non-overlapping.

• 11.1.11 inner administrative area: A specific administrative area whose scope is wholly containedwithin the scope of another specific administrative area of the same type.

• 11.1.17 specific administrative area: A subset (in the form of a subtree) of an autonomousadministrative area defined for a particular aspect of administration: access control, subschema orentry collection administration. When defined, specific administrative areas of a particular kindpartition an autonomous administrative area.

• 11.1.18 specific administrative point: The root vertex of a specific administrative area.

Now take a step back because the above definitions are, well, from a sleep inducing spec. Let's justtalk about some situations.

Presume you're the uber directory administrator over at WallyWorld (a Walmart competitor). Let'ssay WallyWorld uses their corporate directory for various things including their product catalog. Asthe uber admin you're going to have a bunch of people wanting access, update and even administeryour directory. Entire departments within WallyWorld are going to want to control different parts ofthe directory. Sales may want to manage the product catalog, while operations may want to manageinformation in other areas dealing with suppliers and store locations. Whatever the domain somedepartment will need to manage the information as the authority.

Each department will probably designate different people to manage different aspects of their domain.You're not going to want to deal with their little fiefdoms instead you can delegate the administrationof access control policy to a departmental contact. You will want to empower your users andadministrative contacts in these departments so they can do part of the job for you. Plus it's muchbetter than having to communicate with everyone in the company to meet their needs. This is wherethe delegation of authority comes into the picture.

Usually administrators do this already to an extent without defining administrative areas. Giving usersthe ability to change their own passwords for example is a form of delegation. This is generally agood idea because you don't want to set passwords for people. First because you don't want to see thepassword and secondly because of the management nightmare you'd have to deal with. Expand this

Page 25: ApacheDS Guide

Draft Architecture Draft

© 2003-201014

The Apache Software Foundation Privacy Policy

idea out a little further and think about delegating administration not of users on their passwords butof entire subtrees in the directory to administrative contacts in various departments.

Do you really want to manage the corporate product catalog or just let the sales department manage it?But what do we mean by manage? You want sales people to create, and delete entries but they may onlytrust a few people to do this. Others may just view the catelog. Who are the people with add/removepowers and why should you have to be involved with deciding this ever changing departmental policy?Instead you can delegate the management of access controls in this area to a administrative contactin the sales department. The sales contact can then administer access controls for their department.They're closer to the people in sales than you are and they probably have more bandwidth to handlesales related needs than you do. Delegating authority in this fashion is what X.500 engineers pioneeredin the early 80's with the telecom boom in Europe. They knew different authorities will want to managedifferent aspects of directory administration for themselves. These X.500 definitions are there to beable to talk about administrative areas within the directory. Now let's get back to what these thingsare exactly.

An administrative area is some part of the directory tree that is arbitrarily defined. The tree canbe split into different administrative areas to delegate authority for managing various aspects ofadministration. For example you can have a partition hanging off of 'dc=example,dc=com' with an'ou=product catalog' area. You may want this area to be managed by the sales department with respectto the content, schema, it's visibility, and collective attributes. Perhaps you only want to delegateonly one aspect of administration , access control, since you don't want people messing around withschema. To do so you can define everything under 'ou=product catalog' to be an administrativearea specifically for access control and delegate that aspect only. In that case the entry, 'ou=productcatalog,dc=example,dc=com' becomes an administrative entry. It is also the administrative point forthe area which is the tree rooted at this entry.

Not all administrative areas are equal. There are really two kinds : autonomous and inner areas.Autonomous areas are areas of administration that cannot overlap. Meaning someone is assigned asthe supreme authority for that subtree. Inner areas are, as their name suggests, nested administrativeareas within autonomous areas and other inner areas. Yes, you can nest these inner areas as deep asyou like. You may be asking yourself what the point to all this is. Well, say you're the supreme adminof admins. You delegate the authority to manage access control for the corporate catalog to the salesadmin. That admin may in turn decide to delegate yet another area of the catalog to another contactwithin a different department. You delegate access control management to the sales admin over theproduct catalog. The sales admin realizes that the job is way bigger than he can manage so he delegatesadministration of subtrees in the catalog to various contacts in different departments. For exampleregions of the catalog under 'ou=electronics' and 'ou=produce' may be delegated to different contactsin their respective departments. However the sales admin still reserves the ability to override accesscontrols in the catalog. The sales admin can change who manages access controls for different partsof the catalog. This chain of delegation is possible using inner administrative areas.

2.3.4. How are administrative areas defined?Usually an entry is selected as the administrative point and marked with an operational attribute. TheattributeType of the operational attribute is 'administrativeRole'. This attribute can have the followingvalues:

Table 2.2. Administrative areas

OID NAME

2.5.23.1 autonomousArea

2.5.23.2 accessControlSpecificArea

2.5.23.3 accessControlInnerArea

2.5.23.4 subschemaAdminSpecificArea

2.5.23.5 collectiveAttributeSpecificArea

Page 26: ApacheDS Guide

Draft Architecture Draft

© 2003-201015

The Apache Software Foundation Privacy Policy

OID NAME

2.5.23.6 collectiveAttributeInnerArea

As you can see, 3 aspects, schema , collective attributes , and access control are considered. Anautonomous administrative area can hence be considered with respect to all three specific aspect ofadministration. If an AP is marked as an autonomousArea it generally means that administration ofall aspects are allowed by the authority. If marked with a specific aspect then only that aspect ofadministration is delegated. The administrativeRole operational attribute is multivalued so the uberadmin can delegate any number of specific administration aspects as he likes.

Also notice that two aspects, collective attribute and access controls, allow administrative points tobe inner areas. Delegated authorities for these two aspects can create inner administrative areas tofurther delegate their administrative powers. The schema aspect unlike the others cannot have innerareas because of potential conflicts this may cause which would lead to data integrity issues. For thisreason only the authority of an automomous area can manage schema for the entire subtree.

An autonomous administrative area (AAA) includes the AP and spans all descendants below the APdown to the leaf entries of the subtree with one exception. If another AAA, let's call it AAA' (prime)is present and rooted below the first AAA then the first AAA does not include the entries of AAA'.Translation: an AAA spans down until other AAAs or leaf entries are encountered within the subtree.This is due to the fact that AAAs do not overlap as do inner AAs (IAA).

2.3.5. Subentries under an IAA or an AAASubentries hold administrative information for an IAA or an AAA. These entries are of the objectClass'subentry'. The subentry must contain two attributes: a commonName and a subtreeSpecification .The commonName (or cn) is used as the subentry's rdn attribute. The subtreeSpecification describesthe collection of entries within the AA (IAA or AAA) that the administrative instruction applies to.

A subtree specification uses various parameters described below to define the set of entries. Note thatentries need not exist for them to be included in the collection on addition.

2.3.6. Base parameterThis is the relative name of the root vertex of the subtree relative to the AP. So if the AP is 'ou=system'and the base is 'ou=users' , the subtree begins at 'ou=users,ou=system' . The base can be any lengthof name components including 0 where it's the empty name "". In this case, the subtree begins at theAP, 'ou=system' in the example above.

2.3.7. Chop parametersChop specification parameters define specific nodes to be excluded from the collection as well as howdeep the subtree spans and even where it starts relative to the base.

2.3.7.1. chopBefore and chopAfter

These parameters are names relative to the root vertex of the subtree, hence they are relative to thebase parameter. They specify whether or not an entry and its descendants are to be excluded fromthe collection.

When chopBefore is used, the entry specified is excluded from the collection. When chopAfter isused the entry is included however all descendants below the entry are excluded.

2.3.7.2. minimum and maximum

The minimum parameter describes the minimum number of name components (arc) between the baseand the target entry required to include entries within the selection. The maximum parameter describes

Page 27: ApacheDS Guide

Draft Architecture Draft

© 2003-201016

The Apache Software Foundation Privacy Policy

the maximum arc length between the base and the target allowed before entries are excluded fromthe collection.

2.3.8. Specification filter parameterThe specification filter is a unique beast. It's a filter like a search filter, however its syntax andexpressivity is radically different. Think of a specification filter as a simplified form of search filterswhere all terms only test the objectClass attribute and only equality checks can be performed. Oh andyes, you do have logical operators like and , or and not .

So with a filter you have the ability to "refine" the subtree already specified with chop, and baseparameters. This "refinement" makes it so the collection is not really a contiguous subtree of entriesbut a possibly disconnected set of selected based on the objectClass characteristics of entries. Thisfeature of a subtreeSpecification is very powerful. For example, I can define a subtree to cover a regionof an AA yet include only inetOrgPersons within this region.

2.3.9. Subentry types in ApacheDSDifferent subentry objectClasses exist for applying different aspects of administration to the entrycollection described by their subtreeSpecification attribute. By the way the subtreeSpecificationattribute is single valued so there can only be one in a subentry. However you can have severalsubentries of various kinds under an AP. Furthermore their collections can intersect.

The kinds of subentries allowed though are limited by the administrativeRole of the AP. If the AP isfor an access control AA then you can't add a subentry to it for schema administration. The AP musthave the role for schema administration as well to allow both types of subentries.

ApacheDS does not manage schema using subentries in the formal X.500 sense right now. There is asingle global subentry defined at 'cn=schema' for the entire DSA. The schema is static and cannot beupdated at runtime even by the administrator. Pretty rough for now but it's the only lagging subsystem.We'll of course make sure this subsystem catches up.

ApacheDS does however manage collective attributes using subentries. An AP that takes theadministrativeRole for managing collective attributes can have subentries added. These subentries aredescribed in greater detail here: Section 4.2, “Collective Attributes” . In short, collective attributesadded to subentries show up within entries included by the subtreeSpecification. Adding, removing,and modifying the values of collective attributes within the subentries instantly manifest changes inthe entries selected by the subtreeSpecification. Again consult Section 4.2, “Collective Attributes” fora hands on explanation of how to use this feature.

ApacheDS performs access control and allows delegation using subentries, AAAs, and IAAs.ApacheDS uses the Basic Access Control Scheme from X.501 to manage access control. By defaultthis subsystem is deactivated because it locks down everything except access by the admin. Moreinformation about hands on use is available here: Section 3.5, “Authorization” However to summarizeits association with subentries, access control information (ACI) can be added to subentries underan AP for access control AAs. When one or more ACI are added in this fashion, the access rules ofthe ACI set apply to all entries selected by the subtreeSpecification. Even with this powerful featureindividual entries can have ACI added to them for controlling access to them. Also there are things youcan do with ACI added to subentries that cannot be done with entry level ACI. For example you cannotallow entry addition with entry ACI. You must use subtreeSpecifications to define where entries maybe added because those entries and their parents may not exist yet.

2.3.10. How to specify a subentry'ssubtreeSpecification

The best way to demonstrate subtreeSpecification values are through examples. Here's the simplestfilter of them all:

Page 28: ApacheDS Guide

Draft Architecture Draft

© 2003-201017

The Apache Software Foundation Privacy Policy

{}

This basically selects the entire contiguous subtree below the AP. The base is the empty name andit's rooted at the AP.

Next step let's add a base:

{ base "ou=users" }

If this is the subtreeSpecification under the AP, 'ou=system' , then it selects every entry under'ou=users,ou=system' .

OK that was easy so now let's slice and dice the tree now using the minimum and maximum chopparameters.

{ minimum 3, maximum 5 }

This selects all entries below 'ou=system' which have a DN size equal to 3 name components,but no more than 5. So for example 'uid=jdoe,ou=users,ou=system' would be included but'uid=jack,ou=do,ou=not,ou=select,ou=users,ou=system' would not be included. Let's continue andcombine the base with just a minimum parameter:

{ base "ou=users", minimum 4 }

Here the subtree starts at 'ou=users,ou=system' if the subentry subordinates to the AP at 'ou=system'. The user 'uid=jdoe,ou=deepenough,ou=users,ou=system' is selected by the spec where as'uid=jbean,ou=users,ou=system' is not.

It's time to add some chop exclusions:

{ base "ou=users", minimum 4, specificExclusions { chopBefore: "ou=untrusted" }}

Again if placed at the AP 'ou=system' this subtree would begin at 'ou=users,ou=system' .It would not include users that subordinate to it though because of the minimum constraintsince these users would have 3 components in their DN. The specific exclusions prevent'ou=untrusted,ou=users,ou=system' and all its descendants from being included in the collection.However 'uid=jbean,ou=trusted,ou=users,ou=system' would be included since it meets theminimum requirement, is a descendant of 'ou=users,ou=system' and is not under the excluded DN,'ou=untrusted,ou=users,ou=system' .

Note that you can add as many exclusions as you like by comma delimiting them. For example:

{ base "ou=users", minimum 4, specificExclusions { chopBefore: "ou=untrusted", chopAfter: "ou=ugly", chopBefore: "ou=bad" }}

The final example includes a refinement. Again any combination of chop, filter and base parameterscan be used. The following refinement makes sure the users selected are of the objectClassinetOrgPerson and specialUser where the OID for the specialUser class is 32.5.2.1 (fictitious).

{

Page 29: ApacheDS Guide

Draft Architecture Draft

© 2003-201018

The Apache Software Foundation Privacy Policy

base "ou=users", minimum 4, specificExclusions { chopBefore: "ou=untrusted", chopAfter: "ou=ugly", chopBefore: "ou=bad" } specificationFilter and:{ item:32.5.2.1, item:inetOrgPerson }}

If you'd like to see the whole specification of the grammar used for the subtreeSpecification take alook at Appendix A in RFC 3672 [http://www.faqs.org/rfcs/rfc3672.html] .

2.3.11. Future PossibilitiesIn the immediate future we intend to introduce Section 9.2, “LDAP Triggers” , stored procedures andviews into ApacheDS. Subentries will play a critical role in the administration and application of thesefeatures. For example a Trigger specification need not include information on what entries it appliesto since the subtreeSpecification handles this. The question of "on what" a trigger applies to is nicelydisassociated from the "which operation" part of the specification. This makes for much better reuseof triggers. It also allows for the pin point application of triggers to entries in the DIT. Likewise aview itself will be defined by a specification. A view for example in a subentry can define a regionof the tree that does not exist but is shadowed from another region all together. The possibilities hereare limitless.

Of course we will revamp the schema subsystem of ApacheDS to use subentries in AAA to managethe schema in effect within different regions of the DIT. Today most LDAP servers just have a globalscheme in effect for the entire DIT served by a DSA. We don't think that is reasonable at all. So expectsome serious advances in the design of a new schema subsystem based on subentries.

Replication is yet another excellent candidate for using subentries. Replication of specific collectionsof entries can be managed for each cluster rather than replicating the entire DIT served by a DSA toreplicas. This way we don't only control what is replicated but we can also control how and whereit is replicated.

2.3.12. ConclusionsApacheDS has implemented subentries for the administration of various aspects of the directoryand gains several powerful features as a result: namely precision application of control to entrycollections and the ability to delegate administrative authority. For details on the administration of eachaspect using subentries ( Collective [http://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=DIRxSRVx11&title=Collective&linkCreation=true&fromPageId=55219] andSection 3.5, “Authorization” ) please see the respective documentation.

As ApacheDS progresses it will gain an immense advantage from subentries. Both for existing LDAPfeatures like scheme and for new experimental features like triggers, and replication.

2.4. Supported RFCsHere is a list of all LDAP related RFCs (grey and marked

are obsoleted RFCs) in the current 1.5 version of ADS. The flag

is used for implemented RFCs into ADS. The flag

is used for partially implemented RFCs into ADS . The flag

is used for RFC not supported by ADS :

Page 30: ApacheDS Guide

Draft Architecture Draft

© 2003-201019

The Apache Software Foundation Privacy Policy

Table 2.3. LDAP related RFCs

RFC num status Description

RFC 1274 The COSINE and Internet X.500Schema.

RFC 1485 A String Representation ofDistinguished Names (OSI-DS23 (v5)).

RFC 1487 X.500 Lightweight DirectoryAccess Protocol

RFC 1558 A String Representation ofLDAP Search Filters.

RFC 1777 Lightweight Directory AccessProtocol.

RFC 1779 A String Representation ofDistinguished Names.

RFC 1823 The LDAP Application ProgramInterface.

RFC 1959 An LDAP URL Format.

RFC 1960 A String Representation ofLDAP Search Filters.

RFC 2164 Use of an X.500/LDAP directoryto support MIXER addressmapping.

RFC 2247 Using Domains in LDAP/X.500Distinguished Names.

RFC 2251 Lightweight Directory AccessProtocol (v3).

RFC 2252 Lightweight Directory AccessProtocol (v3)| Attribute SyntaxDefinitions.

RFC 2253 Lightweight Directory AccessProtocol (v3)| UTF-8 StringRepresentation of DistinguishedNames.

RFC 2254 The String Representation ofLDAP Search Filters.

RFC 2255 The LDAP URL Format.

RFC 2256 A Summary of the X.500(96)User Schema for use withLDAPv3.

RFC 2307 An Approach for Using LDAP asa Network Information Service.

Page 31: ApacheDS Guide

Draft Architecture Draft

© 2003-201020

The Apache Software Foundation Privacy Policy

RFC num status Description

RFC 2559 Internet X.509 PublicKey Infrastructure OperationalProtocols - LDAPv2.

RFC 2587 Internet X.509 Public KeyInfrastructure LDAPv2 Schema.

RFC 2596 Use of Language Codes in LDAP

RFC 2649 An LDAP Control andSchema for Holding OperationSignatures.

RFC 2657 LDAPv2 Client vs. the IndexMesh.

RFC 2696 LDAP Control Extensionfor Simple Paged ResultsManipulation.

RFC 2713 Schema for RepresentingJava(tm) Objects in an LDAPDirectory.

RFC 2714 Schema for RepresentingCORBA Object References in anLDAP Directory.

RFC 2739 Calendar Attributes for vCardand LDAP.

RFC 2798 Definition of the inetOrgPersonLDAP Object Class.

RFC 2820 Access Control Requirements forLDAP

RFC 2829 Authentication Methods forLDAP

RFC 2830 Lightweight Directory AccessProtocol (v3)| Extension forTransport Layer Security.

RFC 2849 The LDAP Data InterchangeFormat (LDIF) - TechnicalSpecification.

RFC 2891 LDAP Control Extension forServer Side Sorting of SearchResults.

RFC 2926 Conversion of LDAP Schemas toand from SLP Templates.

RFC 3045 Storing Vendor Information inthe LDAP root

RFC 3062 LDAP Password ModifyExtended Operation.

Page 32: ApacheDS Guide

Draft Architecture Draft

© 2003-201021

The Apache Software Foundation Privacy Policy

RFC num status Description

RFC 3088 OpenLDAP Root Service Anexperimental LDAP referralservice.

RFC 3112 LDAP Authentication PasswordSchema.

RFC 3296 Named Subordinate Referencesin Lightweight Directory AccessProtocol (LDAP) Directories.

RFC 3377 Lightweight Directory AccessProtocol (v3)| TechnicalSpecification.

RFC 3383 Internet Assigned NumbersAuthority (IANA)Considerations for theLightweight Directory AccessProtocol (LDAP).

RFC 3384 Lightweight Directory AccessProtocol (version 3) ReplicationRequirements.

RFC 3663 Domain Administrative Data inLightweight Directory AccessProtocol (LDAP).

RFC 3671 Collective Attributes in theLightweight Directory AccessProtocol (LDAP).

RFC 3672 Subentries in the LightweightDirectory Access Protocol(LDAP).

RFC 3673 All Operational Attributes

RFC 3674 Feature Discovery inLightweight Directory AccessProtocol (LDAP).

RFC 3687 Lightweight Directory AccessProtocol (LDAP) and X.500Component Matching Rules.

RFC 3698 Lightweight Directory AccessProtocol (LDAP): AdditionalMatching Rules.

RFC 3703 Policy Core LightweightDirectory Access ProTocol(LDAP) Schema.

RFC 3712 Lightweight Directory AccessProtocol (LDAP): Schema forPrinter Services.

Page 33: ApacheDS Guide

Draft Architecture Draft

© 2003-201022

The Apache Software Foundation Privacy Policy

RFC num status Description

RFC 3771 The Lightweight DirectoryAccess Protocol (LDAP)Intermediate Response Message.

RFC 3727 ASN.1 Module Definition for theLDAP and X.500 ComponentMatching Rules.

RFC 3771 The Lightweight DirectoryAccess Protocol (LDAP)Intermediate Response Message.

RFC 3829 Lightweight Directory AccessProtocol (LDAP) AuthorizationIdentity Request and ResponseControls.

RFC 3866 Language Tags and Ranges in theLightweight Directory AccessProtocol (LDAP).

RFC 3876 Returning Matched Valueswith the Lightweight DirectoryAccess Protocol version 3(LDAPv3).

RFC 3909 Lightweight Directory AccessProtocol (LDAP) CancelOperation.

RFC 3928 Lightweight Directory AccessProtocol (LDAP) Client UpdateProtocol (LCUP).

RFC 4104 Policy Core ExtensionLightweight Directory AccessProtocol Schema (PCELS).

RFC 4370 Lightweight Directory AccessProtocol (LDAP) ProxiedAuthorization Control.

RFC 4373 Lightweight Directory AccessProtocol (LDAP) Bulk Update/Replication Protocol (LBURP).

RFC 4403 Lightweight Directory AccessProtocol (LDAP) Schemafor Universal Description,Discovery, and Integrationversion 3 (UDDIv3).

RFC 4510 Lightweight Directory AccessProtocol (LDAP): TechnicalSpecification Road Map.

RFC 4511 Lightweight Directory AccessProtocol (LDAP): The Protocol.

RFC 4512 Lightweight Directory AccessProtocol (LDAP): DirectoryInformation Models.

Page 34: ApacheDS Guide

Draft Architecture Draft

© 2003-201023

The Apache Software Foundation Privacy Policy

RFC num status Description

RFC 4513 Lightweight Directory AccessProtocol (LDAP): AuthenticationMethods and SecurityMechanisms.

RFC 4514 Lightweight Directory AccessProtocol (LDAP): StringRepresentation of DistinguishedNames.

RFC 4515 Lightweight Directory AccessProtocol (LDAP): StringRepresentation of Search Filters.

RFC 4516 Lightweight Directory AccessProtocol (LDAP): UniformResource Locator.

RFC 4517 Lightweight Directory AccessProtocol (LDAP): Syntaxes andMatching Rules.

RFC 4518 Lightweight Directory AccessProtocol (LDAP):Internationalized StringPreparation.

RFC 4519 Lightweight Directory AccessProtocol (LDAP): Schema forUser Applications.

RFC 4520 Internet Assigned NumbersAuthority (IANA)Considerations for theLightweight Directory AccessProtocol (LDAP).

RFC 4521 Considerations for LightweightDirectory Access Protocol(LDAP) Extensions.

RFC 4522 Lightweight Directory AccessProtocol (LDAP): The BinaryEncoding Option.

RFC 4523 Lightweight Directory AccessProtocol (LDAP) SchemaDefinitions for X.509Certificates.

RFC 4524 COSINE LDAP/X.500 Schema.

RFC 4525 Lightweight Directory AccessProtocol (LDAP) Modify-Increment Extension.

RFC 4526 Lightweight Directory AccessProtocol (LDAP) Absolute Trueand False Filters.

Page 35: ApacheDS Guide

Draft Architecture Draft

© 2003-201024

The Apache Software Foundation Privacy Policy

RFC num status Description

RFC 4527 Lightweight Directory AccessProtocol (LDAP) Read EntryControls.

RFC 4528 Lightweight Directory AccessProtocol (LDAP) AssertionControl.

RFC 4529 Requesting Attributes by ObjectClass in the LightweightDirectory Access Protocol.

RFC 4530 Lightweight Directory AccessProtocol (LDAP) entryUUIDOperational Attribute.

RFC 4531 Lightweight Directory AccessProtocol (LDAP) TurnOperation.

RFC 4532 Lightweight Directory AccessProtocol (LDAP) "Who am I?"Operation.

RFC 4533 The Lightweight DirectoryAccess Protocol (LDAP) ContentSynchronization Operation.

RFC 4876 A Configuration Profile Schemafor Lightweight Directory AccessProtocol (LDAP)-Based Agents.

RFC 5020 The Lightweight DirectoryAccess Protocol (LDAP)entryDN Operational Attribute.

Here is a list of drafts :

I-Ds List Working Group, LDAP Extension (ldapext) [https://datatracker.ietf.org/public/idindex.cgi?command=show_wg_id&id=1363]

Page 36: ApacheDS Guide

Draft Draft

© 2003-201025

The Apache Software Foundation Privacy Policy

Chapter 3. Authentication &Authorization3.1. SASL Authentication to ApacheDS

3.1.1. IntroductionApache Directory currently supports the CRAM-MD5, DIGEST-MD5, and GSSAPI SASLmechanisms. SASL is used during LDAP Binds to authenticate users. Additionally, with theDIGEST-MD5 and GSSAPI mechanisms, SASL can also provide message integrity (checksums) and,optionally, message privacy (encryption). When using SASL message privacy, connections do notneed SSL to protect communications.

3.1.2. ArchitectureSASL workflow is implemented in the LDAP Protocol Provider's BindHandler. At the start of aBind, the BindHandler handles SASL negotiation. During SASL negotiation, the LDAP client isfirst authenticated. After successful authentication, an LDAP context is established and a SUCCESSmessage is returned.

Inbound --> decoder --> BindHandler <--> Backend #1, #2Outbound <-- encoder <------'

Backend #1 is a lookup to authenticate the user using an administrative (internal) directory context.

Backend #2 is an LdapContext establishment for the user that is stored in the user's MINA session.

The DIGEST-MD5 and GSSAPI SASL mechanisms can provide message integrity and, optionally,message confidentiality by "wrapping" or "unwrapping" data with a security layer. After the Bind hascompleted the BindHandler will insert a MINA filter that handles security layer processing into theIoFilterChain for the session that was SASL-authenticated. All subsequent LDAP operations will bewrapped or unwrapped by the SaslFilter (assuming message integrity or privacy are negotiated). Forexample, a subsequent search would arrive wrapped and thus must be unwrapped by the SaslFilterprior to being ASN.1 decoded into a SearchRequest. Similarly, all outbound responses, includingerrors and unbinds, will be wrapped by the SaslFilter.

Inbound --> SaslFilter --> decoder --> SearchHandler <--> backendOutbound <-- SaslFilter <-- encoder <-------'

3.1.3. CRAM-MD5Password must be stored as plaintext in the 'userPassword' attribute.

Username is matched to 'uid' under a base DN.

3.1.4. DIGEST-MD5Password must be stored as plaintext in the 'userPassword' attribute.

Username is matched to 'uid' under a base DN.

Realm must match realms advertised by the LDAP server, but there is no multi-realm support yet.

Page 37: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201026

The Apache Software Foundation Privacy Policy

3.1.5. GSSAPIPrincipal name is matched to the 'krb5PrincipalName' attribute under a base DN.

No multi-realm support yet.

Principal configuration (user, service, krbtgt) can all occur on LDIF load.

3.1.6. Anonymous queriesRootDSE queries will never require authentication.

$ ldapsearch -s base -LLL supportedSASLMechanisms -xsupportedSASLMechanisms: GSSAPIsupportedSASLMechanisms: DIGEST-MD5supportedSASLMechanisms: CRAM-MD5

When anonymous authentication is disabled , queries below the RootDSE will require authentication.The following command will fail if anonymous access is disabled.

$ ldapsearch -b "dc=example,dc=com" "(uid=hnelson)" -x

3.1.7. SASL queriesCRAM-MD5 is a username/password mechanism.

$ ldapsearch -b "dc=example,dc=com" "(uid=hnelson)" -U hnelson -w secret -Y CRAM-MD5

DIGEST-MD5 is a username/password mechanism. DIGEST-MD5 also supports the concept of"realm."

$ ldapsearch -b "dc=example,dc=com" "(uid=hnelson)" -U hnelson -w secret -Y DIGEST-MD5 -R example.com

GSSAPI will use the Kerberos credentials of the current user. GSSAPI supports the concept of "realm,"but the realm is part of the username, eg '[email protected]'.

$ ldapsearch -b "dc=example,dc=com" "(uid=hnelson)" -Y GSSAPI

3.1.8. ResourcesIMAP/POP AUTHorize Extension for Simple Challenge/Responsehttp://www.ietf.org/rfc/rfc2195.txt

Using Digest Authentication as a SASL Mechanismhttp://www.ietf.org/rfc/rfc2831.txt

RFC 4422 - Simple Authentication and Security Layer (SASL)http://www.faqs.org/rfcs/rfc4422.htmlThis document obsoletes RFC 2222.

Lightweight Directory Access Protocol (LDAP): Directory Information Modelshttp://www.faqs.org/rfcs/rfc4512.html

RFC 4513 - Lightweight Directory Access Protocol (LDAP): Authentication Methods and SecurityMechanismshttp://www.faqs.org/rfcs/rfc4513.htmlThis document obsoletes RFC 2251, RFC 2829, and RFC 2830.

Page 38: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201027

The Apache Software Foundation Privacy Policy

Simple Authentication and Security Layer (SASL) Mechanismshttp://www.iana.org/assignments/sasl-mechanisms

RFC 3829 - LDAP Authorization Identity Request and Response Controlshttp://www.faqs.org/rfcs/rfc3829.html

3.2. HOWTO do SASL GSSAPI Authenticationto ApacheDS

3.2.1. IntroductionApache Directory currently supports the SASL GSSAPI mechanism. SASL GSSAPI allows Kerberosauthentication to be used during LDAP Binds. Additionally, the GSSAPI mechanism can providemessage integrity (checksums) and, optionally, message privacy (encryption). When using SASLmessage privacy, connections do not need SSL to protect communications.

3.2.2. Getting Started1. Make sure you are using ApacheDS 1.5.1, which is currently (4-JUN-2007) only available from

the HEAD of trunk in svn. ( Section 1.2, “Building trunks” )

2. You can double-check your version of ApacheDS by interrogating the RootDSE for the supportedSASL mechanisms. Note the use of the fully-qualified domain name (FQDN), 'ldap.example.com'.Regardless of the enabled authentication mechanisms, you will always be able to query theRootDSE. You must see 'GSSAPI' in this returned list.

$ ldapsearch -H ldap://ldap.example.com:10389 -s base -LLL supportedSASLMechanisms -xdn:supportedSASLMechanisms: GSSAPIsupportedSASLMechanisms: DIGEST-MD5supportedSASLMechanisms: CRAM-MD5

3. (OPTIONAL) Install GSSAPI support for LDAP tools on Linux. By default, some Linux variantsdo not have SASL GSSAPI support installed. If Cyrus SASL GSSAPI is not present, install it withan RPM maintenance tool such as 'yum'. Note that the SASL support in ApacheDS is unrelated tothe SASL library implementation being installed here.

$ rpm -qa | grep saslcyrus-sasl-lib-2.1.22-4cyrus-sasl-2.1.22-4...cyrus-sasl-gssapi-2.1.22-4

$ yum install cyrus-sasl-gssapi

4. Open the server.xml for editing.

$ cd <trunk>/server-main$ vi server.xml

5. Enable GSSAPI as a mechanism. GSSAPI is disabled by default.

<!-- The list of supported authentication mechanisms. --><property name="supportedMechanisms"> <list> ... <value>GSSAPI</value>

Page 39: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201028

The Apache Software Foundation Privacy Policy

</list></property>

6. Set the FQDN of the host. The FQDN must resolve, by hosts file, or DNS. Elements of the SASLGSSAPI mechanism are extremely picky about the FQDN you use. The FQDN should be the top-most entry in your hosts file or matching A and PTR records in DNS. If you are running the clientand the server on the same machine, you may need to set the FQDN to be your hostname. Youwill likely find a sniffer (like WireShark) very handy for figuring out what hostnames are beingassumed and whether DNS is working properly.

<!-- The FQDN of this SASL host, validated during SASL negotiation. --><property name="saslHost" value="ldap.example.com" />

7. Set the service principal name that the server-side of the LDAP protocol provider will use to"accept" a GSSAPI context initiated by the LDAP client. The SASL principal MUST followthe name-form ldap/<fqdn>@<realm>. The 'ldap' name component and the @<realm> will beautomatically added to the FQDN by the LDAP client. The LDAP client will then use this as theservice principal name when requesting a service ticket from a KDC. In our case, the KDC isApacheDS, itself.

<!-- The Kerberos principal name for this LDAP service, used by GSSAPI. --><property name="saslPrincipal" value="ldap/[email protected]" />

8. (OPTIONAL) Enforce quality-of-protection (QoP). The QoP level directly maps to the JNDI levels.Listing all possible levels means any level will be accepted. Listing only 'auth-conf' will allowonly 'auth-conf' connections. These SASL QoP levels are global; they affect all connections usingDIGEST-MD5 or GSSAPI.

Table 3.1. SASL QoP levels

QoP Description

auth Use SASL for authentication only (no integrityor confidentiality protection).

auth-int Use SASL with integrity protection. Integritybasically means "with a checksum." ForGSSAPI integrity is always enabled.

auth-conf Use SASL with confidentiality protection.Confidentiality means "with encryption."Confidentiality is sometimes called privacy.When Confidentiality is enabled, you do notneed SSL/TLS to protect connections.

<!-- The desired quality-of-protection, used by DIGEST-MD5 and GSSAPI. --><property name="saslQop"> <list> <value>auth</value> <value>auth-int</value> <value>auth-conf</value> </list></property>

9. Configure SASL realms. If the realm is not enabled, the connection will be rejected. Note that ifyour realm does not appear here, you will see an error similar to "Nonexistent realm: dummy.com."

<!-- The realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI. --><property name="saslRealms"> <list> <value>example.com</value> <value>apache.org</value>

Page 40: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201029

The Apache Software Foundation Privacy Policy

</list></property>

10.Set the search base DN. The search base DN is where a subtree-scoped DIT search will beperformed. This is BOTH where the LDAP service principal must reside, as well as where userprincipals must reside. That all principals must reside in a single sub-tree is currently (4-JUN-2007)a limitation of the SASL implementation. Work is underway to enable "multi-realm" capability, aswell as "split realm" capability. "Split realm" capability will allow you to split principals (users,admins, services, machines) into separate subtrees.

<!-- The base DN containing users that can be SASL authenticated. --><property name="searchBaseDn" value="ou=users,dc=example,dc=com" />

11.Configure your host so that it knows where to get Kerberos tickets. On linux this is configured in '/etc/krb5.conf'. The minimum config file must list the default Kerberos realm and the location of atleast one key distribution center (KDC). With ApacheDS, the KDC and LDAP server are the same,so we'll re-use our 'ldap.example.com' hostname here.

[libdefaults] default_realm = EXAMPLE.COM

[realms] EXAMPLE.COM = { kdc = ldap.example.com }

[domain_realm] .example.com = EXAMPLE.COM example.com = EXAMPLE.COM

12.Enable the Kerberos protocol provider. By default, the LDAP protocol is enabled, but the Kerberosprotocol is not. You may also change the Kerberos port so that Kerberos can bind if you're logged-in as a non-root user. If you change the default port of '88', you must change the KDC port in thekrb5.conf, as well.

#

<bean id="kdcConfiguration" class="org.apache.directory.server.kerberos.kdc.KdcConfiguration"> <!-- Whether to enable the Kerberos protocol. --> <property name="enabled" value="true" /> <!-- The port to run the Kerberos protocol on. --> <property name="ipPort" value="88" /></bean>

13.Enable the KeyDerivationService. In contrast to the SIMPLE, CRAM-MD5, and DIGEST-MD5SASL mechanisms, Kerberos authentication is based on symmetric keys. Since a user can't beexpected to remember a symmetric key, there are "key derivation functions" that will producesymmetric key material based on the concatenation of the password, realm, and username. Anychanges to the user's password must result in new keys being generated. Luckily, ApacheDS hasthe "KeyDerivationService" interceptor. This service will intercept any adds or modifications to theuser's 'userPassword' attribute and generate keys. Service principals typically use random keys, sothe interceptor will generate random keys when the special keyword 'randomKey' is used. Unlikeother combinations of separate LDAP and Kerberos servers, we do not need to export the serviceprincipal keys to a keytab file from the KDC and use it to configure the LDAP server. SinceApacheDS' LDAP and Kerberos protocol both have access to the DIT, we simply need to enablethe KeyDerivationService and add some principals.

<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration"> <property name="name" value="keyDerivationService" /> <property name="interceptor"> <bean class="org.apache.directory.server.core.kerberos.KeyDerivationService" /> </property></bean>

Page 41: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201030

The Apache Software Foundation Privacy Policy

14.Pre-load principals using an LDIF file. If the LDAP SASL GSSAPI mechanism is enabled butthe service principal is not found then you may see a WARN'ing in the server logs. With theKeyDerivationService enabled, you should be able to use LDIFs or LDAP to configure principalson-the-fly. For this example, since the LDIF format is concise, we review some LDIF entries.You will find attached to this page an example LDIF. Download the LDIF [data/sasl-gssapi-example.ldif] and configure the 'ldifDirectory' in server.xml.

<property name="ldifDirectory"> <value>/path/to/sasl-gssapi-example.ldif</value></property>

15.Review the LDIF entries. The metaphor for Kerberos comes from the fact that it is "three-headed";there is always a KDC principal, service principal, and user principal. All of these principals usethe same objectClass'es. The attributes are the minimum to satisfy their respective schema, withthe exception of the Kerberos schema. Because we are using the KeyDerivationService, we don'tneed to specify the Kerberos key, key types, or key version number (kvno); they are automaticallyadded by the interceptor, which will also increment the kvno when the password changes. Lookingat the LDIF file you'll see the ASL license, an organizational unit (ou) for our 'users' subcontext,and the following entries:

Table 3.2. To be named

Entry RDN Password Principal Name Description

uid=hnelson userpassword: s3crEt krb5PrincipalName:[email protected]

Our user principal.Note the userpassword.

uid=krbtgt userpassword:randomKey

krb5PrincipalName:krbtgt/[email protected]

The KDC principal,with a random key.

uid=hostldap userpassword:randomKey

krb5PrincipalName:ldap/[email protected]

The LDAP principal,with a random key.

16.You are now ready to start the server. Upon startup, the server will load the entries from the LDIF.

$ cd <trunk>/server-main$ ./apacheds.sh

17.Request a ticket-granting ticket (TGT) using 'kinit'. If you have not already "logged in," you mustrequest a fresh TGT. Without a TGT, 'ldapsearch', for example, will fail with error "No credentialscache found." Also, if you don't specify the user principal, kinit will guess the principal name basedon the logged-in user and the realm configured in the krb5.conf.

$ kinit [email protected] for [email protected]: <s3crEt>

18.You should now be able to query the DIT using Kerberos credentials. GSSAPI will use the Kerberoscredentials (TGT) of the current user. GSSAPI supports the concept of "realm," but the realm is partof the username, eg '[email protected]'. This is in contrast to other SASL mechanismswhere the realm is separately and explicitly specified.

$ ldapsearch -H ldap://ldap.example.com:10389 -b "dc=example,dc=com" "(uid=hnelson)" -Y GSSAPI

19.(OPTIONAL) List your Kerberos credentials. You'll see that in addition to a TGT, you also nowhave a service ticket for the LDAP server.

Page 42: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201031

The Apache Software Foundation Privacy Policy

$ klist -5feaTicket cache: FILE:/tmp/krb5cc_0Default principal: [email protected] starting Expires Service principal06/04/07 20:42:19 06/05/07 20:41:37 krbtgt/[email protected] Etype (skey, tkt): DES cbc mode with RSA-MD5, DES cbc mode with RSA-MD5 Addresses: (none)06/04/07 20:42:22 06/05/07 20:41:37 ldap/[email protected] Etype (skey, tkt): DES cbc mode with RSA-MD5, DES cbc mode with RSA-MD5 Addresses: (none)

3.3. Start TLS with ApacheDS

3.3.1. IntroductionWith Start TLS, the client sends an extended operation to the server that says 'after you send me apositive response to this operation, flip the connection over to TLS'. Start TLS is a mechanism foravoiding the need to listen on a separate port for SSL connections.

3.3.2. Testing LDAP binds with TLSThe following commands perform anonymous binds with TLS.

$ ldapsearch -H ldap://ldap.example.com/ -s base -LLL supportedSASLMechanisms -x -ZZ

can also use TLS (and SSL) with the SASL authentication mechanisms.

$ ldapsearch -H ldap://ldap.example.com -b "dc=example,dc=com" "(uid=hnelson)" -ZZ -Y DIGEST-MD5 -U hnelson -R example.com -w secret$ ldapsearch -H ldap://ldap.example.com -b "dc=example,dc=com" "(uid=hnelson)" -ZZ -Y CRAM-MD5 -U hnelson -w secret$ ldapsearch -H ldap://ldap.example.com -b "dc=example,dc=com" "(uid=hnelson)" -ZZ -Y GSSAPI

Note that SSL certificates may be verified, depending on the LDAP client, so you should use theFQDN of the ldap server that matches the cn in the certificate.

3.3.3. ResourcesRFC 2830 - Lightweight Directory Access Protocol (v3): Extension for Transport Layer Securityhttp://www.faqs.org/rfcs/rfc2830.html

SSL and Custom Socketshttp://java.sun.com/products/jndi/tutorial/ldap/security/ssl.html

3.4. Writing a custom authenticatorThis page is out of date

3.4.1. Using custom authenticatorsAuthenticator SPI provides a way to implement your own authentication mechanism, for instancesimple mechanism using password encryption such as MD5 or SHA1, or SASL mechanism. See thefollowing example:

import javax.naming.NamingException;

import org.apache.directory.server.core.authn.AbstractAuthenticator;import org.apache.directory.server.core.authn.LdapPrincipal;import org.apache.directory.server.core.jndi.ServerContext;import org.apache.directory.shared.ldap.aci.AuthenticationLevel;

Page 43: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201032

The Apache Software Foundation Privacy Policy

import org.apache.directory.shared.ldap.name.LdapDN;

public class CustomAuthenticator extends AbstractAuthenticator { public CustomAuthenticator() { // create authenticator that will handle "simple" authentication mechanism super("simple"); }

public void init() throws NamingException { // ... }

public LdapPrincipal authenticate(LdapDN bindDn, ServerContext ctx) throws NamingException { // ...

LdapPrincipal principal = AbstractAuthenticator.createLdapPrincipal(bindDn.toNormName(), AuthenticationLevel.SIMPLE); // .. return principal;

}}

The authenticator class has to extend theorg.apache.directory.server.core.authn.AbstractAuthenticator. This class needs to have a no-argumentconstructor that calls the super() constructor with parameter the authentication mechanism it is goingto handle. In the above example, MyAuthenticator class is going to handle the simple authenticationmechanism.

You can optionally implement the init() method to initialize your authenticator class. This will becalled when the authenticator is loaded by ApacheDS during start-up.

When a client performs an authentication, ApacheDS will call the authenticate() method. Youcan get the client authentication info from the server context. After you authenticate theclient, you need to return the authorization id. If the authentication fails, you should throw anLdapNoPermissionException.

When there are multiple authenticators registered with the same authentication type, ApacheDS willtry to use them in the order it was registered. If one fails it will use the next one, until it finds onethat successfully authenticates the client.

To tell ApacheDS to load your custom authenticators, you need to specify it in the server.xml. Youcan also optionally specify the location of a .properties file containing the initialization parameters.See the following example:

EXAMPLE BELOW IS NO LONGER VALID WITH XML CONFIGURATION

server.authenticators=myauthenticator yourauthenticator

server.authenticator.class.myauthenticator=com.mycompany.MyAuthenticatorserver.authenticator.properties.myauthenticator=myauthenticator.properties

server.authenticator.class.yourauthenticator=com.yourcompany.YourAuthenticatorserver.authenticator.properties.yourauthenticator=yourauthenticator.properties

3.5. AuthorizationApacheDS uses an adaptation of the X.500 basic access control scheme in combination with X.500subentries to control access to entries and attributes within the DIT. This document will show youhow to enable the basic access control mechanism and how to define access control information tomanage access to protected resources.

3.5.1. Enabling Basic Access ControlsBy default the access control subsystem is turned off. Once enabled everything is tightly locked down.Only the special admin user, 'uid=admin,ou=system' , is not affected by permissions. Access to all

Page 44: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201033

The Apache Software Foundation Privacy Policy

operations are denied by default until enabled using an ACIItem. For this reason enabling basic accesscontrols is a configuration option.

To turn on the basic access control mechanism you need to set the accessControlEnabled propertyin the configuration to true. This can be set programatically on the StartupConfiguration or via theserver.xml.

3.5.2. Types of ACI (Access Control Information)Three different types of ACI exist. All types use the same specification syntax for an ACIITem. Thesetypes differ in their placement and manner of use within the directory.

3.5.2.1. Entry ACI

Entry ACI are access controls added to entries to protect that entry specifically. Meaning the protoectedentry is the entry where the ACI resides. When performing an operation on an entry, ApacheDSchecks for the presence of the multivalued operational attribute, entryACI. The values of the entryACIattribute contain ACIItems.

There is one exception to the rule of consulting entryACI attributes within ApacheDS: addoperations do not consult the entryACI within the entry being added. This is a securityprecaution. If allowed users can arbitrarily add entries where they wanted by putting entryACIinto the new entry being added. This could comprimise the DSA.

3.5.2.2. Prescriptive ACI

Prescriptive ACI are access controls that are applied to a collection of entries, not just to a singleentry. Collections of entries are defined by the subtreeSpecifications of subentries. Hence prescriptiveACI are added to subentries as attributes and are applied by ApacheDS to the entries selected bythe subentry's subtreeSpecification. ApacheDS uses the prescriptiveACI multivalued operationalattribute within subentries to contain ACIItems that apply to the entry collection.

Prescriptive ACI can save much effort when trying to control access to a collection of resources.Prescriptive ACI can even be specified to apply access controls to entries that do not yet exist withinthe DIT. They are a very powerful mechanism and for this reason they are the prefered mechanismfor managing access to protected resources. ApacheDS is optimized specifically for managing accessto collections of entries rather than point entries themselves.

Users should try to avoid entry ACIs whenever possible, and use prescriptive ACIs instead. EntryACIs are more for managing exceptional cases and should not be used excessively.

3.5.2.3. Subentry ACI

Access to subentries also needs to be controlled. Subentries are special in ApacheDS. Althoughthey subordinate to an administrative entry (entry of an Administrative Point), they are technicallyconsidered to be in the same context as their administrative entry. ApacheDS considers the perscriptiveACI applied to the administrative entry, to also apply to its subentries.

This however is not the most intuitive mechanism to use for explicitly controlling access to subentries.A more explicit mechanism is used to specify ACIs specifically for protecting subentries. ApacheDSuses the multivalued operational attribute, subentryACI , within administrative entries to controlaccess to immediately subordinate subentries.

Protection policies for ACIs themselves can be managed within the entry of an administrative point.

3.5.3. Some Simple ExamplesThe ACIItem syntax is very expressive and that makes it extremely powerful for specifying complexaccess control policies. However the syntax is not very easy to grasp for beginners. For this reason

Page 45: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201034

The Apache Software Foundation Privacy Policy

we start with simple examples that focus on different protection mechanisms offered by the ACIItemsyntax. We do this instead of specifying the grammar which is not the best way to learn a language.

Please don't go any further until you have read up on the use of Subentries. Knowledge ofsubentries, subtreeSpecifications, administrative areas, and administrative roles are requiredto properly digest the following material.

Before going on to these trails you might want to set up an Administrative Area for managingaccess control via prescriptiveACI. Both subentryACI and prescriptiveACI require the presence of anAdministrative Point entry. For more information and code examples see Section 3.5.4, “ACAreas” .

3.5.3.1. ACI Trails

Here are some trails that resemble simple HOWTO guides. They're ordered with the most pragmaticusage first. We will add to these trails over time.

Table 3.3. ACI Trails

Trail Description

Section 3.5.6, “EnableSearchForAllUsers” access to browse and read all entries and theirattributes by authenticated users.

DenySubentryAccess (TBW) Protecting access to subentries themselves.

Section 3.5.5, “AllowSelfPasswordModify” Granting users the rights needed to change theirown passwords.

GrantAddDelModToGroup (TBW) Granting add, delete, and modify permissions to agroup of users.

GrantModToEntry (TBW) Applying ACI to a single entry.

3.5.4. ACAreas

3.5.4.1. Introduction

This guide will show you how to create an Access Control Specific Area and Access ControlInner Areas for administering access controls within ApacheDS. Basic knowledge of the X.500administrative model is presumed along with an understanding of the Basic Access Control Schemein X.501. For quick primers please take a look at the following documentation:

• ??? and the Section 2.3, “The Administrative Model”

• Section 3.5, “Authorization”

3.5.4.2. Creating Access Control Specific Areas (ACSA)

An access control specific area is an Autonomous Administrative Area (AAA) for managing accesscontrol specific aspects of a subtree within the DIT. Like all administrative areas, an access controlspecific area is rooted at a vertex entry called the Administrative Point (AP). The ACSA spans downuntil leaf entries are encountered or until another ACSA is encountered. Access control specific areasdo not overlap.

Under the AP, you can add subentries that contain prescriptiveACI attributes. Zero or more subentriescan be added, each with one or more prescriptiveACI. These subentries apply access controlinformation (ACI) in these prescriptiveACI attributes to collections of entries within the ACSA.

3.5.4.2.1. Adding an 'administrativeRole' Attribute

An entry becomes an AP when it has an administrativeRole attribute added to it with the appropriatevalue(s). For an ACSA, we need to add the 'accessControlSpecificArea' value to this attribute.

Page 46: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201035

The Apache Software Foundation Privacy Policy

Most of the time users will create partitions in the server and set the root context of the partition(its suffix) to be the AP for a ACSA. For example the default server.xml for ApacheDS ships with apartition with the suffix, 'dc=example,dc=com'. We can use this suffix entry as the AP and our ACSAcan cover all entries under and including 'dc=example,dc=com'.

The code below binds to the server as admin ('uid=admin,ou=system') and modifies the suffix entryto become an ACSA. Note that we check to make sure the attribute does not already exist beforeattempting the add operation.

... // Get a DirContext on the dc=example,dc=com entry Hashtable env = new Hashtable(); env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" ); env.put( "java.naming.provider.url", "ldap://localhost:389/dc=example,dc=com" ); env.put( "java.naming.security.principal", "uid=admin,ou=system" ); env.put( "java.naming.security.credentials", "secret" ); env.put( "java.naming.security.authentication", "simple" ); ctx = new InitialDirContext( env );

// Lookup the administrativeRole specifically since it is operational Attributes ap = ctx.getAttributes( "", new String[] { "administrativeRole" } ); Attribute administrativeRole = ap.get( "administrativeRole" );

// If it does not exist or has no ACSA value then add the attribute if ( administrativeRole == null || ! administrativeRole.contains( "accessControlSpecificArea" ) ) { Attributes changes = new BasicAttributes( "administrativeRole", "accessControlSpecificArea", true ); ctx.modifyAttributes( "", DirContext.ADD_ATTRIBUTE, changes ); } ...

This simple modification of adding the value 'accessControlSpecificArea' to the administrativeRolemakes the suffix entry 'dc=example,dc=com' an AP for an access control specific area. Now you canadd subentries to your heart's content which subordinate to the AP.

3.5.4.3. Creating an Access Control Inner Administrative Area

Creating an inner area involves the same process. In fact the same code can be used bychanging the value added to the administrativeRole attribute. To create the inner area just add'accessControlInnerArea' for the administrativeRole within the AP: same steps, same code, differentvalue for the administrativeRole.

3.5.4.4. Access Control Subentries

After creating the access control area you can create subentries that subordinate to this AP formanaging access to it and anything below. Access control subentries are entries with the objectClasses:'subentry' and 'accessControlSubentry'. An access control subentry must contain 3 attributes other thanthe obvious objectClass attribute. These required attributes are listed below:

Table 3.4. Access Control Subentries

Attribute SINGLE-VALUED Description

cn no The name of the subentry used asits RDN

subtreeSpecification yes The specification for thecollection of entries the ACI is tobe applied to.

prescriptiveACI no The attribute holding theACIItem

3.5.5. AllowSelfPasswordModify

Page 47: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201036

The Apache Software Foundation Privacy Policy

{ identificationTag "allowSelfAccessAndModification", precedence 14, authenticationLevel none, itemOrUserFirst userFirst: { userClasses { thisEntry }, userPermissions { { protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse, grantRead } }, { protectedItems {allAttributeValues {userPassword}}, grantsAndDenials { grantAdd, grantRemove } } } } }

3.5.5.1. Commentary

Note that two different user permissions are used to accurately specify self access and self modificationof the userPassword attribute within the entry. So with the first userPermission of this ACI a userwould be able to read all attributes and values within his/her entry. They also have the ability to modifythe entry but this is moot since they cannot add, remove or replace any attributes within their entry. Thesecond user permission completes the picture by granting add and remove permissions to all valuesof userPassword. This means the user can replace the password.

3.5.6. EnableSearchForAllUsers

3.5.6.1. Enable Authenticated Users to Browse and Read Entriesin a Subtree

We presume this is your first encounter and so many bases will be covered this time around.Every other trail will build on this information. So expect a little less to read as you gainmomentum.

Since the entire directory is locked down for all but the superuser, you're going to want to grant readand browse access to users for certain regions of the DIT. This will probably be the first thing you'llwant to do after turning on access controls.

3.5.6.1.1. Check for insufficientAccessRights for Normal Users

Just to make sure everything is locked down login as admin and create a new non-superuser. For moreinformation on how to do this see ??? . After creating the normal user make sure you cannot bindto dc=example,dc=com with access controls enabled. You should get an error trying to bind with aresult code of 50 (insufficientAccessRights). If using JNDI to connect to the server you should get aNoPermissionException. After we apply the following ACI you can check again.

3.5.6.1.2. Partition and Access Control Area Setup

For this example we presume you have setup a partition at the namingContext dc=example,dc=comand have turned on access controls. Now you want to grant browse and read access to entries andtheir attributes.

Before you can add a subentry with the prescriptiveACI you'll need to create an administrative area.For now we'll make the root of the partition the adminstrative point (AP). Every entry including thisentry and those underneath it will be part of the autonous administrative area for managing accesscontrols. To do this we must add the administrativeRole operational attribute to the AP entry. See ???for code and information about creating access control administrative areas.

3.5.6.1.3. Adding the Subentry

The subentry can be added using an LDIF or via code. We'll show the code but the LDIF can beaccessed here enableSearchForAllUsers.ldif [data/enableSearchForAllUsers.ldif] :

Page 48: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201037

The Apache Software Foundation Privacy Policy

// Get a DirContext on the dc=example,dc=com entry Hashtable env = new Hashtable(); env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" ); env.put( "java.naming.provider.url", "ldap://localhost:" + port + "/dc=example,dc=com" ); env.put( "java.naming.security.principal", "uid=admin,ou=system" ); env.put( "java.naming.security.credentials", "secret" ); env.put( "java.naming.security.authentication", "simple" ); ctx = new InitialDirContext( env );

// now add the A/C subentry below dc=example,dc=com Attributes subentry = new BasicAttributes( "cn", "enableSearchForAllUsers", true ); Attribute objectClass = new BasicAttribute( "objectClass" ); subentry.put( objectClass ); objectClass.add( "top" ); objectClass.add( "subentry" ); objectClass.add( "accessControlSubentry" ); subentry.put( "subtreeSpecification", "{}" ); subentry.put( "prescriptiveACI", "{ \n" + " identificationTag \"enableSearchForAllUsers\",\n" + " precedence 14,\n" + " authenticationLevel simple,\n" + " itemOrUserFirst userFirst: \n" + " { \n" + " userClasses { allUsers }, \n" + " userPermissions \n" + " { \n" + " {\n" + " protectedItems {entry, allUserAttributeTypesAndValues}, \n" + " grantsAndDenials { grantRead, grantReturnDN, grantBrowse } \n" + " }\n" + " } \n" + " } \n" + "}" ); ctx.createSubcontext( "cn=enableSearchForAllUsers", subentry );

Before we cover the anatomy of this ACIItem, you might want to add the subentry and test accesswith a normal non-super user to make sure access is now granted.

3.5.6.1.4. ACIItem Description

Here's the ACIItem you just added above without all the Java clutter:

{ identificationTag "enableSearchForAllUsers", precedence 14, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { allUsers }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues}, grantsAndDenials { grantRead, grantReturnDN, grantBrowse } } } } }

There are several parameters to this simple ACIItem. Here's a breif exaplanation of each field and it'smeaning or significance.

Table 3.5. ACIItem fields

Fields Description

identificationTag Identifies the ACIItem within an entry.

precedence Determine which ACI to apply with conflictingACIItems.

authenticationLevel User's level of trust with values of none, simple,strong

Page 49: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201038

The Apache Software Foundation Privacy Policy

Fields Description

itemOrUserFirst Determines order of item permissions or userpermissions.

userClasses The set of users the permissions apply to.

userPermissions Permissions on protected items

3.5.6.1.4.1. identificationTag

The identificationTag is just that a tag. It's often used with a subtring search filter to lookup a specificACIItem within an entry. One or more ACIItems may be present within a subentry, zero or more inentries, so this serves as a means to address the ACIItem within entries.

3.5.6.1.4.2. precedence

Precendence is used to determine the ACI to apply when two or more ACIItem's applied to an entryconflict. The ACIItem with the highest precedence is applied over other conflicting ACIItems.

When two or more conflicting ACIItems are encountered with the same precedence theACIItems with denials overpower ACIItems with grants.

Right now the use of this field may not mean too much to you. We're dealing with a very simplesituation with a single access control area. Later as you add more subentries their subtreeSpecificationsmay define collections that intersect. When this happens two or more conflicting ACIItems may applyto the same entry. Precendence is then applied to determine which permissions apply.

Another complex situation requiring precedence is the use of inner areas. These nested inneradministrative areas overlap and so do their effects. The authority within an AA may deny someoperation to all entries but grant access to subentries of inner areas so minor authorities can controlaccess to inner areas. Their grants to users may need to have a higher precedence over denials in outerareas. Such situations will arise and precedence will need to be used. In this example we just assignan arbitrary value to the precedence.

3.5.6.1.4.3. authenticationLevel

The authenticationLevel is the minimum authentication requirement for requestor for the ACI to byapplied: According to X.501:

The authenticationLevel can have three values: none, simple and strong. It's used to be able to associatepermissions with the level of trust in users. For none, the identity of the user is anonymous or doesnot matter. The user can be anyone. The simple authenticationLevel means the user has authenticatedbut is using a simple bind with clear text passwords. The strong authenticationLevel represents usersthat bind to the directory using strong authentication mechanisms via SASL.

SASL can allow annonynous binds as well so there is a distinction here. Using SASL alone doesnot mean the authenticationLevel is strong. As we add SASL mechanisms to the server, we'll qualifyeach one with none, simple or strong. This will be reflected in the authenticationLevel property of theprincipal making requests.

3.5.6.1.4.4. itemOrUserFirst

This field describes the order of information within the ACI whether protected items are described firstor user classes and permissions are described first. For simplicity we will only describe the userFirstconfiguration in this tutorial.

3.5.6.1.4.5. userClasses

UserClasses is used to list the sets of users to which this permission applies. Several mechanisms canbe used here to define userClasses. They can be defined by name per user, by group membership, orby the superset of all users possible and many more. In our example we have applied the ACI to allusers that have authenticated by simple or strong means.

Page 50: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201039

The Apache Software Foundation Privacy Policy

For more information see Section 3.5.7, “UserClasses” .

3.5.6.1.4.6. userPermissions

These are the permissions granted or denied to those users included by the userClasses field. Thegrants or denials however are qualified by the protected items operated upon. In our example we grantread, return DN and browse to all entries, their attributes and all possible values they may have.

For more information see ??? .

3.5.7. UserClasses

3.5.7.1. What are User Classes?

A large part of managing access control information involves the specification of who can performwhich operation on what protected resource (entries, attributes, values etc). At evaluation time arequestor of an operation is known. The identity of the requestor is checked to see if it falls into theset of users authorized to perform the operation. User classes are hence definitions of a set of zero ormore users permissions apply to. Several constructs exist for specifying a user class.

3.5.7.2. Simple User Classes

There are 3 really simple constructs for specifying the user. These constructs are listed in the tablebelow:

Table 3.6. Simple User Classes

User Class Construct Meaning Example

allUsers Any user with possiblerequirements forAuthenticationLevel

allUsers

thisEntry The user with the same DN asthe entry being accessed

thisEntry

name The user with the specified DN name{ "uid=admin,ou=system" }

These are pretty intuitive. Two other user classes may be a bit less easy to understand or may requiresome explanation. For these we discuss them in the sections below.

3.5.7.3. User Class: userGroup

The userGroup user class construct is also pretty intuitive. It does however require some backgroundinformation about how group membership is determined for this purpose.

ApacheDS associates users within a group using the groupOfNames and groupOfUniqueNamesobjectClasses. To define groups an entry of either of these objectClasses is added anywhere in theserver's DIT. member or uniqueMember attributes whose values are the DN of user entries arepresent within the entry to represent membership within the group.

Although such group entries can be added anywhere within the DIT to be recognized by theAuthorization subsystem, a recommended convention exists. Use the 'ou=groups' containerunder a namingContext/partition within the server to localize groups. Most of the time groupinformation can be stored under 'ou=groups,ou=system'.

Just like the name construct, the userGroup construct takes a single parameter: the DN of the groupentry. During ACI evaluation ApacheDS checks to see if the requestor's DN is contained within thegroup. Below is a section from X.501 specification which explains just how this is done:

Page 51: ApacheDS Guide

Draft Authentication & Authorization Draft

© 2003-201040

The Apache Software Foundation Privacy Policy

Section 18.4.2.5 Determining group membership (b)

In order to determine whether the requestor is a member of a userGroup user class, the followingcriteria apply:

• The entry named by the userGroup specification shall be an instance of the object classgroupOfNames or groupOfUniqueNames.

• The name of the requestor shall be a value of the member or uniqueMember attribute of that entry.

3.5.7.4. User Class: subtree

Here the user class specification construct is a subtree specification without a refinement filter. Sucha specification is simple yet very powerful. The subtree defines a collection of entries. During ACIevaluation, ApacheDS will check to see if the requestor's DN is included by this collection.

For more information on how to define a subtreeSpecification please see ??? and Section 2.3, “TheAdministrative Model” .

For this purpose a subtree is not refined. Meaning it does not evaluate refinement filters. Thisis to restrict the information needed to make a determination to just the DN of the requestorand not the entry of the requestor.

3.5.8. Combining Multiple UserClass SpecificationMechanisms

The same userClass mechanism can be specified more than once if it makes sense. There is no reasonto specify allUsers more than once. More than one type of user class mechanism can be used as well.Again some combinations just will not make sense like having a name based userClass then allUsers.The following ACIItem grants delete abilities to a set of users using more than one machanism. Itallows jbean, jdoe, all users in the Administrators group to delete entries. It also allows requestors todelete their own user entry.

{ identificationTag "deleteAci" precedence 255, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { thisEntry, name { "uid=jbean,ou=users,ou=system" }, name { "uid=jdoe,ou=users,ou=system" }, userGroup { "cn=Administrators,ou=groups,ou=system" } }, userPermissions { { protectedItems {entry}, grantsAndDenials { grantRemove } } } } }

Page 52: ApacheDS Guide

Draft Draft

© 2003-201041

The Apache Software Foundation Privacy Policy

Chapter 4. Attributes, Entries &Schemas

4.1. Add your first elements to the schemaThis section shows how to define custom schema elements, and how to add them to an ApacheDS1.5 instance.

• Section 4.1.1, “Motivation”

• Section 4.1.2, “Browsing the schema of ApacheDS”

• Section 4.1.3, “Which OIDs should you use?”

• Section 4.1.4, “A simple example”

• Section 4.1.5, “Using Apache Directory Studio Schema Editor to load the new schema elements”

• Section 4.1.6, “Using LDIF to load schema elements in RFC 4512 format”

• Section 4.1.7, “Using JNDI to add the schema elements programmatically”

• Section 4.1.8, “Using JNDI to add schema elements in RFC 4512 format programmatically”

• Section 4.1.9, “Resources”

4.1.1. Motivation

The schema of an LDAP server is comprised of object classes, attributes, syntaxes and matching rules.Basically it defines which entries are allowed within the server and how the server should handle them.In contrast to the 1.0 release, ApacheDS 1.5.0 comes with a completely redesigned schema subsystem.It enables dynamic schema updates, like the creation of new attribute types or object classes at runtime(i.e. without restarting the server).

No. ApacheDS comes with a comprehensive set of predefined, standardized schema elements(like inetOrgPerson ). It is quite common to solely use the predefined schema. The same holdstrue for other directory servers, by the way.

In the following text the addition of user defined schema elements to the schema is described in tutorialstyle.

4.1.2. Browsing the schema of ApacheDS

LDAPv3 servers publish their schema via LDAP. Thus it is possible to list the schema elements withstandard LDAP tools. For instance it is possible to use the ldapsearch command line tool to list allobject classes

$ ldapsearch -h zanzibar -p 10389 -D "uid=admin,ou=system" -w ****** \ -b "cn=schema" -s base "(objectclass=subschema)" objectclasses...objectClasses: ( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top STRUCTURAL MUST ( sn $ cn ) MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) X-SCHEMA 'core' )...

Page 53: ApacheDS Guide

Draft Attributes, Entries & Schemas Draft

© 2003-201042

The Apache Software Foundation Privacy Policy

The output (formatted as defines in RFC 4512 [http://www.ietf.org/rfc/rfc4512.txt] ) contains all thingswhich are interesting to know about an object class (required attributes, optional attributes etc.), butis not easy to read by a human user. It is therefore often appropriate to use a GUI tool to browse theschema (which basically performs the same search operations but presents the output prettily). Oneoption is Apache Directory Studio [http://directory.apache.org/studio/] , an Eclipse based LDAP toolset which contains a powerful graphical Schema browser:

Figure 4.1. Schema Browser Person

The techniques described above work for all LDAP v3 compliant servers. The ability to browse theschema gives us a chance to check whether our future changes to the schema really took place.

The schema subsystem of ApacheDS 1.5 stores the schema elements as entries in the DIT. You canfind them within a special partition with suffix ou=schema ; simply browse the content with yourfavorite LDAP Browser. With Apache Directory Studio, it looks like this:

Page 54: ApacheDS Guide

Draft Attributes, Entries & Schemas Draft

© 2003-201043

The Apache Software Foundation Privacy Policy

Figure 4.2. Schema Browser Tree

Browsing the schema like this gives a good impression of the ApacheDS implementation of the schemasubsystem and an even better way to analyze effects during schema updates. But keep in mind that thestorage scheme is server dependent; not all LDAP server implementations store the schema elementsin the DIT.

4.1.3. Which OIDs should you use?If you plan to add custom schema elements, you need numerical OIDs (object identifiers) for them. Ifyou implement schema elements defined somewhere else (like eduPerson [http://www.educause.edu/eduperson/] ), you can use the OIDs which are are part of their descriptions. But what if you plan todesign your own?

4.1.3.1. Some OID background information

An OID is a string formed by a series of numbers which are seperated by a dot (like "12.4.1971.0.1").Many elements in directory world use OIDs: Controls, extended operations and schema elements (like"2.5.6.6" for object class person). They identify these objects in a unique fashion and therefore avoidname clashes.

How is this accomplished? OIDs are assigned hierarchically: The owner of an OID is allowed to createnew IDs by simply appending numbers. S/he is also allowed to delegate ownership of newly created

Page 55: ApacheDS Guide

Draft Attributes, Entries & Schemas Draft

© 2003-201044

The Apache Software Foundation Privacy Policy

OIDs to someone else. This way every person or organization is able to allocate an arbitrary numberof new OIDs after obtaining one from "higher command", and they are still unique world-wide.

4.1.3.2. OIDs in the example

OIDs starting with 1.3.6.1.4.1 represent IANA-registered private enterprises, Apache SoftwareFoundation for instance owns the OID 1.3.6.1.4.1.18060. The 1.3.6.1.4.1.18060.0 has beenassigned to the Apache Directory project by the ASF, and we have decided to use the branch"1.3.6.1.4.1.18060.0.4.3" for schema elements used as examples in the documentation.

4.1.3.3. OIDs for your own custom schema elements

If you just want to play around with the schema subsystem, want to explore the capabilities, or learnabout LDAP in general, you will probably not mind about unique OIDs. This is comparable to usingself-signed certificates for SSL experiments. But it is nevertheless necessary that you use OIDs whichare not used in the schema yet (otherwise addition will fail).

But if you plan to use your schema elements in a production environment (an object class for instancewhich describes employees with company specific attributes), or to ship your schema elements witha product (e.g. a CRM or portal solution), you should definitely use unique OIDs. In order to do thisyou have to obtain OIDs from a branch assigned to your company or organization (your networkadministrators will be helpful here, do not invent OIDs without asking or obtaining a branch fromsomeone who owns the prefix OID). If your company or organization does not own on OID, thereare several option to obtain one, one is the IANA (Internet Assigned Numbers Authority). It is alsopossible to get an OID branch as an individual.

You can ask for your own PEN (Private Enterprise Number) here : http://pen.iana.org/pen/PenApplication.page It takes a few weeks to have a private OID assigned to you, so be patient,or do it early !

4.1.4. A simple example

The goal is to store ship entries in our directory, backing the "Seven Seas" example used throughoutthe Basic User's Guide. There are no schema elements shipped with ApacheDS covering our navalrequirements. So we add some.

Here is a sample entry for a ship in LDIF:

dn: cn=HMS Victory,ou=ships,o=sevenSeasobjectClass: topobjectClass: shipcn: HMS VictorynumberOfGuns: 104description: a ship of the line of the Royal Navydescription: built between 1759 and 1765

A ship entry is comprised of a mandatory value for common name ( cn ) of the ship, description valuesand the number of guns ( numberOfGuns ). Thus a new object class ship and a new attribute typenumberOfGuns have to be added to the schema. There are different ways to accomplish the task. Inany case, we have to add the attribute type first, because the object class refers to it.

4.1.4.1. attribute type numberOfGuns

Here is the definition of our custom attribute type numberOfGuns formatted according to RFC 4512.

( 1.3.6.1.4.1.18060.0.4.3.2.1 NAME 'numberOfGuns' DESC 'Number of guns of a ship' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27

Page 56: ApacheDS Guide

Draft Attributes, Entries & Schemas Draft

© 2003-201045

The Apache Software Foundation Privacy Policy

SINGLE-VALUE )

4.1.4.2. object class ship

Custom object class ship is defined as follows

( 1.3.6.1.4.1.18060.0.4.3.3.1 NAME 'ship' DESC 'An entry which represents a ship' SUP top STRUCTURAL MUST cn MAY ( numberOfGuns $ description ) )

4.1.5. Using Apache Directory Studio Schema Editor toload the new schema elements

A very convenient way to add your own schema elements to Apache Directory Server is to use theSchema Editor of Apache Directory Studio. It is even possible to define/design them within the UI,but we opt here use a prepared file in OpenLDAP format and import it using Studio. This is a goodchoice if you have the schema to add already described that way.

Our file sevenSeas.schema [data/sevenSeas.schema] looks like this:

attributetype ( 1.3.6.1.4.1.18060.0.4.3.2.1 NAME 'numberOfGuns' DESC 'Number of guns of a ship' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )objectclass ( 1.3.6.1.4.1.18060.0.4.3.3.1 NAME 'ship' DESC 'An entry which represents a ship' SUP top STRUCTURAL MUST cn MAY ( numberOfGuns $ description ) )

In Eclipse with the Apache Directory Studio plugins installed (or alternatively the standalone RCPapplication of Apache Directory Studio, if you prefer this), open the Schemas view.

Page 57: ApacheDS Guide

Draft Attributes, Entries & Schemas Draft

© 2003-201046

The Apache Software Foundation Privacy Policy

Figure 4.3. Schemas view

When it is shown, press the Open a schema file button in the toolbar of it. In the file dialog, open thesevenSeas.schema . It is loaded and added to the schemas within the view.

Figure 4.4. Schemas view with loaded schemas

Select Export For ApacheDS ... in the context menu of the sevenSeas elements. The schema willbe stored in an LDIF file which can directly be imported into ApacheDS (we choose the file namesevenSeas.ldif [data/sevenSeas.ldif] ).

Use Apache Directory Studio to open a connection to your ApacheDS server, bind as administrator,and select Import | LDIF Import ... in the context menu of the DIT. Choose the LDIF file previouslystored, and import the file. Alternatively, you can use command line tools like ldapmodify to load thefile. If no errors are displayed, you are done.

There are several options to check whether the additions has be successful. One is to use the browsetechniques described above. You can also use specific search commands like this one:

Page 58: ApacheDS Guide

Draft Attributes, Entries & Schemas Draft

© 2003-201047

The Apache Software Foundation Privacy Policy

$ ldapsearch -h zanzibar -p 10389 -D "uid=admin,ou=system" -w ****** \\ -b "ou=schema" -s sub "(m-name=numberOfGuns)"version: 1dn: m-oid=1.3.6.1.4.1.18060.0.4.3.2.1,ou=attributeTypes,cn=other,ou=schemam-usage: USER_APPLICATIONSm-equality: integerOrderingMatchobjectClass: metaAttributeTypeobjectClass: metaTopobjectClass: topm-name: numberOfGunsm-oid: 1.3.6.1.4.1.18060.0.4.3.2.1m-singleValue: TRUEm-description: Number of guns of a shipm-collective: FALSEm-obsolete: FALSEm-noUserModification: FALSEm-syntax: 1.3.6.1.4.1.1466.115.121.1.27

Of course it visible possible within the Apache Directory Studio UI as well. You will likely have torefresh the schema to see the new elements in the schema browser

Figure 4.5. Schema browser ship

Now you are done: The schema elements are ready to use. Feel free to add your fleet!

Figure 4.6. Entry editor with ship

Page 59: ApacheDS Guide

Draft Attributes, Entries & Schemas Draft

© 2003-201048

The Apache Software Foundation Privacy Policy

4.1.6. Using LDIF to load schema elements in RFC4512 format

You could write an LDIF with your schema elements in RFC 4512 format and import the LDIF usingcommand line or Apache Directory Studio. The LDIF for our example looks like this:

dn: cn=schemachangetype: modifyadd: attributeTypesattributeTypes: ( 1.3.6.1.4.1.18060.0.4.3.2.1 NAME 'numberOfGuns' DESC 'Number of guns of a ship' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )-add: objectClassesobjectClasses: ( 1.3.6.1.4.1.18060.0.4.3.3.1 NAME 'ship' DESC 'An entry which represents a ship' SUP top STRUCTURAL MUST cn MAY ( numberOfGuns $ description ) )-

4.1.7. Using JNDI to add the schema elementsprogrammatically

You may want to add schema elements programmatically (for instance in a unit test) via a Java programacting as a client. One option here is to use JNDI and its LDAP provider. The advantage of thisapproach is that it is server independent; it works on LDAP servers other than ApacheDS as well aslong as the server supports dynamic updates and the bind user is allowed to perform these operations(normally only admistrators are allowed to do this).

4.1.7.1. Some simple Java programs

In the following you find source code examples on how to add the two elements. The proceedingis described in more detail in the JNDI Tutorial [http://java.sun.com/products/jndi/tutorial/] (Chapter"Tips for LDAP Users // Schema "). Both use connection data provided by jndi.properties of thefollowing form

java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactoryjava.naming.provider.url=ldap://zanzibar:10389/java.naming.security.principal=uid=admin,ou=systemjava.naming.security.credentials=******java.naming.security.authentication=simple

This simple program (file CreateAttributeType.java [data/CreateAttributeType.java] ) creates theattribute type numberOfGuns

import javax.naming.NamingException;import javax.naming.directory.Attributes;import javax.naming.directory.BasicAttributes;import javax.naming.directory.DirContext;import javax.naming.directory.InitialDirContext;

public class CreateAttributeType {

public static void main(String[] args) throws NamingException {

DirContext ctx = new InitialDirContext(); DirContext schema = ctx.getSchema("");

Page 60: ApacheDS Guide

Draft Attributes, Entries & Schemas Draft

© 2003-201049

The Apache Software Foundation Privacy Policy

Attributes attrs = new BasicAttributes(true); attrs.put("NUMERICOID", "1.3.6.1.4.1.18060.0.4.3.2.1"); attrs.put("NAME", "numberOfGuns"); attrs.put("DESC", "Number of guns of a ship"); attrs.put("EQUALITY", "integerOrderingMatch"); attrs.put("SYNTAX", "1.3.6.1.4.1.1466.115.121.1.27"); attrs.put("SINGLE-VALUE", "true");

schema.createSubcontext("AttributeDefinition/numberOfGuns", attrs); }}

and this one (file CreateObjectClass.java [data/CreateObjectClass.java] ) the object class ship

import javax.naming.NamingException;import javax.naming.directory.Attribute;import javax.naming.directory.Attributes;import javax.naming.directory.BasicAttribute;import javax.naming.directory.BasicAttributes;import javax.naming.directory.DirContext;import javax.naming.directory.InitialDirContext;

public class CreateObjectClass {

public static void main(String[] args) throws NamingException {

DirContext ctx = new InitialDirContext(); DirContext schema = ctx.getSchema("");

Attributes attrs = new BasicAttributes(true); attrs.put("NUMERICOID", "1.3.6.1.4.1.18060.0.4.3.3.1"); attrs.put("NAME", "ship"); attrs.put("DESC", "An entry which represents a ship"); attrs.put("SUP", "top"); attrs.put("STRUCTURAL", "true");

Attribute must = new BasicAttribute("MUST"); must.add("cn"); attrs.put(must);

Attribute may = new BasicAttribute("MAY"); may.add("numberOfGuns"); may.add("description"); attrs.put(may);

schema.createSubcontext("ClassDefinition/ship", attrs); }}

After successfully running the programs against the LDAP server defined in the connection data. Theschema elements can also be found within a schema browser, but you may have to refresh the schemahere as well. They are also ready to use

A final note for the JNDI approach: With the code shown above, the elements will be created by theApacheDS schema subsystem within the other schema (in contrast to the sevenSeas schema ). Youcan also create them programmatically in a specific schema with the help of the X-SCHEMA attribute:

...attrs.put("X-SCHEMA", "sevenSeas");...

but in this case you have to create the skeleton entries for the sevenSeas schema before (loading anLDIF file like the one generated by Apache Directory Studio as depicted above). Otherwise you willget an NamingException ("LDAP: error code 54 - failed to modify entry cn=schema ...").

4.1.8. Using JNDI to add schema elements in RFC 4512format programmatically

It is also possible to add schema elements in RFC 4512 format using JNDI:

Page 61: ApacheDS Guide

Draft Attributes, Entries & Schemas Draft

© 2003-201050

The Apache Software Foundation Privacy Policy

import javax.naming.NamingException;import javax.naming.directory.Attributes;import javax.naming.directory.BasicAttributes;import javax.naming.directory.DirContext;import javax.naming.directory.InitialDirContext;

public class CreateSevenSeasSchema{

public static void main(String[] args) throws NamingException { DirContext ctx = new InitialDirContext();

Attributes atAttrs = new BasicAttributes(true); atAttrs.put("attributeTypes", "( 1.3.6.1.4.1.18060.0.4.3.2.1 NAME 'numberOfGuns' DESC 'Number of guns of a ship' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )"); ctx.modifyAttributes("cn=schema", DirContext.ADD_ATTRIBUTE, atAttrs);

Attributes ocAttrs = new BasicAttributes(true); ocAttrs.put("objectClasses", "( 1.3.6.1.4.1.18060.0.4.3.3.1 NAME 'ship' DESC 'An entry which represents a ship' SUP top STRUCTURAL MUST cn MAY ( numberOfGuns $ description ) )"); ctx.modifyAttributes("cn=schema", DirContext.ADD_ATTRIBUTE, ocAttrs); }

}

4.1.9. Resources

• Internet Assigned Numbers Authority (IANA)http://www.iana.org

• Apache Directory Studio [http://directory.apache.org/ldapstudio/] , a complete LDAP toolingplatform

• RFC 4512 [http://www.ietf.org/rfc/rfc4512.txt] Lightweight Directory Access Protocol (LDAP):Directory Information Models, Section 4: Directory Schema

• The JNDI Tutorial [http://java.sun.com/products/jndi/tutorial/] at Sun Microsystems

4.2. Collective AttributesThis page needs to be overworked

4.2.1. Introduction

Collective attributes are attributes whose values are shared across a collection of entries. It's verycommon to encounter situations where a bunch of entries have the same value for an attribute.Collective attributes for LDAP are defined in RFC 3671 [http://www.faqs.org/rfcs/rfc3671.html] .ApacheDS implements this RFC.

4.2.1.1. Use Case

For example one might organize everyone in an engineering department under an ou, 'ou=engineering'.If the engineering team is located in the same area and building then several attributes in each userentry within engineering will have the same value. An example of such an attribute would be the locale.If engineering is located in Sunnyvale CA then all locale attributes of entries under 'ou=engineering'would be set to Sunnyvale.

Rather than manage the value for this attribute in each entry a single collective attribute can be usedin a subentry. Changes to the value of this attribute would immediately be reflected to those entriesselected by the subtreeSpecification of subentry. For more information on specifying subtrees takeat ??? .

Page 62: ApacheDS Guide

Draft Attributes, Entries & Schemas Draft

© 2003-201051

The Apache Software Foundation Privacy Policy

4.2.2. Setting up a Collective Attribute AdministrationArea (AA)

To manage collective attributes for a collection of entries you must add collective subentries tothe Administrative Point (AP) of the collective AA. For more information on AAs see ??? . Thesecollective subentries must have the objectClass subentry as well as collectiveAttributeSubentry.Also the AP, of the AA, must have an administrativeRole value of collectiveAttributeSpecificArea(2.5.23.5) or collectiveAttributeInnerArea (2.5.23.6).

4.2.2.1. Example

For the use case above we can presume a partition at the namingContext 'dc=example,dc=com' with an'ou=engineering' entry below containing users from the engineering team in Sunnyvale. Let's presumeno AA has yet been defined so we have to create one. We'll set the partition root 'dc=example,dc=com'as the AP of an AA that spans the entire subtree. For this simple example the AA will be autonomousfor the collective aspect. Setting this up is just a matter of modifying the 'dc=example,dc=com' entry soit contains the operational attribute administrativeRole with the value collectiveAttributeSpecificArea.The code below sets up this AAA for collective attribute administration.

// Get a DirContext on the dc=example,dc=com entry Hashtable env = new Hashtable(); env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" ); env.put( "java.naming.provider.url", "ldap://localhost:" + port + "/dc=example,dc=com" ); env.put( "java.naming.security.principal", "uid=admin,ou=system" ); env.put( "java.naming.security.credentials", "secret" ); env.put( "java.naming.security.authentication", "simple" ); ctx = new InitialDirContext( env );

// Modify the entry to make it an AAA for collective attribute administration Attributes mods = new BasicAttributes( "administrativeRole", "collectiveAttributeSpecificArea", true ); ctx.modifyAttributes( "", DirContext.ADD_ATTRIBUTE, mods );

Now 'dc=example,dc=com' is the AP for a collective attribute AAA that spans the entire subtree underand including it down to every leaf entry. All that remains is the addition of the subentry with thecollective attributes we want included in the entries of all engineering users. Here's what the LDIFwould look like for this subentry given that its commonName is 'engineeringLocale'.

dn: cn=engineeringLocale,dc=example,dc=comobjectClass: topobjectClass: subentryobjectClass: collectiveAttributeSubentrycn: engineeringLocalec-l: SunnyvalesubtreeSpecification: {base "ou=engineering", minimum 4}

The following picture present the structure of our tree :

Page 63: ApacheDS Guide

Draft Attributes, Entries & Schemas Draft

© 2003-201052

The Apache Software Foundation Privacy Policy

Figure 4.7. SubEntry

A couple points regarding this subentry's LDIF:

1. It subordinates to the AP ('dc=example,dc=com')

2. It contains the objectClasses: subentry and collectiveAttributeSubentry

3. It contains the collective version of locale (l): c-l

4. Its subtreeSpecification excludes entries whose number of DN name components is less than 4

Note that the minimum value of 4 is used in the subtreeSpecification to make sure that the entry'ou=engineering,dc=example,dc=com' does not have c-l: Sunnyvale added to it. It's got 3 componentsto the DN so minimum 4 chops it out of the collection.

4.2.3. Collective Attribute TypesAs one can see from the example above, special collective attributes are used for regular attributes: c-l for l. These attributes are derived from the original attribute and are marked as COLLECTIVE. RFC3671 defines a bunch of these which are listed below. If you don't find what you're looking for justadd it to your own schema using this pattern.

We have included this list from RFC 3671 into the collective.schema which comes standard withApacheDS.

3.1. Collective Locality Name

The c-l attribute type specifies a locality name for a collection of entries.

( 2.5.4.7.1 NAME 'c-l' SUP l COLLECTIVE )

3.2. Collective State or Province Name

The c-st attribute type specifies a state or province name for a collection of entries.

( 2.5.4.8.1 NAME 'c-st' SUP st COLLECTIVE )

3.3. Collective Street Address

Page 64: ApacheDS Guide

Draft Attributes, Entries & Schemas Draft

© 2003-201053

The Apache Software Foundation Privacy Policy

The c-street attribute type specifies a street address for a collection of entries.

( 2.5.4.9.1 NAME 'c-street' SUP street COLLECTIVE )

3.4. Collective Organization Name

The c-o attribute type specifies an organization name for a collection of entries.

( 2.5.4.10.1 NAME 'c-o' SUP o COLLECTIVE )

3.5. Collective Organizational Unit Name

The c-ou attribute type specifies an organizational unit name for a collection of entries.

( 2.5.4.11.1 NAME 'c-ou' SUP ou COLLECTIVE )

3.6. Collective Postal Address

The c-PostalAddress attribute type specifies a postal address for a collection of entries.

( 2.5.4.16.1 NAME 'c-PostalAddress' SUP postalAddress COLLECTIVE )

3.7. Collective Postal Code

The c-PostalCode attribute type specifies a postal code for a collection of entries.

( 2.5.4.17.1 NAME 'c-PostalCode' SUP postalCode COLLECTIVE )

3.8. Collective Post Office Box

The c-PostOfficeBox attribute type specifies a post office box for a collection of entries.

( 2.5.4.18.1 NAME 'c-PostOfficeBox' SUP postOfficeBox COLLECTIVE )

3.9. Collective Physical Delivery Office Name

The c-PhysicalDeliveryOfficeName attribute type specifies a physical delivery office name for a collection of entries.

( 2.5.4.19.1 NAME 'c-PhysicalDeliveryOfficeName' SUP physicalDeliveryOfficeName COLLECTIVE )

3.10. Collective Telephone Number

The c-TelephoneNumber attribute type specifies a telephone number for a collection of entries.

Page 65: ApacheDS Guide

Draft Attributes, Entries & Schemas Draft

© 2003-201054

The Apache Software Foundation Privacy Policy

( 2.5.4.20.1 NAME 'c-TelephoneNumber' SUP telephoneNumber COLLECTIVE )

3.11. Collective Telex Number

The c-TelexNumber attribute type specifies a telex number for a collection of entries.

( 2.5.4.21.1 NAME 'c-TelexNumber' SUP telexNumber COLLECTIVE )

3.13. Collective Facsimile Telephone Number

The c-FacsimileTelephoneNumber attribute type specifies a facsimile telephone number for a collection of entries.

( 2.5.4.23.1 NAME 'c-FacsimileTelephoneNumber'

SUP facsimileTelephoneNumber COLLECTIVE )

3.14. Collective International ISDN Number

The c-InternationalISDNNumber attribute type specifies an international ISDN number for a collection of entries.

( 2.5.4.25.1 NAME 'c-InternationalISDNNumber' SUP internationalISDNNumber COLLECTIVE )

Page 66: ApacheDS Guide

Draft Draft

© 2003-201055

The Apache Software Foundation Privacy Policy

Chapter 5. Embedding ApacheDS

5.1. Embedding ApacheDS into anapplication

The idea is to use the server directly without having to communicate with a remote server, eliminatingall the network layer. This is one of the reason ADS has been developed in Java: to allow such usage.

will go through a very simple example step by step to show you how this can be done.

5.1.1. Setting up the environmentWe first need to define a base for our project. We use Maven (2.0.9 or above) to build our project,so the structure we will use looks like this:

.|-- pom.xml`-- src `-- main `-- java `-- org `-- apache `-- directory `-- EmbeddedADS.java

You could download both files here:

• data/EmbeddedADS.java

• pom.xml [data/pom.xml]

If you don't want to use Maven you need to add the following dependencies to your classpathin order to compile and run this sample.

• apacheds-all-1.5.5.jar

• slf4j-api-1.5.6.jar

• slf4j-log4j12-1.5.6.jar

• log4j-1.2.14.jar

5.1.2. Creating the applicationSo let's start with the code. It's quite simple: we define a class, add a main() method, and initializethe server, before using it. In the code snippet below, we have removed all the initialization part tokeep only the main() method.

package org.apache.directory;

/** * A simple example exposing how to embed Apache Directory Server * into an application. * * @author <a href="mailto:[email protected]">Apache Directory Project</a> * @version $Rev: 985583 $, $Date: 2010-08-14 23:19:48 +0200 (Sat, 14 Aug 2010) $ */public class EmbeddedADS{

Page 67: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201056

The Apache Software Foundation Privacy Policy

/** The directory service */ private DirectoryService service;

...

/** * Creates a new instance of EmbeddedADS. It initializes the directory service. * * @throws Exception If something went wrong */ public EmbeddedADS() throws Exception { init(); }

/** * Main class. We just do a lookup on the server to check that it's available. * * @param args Not used. */ public static void main( String[] args ) //throws Exception { try { // Create the server EmbeddedADS ads = new EmbeddedADS(); // Read an entry Entry result = ads.service.getAdminSession().lookup( new LdapDN( "dc=apache,dc=org" ) ); // And print it if available System.out.println( "Found entry : " + result ); } catch ( Exception e ) { // Ok, we have something wrong going on ... e.printStackTrace(); } }}

As you can see, we first initialize the server, and immediately do a lookup to check that we can readan entry from it.

Let's focus on the initialization part now.

5.1.3. Initializing the server

This is done in the init() method. It will create the DirectoryService global object ( service ), andcreate a partition in which we will store the entries.

A partition is a storage point, associated with a DN, root point for this partition. It's a bit likea mounting point on Unix. We also need a context entry associated to this DN.

Here, we will create the apache partition, associated with the 'dc=apache,dc=org' DN.

Here is the code for this method :

...

/** * Initialize the server. It creates the partition, adds the index, and * injects the context entries for the created partitions. * * @throws Exception if there were some problems while initializing the system */ private void init() throws Exception { // Initialize the LDAP service service = new DefaultDirectoryService(); // Disable the ChangeLog system service.getChangeLog().setEnabled( false );

Page 68: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201057

The Apache Software Foundation Privacy Policy

// Create a new partition named 'apache'. Partition apachePartition = addPartition( "apache", "dc=apache,dc=org" ); // Index some attributes on the apache partition addIndex( apachePartition, "objectClass", "ou", "uid" ); // And start the service service.startup(); // Inject the apache root entry if it does not already exist if ( !service.getAdminSession().exists( apachePartition.getSuffixDn() ) ) { LdapDN dnApache = new LdapDN( "dc=Apache,dc=Org" ); ServerEntry entryApache = service.newEntry( dnApache ); entryApache.add( "objectClass", "top", "domain", "extensibleObject" ); entryApache.add( "dc", "Apache" ); service.getAdminSession().add( entryApache ); } // We are all done ! }

...

We disabled the ChangeLog service because it's useless in our case. As you can see, the steps toinitialize the server are:

• create a new DirectoryService instance

• add a partition

• add some index

• start the service

• add the context entry

One important point: as the data are remanent, we have to check that the added context entry doesnot exist already before adding it.

Some helper methods have been used : addPartition and addIndex . Here they are :

...

/** * 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'. Partition partition = new JdbmPartition(); partition.setId( 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

Page 69: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201058

The Apache Software Foundation Privacy Policy

HashSet<Index<?, ServerEntry>> indexedAttributes = new HashSet<Index<?, ServerEntry>>(); for ( String attribute:attrs ) { indexedAttributes.add( new JdbmIndex<String,ServerEntry>( attribute ) ); } ((JdbmPartition)partition).setIndexedAttributes( indexedAttributes ); }

...

That's it! (the attached code will contain the needed imports)

5.1.4. Building the sampleUsing Maven this is easy:

$ mvn clean compile[INFO] Scanning for projects...[INFO] ------------------------------------------------------------------------[INFO] Building ApacheDS embedded sample[INFO] task-segment: [clean, compile][INFO] ------------------------------------------------------------------------[INFO] [clean:clean {execution: default-clean}][INFO] Deleting directory /tmp/EmbeddedADS/target[INFO] [resources:resources {execution: default-resources}][WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory /tmp/EmbeddedADS/src/main/resources[INFO] [compiler:compile {execution: default-compile}][INFO] Compiling 1 source file to /tmp/EmbeddedADS/target/classes[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESSFUL[INFO] ------------------------------------------------------------------------[INFO] Total time: 2 seconds[INFO] Finished at: Sat Nov 28 20:02:23 CET 2009[INFO] Final Memory: 17M/76M[INFO] ------------------------------------------------------------------------

The resulting jar can be found in the target directory.

5.1.5. Running the sampleUsing Maven this is easy:

$ mvn exec:java -Dexec.mainClass=org.apache.directory.EmbeddedADS[INFO] Scanning for projects...[INFO] Searching repository for plugin with prefix: 'exec'.[INFO] ------------------------------------------------------------------------[INFO] Building ApacheDS embedded sample[INFO] task-segment: [exec:java][INFO] ------------------------------------------------------------------------[INFO] Preparing exec:java[INFO] No goals needed for project - skipping[INFO] [exec:java {execution: default-cli}]

When the main method is run, you should obtain something like :

log4j:WARN No appenders could be found for logger (org.apache.directory.server.schema.registries.DefaultNormalizerRegistry).log4j:WARN Please initialize the log4j system properly.Found entry : ServerEntry dn[n]: dc=Apache,dc=Org objectClass: extensibleObject objectClass: domain objectClass: top dc: Apache

That's it!

Page 70: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201059

The Apache Software Foundation Privacy Policy

5.2. Using ApacheDS for unit testsThis page describes how to define your own unit tests, using ApacheDS 1.5.6.

The idea is to use ADS as an embedded server for Ldap junit tests. We will build an environment inwhich it will be convenient to test Ldap applications.

We also want to avoid launching the server for every test, as it's an expensive operation. We have builtApacheDS so that you can start a server, inject some data, launch a test, then revert the data and goon to another test. At the end of the tests, the server is stopped.

5.2.1. First stepsWe have two choices : either we launch the server totally embedded, without having to communicatewith it using the Ldap Protocol, or we want to use the server as a remote server, with Ldap protocolin the middle (it can be useful if one want to test specific applications). In both cases, the server isstarted and stopped by the unit test.

We will simply launch only one server (if one want to test referrals, it might be necessary to initialize2 or more servers)

We are using JUnit 4.7

We have to define a layout for the files and directory we will use in this tutorial. Let's use the mavenlayout :

/|+--src | +--test | +--java : we will put all the sources into this directory | +--resources : we will put the resources files into this directory

5.2.2. Creating a blank testSo let's define the framework we need for a simple unit test, using a server which will be invokedthrough socket (the first free port above 1023 will be used). This first test will do a search operationon a server.

package org.apache.directory.server.test;

import static org.apache.directory.server.integ.ServerIntegrationUtils.getWiredContext;import static org.junit.Assert.assertTrue;

import javax.naming.NamingEnumeration;import javax.naming.directory.SearchControls;import javax.naming.directory.SearchResult;import javax.naming.ldap.LdapContext;

import org.apache.directory.server.annotations.CreateLdapServer;import org.apache.directory.server.annotations.CreateTransport;import org.apache.directory.server.core.integ.AbstractLdapTestUnit;import org.apache.directory.server.core.integ.FrameworkRunner;import org.apache.directory.server.ldap.LdapServer;import org.junit.Test;import org.junit.runner.RunWith;

/** * Tests *

Page 71: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201060

The Apache Software Foundation Privacy Policy

* @author <a href="mailto:[email protected]">Apache Directory Project</a> * @version $Rev: 985583 $, $Date: 2010-08-14 23:19:48 +0200 (Sat, 14 Aug 2010) $ */@RunWith(FrameworkRunner.class)@CreateLdapServer( transports = { @CreateTransport(protocol = "LDAP") })public class SearchTests extends AbstractLdapTestUnit{ public static LdapServer ldapServer;

@Test public void testSearchAllAttrs() throws Exception { LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer, null ).lookup( "ou=system" );

SearchControls controls = new SearchControls(); controls.setSearchScope( SearchControls.ONELEVEL_SCOPE ); controls.setReturningAttributes( new String[] { "+", "*" } );

NamingEnumeration<SearchResult> res = ctx.search( "", "(ObjectClass=*)", controls );

assertTrue( res.hasMore() );

while ( res.hasMoreElements() ) { SearchResult result = ( SearchResult ) res.next();

System.out.println( result.getName() ); } }}

In order to have this test running, you will need to declare some libraries. The best solution is clearlyto define a pom.xml file for that purpose. Here it is :

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.apache.directory.server</groupId> <artifactId>apacheds-unit-test</artifactId> <version>1.5.5-SNAPSHOT</version> <name>ApacheDS Server Unit</name> <packaging>jar</packaging>

<description> Unit test for ApacheDS Server JNDI Provider </description>

<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.7</version> <scope>provided</scope> </dependency>

<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version> <scope>provided</scope> </dependency>

<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.5.10</version> <scope>provided</scope> </dependency>

<dependency> <groupId>org.apache.directory.server</groupId> <artifactId>apacheds-all</artifactId> <version>1.5.6-SNAPSHOT</version>

Page 72: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201061

The Apache Software Foundation Privacy Policy

</dependency>

<dependency> <groupId>org.apache.directory.server</groupId> <artifactId>apacheds-server-integ</artifactId> <version>1.5.6-SNAPSHOT</version> </dependency>

<dependency> <groupId>org.apache.directory.server</groupId> <artifactId>apacheds-core-integ</artifactId> <version>1.5.6-SNAPSHOT</version> </dependency>

<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>1.4</version> </dependency> </dependencies>

<build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> <configuration> <source>1.5</source> <target>1.5</target>

<optimize>true</optimize> <showDeprecations>true</showDeprecations> <encoding>ISO-8859-1</encoding> </configuration> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <argLine>-Xmx1024m</argLine> </configuration> </plugin> </plugins> </pluginManagement> </build></project>

Is that it ? Pretty much. All you have to do now is to run the test, using a Java 5 JVM and Maven 2.0.9 :

#user:~/ws-ads-1.5.4/UnitTest$ mvn test[INFO] Scanning for projects...[INFO] ------------------------------------------------------------------------[INFO] Building ApacheDS Server Unit[INFO] task-segment: [test][INFO] ------------------------------------------------------------------------[INFO] [resources:resources][INFO] Using default encoding to copy filtered resources.[INFO] [compiler:compile][INFO] No sources to compile[INFO] [resources:testResources][INFO] Using default encoding to copy filtered resources.[INFO] [compiler:testCompile][INFO] Nothing to compile - all classes are up to date[INFO] [surefire:test][INFO] Surefire report directory: /home/elecharny/ws-ads-1.5.4/UnitTest/target/surefire-reports

------------------------------------------------------- T E S T S-------------------------------------------------------Running SimpleTestlog4j:WARN No appenders could be found for logger (org.apache.directory.server.integ.SiRunner).log4j:WARN Please initialize the log4j system properly.Ldap service started.Ldap service stopped.Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.114 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

Page 73: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201062

The Apache Software Foundation Privacy Policy

[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESSFUL[INFO] ------------------------------------------------------------------------[INFO] Total time: 10 seconds[INFO] Finished at: Fri Nov 21 15:40:32 CET 2008[INFO] Final Memory: 11M/83M[INFO] ------------------------------------------------------------------------#user:~/ws-ads-1.5.4/UnitTest$

You have written your very first test using the test framework provided in ADS 1.5.5 !

Here are the test files :

• SearchTests.java [data/unit-tests/SearchTests.java]

• pom.xml [data/unit-tests/pom.xml]

5.2.2.1. Test description

Ok, we have a running test, but when it comes to write your own, you need a bit more information.Let's try to explain the different parts of this test.

5.2.2.1.1. Annotations

The first interesting part is the annotations we are using. As we said, the server is launchedautomatically, and we are using the ChangeLog mechanism to restore the base in a pristine statebetween each test. This is done with annotations.

Table 5.1. Test Annotations

Annotation Parameter Default value Description

@RunWith FrameworkRunner.class none Run the test with thedefined Runner, insteadof the default JUNITone.This is mandatory toadd this annotation, asit determinate the waythe server will be cleanwhen each test has run

@CreateLdapServer transports none Create the LdapServerthat will be used for thetests

@CreateTransports protocol none Define the transport touse

@ApplyLdifs A list of entries in aLDIF format

none This is one of the mostinteresting new feature :you can define thedata you need to bepresent when the serveris started, they willbe injected before thefirst test is run (itwill also depend on theCleanupLevel).

@ApplyLdifFiles A list of files containingLDIF entries

none Give sthe list of filesto be injected into the

Page 74: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201063

The Apache Software Foundation Privacy Policy

Annotation Parameter Default value Description

server before the testsare run.

5.2.2.1.2. Server startup

As you can see in the test, there is no place where you tell the server to be started. This is done bythe FrameworkRunner. When the tests are all done, the server is also automatically shutdown, and allthe created files are removed.

The initialization will update a static ldapServer instance which is declared in the inheritedAbstractLdapTestUnit class.

You just have to focus on writing your own tests !

5.2.2.1.3. Writing your own test using JNDI

All the LDAP operation are supported, you just have to use the JNDI API to write your tests. The onlydifference is the way you get a context : you have to use one of those methods :

/** * Creates a JNDI LdapContext with a connection over the wire using the * SUN LDAP provider. The connection is made using the administrative * user as the principalDN. The context is to the rootDSE. * * @param ldapServer the LDAP server to get the connection to * @return an LdapContext as the administrative user to the RootDSE * @throws Exception if there are problems creating the context */public static LdapContext getWiredContext( LdapServer ldapServer )

/** * Creates a JNDI LdapContext with a connection over the wire using the * SUN LDAP provider. The connection is made using the administrative * user as the principalDN. The context is to the rootDSE. * * @param ldapServer the LDAP server to get the connection to * @return an LdapContext as the administrative user to the RootDSE * @throws Exception if there are problems creating the context */public static LdapContext getWiredContext( LdapServer ldapServer, Control[] controls )

/** * Creates a JNDI LdapContext with a connection over the wire using the * SUN LDAP provider. The connection is made using the administrative * user as the principalDN. The context is to the rootDSE. * * @param ldapServer the LDAP server to get the connection to * @return an LdapContext as the administrative user to the RootDSE * @throws Exception if there are problems creating the context */public static LdapContext getWiredContext( LdapServer ldapServer, String principalDn, String password )

That's it ! Everything else is just pure JNDI

5.2.2.1.4. Writing your own tests using the Netscape API

If you don't like JNDI, or prefer to use the Netscape API (LdapSdk-4.1), you have two majordifferences :

• first you have to add this API jar into the dependencies in the pom.xml file

• second you will use the getWiredConnection() method instead of the getWiredContext().

The API is :

Page 75: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201064

The Apache Software Foundation Privacy Policy

public static LDAPConnection getWiredConnection( LdapServer ldapServer )public static LDAPConnection getWiredConnection( LdapServer ldapServer, String principalDn, String password )

Both methods are similar to the getWiredContext which has been described before, except that theyreturn a LdapConnection instance.

Starting here, the document has to be reviewed...

5.2.3. Creating our own partitionAt the moment, we have created a server which is not totally empty : one partition is created by default,the system partition. We won't use it for our tests, so we will need to create our own partition to playwith. Let's call it 'o=sevenseas' ( o stands for organization )

The setUp() method will be completed with all the needed instruction to create a new partition

import java.io.File;import java.util.HashSet;import java.util.Hashtable;import java.util.Set;

import javax.naming.Context;import javax.naming.InitialContext;import javax.naming.NamingException;import javax.naming.directory.Attribute;import javax.naming.directory.Attributes;import javax.naming.directory.BasicAttribute;import javax.naming.directory.BasicAttributes;import javax.naming.directory.DirContext;

import org.apache.directory.server.core.configuration.MutablePartitionConfiguration;import org.apache.directory.server.unit.AbstractServerTest;...

/** * Initialize the server. */ public void setUp() throws Exception { // Add partition 'sevenSeas' MutablePartitionConfiguration pcfg = new MutablePartitionConfiguration(); pcfg.setName( "sevenSeas" ); pcfg.setSuffix( "o=sevenseas" );

// Create some indices Set<String> indexedAttrs = new HashSet<String>(); indexedAttrs.add( "objectClass" ); indexedAttrs.add( "o" ); pcfg.setIndexedAttributes( indexedAttrs );

// Create a first entry associated to the partition Attributes attrs = new BasicAttributes( true );

// First, the objectClass attribute Attribute attr = new BasicAttribute( "objectClass" ); attr.add( "top" ); attr.add( "organization" ); attrs.put( attr );

// The the 'Organization' attribute attr = new BasicAttribute( "o" ); attr.add( "sevenseas" ); attrs.put( attr );

// Associate this entry to the partition pcfg.setContextEntry( attrs );

// As we can create more than one partition, we must store // each created partition in a Set before initialization Set<MutablePartitionConfiguration> pcfgs = new HashSet<MutablePartitionConfiguration>(); pcfgs.add( pcfg );

configuration.setContextPartitionConfigurations( pcfgs );

Page 76: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201065

The Apache Software Foundation Privacy Policy

// Create a working directory File workingDirectory = new File( "server-work" ); configuration.setWorkingDirectory( workingDirectory );

// Now, let's call the upper class which is responsible for the // partitions creation super.setUp(); }

Ok, now the partition sevenseas should be created. How can we be sure of that ? let's write a test toreplace the emptytest() method :

/** * Test that the partition has been correctly created */ public void testPartition() throws NamingException { Hashtable<Object, Object> env = new Hashtable<Object, Object>( configuration.toJndiEnvironment() );

// Create a new context pointing to the overseas partition env.put( Context.PROVIDER_URL, "o=sevenSeas" ); env.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" ); env.put( Context.SECURITY_CREDENTIALS, "secret" ); env.put( Context.SECURITY_AUTHENTICATION, "simple" ); env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.directory.server.jndi.ServerContextFactory" );

// Let's open a connection on this partition InitialContext initialContext = new InitialContext( env );

// We should be able to read it DirContext appRoot = ( DirContext ) initialContext.lookup( "" ); assertNotNull( appRoot );

// Let's get the entry associated to the top level Attributes attributes = appRoot.getAttributes( "" ); assertNotNull( attributes ); assertEquals( "sevenseas", attributes.get( "o" ).get() );

Attribute attribute = attributes.get( "objectClass" ); assertNotNull( attribute ); assertTrue( attribute.contains( "top" ) ); assertTrue( attribute.contains( "organization" ) ); // Ok, everything is fine }

The test should succeed. Is that all ? Well, almost. As you can see, a working space has been created( "server-work", at the end of the setup). Do we have to take care of this working space? No. It hasbeen cleaned by the super class !

So everything is fine, the partition is up and running, you are ready to add more tests.

One line in the logs is interesting :

3879 [main] INFO org.apache.directory.server.jndi.ServerContextFactory -LDIF load directory not specified. No LDIF files will be loaded.

The setup has tried to load an LDIF file to inject some data into the partition, but as we didn't specifyany Ldif file to be loaded, nothing has been done. let's add some data !

5.2.4. Adding some data into the partitionThe AbstractServerTest class provide a method called importLdif( InputStream in ) . It allows youto inject some entries into the newly created partition. How d we use it?

First, we need to have a valid LDIF file containing your entries. We will create two branches in oursevenseas organization :

• one for groups

Page 77: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201066

The Apache Software Foundation Privacy Policy

• one for people

Here is the ldif file we will create :

dn: ou=groups,o=sevenSeasobjectClass: organizationalUnitobjectClass: topou: groupsdescription: Contains entries which describe groups (crews, for instance)

dn: ou=people,o=sevenSeasobjectClass: organizationalUnitobjectClass: topou: peopledescription: Contains entries which describe persons (seamen)

Save it as a text file into a directory where we will be able to read it directly. But where?

We have created the test into a directory src/test/java/org/apache/directory/demo. This is the mavenway to organized the sources, as seen before. Let's create another directory for the resources : src/test/resources/org/apache/directory/demo. Tis is the place where we will save the ldif file.

Now, to let the server know about the ldif file, just add this line after the call to the setup() method :

... // Now, let's call the upper class which is responsible for the // partitions creation super.setUp();

// Load a demo ldif file importLdif( this.getClass().getResourceAsStream( "demo.ldif" ) ); }

This is important to add the import after the setup : you can't import data while the partitionhas not been created ...

The getResourceAsStream call will automatically read the file from the resources directory, basedon the current class package.

How can we be sure that the data has been imported ? Let's do a search request !

5.2.5. Cleanup the codeBefore that, let's do some cleanup. The context creation is something we will have to do in each test.We should create a common method called every time to avoid duplicating this code. Let's create thismethod :

/** * Create a context pointing to a partition */ private DirContext createContext( String partition ) throws NamingException { // Create a environment container Hashtable<Object, Object> env = new Hashtable<Object, Object>( configuration.toJndiEnvironment() );

// Create a new context pointing to the partition env.put( Context.PROVIDER_URL, partition ); env.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" ); env.put( Context.SECURITY_CREDENTIALS, "secret" ); env.put( Context.SECURITY_AUTHENTICATION, "simple" ); env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.directory.server.jndi.ServerContextFactory" );

// Let's open a connection on this partition InitialContext initialContext = new InitialContext( env );

// We should be able to read it DirContext appRoot = ( DirContext ) initialContext.lookup( "" );

Page 78: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201067

The Apache Software Foundation Privacy Policy

assertNotNull( appRoot );

return appRoot; }

This method is added into the body of the test class. This method is very simple and quitestraightforward : we just create an initial context pointing to the requested partition, and return adirectory context on this partition. It takes a parameter, the partition name.

Let's modify the test partition method :

/** * Test that the partition has been correctly created */ public void testPartition() throws NamingException { DirContext appRoot = createContext( "o=sevenSeas" );

// Let's get the entry associated to the top level Attributes attributes = appRoot.getAttributes( "" ); ...

We just replaced the first lines by a call to the newly created createContext() method.

If you launch the unit test, it should still be ok.

5.2.6. Searching for entriesThis is really simple. What we will do is to search for the imported entries. Let's go directly to thecode. We will add a new unit test

/** * Test that the ldif data has correctly been imported */ public void testImport() throws NamingException { // Searching for all Set<String> result = searchDNs( "(ObjectClass=*)", "o=sevenSeas", "", SearchControls.ONELEVEL_SCOPE );

assertTrue( result.contains( "ou=groups,o=sevenSeas" ) ); assertTrue( result.contains( "ou=people,o=sevenSeas" ) ); }

Here, we are looking for all the entries starting at the top level of the partition, within the level. Weshould only get two entries.

It's not enough : the searchDNs() method does not exist. It is a private method we have created toavoid duplicating some code all over the unit tests. Here is its code :

/** * Performs a single level search from a root base and * returns the set of DNs found. */ private Set<String> searchDNs( String filter, String partition, String base, int scope ) throws NamingException { DirContext appRoot = createContext( partition );

SearchControls controls = new SearchControls(); controls.setSearchScope( scope ); NamingEnumeration result = appRoot.search( base, filter, controls );

// collect all results HashSet<String> entries = new HashSet<String>();

while ( result.hasMore() ) { SearchResult entry = ( SearchResult ) result.next();

Page 79: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201068

The Apache Software Foundation Privacy Policy

entries.add( entry.getName() ); }

return entries; }

As for the test partiton, we call the createContext() method, then we just do some JNDI magic :

• creating a SearchControl,

• setting the scope,

• calling the search

• and gathering the returned DN if any

If the test is successful, you get the imported DNs !

5.2.7. Adding your own schemaThis paragraph is totally outdated. It should be rewriten from scratch !

Ok, let's go deeper into the server configuration. Working with default schema is fine, but some point,you may want to use your own ObjectClasses and AttributeTypes. let's assume you have created them,and that you have been throw the process of generating the class files for it (this process is describedin Custom Schema [http://directory.apache.org/apacheds/DIRxSRVx10/custom-schema.html] ) into anew package (org.apache.directory.demo.schema) where all the generated files will be put.

You will just have to add those lines at the end of the setUp() method (just before the call to the super()method) :

...import org.apache.directory.server.core.configuration.MutablePartitionConfiguration;import org.apache.directory.server.core.schema.bootstrap.AbstractBootstrapSchema;import org.apache.directory.server.unit.AbstractServerTest;

import org.apache.directory.demo.schema.DemoSchema;

... ... /// /// add the Demo schema /// Set<AbstractBootstrapSchema> schemas = configuration.getBootstrapSchemas(); schemas.add( new DemoSchema() );

configuration.setBootstrapSchemas(schemas);

// Now, let's call the upper class which is responsible for the // partitions creation super.setUp(); }

If we launch the test, nothing special will happen, except that the test will succeed. That's not veryimpressive...

5.2.8. ConclusionOk, this tutorial was a short one, but you get everything you need to play with Apache DirectoryServer as a Unit Test Engine for your Ldap application. Just create your own partition, defineyour schema, import your ldif file, and add all the tests you need. it's as simple as explained

Page 80: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201069

The Apache Software Foundation Privacy Policy

If you have any problem, just feel free to post a mail to [email protected], we will be thereto help !

5.2.9. ResourcesEmbedding ApacheDS - Conference Materials [http://directory.apache.org/community%26resources/embedding-apacheds.html]

5.3. Embedding ApacheDS as a WebApplication

This site was updated for ApacheDS 1.5.5.

My initial aim was to demonstrate embedding ApacheDS in a very simple, but nevertheless impressiveway. I thought about embedding the server in Apache Tomcat first. But then I got a better plan:Creating a standard web application which wraps ApacheDS and can be deployed on any compliantapplication server. ApacheDS in a war-archive!

• Section 5.3.1, “Solution Outline”

• Section 5.3.2, “Step 1: The web component which starts and stops the server”

• Section 5.3.3, “Packaging and Deploying the WebApp”

• Section 5.3.4, “Step 2: Adding functionality: A servlet which displays the Root DSE”

Although the concepts depicted below apply to all version of ApacheDS (even before 1.0),the configuration for starting and stopping the embedded server uses the style introduced withApacheDS 1.5.5. Be sure that you use this version of the server, or a later one.

5.3.1. Solution OutlineAlthough it works well, please note that this is just an example on how to embed ApacheDSin an application! If you plan to run the server as LDAP production system, this is not the firstoption to consider. Some more steps have to be done, especially in the area of configuration.

The solution is quite simple. A web application carries all the necessary jar files for ApacheDS withinthe lib-directory of the WEB-INF folder. When the web application is started by the servlet container,appropriate code has to be executed to start ApacheDS. And the server has to be stopped, if theweb application goes down (for instance if the server shuts down). There are (at least) two standardcompliant ways to acomplish this:

• A Servlet (automatically started with the web application, using the lifecycle methods init anddestroy)

• A ServletContextListener

In the following we have choosen the second option.

5.3.1.1. A Servlet Context Listener to start and stop ApacheDS

A servlet context listener receives notifications about changes to the servlet context of the webapplication it is part of. Documentation of the ServletContextListener interface can be foundhere [http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/ServletContextListener.html] .To receive notification events, the implementation class must be configured in the deploymentdescriptor for the web application. The two life cycle methods contextInitialized and contextDestroyedare suitable to start and stop ApacheDS.

Page 81: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201070

The Apache Software Foundation Privacy Policy

5.3.1.2. A client within

After the server has been started from the Listener, it will be accessible from the outside via the networkusing LDAP. In order to demonstrate how to interact with the server from within the VM, a simpleservlet is shown. It allows you to communicate with the embedded server via web browser. This is sosimple, because the server already lives within a web application, only a servlet has to added to act asan entry point. Our sample servlet will display the Root DSE of the server.

The following class diagram visualizes the complete example. The gray elements will be developedin two steps and use Servlet and ApacheDS API.

Figure 5.1. ApacheDS as a Web Application

5.3.2. Step 1: The web component which starts andstops the server

The ApacheDS core is comprised of JavaBeans components, and can easily be instantiated started andstopped with simple Java code. This is done by the following listener.

The class StartStopListener [http://svn.apache.org/repos/asf/directory/samples/trunk/apacheds-archetype-webapp/src/main/resources/archetype-resources/src/main/java/StartStopListener.java]implements ServletContextListener and therefore contains the following two life cycle methods:

• contextInitialized() is executed if the web application is started by the servlet container, it startsApacheDS embedded

Page 82: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201071

The Apache Software Foundation Privacy Policy

• contextDestroyed() is executed if the web application is stopped by the servlet container, it stopsthe embedded server

The contextInitialized method creates a DefaultDirectoryService object. It configures the LDAPprotocol and determines an appropriate working directory for the server. This directory is need topersist the partition data (entries). Our example uses a simple yet portable way for this task: the contextattribute javax.servlet.context.tempdir .

Afterwards the method starts network protocol and directory service.

Finally the DirectoryService component is stored in the application context of the web application.This is done in order to provided it to embedded clients in the same web app (see the servlet belowfor an example).

The method contextDestroyed simply stops the protocol and shuts down the service.

StartStopListener.java package org.apache.directory.samples.embed.webapp;

import java.io.File;

import javax.servlet.ServletContext;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;

import org.apache.directory.server.core.DefaultDirectoryService;import org.apache.directory.server.core.DirectoryService;import org.apache.directory.server.ldap.LdapServer;import org.apache.directory.server.protocol.shared.transport.TcpTransport;

/** * A Servlet context listener to start and stop ApacheDS. * * @author <a href="mailto:[email protected]">Apache Directory Project</a> */public class StartStopListener implements ServletContextListener{ private DirectoryService directoryService;

private LdapServer ldapServer;

/** * Startup ApacheDS embedded. */ public void contextInitialized( ServletContextEvent evt ) { try { directoryService = new DefaultDirectoryService(); directoryService.setShutdownHookEnabled( true );

ldapServer = new LdapServer(); ldapServer.setDirectoryService( directoryService ); ldapServer.setAllowAnonymousAccess( true );

// Set LDAP port to 10389 TcpTransport ldapTransport = new TcpTransport( 10389 ); ldapServer.setTransports( ldapTransport );

// Determine an appropriate working directory ServletContext servletContext = evt.getServletContext(); File workingDir = ( File ) servletContext.getAttribute( "javax.servlet.context.tempdir" ); directoryService.setWorkingDirectory( workingDir );

directoryService.startup(); ldapServer.start();

// Store directoryService in context to provide it to servlets etc. servletContext.setAttribute( DirectoryService.JNDI_KEY, directoryService ); } catch ( Exception e ) { throw new RuntimeException( e ); } }

Page 83: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201072

The Apache Software Foundation Privacy Policy

/** * Shutdown ApacheDS embedded. */ public void contextDestroyed( ServletContextEvent evt ) { try { ldapServer.stop(); directoryService.shutdown(); } catch ( Exception e ) { throw new RuntimeException( e ); } }}

5.3.2.1. Deployment descriptor

In order to execute the listener code, the class has to be defined in the deployment descriptor of a webapplication, as depicted below:

web.xml <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><web-app> <display-name>ApacheDS embedded in a WebApp</display-name> <description> A simple yet portable way to run ApacheDS within a servlet container </description>

<listener> <listener-class> org.apache.directory.samples.embed.webapp.StartStopListener </listener-class> </listener></web-app>

5.3.3. Packaging and Deploying the WebAppA standard web archive (war-File) is needed in order to deploy the application to a servlet container.The easiest way to create such a web archive including all dependencies is to use an Maven archetypewe provide.

5.3.3.1. Creating the WebApp using the ApacheDS MavenArchetype

We assume you have Java Subversion and Maven 2.0.9 installed on your system.

To use the archetype you'll need to check it out and install it to your local repository:

svn co http://svn.apache.org/repos/asf/directory/samples/trunk/apacheds-archetype-webappcd apacheds-archetype-webappmvn install

Then change to your preferred location to create the new project and execute following command:

mvn archetype:generate -DarchetypeGroupId=org.apache.directory.samples \ -DarchetypeArtifactId=apacheds-archetype-webapp \ -DarchetypeVersion=1.5.5-SNAPSHOT \ -DgroupId=org.apache.directory.samples.embed.webapp \ -DartifactId=ApacheDS -Dversion=1.0-SNAPSHOT

Page 84: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201073

The Apache Software Foundation Privacy Policy

Then change to the created directory and run the following command:

mvn package

This creates an ApacheDS.war file below the target folder.

5.3.3.2. Run on embedded Jetty

The fastest way to run the web application is to use the Maven Jetty plugin:

mvn jetty:run

5.3.3.3. Deploying on Apache Tomcat

In order to run the application within Tomcat, simply put the ApacheDS.war file in the webappsdirectory of your Tomcat installation and start the server. If you have the manager application enabled(as described here [http://tomcat.apache.org/tomcat-6.0-doc/manager-howto.html] ), you can see and"manage" (start/stop) ApacheDS within its list view:

Figure 5.2. Tomcat Manager App in Browser

5.3.3.4. Connecting to ApacheDS from the outside

ApacheDS is up and running within the servlet container. Besides the administration tool listing, itseems to be invisible. But because we have configured network access via port 10389, you can easilyaccess the server with an arbitrary LDAP client from outside.

One option is a command line tool like ldapsearch (see ApacheDS Basic User's Guide[http://directory.apache.org/apacheds/1.5/apacheds-v15-basic-users-guide.html] for details on how to

Page 85: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201074

The Apache Software Foundation Privacy Policy

connect to ApacheDS with such tools in general). Here is an example how to connect as administrator(simple bind) and fetch the Root DSE of our embedded ApacheDS instance:

$ ldapsearch -h localhost -p 10389 -D "uid=admin,ou=system" -w secret \\ -b "" -s base "(objectClass=*)" * +version: 1dn:supportedControl: 2.16.840.1.113730.3.4.3supportedControl: 2.16.840.1.113730.3.4.7supportedControl: 1.3.6.1.4.1.4203.1.10.1supportedControl: 2.16.840.1.113730.3.4.2supportedControl: 1.3.6.1.4.1.18060.0.0.1namingContexts: ou=systemnamingContexts: ou=schemasupportedLDAPVersion: 3objectClass: extensibleObjectobjectClass: topsupportedFeatures: 1.3.6.1.4.1.4203.1.5.1supportedExtension: 1.3.6.1.4.1.1466.20036subschemaSubentry: cn=schemavendorName: Apache Software FoundationvendorVersion: 1.5.4$

Another choice are graphical LDAP clients (see ApacheDS Basic User's Guide [http://directory.apache.org/apacheds/1.5/apacheds-v15-basic-users-guide.html] for details on how toconnect to ApacheDS with such tools in general).

With our popular Eclipse RCP application Directory studio [http://directory.apache.org/studio/] forinstance, connecting goes like this: In the Connections view, select "New connection ...". Within awizard dialog, you provide the connection data (host name, port, bind DN and password).

Figure 5.3. New LDAP Connection Directory Studio 1

Page 86: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201075

The Apache Software Foundation Privacy Policy

Figure 5.4. New LDAP Connection Directory Studio 2

After successfully connecting to the embedded ApacheDS, you can browse the tree, add andmanipulate entries and so on. If you check the connection properties, you can study the Root DSEas well.

Page 87: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201076

The Apache Software Foundation Privacy Policy

Figure 5.5. Properties New LDAP Connection Directory Studio

5.3.3.5. Other Web Application Servers

The web application described here has been successfully deployed on

• Apache Tomcat 5.5.20 and 6.0.18 ( Homepage [http://tomcat.apache.org/] )

• IBM WebSphere Application Server 6.1 ( Homepage [http://www.ibm.com/software/webservers/appserv/was/] )

• Jetty 6.1.0 ( Homepage [http://jetty.mortbay.org/] )

Here is a screen shot of the web based administration console of WebSphere Application Server 6.1with the ApacheDS.war deployed and running, no changes in the deployment archive were needed.

Page 88: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201077

The Apache Software Foundation Privacy Policy

Figure 5.6. WebSphere Admin Console

5.3.4. Step 2: Adding functionality: A servlet whichdisplays the Root DSE

To finish with, here is a simple example on how to access the server internally (Note: the servlet wasalready created by the maven archetype).

The following servlet, which will be deployed together with the other class in the web archive, connectsto ApacheDS directly, i.e. via the internal JNDI provider. No network access is needed. In the doGetmethod it performs a search operation against the Root DSE of the server, as the examples above do.

RootDseServlet.javapackage org.apache.directory.samples.embed.webapp;

import java.io.PrintWriter;import java.util.Hashtable;

import javax.naming.Context;import javax.naming.NamingEnumeration;import javax.naming.directory.Attribute;import javax.naming.directory.Attributes;import javax.naming.directory.DirContext;import javax.naming.directory.InitialDirContext;import javax.naming.directory.SearchControls;import javax.naming.directory.SearchResult;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;

import org.apache.directory.server.core.DirectoryService;import org.apache.directory.server.core.jndi.CoreContextFactory;

Page 89: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201078

The Apache Software Foundation Privacy Policy

/** * A servlet which displays the Root DSE of the embedded server. * * @author <a href="mailto:[email protected]">Apache Directory * Project</a> */public class RootDseServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException {

try { resp.setContentType("text/plain"); PrintWriter out = resp.getWriter();

out.println("*** ApacheDS RootDSE ***\n");

DirContext ctx = new InitialDirContext(this.createEnv());

SearchControls ctls = new SearchControls(); ctls.setReturningAttributes(new String[] { "*", "+" }); ctls.setSearchScope(SearchControls.OBJECT_SCOPE);

NamingEnumeration<SearchResult> result = ctx.search("", "(objectClass=*)", ctls); if (result.hasMore()) { SearchResult entry = result.next(); Attributes as = entry.getAttributes();

NamingEnumeration<String> ids = as.getIDs(); while (ids.hasMore()) { String id = ids.next(); Attribute attr = as.get(id); for (int i = 0; i < attr.size(); ++i) { out.println(id + ": " + attr.get(i)); } } } ctx.close();

out.flush(); } catch (Exception e) { throw new ServletException(e); } }

/** * Creates an environment configuration for JNDI access. */ protected Hashtable<Object, Object> createEnv() {

// Fetch directory servive from servlet context ServletContext servletContext = this.getServletContext(); DirectoryService directoryService = (DirectoryService) servletContext .getAttribute(DirectoryService.JNDI_KEY);

Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(DirectoryService.JNDI_KEY, directoryService); env.put(Context.PROVIDER_URL, ""); env.put(Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class .getName());

env.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system"); env.put(Context.SECURITY_CREDENTIALS, "secret"); env.put(Context.SECURITY_AUTHENTICATION, "simple");

return env; }}

In order to make the servlet available to clients, it has to be declared in the deployment descriptorweb.xml , here are the additions (a servlet named RootDseServlet for the class above, and a URLmapping)

web.xml, extended<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd">

Page 90: ApacheDS Guide

Draft Embedding ApacheDS Draft

© 2003-201079

The Apache Software Foundation Privacy Policy

<web-app>

... <servlet> <servlet-name>RootDseServlet</servlet-name> <servlet-class> org.apache.directory.samples.embed.webapp.RootDseServlet </servlet-class> </servlet>

<servlet-mapping> <servlet-name>RootDseServlet</servlet-name> <url-pattern>/RootDse</url-pattern> </servlet-mapping></web-app>

Redeploy the web application. If you point to your tomcat server with the appropriate URL ( http://localhost:8080/ApacheDS/RootDse ), you'll see the content of the Root DSE as depicted below:

Figure 5.7. RootDSE Servlet in a Browser

Page 91: ApacheDS Guide

Draft Draft

© 2003-201080

The Apache Software Foundation Privacy Policy

Chapter 6. Protocol Providers6.1. Protocol Providers

This site is in the process of being reviewed and updated.

You are viewing pre-release documentation that contains changes to configuration that arescheduled for the Apache Directory 1.5.1 release.

6.1.1. Apache Directory Protocol ProvidersThe Apache Directory Project's Protocol Providers are Java implementations of standard Internetservices. These Protocol Providers, in conjunction with the MINA network layer and the ApacheDirectory read-optimized backing store, provide easy-to-use yet fully-featured Internet services. Asimplemented within the Apache Directory, these services benefit from:

• Standard directory model and schema support

• Standard LDAP data interchange format (LDIF) (RFC 2849)

• Optional LDAP management

• UDP and TCP Support (MINA)

• Easy POJO embeddability for containers such as Geronimo, JBoss, and OSGi

6.1.2. Service ConfigurationAll protocol providers are configured in a similar manner. Behind the scenes, all protocol providerConfiguration beans inherit from the same ServiceConfiguration and, therefore, they share many ofthe same configuration parameters. For more information on the service configuration common to allprotocol providers, please see Section 6.2, “Common Parameters for Configuration” .

6.1.3. Changes from 1.5 to 1.5.1Configuration has been revamped for the 1.5.1 release, along with the addition of SASL support in theLDAP protocol. For more information on changes to configuration, please see Section 6.2.1, “Changesto Configuration”

6.1.4. Protocol Providers

Table 6.1. Protocol Providers

Name Configuration Description

Section 6.3, “LDAP ProtocolProvider”

??? A Lightweight DirectoryAccess Protocol (LDAP)implementation based on RFC2251 [http://www.faqs.org/rfcs/rfc2251.html] . Apache LDAPprovides lightweight access to theApache Directory backing store.

Section 6.4, “Kerberos ProtocolProvider”

Section 6.4.4, “KerberosProtocol Configuration”

A Kerberos implementationbased on RFC 1510 [http://

Page 92: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201081

The Apache Software Foundation Privacy Policy

Name Configuration Description

www.faqs.org/rfcs/rfc1510.html]. Apache Kerberos verifiesthe identities of principals(users or services) on anunprotected network usingprincipal information stored inthe Apache Directory backingstore.

Section 6.5, “Change PasswordProtocol Provider”

Section 6.5.3, “ChangePassword Configuration”

A Change Passwordimplementation based onRFC 3244 [http://www.faqs.org/rfcs/rfc3244.html] . ApacheChange Password uses Kerberosinfrastructure to allow users tosecurely set initial passwordsor to change existing passwordsstored in the Apache Directorybacking store.

Section 6.6, “DNS ProtocolProvider”

Section 6.6.4, “DNS ProtocolConfiguration”

A Domain Name System (DNS)implementation based on RFC1034 [http://www.faqs.org/rfcs/rfc1034.html] . Apache DNSserves host name to addressmappings and other resourcerecord types using resourcerecords stored in the ApacheDirectory backing store.

Section 6.7, “NTP ProtocolProvider”

Section 6.7.4, “NTP ProtocolConfiguration”

A Network Time Protocol (NTP)implementation based on RFC2030 [http://www.faqs.org/rfcs/rfc2030.html] . Apache NTPsupports time synchronizationfor LDAP replication and theKerberos protocol, eliminatingthe need for externalinfrastructure.

Section 6.8, “DHCP ProtocolProvider”

n/a A Dynamic Host ConfigurationProtocol (DHCP)implementation based on RFC2131 [http://www.faqs.org/rfcs/rfc2131.html] . Apache DHCPhelps configure hosts usingconfiguration information storedin the Apache Directory backingstore.

6.2. Common Parameters for ConfigurationThis site is in the process of being reviewed and updated.

6.2.1. Changes to ConfigurationThis site is in the process of being reviewed and updated.

Page 93: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201082

The Apache Software Foundation Privacy Policy

6.2.1.1. Changes to LDAP configuration in 1.5.1

LDAP and LDAPS now use separate beans for configuration. The only difference is that the use ofSSL is determined by parameter 'enabledLdaps'. Both LDAP and LDAPS must support certificateconfiguration because LDAP may use Start TLS, while LDAPS has SSL enabled "full time." BothLDAP and LDAPS follow parameter naming conventions with all the other protocol providers. So,the former ldapPort is now ipPort and the former ldapsPort is also now ipPort.

Also due to the common configuration used by all protocol providers, individual protocols are nolonger enabled in MutableServerStartupConfiguration. Instead, individual services are enabled usingthe parameter 'enabled' on their individual beans.

6.2.1.2. Changes to the other protocols in 1.5.1

All protocols except LDAP are disabled by default.

The Kerberos protocol provider is no longer configured with a Map of properties. All configurationproperties are now available on a bean and configurable using Spring XML.

The Change Password protocol provider is no longer configured with a Map of properties. Allconfiguration properties are now available on a bean and configurable using Spring XML.

The NTP protocol provider is no longer configured with a Map of properties. All configurationproperties are now available on a bean and configurable using Spring XML.

DNS has now been enabled in ServerContextFactory. The DNS protocol provider is no longerconfigured with a Map of properties. All configuration properties are now available on a bean andconfigurable using Spring XML.

6.2.2. Configuration Parameters Reference

This page lists all configuration parameters which can be used in conf/server.xml in Version 1.5.1.For a more detailed description look at the corresponding section in the Advanced User's Guide.

• Section 6.2.2.1, “Environment parameters”

• Section 6.2.2.2, “Protocol providers”

• Section 6.2.2.2.1, “Parameters common to all protocol providers”

• Section 6.3.4, “LDAP-Specific Configuration Parameters”

• Section 6.2.2.2.3, “Kerberos-Specific Configuration Parameters”

• Section 6.2.2.2.4, “Change Password-Specific Configuration Parameters”

• Section 6.2.2.2.5, “NTP-Specific configuration parameters”

• Section 6.2.2.2.6, “DHCP-Specific configuration parameters”

• Section 6.2.2.3, “Server Startup Configuration”

• Section 6.2.2.3.1, “Replication”

• Section 6.2.2.4, “Partition Configuration”

6.2.2.1. Environment parameters

Those parameters are loaded in the org.apache.directory.server.Service.java class, when the serveris started, in the init method :

Page 94: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201083

The Apache Software Foundation Privacy Policy

public void init( InstallationLayout install, String[] args ) throws Exception { ...

if ( install != null ) { log.info( "server: loading settings from ", install.getConfigurationFile() ); ... env = ( Properties ) factory.getBean( "environment" ); ...

They are used everywhere in the server.

The "environment" bean is read from the Spring configuration file, server.xml , shown below :

<bean id="environment" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="properties"> <props> <!-- JNDI security properties used to get initial contexts. --> <prop key="java.naming.security.authentication">simple</prop> <prop key="java.naming.security.principal">uid=admin,ou=system</prop> <prop key="java.naming.security.credentials">secret</prop> <!-- <prop key="java.naming.ldap.attributes.binary"></prop> --> </props> </property> </bean>

The bean name ("environment") may be renamed to something more explicit, like"serverEnvironment", IMHO

Table 6.2. Environment parameters

Parameter Default value Description Comment

java.naming.security.authenticationsimple The kind ofauthentication used forthe admin.

Shouldn't it be SASLnow ?

java.naming.security.principaluid=admin,ou=system The admin DN Can be changed toanother DN

java.naming.security.credentialssecret The principal password must be changed atstartup!!!

java.naming.ldap.attributes.binaryempty The list of binaryattributes

In LDAP, only a few ATare declared as binary.This is were we shoulddescribe the other ones

The admin password should be changed when the server is started. A good thing would be thatthe server cannot start if this password is kept as is.

6.2.2.2. Protocol providers

6.2.2.2.1. Parameters common to all protocol providers

Since all protocol provider Configuration beans inherit from the same ServiceConfiguration, theyshare many of the same configuration parameters.

Table 6.3. Parameters common to all protocol providers

Parameter Default value Description

enabled false Whether this service is enabled.

Page 95: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201084

The Apache Software Foundation Privacy Policy

Parameter Default value Description

ipPort No default. The IP port for this service.

ipAddress No default. The IP address for this service.

searchBaseDn "ou=users,ou=system" The single location where usersthat can be SASL authenticatedare stored. <to be clarified> Thedefinition of "entries" dependson the protocol. For example,for LDAP, Kerberos, and ChangePassword, entries are usersfor purposes of authentication.For DNS, entries are resourcerecords. If this property is notset the store will search thesystem partition configuration forcatalog entries. Catalog supportis highly experimental and isonly tested in the OSGi buildof ApacheDS using the ConfigAdmin service.<to be clarified/>

This last parameter has been included with the last SASL addition. The description is not givinga lot of information about what is this parameter about, except for SASL authentication. Theparameter name is not significant, and another one should be selected, IMHO.

Can soemone elaborate what this parameter is about ?

Table 6.4. Parameters common to all protocol providers 1

Parameter Default value Description

initialContextFactory "org.apache.directory.server.core.jndi.CoreContextFactory"The JNDI initial context factoryto use.

securityAuthentication "simple" The authentication mechanismto use for establishing a JNDIcontext.

securityPrincipal "uid=admin,ou=system" The principal to use forestablishing a JNDI context.

securityCredentials "secret" The credentials to use forestablishing a JNDI context.

serviceName No default. The friendly name of this service.

servicePid No default. The PID for this service. A PID isa unique identifier for an instanceof a service. PID's are used byOSGi's Config Admin service todynamically inject configurationinto a service when the service isstarted.

bufferSize No default. The MINA buffer size for thisservice.

catalogBaseDn No default. The single location where catalogentries are stored. A catalog entryis a mapping of a realm (or zonefor DNS) to a search base DN. Ifthis property is not set the store

Page 96: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201085

The Apache Software Foundation Privacy Policy

Parameter Default value Description

will expect a single search baseDN to be set. Catalog supportis highly experimental and isonly tested in the OSGi buildof ApacheDS using the ConfigAdmin service.

It would be good to have more insight about catalogs.

6.2.2.2.2. LDAP-Specific Configuration Parameters

We have had a lot of modification in this part. Some of them are really going in theright direction, some other needs to be tuned. First, all the previous configuration hasbeen moved from the common part to a specific LdapConfiguration part : that is a goodmove Second, we now have a new configuration called "ldapsConfiguration", but I'm afraidthat some informations are missing. Third, I don't know if we should have only oneconfiguration called "ldapConfiguration", or three ("ldapConfiguration", "ldapsConfiguration"and" ldapSASLConfiguration". Atm, we have two.

Here is the latest version of the ldap configuration :

<bean id="ldapConfiguration" class="org.apache.directory.server.ldap.LdapConfiguration"> <!-- The port to run the LDAP protocol on. --> <property name="ipPort" value="10389" />

<!-- Whether to allow anonymous access. --> <property name="allowAnonymousAccess" value="false" /> <!-- The list of supported authentication mechanisms. --> <property name="supportedMechanisms"> <list> <value>SIMPLE</value> <value>CRAM-MD5</value> <value>DIGEST-MD5</value> <!--<value>GSSAPI</value>--> </list> </property> <!-- The FQDN of this SASL host, validated during SASL negotiation. --> <property name="saslHost" value="ldap.example.com" /> <!-- The Kerberos principal name for this LDAP service, used by GSSAPI. --> <property name="saslPrincipal" value="ldap/[email protected]" /> <!-- The desired quality-of-protection, used by DIGEST-MD5 and GSSAPI. --> <property name="saslQop"> <list> <value>auth</value> <value>auth-int</value> <value>auth-conf</value> </list> </property> <!-- The realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI. --> <property name="saslRealms"> <list> <value>example.com</value> <value>apache.org</value> </list> </property> <!-- The base DN containing users that can be SASL authenticated. --> <property name="searchBaseDn" value="ou=users,ou=system" /> <!-- SSL CONFIG CAN GO HERE--> <!-- limits searches by non-admin users to a max time of 15000 --> <!-- milliseconds and has a default value of 10000 --> <property name="maxTimeLimit" value="15000" />

<!-- limits searches to max size of 1000 entries: default value is 100 -->

Page 97: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201086

The Apache Software Foundation Privacy Policy

<property name="maxSizeLimit" value="1000" />

<!-- the collection of extended operation handlers to install --> <property name="extendedOperationHandlers"> <list> <!--<bean class="org.apache.directory.server.ldap.support.starttls.StartTlsHandler"/>--> <bean class="org.apache.directory.server.ldap.support.extended.GracefulShutdownHandler"/>

<bean class="org.apache.directory.server.ldap.support.extended.LaunchDiagnosticUiHandler"/> </list> </property> </bean>

Table 6.5. LDAP-Specific Configuration Parameters 1

Parameter Default value Description Comments

ipPort 10389 The IP port used by theldap server

We are using a portabove 1024 to allow nonroot users to launch theserver

allowAnonymousAccess false Whether to allowanonymous access

Was true in theprevious version

supportedMechanisms SIMPLE, CRAM-MD5,DIGEST-MD5

The supportedauthenticationmechanisms

The GSSAPImechanism has beentemporarilly disabled

We have to figure out if we should reactivate this GSSAPI configuration, or not. Not a simplematter, right now. If SASL is to be moved to another configuration, then maybe it should beactivated as a default value. TO BE DISCUSSED...

Table 6.6. LDAP-Specific Configuration Parameters 2

Parameter Default value Description Comments

saslHost ldap.example.com The name of this host,validated during SASLnegotiation.

The host name mustbe selected with greatcaution

saslPrincipal ldap/[email protected]

The service principal,used by GSSAPI.

saslQop auth, auth-int, auth-conf The quality ofprotection (QoP), usedby DIGEST-MD5 andGSSAPI.

saslRealms example.com The list of realmsserviced by this host.

maxSizeLimit 100 The maximum sizelimit.

maxTimeLimit 10000 The maximum timelimit.

enableLdaps false Whether LDAPS isenabled.

ldapsCertificateFile server-work/certificates/server.cert

The path to thecertificate file.

ldapsCertificatePasswordchangeit The certificatepassword.

extendedOperationHandlersNo default. The extended operationhandlers.

Page 98: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201087

The Apache Software Foundation Privacy Policy

6.2.2.2.3. Kerberos-Specific Configuration Parameters

<bean id="kdcConfiguration" class="org.apache.directory.server.kerberos.kdc.KdcConfiguration"> <!-- Whether to enable the Kerberos protocol. --> <property name="enabled" value="false" /> <!-- The port to run the Kerberos protocol on. --> <property name="ipPort" value="88" /></bean>

Table 6.7. Kerberos-Specific Configuration Parameters

Parameter Default value Description

encryptionTypes des-cbc-md5 The encryption types.

primaryRealm EXAMPLE.COM The primary realm.

servicePrincipal krbtgt/[email protected]

The service principal name.

allowableClockSkew 5 minutes The allowable clock skew.

paEncTimestampRequired true Whether pre-authentication byencrypted timestamp is required.

maximumTicketLifetime 1440 (24 hours) The maximum ticket lifetime.

maximumRenewableLifetime 10080 (1 week) The maximum renewablelifetime.

emptyAddressesAllowed true Whether ticket issuance forempty Host Addresses is allowed.

forwardableAllowed true Whether forwardable tickets areallowed.

proxiableAllowed true Whether proxiable tickets areallowed.

postdateAllowed true Whether postdated tickets areallowed.

renewableAllowed true Whether renewable tickets areallowed.

6.2.2.2.4. Change Password-Specific Configuration Parameters

<bean id="changePasswordConfiguration" class="org.apache.directory.server.changepw.ChangePasswordConfiguration"> <!-- Whether to enable the Change Password protocol. --> <property name="enabled" value="false" /> <!-- The port to run the Change Password protocol on. --> <property name="ipPort" value="464" /></bean>

Table 6.8. Change Password-Specific Configuration Parameters

Parameter Default value Description

encryptionTypes des-cbc-md5 The encryption types.

primaryRealm EXAMPLE.COM The primary realm.

servicePrincipal kadmin/[email protected]

The service principal name.

allowableClockSkew 5 minutes The allowable clock skew.

emptyAddressesAllowed true Whether tickets issued withempty Host Addresses areallowed.

Page 99: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201088

The Apache Software Foundation Privacy Policy

Parameter Default value Description

policyPasswordLength 6 characters The policy for minimumpassword length.

policyCategoryCount 3 (out of 4) The policy for number ofcharacter categories required (A- Z), (a - z), (0 - 9), non-alphanumeric (!, $, #, %, ... ).

policyTokenSize 3 characters The policy for minimumtoken size. Passwords mustnot contain tokens larger than'policyTokenSize' that occur inthe user's principal name.

6.2.2.2.5. NTP-Specific configuration parameters

The NTP parameters are very limited :

<bean id="ntpConfiguration" class="org.apache.directory.server.ntp.NtpConfiguration"> <!-- Whether to enable the NTP protocol. --> <property name="enabled" value="true" />

<!-- The port to run the NTP protocol on. --> <property name="ipPort" value="123" /></bean>

Here is the table containing the default configuration :

Table 6.9. NTP-Specific configuration parameters

Parameter Default value Description Comments

enabled true Tells if the service is onor off

Should be OFF bydefault

ipPort 123 The default port

Just wanted to know if the UDP and TCP should be enabled or if the server just accept TCP ?

6.2.2.2.6. DHCP-Specific configuration parameters

There is no description about DHCP parameters atm.

6.2.2.3. Server Startup Configuration

6.2.2.3.1. Replication

<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration"> <property name="name" value="replicationService" /> <property name="interceptor"> <bean class="org.apache.directory.mitosis.service.ReplicationService"> <property name="configuration"> <bean class="org.apache.directory.mitosis.configuration.ReplicationConfiguration"> <property name="replicaId"> <bean class="org.apache.directory.mitosis.common.ReplicaId"> <constructor-arg> <value>instance_a</value> </constructor-arg> </bean> </property> <property name="serverPort" value="10390" /> <property name="peerReplicas" value="instance_b@localhost:10392" /> </bean> </property> </bean>

Page 100: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201089

The Apache Software Foundation Privacy Policy

</property></bean>

Table 6.10. Replication Startup Configuration

Parameter Default value Description Comments

6.2.2.4. Partition Configuration

TODO ???

6.3. LDAP Protocol ProviderThis site is in the process of being reviewed and updated.

LDAP Protocol configuration is currently being revamped in the SASL branch, as part ofmaking SASL configurable.

6.3.1. BeforePreviously, LDAP protocol configuration existed in the MutableServerStartupConfiguration, alongwith Core and Partition configuration.

<bean id="configuration" class="org.apache.directory.server.configuration.MutableServerStartupConfiguration"> <property name="ldapPort" value="389" /> <property name="allowAnonymousAccess" value="false" />

<!-- limits searches by non-admin users to a max time of 15000 --> <!-- milliseconds and has a default value of 10000 --> <property name="maxTimeLimit" value="15000" />

<!-- limits searches to max size of 1000 entries: default value is 100 --> <property name="maxSizeLimit" value="1000" />

<property name="extendedOperationHandlers"> <list> <bean class="org.apache.directory.server.ldap.support.starttls.StartTlsHandler"/> <bean class="org.apache.directory.server.ldap.support.extended.GracefulShutdownHandler"/> <bean class="org.apache.directory.server.ldap.support.extended.LaunchDiagnosticUiHandler"/> </list> </property> </bean>

6.3.2. AfterAt the same time as the addition of numerous configuration parameters for SASL, LDAP protocolconfiguration has all moved to an LdapConfiguration bean.

<bean id="ldapConfiguration" class="org.apache.directory.server.ldap.LdapConfiguration"> <!-- The port to run the LDAP protocol on. --> <property name="ipPort" value="389" /> <!-- Whether to allow anonymous access. --> <property name="allowAnonymousAccess" value="true" /> <!-- BEGIN NEW SASL CONFIG --> <!-- The list of supported authentication mechanisms. --> <property name="supportedMechanisms"> <list> <value>SIMPLE</value> <value>CRAM-MD5</value> <value>DIGEST-MD5</value> <value>GSSAPI</value>

Page 101: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201090

The Apache Software Foundation Privacy Policy

</list> </property> <!-- The FQDN of this SASL host, validated during SASL negotiation. --> <property name="saslHost" value="ldap.example.com" /> <!-- The Kerberos principal name for this LDAP service, used by GSSAPI. --> <property name="saslPrincipal" value="ldap/[email protected]" /> <!-- The desired quality-of-protection, used by DIGEST-MD5 and GSSAPI. --> <property name="saslQop"> <list> <value>auth</value> <value>auth-int</value> <value>auth-conf</value> </list> </property> <!-- The realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI. --> <property name="saslRealms"> <list> <value>example.com</value> <value>apache.org</value> </list> </property> <!-- The base DN containing users that can be SASL authenticated. --> <property name="searchBaseDn" value="ou=users,dc=example,dc=com" /> <!-- END NEW SASL CONFIG --> <!-- SSL CONFIG CAN GO HERE--> <!-- limits searches by non-admin users to a max time of 15000 --> <!-- milliseconds and has a default value of 10000 --> <property name="maxTimeLimit" value="15000" /> <!-- limits searches to max size of 1000 entries: default value is 100 --> <property name="maxSizeLimit" value="1000" /> <!-- the collection of extended operation handlers to install --> <property name="extendedOperationHandlers"> <list> <bean class="org.apache.directory.server.ldap.support.starttls.StartTlsHandler"/> <bean class="org.apache.directory.server.ldap.support.extended.GracefulShutdownHandler"/> <bean class="org.apache.directory.server.ldap.support.extended.LaunchDiagnosticUiHandler"/> </list> </property> </bean>

The LdapConfiguration bean is subordinate to the MutableServerStartupConfiguration.

<bean id="configuration" class="org.apache.directory.server.configuration.MutableServerStartupConfiguration"> ... <property name="ldapConfiguration" ref="ldapConfiguration" /> ...</bean>

6.3.3. Common Service Configuration Parameters

Table 6.11. Common Service Configuration Parameters

Parameter Default value Description

enabled true Whether this service is enabled.

ipPort 389 The IP port for this service.

ipAddress No default. The IP address for this service.

searchBaseDn "ou=users,dc=example,dc=com" The single location where usersare stored. If this property isnot set the store will search thesystem partition configuration forcatalog entries. Catalog supportis highly experimental and is

Page 102: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201091

The Apache Software Foundation Privacy Policy

Parameter Default value Description

only tested in the OSGi buildof ApacheDS using the ConfigAdmin service.

initialContextFactory "org.apache.directory.server.core.jndi.CoreContextFactory"The JNDI initial context factoryto use.

securityAuthentication "simple" The authentication mechanismto use for establishing a JNDIcontext.

securityPrincipal "uid=admin,ou=system" The principal to use forestablishing a JNDI context.

securityCredentials secret The credentials to use forestablishing a JNDI context.

serviceName Apache LDAP Service The friendly name of this service.

servicePid org.apache.directory.server.ldap The PID for this service. A PID isa unique identifier for an instanceof a service. PID's are used byOSGi's Config Admin service todynamically inject configurationinto a service when the service isstarted.

catalogBaseDn No default. The single location where catalogentries are stored. A catalog entryis a mapping of a realm (or zonefor DNS) to a search base DN. Ifthis property is not set the storewill expect a single search baseDN to be set. Catalog supportis highly experimental and isonly tested in the OSGi buildof ApacheDS using the ConfigAdmin service.

6.3.4. LDAP-Specific Configuration Parameters

Table 6.12. LDAP-Specific Configuration Parameters

Parameter Default value Description

allowAnonymousAccess true Whether to allow anonymousaccess.

maxSizeLimit 100 The maximum size limit.

maxTimeLimit 10000 The maximum time limit.

enableLdaps false Whether LDAPS is enabled.

ldapsCertificateFile server-work/certificates/server.cert

The path to the certificate file.

ldapsCertificatePassword changeit The certificate password.

extendedOperationHandlers No default. The extended operation handlers.

supportedMechanisms SIMPLE, CRAM-MD5,DIGEST-MD5, GSSAPI

The supported authenticationmechanisms.

saslHost ldap.example.com The name of this host, validatedduring SASL negotiation.

Page 103: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201092

The Apache Software Foundation Privacy Policy

Parameter Default value Description

saslPrincipal ldap/[email protected]

The service principal, used byGSSAPI.

saslQop auth, auth-int, auth-conf The quality of protection (QoP),used by DIGEST-MD5 andGSSAPI.

saslRealms example.com The list of realms serviced by thishost.

6.3.5. More InformationFor help with more advanced configurations, check out our Interoperability Guide [http://cwiki.apache.org/confluence/pages/viewpage.action?spaceKey=DIRxSRVx10&title=Interoperability] .

6.4. Kerberos Protocol ProviderThis site is in the process of being reviewed and updated.

• ???

• Section 6.4.5, “Kerberos and Unlimited Strength Policy”

• Section 6.4.6, “Kerberos in ApacheDS 1.5.5”

6.4.1. IntroductionThe Kerberos provider for Apache Directory implements RFC 1510 [http://www.ietf.org/rfc/rfc1510.txt] , the Kerberos V5 Network Authentication Service. The purpose of Kerberos is to verifythe identities of principals (users or services) on an unprotected network. While generally thoughtof as a single-sign-on technology, Kerberos' true strength is in authenticating users without eversending their password over the network. Kerberos is designed for use on open (untrusted) networksand, therefore, operates under the assumption that packets traveling along the network can be read,modified, and inserted at will. This chart [http://www.computerworld.com/computerworld/records/images/pdf/kerberos_chart.pdf] provides a good description of the protocol workflow.

Kerberos is named for the three-headed dog that guards the gates to Hades. The three heads are theclient, the Kerberos server, and the network service being accessed.

The Apache Directory Kerberos provider is implemented as a protocol-provider plugin. As a plugin,the Kerberos provider leverages Apache Directory's MINA for front-end services and the ApacheDirectory read-optimized backing store via JNDI for persistent directory services.

The Kerberos provider for Apache Directory, in conjunction with MINA and the Apache Directorystore, provides an easy-to-use yet fully-featured network authentication service. As implementedwithin the Apache Directory, the Kerberos provder will provide:

• Authentication service (RFC 1510)

• Ticket-granting service (RFC 1510)

• Pre-authentication support (RFC 1510)

• DES encryption systems (RFC 1510)

• Triple-DES (DES3) encryption systems

• UDP and TCP Support (MINA)

Page 104: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201093

The Apache Software Foundation Privacy Policy

• Easy POJO embeddability for containers such as Geronimo, JBoss, and OSGi

6.4.2. More InformationFor help with Kerberos client configurations, check out our Interoperability Guide [http://cwiki.apache.org/DIRxINTEROP] .

6.4.3. Resources

6.4.3.1. Kerberos Articles

• Centralized Authentication with Kerberos 5, Part I [http://www.linuxjournal.com/article/7336]

• Centralized Authorization Using a Directory Service, Part II [http://www.linuxjournal.com/article/7334]

6.4.3.2. Microsoft Interoperability

• HTTP-Based Cross-Platform Authentication via the Negotiate Protocol [http://msdn.microsoft.com/library/default.asp?url=%2Flibrary%2Fen-us%2Fdnsecure%2Fhtml%2Fhttp-sso-2.asp]

• RFC 2478 - The Simple and Protected GSS-API Negotiation Mechanism

6.4.3.3. Standards

• Encryption and Checksum Specifications for Kerberos 5 [http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-crypto-07.txt]

• Key Derivation for Kerberos V5 [http://mirrors.isc.org/pub/www.watersprings.org/pub/id/draft-ietf-cat-kerb-key-derivation-00.txt]

• Key Derivation for Authentication, Integrity, and Privacy [http://mirrors.isc.org/pub/www.watersprings.org/pub/id/draft-horowitz-key-derivation-00.txt]

• RFC 1510 - The Kerberos Network Authentication Service (V5) [http://www.faqs.org/rfcs/rfc1510.html]

• RFC 1964 - The Kerberos Version 5 GSS-API Mechanism [http://www.faqs.org/rfcs/rfc1964.html]

• Simplify enterprise Java authentication with single sign-on [http://www-106.ibm.com/developerworks/java/library/j-gss-sso/]

• Lock down J2ME applications with Kerberos, Part 1: Introducing Kerberos data formats [http://www-106.ibm.com/developerworks/wireless/library/wi-kerberos/]

• Lock down J2ME applications with Kerberos, Part 2: Authoring a request for a Kerberos ticket[http://www-106.ibm.com/developerworks/wireless/library/wi-kerberos2.html]

• Lock down J2ME applications with Kerberos, Part 3: Establish secure communication with an e-bank [http://www-106.ibm.com/developerworks/wireless/library/wi-kerberos3/]

6.4.4. Kerberos Protocol ConfigurationThis site is in the process of being reviewed and updated.

6.4.4.1. Before

Previously, Kerberos protocol configuration existed in a PropertiesFactoryBean, along with JNDIenvironment properties.

Page 105: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201094

The Apache Software Foundation Privacy Policy

<bean id="environment" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="properties"> <props> <prop key="java.naming.security.authentication">simple</prop> <prop key="java.naming.security.principal">uid=admin,ou=system</prop> <prop key="java.naming.security.credentials">secret</prop> <prop key="kdc.entryBaseDn">ou=users,dc=example,dc=com</prop> <prop key="kdc.java.naming.security.credentials">secret</prop> </props> </property></bean>

6.4.4.2. After

At the same time as the addition of numerous configuration parameters for SASL to the LDAPprotocol, Kerberos configuration has all moved to a KdcConfiguration bean.

<bean id="kdcConfiguration" class="org.apache.directory.server.kerberos.kdc.KdcConfiguration"> <!-- The port to run the Kerberos protocol on. --> <property name="ipPort" value="88" /></bean>

The KdcConfiguration bean is subordinate to the MutableServerStartupConfiguration.

<bean id="configuration" class="org.apache.directory.server.configuration.MutableServerStartupConfiguration"> ... <property name="kdcConfiguration" ref="kdcConfiguration" /> ...</bean>

6.4.4.3. Common Service Configuration Parameters

Table 6.13. Common Service Configuration Parameters

Parameter Default value Description

enabled false Whether this service is enabled.

ipPort 88 The IP port for this service.

ipAddress No default. The IP address for this service.

searchBaseDn "ou=users,dc=example,dc=com" The single location whereprincipals are stored. If thisproperty is not set the storewill search the system partitionconfiguration for catalog entries.Catalog support is highlyexperimental and is onlytested in the OSGi build ofApacheDS using the ConfigAdmin service.

initialContextFactory "org.apache.directory.server.core.jndi.CoreContextFactory"The JNDI initial context factoryto use.

securityAuthentication "simple" The authentication mechanismto use for establishing a JNDIcontext.

securityPrincipal "uid=admin,ou=system" The principal to use forestablishing a JNDI context.

securityCredentials "secret" The credentials to use forestablishing a JNDI context.

Page 106: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201095

The Apache Software Foundation Privacy Policy

Parameter Default value Description

serviceName Apache Kerberos Service The friendly name of this service.

servicePid org.apache.kerberos The PID for this service. A PID isa unique identifier for an instanceof a service. PID's are used byOSGi's Config Admin service todynamically inject configurationinto a service when the service isstarted.

catalogBaseDn No default. The single location where catalogentries are stored. A catalog entryis a mapping of a realm (or zonefor DNS) to a search base DN. Ifthis property is not set the storewill expect a single search baseDN to be set. Catalog supportis highly experimental and isonly tested in the OSGi buildof ApacheDS using the ConfigAdmin service.

6.4.4.4. Kerberos-Specific Configuration Parameters

Table 6.14. Kerberos-Specific Configuration Parameters

Parameter Default value Description

encryptionTypes des-cbc-md5 The encryption types.

primaryRealm EXAMPLE.COM The primary realm.

servicePrincipal krbtgt/[email protected]

The service principal name.

allowableClockSkew 5 minutes The allowable clock skew.

paEncTimestampRequired true Whether pre-authentication byencrypted timestamp is required.

maximumTicketLifetime 1440 (24 hours) The maximum ticket lifetime.

maximumRenewableLifetime 10080 (1 week) The maximum renewablelifetime.

emptyAddressesAllowed true Whether ticket issuance forempty Host Addresses is allowed.

forwardableAllowed true Whether forwardable tickets areallowed.

proxiableAllowed true Whether proxiable tickets areallowed.

postdateAllowed true Whether postdated tickets areallowed.

renewableAllowed true Whether renewable tickets areallowed.

6.4.4.5. More Information

For help with more advanced configurations, check out our Interoperability Guide [http://cwiki.apache.org/DIRxINTEROP] .

Page 107: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201096

The Apache Software Foundation Privacy Policy

6.4.5. Kerberos and Unlimited Strength PolicyThis site is in the process of being reviewed and updated.

6.4.5.1. Introduction

Due to export control restrictions, JDK 5.0 environments do not ship with support for AES-256enabled. Kerberos uses AES-256 in the 'aes256-cts-hmac-sha1-96' encryption type. To enableAES-256, you must download "unlimited strength" policy JAR files for your JRE. Policy JAR filesare signed by the JRE vendor so you must download policy JAR files for Sun, IBM, etc. separately.Also, policy files may be different for each platform, such as i386, Solaris, or HP.

6.4.5.2. Installation

1. Download the unlimited strength policy JAR files.

Table 6.15. Download the unlimited strength policy JAR files

Vendor Link Details

IBM IBM Security information[http://www.ibm.com/developerworks/java/jdk/security/50/]

Scroll down to "IBM SDKPolicy files." The same files areused for the Version 1.4 andVersion 5 SDKs.

Sun Java SE Downloads -Previous Release - JDK5 [http://java.sun.com/javase/downloads/index_jdk5.jsp]

Scroll down to "JavaCryptography Extension (JCE)Unlimited Strength JurisdictionPolicy Files 5.0" under "OtherDownloads"

2. Extract the unlimited strength policy JAR files.

Table 6.16. Extract the unlimited strength policy JAR files

File Description

local_policy.jar Unlimited strength local policy file

US_export_policy.jar Unlimited strength US export policy file

3. Install the unlimited strength policy JAR files by copying them to the standard location. <jre-home>refers to the directory where the J2SE Runtime Environment (JRE) was installed. Adjust pathnameseparators for your environment.

Table 6.17. Install the unlimited strength policy JAR files

Standard Location Platform

<jre-home>/lib/security Solaris

<jre-home>\lib\security Win32

4. Optionally, create subfolders in <jre-home>/lib/security, named, for example, "limited" and"unlimited" so you can switch between policy files easily, by copying the policy JAR files fromone of the subfolders to the <jre-home>/lib/security directory.

6.4.6. Kerberos in ApacheDS 1.5.5This site was updated for ApacheDS 1.5.5.

Page 108: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201097

The Apache Software Foundation Privacy Policy

6.4.6.1. Overview

This page shows how to activate and setup the KDC server of ApacheDS 1.5.5 (build from trunk2009-08-04). This is a very simple setup (host: localhost, realm: EXAMPLE.COM). Need to checkthe setup for other hosts and realms...

6.4.6.2. Activate Kerberos

Acivate the keyDerivationInterceptor and the kdcServer. Also set saslHost and saslPrincipal tolocalhost. Add entries for users not before you have activated those elements, otherwise the krb5Keywon't be created!

server.xml

<spring:beans ...> <defaultDirectoryService ...> ... <interceptors> ... <keyDerivationInterceptor/> ... </interceptors> </defaultDirectoryService> ...

<!-- +============================================================+ | Kerberos server configuration | +============================================================+ --> <kdcServer id="kdcServer" searchBaseDn="ou=Users,dc=example,dc=com"> <transports> <tcpTransport port="60088" nbThreads="4" backLog="50"/> <udpTransport port="60088" nbThreads="4" backLog="50"/> </transports> <directoryService>#directoryService</directoryService> </kdcServer>

...

<ldapServer ... saslHost="localhost" saslPrincipal="ldap/[email protected]" searchBaseDn="ou=users,dc=example,dc=com" ...> ...

</spring:beans>

Here is a complete server.xml: server.xml [data/server.xml]

6.4.6.3. Optional: Logging

Configure debug level logging in log4j.properties:

log4j.logger.org.apache.directory.server.kerberos=DEBUG

6.4.6.4. Restart the Server

Restart the server, you should see the following output:

Starting the Kerberos server _ _ _ __ ____ ___ / \ _ __ ___ ___| |__ ___| |/ /| _ \ / __| / _ \ | '_ \ / _` |/ __| '_ \ / _ \ ' / | | | / / / ___ \| |_) | (_| | (__| | | | __/ . \ | |_| \ \__ /_/ \_\ .__/ \__,_|\___|_| |_|\___|_|\_\|____/ \___| |_|

Page 109: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201098

The Apache Software Foundation Privacy Policy

[19:28:03] INFO [org.apache.directory.server.kerberos.kdc.KdcServer] - Kerberos service started.Kerberos service started.Kerberos server started

6.4.6.5. Load User Data

Load the following data into the server, e.g. using Apache Directory Studio: kdc-data.ldif [data/kdc-data.ldif]

Note: The activated keyDerivationInterceptor automatically creates the krb5Key attributes:

Figure 6.1. The activated keyDerivationInterceptor automatically creates thekrb5Key attributes

6.4.6.6. Authenticate using kinit (Unix/Linux)

Make sure kinit is installed.

A minimal /etc/krb5.conf file looks as follows (make sure the port matches!):

[libdefaults] default_realm = EXAMPLE.COM

[realms] EXAMPLE.COM = { kdc = localhost:60088 }

[domain_realm] .example.com = EXAMPLE.COM example.com = EXAMPLE.COM

[login] krb4_convert = true krb4_get_tickets = false

Then try to authenticate, password is 'secret':

stefan@r61:~$ kinit [email protected] for [email protected]:

stefan@r61:~$ klist

Page 110: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-201099

The Apache Software Foundation Privacy Policy

Ticket cache: FILE:/tmp/krb5cc_1000Default principal: [email protected]

Valid starting Expires Service principal08/04/09 19:54:22 08/05/09 19:54:21 krbtgt/[email protected]

Kerberos 4 ticket cache: /tmp/tkt1000klist: You have no tickets cached

6.4.6.7. Authenticate using Apache Directory Studio

You can also configure Apache Directory Studio to use Kerberos (GSSAPI) for authentication. If youuse the following authentication parameters you don't need to configure any Kerberos settings in yournative operating system.

Figure 6.2. Authenticate using Apache Directory Studio

6.5. Change Password Protocol Provider

6.5.1. IntroductionThe Change Password service is a protocol provider that implements RFC 3244 [http://www.faqs.org/rfcs/rfc3244.html] to service Kerberos Change Password and Set Password Protocol requests. ChangePassword is a request-reply protocol that uses Kerberos infrastructure to allow users to securely setinitial passwords or to change existing passwords. The Change Password protocol interoperates with

Page 111: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-2010100

The Apache Software Foundation Privacy Policy

the original Kerberos Change Password protocol, while adding the ability for an administrator to seta password for a new user.

The Change Password service is implemented as a protocol-provider plugin for the Apache Directoryserver. As a plugin, Change Password leverages Apache MINA for front-end services and the ApacheDirectory read-optimized backing store via JNDI for persistent directory services.

Change Password, in conjunction with MINA and the Apache Directory, provides an easy-to-use yetfully-featured password service. As implemented within the Apache Directory, Change Password willprovide:

• Original Kerberos password changing service

• Initial password setting service (RFC 3244)

• Optional LDAP management

• UDP and TCP Support (MINA)

• Easy POJO embeddability for containers such as Geronimo, JBoss, and OSGi

6.5.2. Changing Passwords with Windows 2003

6.5.2.1. Configure the Windows 2003 workstation to use anApache Change Password server

C:> Ksetup /addkpasswd REALM.EXAMPLE.COM kdc.realm.example.com

6.5.2.2. Change a password using Windows Security

1. After logging on, press CTRL+ALT+DEL.

Figure 6.3. Windows Security

2. Click on the button labeled "Change Password ..."

3. Enter the Old Password and New Password (twice) and click OK.

Page 112: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-2010101

The Apache Software Foundation Privacy Policy

Figure 6.4. Windows Change Password

6.5.2.3. Or change a password using the Command Prompt

C:> Ksetup /domain /changepassword <old-password> <new-password>

6.5.3. Change Password ConfigurationThis site is in the process of being reviewed and updated.

6.5.3.1. Before

Previously, Change Password protocol configuration existed in a PropertiesFactoryBean, along withJNDI environment properties.

<bean id="environment" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="properties"> <props> <prop key="java.naming.security.authentication">simple</prop> <prop key="java.naming.security.principal">uid=admin,ou=system</prop> <prop key="java.naming.security.credentials">secret</prop> <prop key="changepw.entryBaseDn">ou=users,dc=example,dc=com</prop> <prop key="changepw.java.naming.security.credentials">secret</prop> </props> </property></bean>

6.5.3.2. After

At the same time as the addition of numerous configuration parameters for SASL to the LDAPprotocol, Change Password configuration has all moved to a ChangePasswordConfiguration bean.

<bean id="changePasswordConfiguration" class="org.apache.directory.server.changepw.ChangePasswordConfiguration"> <!-- Whether to enable the Change Password protocol. --> <property name="enabled" value="true" /> <!-- The port to run the Change Password protocol on. --> <property name="ipPort" value="464" />

Page 113: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-2010102

The Apache Software Foundation Privacy Policy

</bean>

The ChangePasswordConfiguration bean is subordinate to the MutableServerStartupConfiguration.

<bean id="configuration" class="org.apache.directory.server.configuration.MutableServerStartupConfiguration"> ... <property name="changePasswordConfiguration" ref="changePasswordConfiguration" /> ...</bean>

6.5.3.3. Common Service Configuration Parameters

Table 6.18. Common Service Configuration Parameters

Parameter Default value Description

enabled false Whether this service is enabled.

ipPort 464 The IP port for this service.

ipAddress No default. The IP address for this service.

searchBaseDn "ou=users,dc=example,dc=com" The single location whereprincipals are stored. If thisproperty is not set the storewill search the system partitionconfiguration for catalog entries.Catalog support is highlyexperimental and is onlytested in the OSGi build ofApacheDS using the ConfigAdmin service.

initialContextFactory "org.apache.directory.server.core.jndi.CoreContextFactory"The JNDI initial context factoryto use.

securityAuthentication "simple" The authentication mechanismto use for establishing a JNDIcontext.

securityPrincipal "uid=admin,ou=system" The principal to use forestablishing a JNDI context.

securityCredentials "secret" The credentials to use forestablishing a JNDI context.

serviceName Apache Change PasswordService

The friendly name of this service.

servicePid org.apache.changepw The PID for this service. A PID isa unique identifier for an instanceof a service. PID's are used byOSGi's Config Admin service todynamically inject configurationinto a service when the service isstarted.

catalogBaseDn No default. The single location where catalogentries are stored. A catalog entryis a mapping of a realm (or zonefor DNS) to a search base DN. Ifthis property is not set the storewill expect a single search baseDN to be set. Catalog supportis highly experimental and is

Page 114: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-2010103

The Apache Software Foundation Privacy Policy

Parameter Default value Description

only tested in the OSGi buildof ApacheDS using the ConfigAdmin service.

6.5.3.4. Change Password-Specific Configuration Parameters

Table 6.19. Change Password-Specific Configuration Parameters

Parameter Default value Description

encryptionTypes des-cbc-md5 The encryption types.

primaryRealm EXAMPLE.COM The primary realm.

servicePrincipal kadmin/[email protected]

The service principal name.

allowableClockSkew 5 minutes The allowable clock skew.

emptyAddressesAllowed true Whether tickets issued withempty Host Addresses areallowed.

policyPasswordLength 6 characters The policy for minimumpassword length.

policyCategoryCount 3 (out of 4) The policy for number ofcharacter categories required (A- Z), (a - z), (0 - 9), non-alphanumeric (!, $, #, %, ... ).

policyTokenSize 3 characters The policy for minimumtoken size. Passwords mustnot contain tokens larger than'policyTokenSize' that occur inthe user's principal name.

6.5.3.5. More Information

For help with more advanced configurations, check out our Interoperability Guide [http://cwiki.apache.org/DIRxINTEROP] .

6.5.4. Change Password in ApacheDS 1.5.5WARNING: Don't use this in a productive environment!

6.5.4.1. Activating the Change Password Server

This requires that the Change Password Server is active and that the allowable Clock Skew for theKerberos Server as well as the Change Password Server is less than 5 minutes (5 * 6000 milliseconds).This is because the ticket lifetime for kpasswd is 5 minutes per default and the ticket lifetime has togreater than the allowable clock skew + network latency.

<changePasswordServer id="changePasswordServer" allowableClockSkew="24000"> <tcpTransport> <tcpTransport port="60464" nbThreads="2" backLog="50"/> </tcpTransport> <udpTransport> <udpTransport port="60464" nbThreads="2" backLog="50"/> </udpTransport> <directoryService>#directoryService</directoryService> </changePasswordServer>

Page 115: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-2010104

The Apache Software Foundation Privacy Policy

<kdcServer id="kdcServer" allowableClockSkew="24000"> ... </kdcServer>

6.6. DNS Protocol ProviderThis site is in the process of being reviewed and updated.

6.6.1. IntroductionApacheDS Domain Name Service (DNS) provider implements RFC 1034 [http://www.faqs.org/rfcs/rfc1034.html] and RFC 1035 [http://www.faqs.org/rfcs/rfc1034.html] to service DNS Protocolrequests.

The DNS provider plugins into the Apache Directory server. As a plugin, the DNS provider uses thenetwork layer (MINA) for front-end services and the Apache Directory read-optimized backing storevia JNDI for a persistent store.

The ApacheDS DNS provider, in conjunction with MINA and the ApacheDS LDAP JNDI store,provides an easy-to-use yet fully-featured name resolution service. As implemented within the ApacheDirectory, it will provide:

• Domain name service (RFC 1034, 1035)

• Service location support (SRV) (RFC 2782)

• Certificate support (CERT) (RFC 2782)

• Security Extensions (DNSSEC) (RFC 2535)

• Secure query and dynamic update support (GSS-TSIG) (RFC 3645)

• LDAP/JMX management

• UDP and TCP Support (MINA)

• Easy POJO embeddability for containers such as Geronimo, JBoss, and OSGi

6.6.1.1. Basic Testing

On Linux, a typical invocation of dig looks like:

dig @server name type

If no type argument is supplied, dig will perform a lookup for an A record. For example:

bash-2.05b# dig @localhost www.example.com

6.6.1.2. ApacheDS schema for storing DNS zones in LDAP

6.6.1.2.1. Abstract objectClass used to build all DNS record objectclasses

Table 6.20. Abstract objectClass used to build all DNS record objectclasses

objectclass apacheDnsAbstractRecord

apacheDnsName A sequence of labels representing a domain nameor host name

Page 116: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-2010105

The Apache Software Foundation Privacy Policy

objectclass apacheDnsAbstractRecord

apacheDnsType The type of a resource record

apacheDnsClass The class of a resource record

apacheDnsTtl An integer denoting time to live

6.6.1.2.2. Address (A) record

Table 6.21. Address (A) record

objectclass apacheDnsAddressRecord

apacheDnsName A sequence of labels representing a domain nameor host name

apacheDnsType The type of a resource record

apacheDnsClass The class of a resource record

apacheDnsTtl An integer denoting time to live

apacheDnsIpAddress A 4 octet IP address

6.6.1.2.3. Pointer (PTR) record

Table 6.22. Pointer (PTR) record

objectclass apacheDnsPointerRecord

apacheDnsName A sequence of labels representing a domain nameor host name

apacheDnsType The type of a resource record

apacheDnsClass The class of a resource record

apacheDnsTtl An integer denoting time to live

apacheDnsDomainName A domain or sequence dotted labels

6.6.1.2.4. Name Server (NS) record

Table 6.23. Name Server (NS) record

objectclass apacheDnsNameServerRecord

apacheDnsName A sequence of labels representing a domain nameor host name

apacheDnsType The type of a resource record

apacheDnsClass The class of a resource record

apacheDnsTtl An integer denoting time to live

apacheDnsDomainName A domain or sequence dotted labels

6.6.1.2.5. Start Of Authority (SOA) record

Table 6.24. Start Of Authority (SOA) record

objectclass apacheDnsStartOfAuthorityRecord

apacheDnsName A sequence of labels representing a domain nameor host name

apacheDnsType The type of a resource record

apacheDnsClass The class of a resource record

Page 117: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-2010106

The Apache Software Foundation Privacy Policy

objectclass apacheDnsStartOfAuthorityRecord

apacheDnsTtl An integer denoting time to live

apacheDnsSoaMName A domain of the server that was the primarysource of data for this zone

apacheDnsSoaRName The domain which specifies the mailbox of theperson responsible for this zone

apacheDnsSoaSerial The unsigned 32 bit ver num of the original copyof the zone

apacheDnsSoaRefresh A 32 bit time interval before the zone should berefreshed

apacheDnsSoaRetry A 32 bit time interval that should elapse before afailed refresh should be retired

apacheDnsSoaExpire A 32 bit time value that specifies the upper limiton the time interval that can elapse before the zoneis no longer authoritative

apacheDnsSoaMinimum The unsigned 32 bit minimum TTL field thatshould be exported with any RR from this zone.

6.6.1.3. Configuring DNS Zones

Figure 6.5.

6.6.1.3.1. The STRUCTURAL 'dcObject' objectClass

( 1.3.6.1.4.1.1466.344 NAME 'dcObject' SUP top AUXILIARY MUST dc )

6.6.1.3.1.1. An example entry using the STRUCTURAL objectClass domain

dn: dc=tcp,dc=example,dc=comobjectClass: topobjectClass: domaindc: tcpdescription: a placeholder entry used with SRV records

Page 118: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-2010107

The Apache Software Foundation Privacy Policy

6.6.1.3.2. The AUXILIARY 'domain' objectClass

( 0.9.2342.19200300.100.4.13 NAME 'domain' SUP top STRUCTURALMUST dcMAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $x121Address $ registeredAddress $ destinationIndicator $preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $telephoneNumber $ internationaliSDNNumber $ facsimileTelephoneNumber $street $ postOfficeBox $ postalCode $ postalAddress $physicalDeliveryOfficeName $ st $ l $ description $ o $associatedName ) )

6.6.1.3.2.1. An example entry using the AUXILIARY objectClass dcObject

dn: dc=example,dc=comobjectClass: topobjectClass: organizationobjectClass: dcObjectdc: exampleo: Example Inc.

6.6.1.3.2.2. Resources

• RFC 2247 - Using Domains in LDAP/X.500 Distinguished Names [http://www.faqs.org/rfcs/rfc2247.html]

6.6.2. DNS Best Practices

6.6.2.1. DNS Testing Tool

Useful tool for testing DNS configuration: www.dnsreport.com [http://www.dnsreport.com/]

There are other tools available from the same people, at www.dnsstuff.com [http://www.dnsstuff.com/] , but I have not tested any of them.

1. MX - Change MX records from CNAME's to A records. This is supposed to improve lookup speedand MX pointing to CNAME's is an RFC violation.

2. SOA - Change SOA values to come in line with recommended values, per dnsreports.com.

3. PTR - Add PTR records for server1.example.com. This is to address an error being generated byAOL and Hotmail, which use reverse lookups on mail servers to weed out spam. Mail on theexample.com mailing lists has increasingly been bounced by AOL and Hotmail as spam and headerinspection points to lack of PTR record. Setting PTR records at the hosting provider is a relativelynew feature, probably added to address this problem.

6.6.3. Notes

6.6.3.1. A Zone is a Pruned Subtree

4.2 Zone "pruned subtree."Subtree of 1..n nodes/domainNamesZones are split by org controlA zone is a set of types.Highest node contains SOA. SOA is 1..1 with highest node.Below SOA is authoritative.Highest node contains 1..n NS.Authoritative NS only at top of zone.A domain name id's a node.

Page 119: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-2010108

The Apache Software Foundation Privacy Policy

A node is a set of RR's.

NS in leaf is:

• non-authoritative

• referral

• aka "delegation NS RR"

A in leaf is:

• non-authoritative

• aka "glue RR"

Iterative - server refers client (preferred, required)Recursive - server persues query for client (optional)Cache - in-memory partition non-authoritativeAuthority - points to authority

Non-recursive 4.3.1

1. error

2. answer

3. referral

Unit tests for all 6.2.*Key algorithm 4.3.1 & 4.3.2

6.6.3.2. Sender Permitted From

• Sender Permitted From [http://spf.pobox.com/] is a DNS-based method for preventing SMTPspoofing.

6.6.3.3. Secret Key Transaction Authentication for DNS (TSIG)

• RFC 2845 [http://www.faqs.org/rfcs/rfc2845.html]

6.6.4. DNS Protocol ConfigurationThis site is in the process of being reviewed and updated.

6.6.4.1. Common Service Configuration Parameters

Table 6.25. Common Service Configuration Parameters

Parameter Default value Description

enabled false Whether this service is enabled.

ipPort 53 The IP port for this service.

ipAddress No default. The IP address for this service.

searchBaseDn "ou=users,dc=example,dc=com" The single location whereresource records are stored.If this property is not setthe store will search thesystem partition configuration for

Page 120: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-2010109

The Apache Software Foundation Privacy Policy

Parameter Default value Description

catalog entries. Catalog supportis highly experimental and isonly tested in the OSGi buildof ApacheDS using the ConfigAdmin service.

initialContextFactory "org.apache.directory.server.core.jndi.CoreContextFactory"The JNDI initial context factoryto use.

securityAuthentication "simple" The authentication mechanismto use for establishing a JNDIcontext.

securityPrincipal "uid=admin,ou=system" The principal to use forestablishing a JNDI context.

securityCredentials "secret" The credentials to use forestablishing a JNDI context.

serviceName Apache DNS Service The friendly name of this service.

servicePid org.apache.dns The PID for this service. A PID isa unique identifier for an instanceof a service. PID's are used byOSGi's Config Admin service todynamically inject configurationinto a service when the service isstarted.

catalogBaseDn No default. The single location where catalogentries are stored. A catalog entryis a mapping of a zone to a searchbase DN. If this property is notset the store will expect a singlesearch base DN to be set. Catalogsupport is highly experimentaland is only tested in the OSGibuild of ApacheDS using theConfig Admin service.

6.6.4.2. More Information

For help with more advanced configurations, check out our Interoperability Guide [http://cwiki.apache.org/DIRxINTEROP] .

6.7. NTP Protocol ProviderThis site is in the process of being reviewed and updated.

6.7.1. IntroductionThe Apache NTP Protocol Provider is a Java server that implements RFC 2030 [http://www.faqs.org/rfcs/rfc2030.html] to service Simple Network Time Protocol requests. The Network Time Protocol isused to synchronize computer clocks on the Internet.

Apache NTP, in conjunction with MINA and the Apache Directory, provides an easy-to-use yet fully-featured network time synchronization service. As implemented within the Apache Directory, ApacheNTP will provide:

• Simple Network Time Protocol (SNTP) service (RFC 2030)

Page 121: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-2010110

The Apache Software Foundation Privacy Policy

• JMX remote management (JSR 160, JSR 28)

• UDP and TCP Support (MINA)

• Easy POJO embeddability for containers such as Geronimo, JBoss, and OSGi

6.7.2. Basic TestingOn Linux:

bash-2.05b# ntpdate -u localhost

6.7.3. Resources

6.7.3.1. SNTP RFC's

• RFC 2030 - Simple Network Time Protocol (SNTP) Version 4 for IPv4, IPv6 and OSI http://www.faqs.org/rfcs/rfc2030.html

• RFC 1305 - Network Time Protocol (Version 3) Specification, Implementation and Analysis http://www.faqs.org/rfcs/rfc1305.html

6.7.4. NTP Protocol ConfigurationThis page is only valid with ADS 1.5.5 !

The server.xml file contains the bas configuration for the NTP server :

<ntpServer id="ntpServer" ipPort="60123" nbThreads="2"/>

With such a configuration, the NTP server will listen to port 60123, with UDP and TCP transportsselected.

6.7.4.1. Common Service Configuration Parameters

Here is the list of parameters you can set. The bold parameters are mandatory.

Table 6.26. Common Service Configuration Parameters

Parameter value Description Optional

id "ntpServer" Do not change thisvalue : it is usedinternally to identify theNTP server instance

NA

serviceName Apache NTP Service The friendly name ofthis service.

yes

enabled true Tells if the server isenabled or not.

yes

ipAddress localhost The IP address for thisservice.

yes

ipBacklog 50 The backlog size forboth UDP and TCPtransport

yes

Page 122: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-2010111

The Apache Software Foundation Privacy Policy

Parameter value Description Optional

ipPort 123 The IP port for thisservice. It is valid forboth UDP and TCPtransports. To defineonly one of those twotransports, or to set aspecific port for eachtransport, use the twofollowing parameters

yes

nbThreads 2 The number of threadused by the serviceIoProcessor

yes

tcpBacklog 50 The backlog size for theTCP transport.

yes

tcpPort 123 The TCP port for thisservice.

yes

nbTcpThreads 2 The number of threadused by the TCP serviceIoProcessor

yes

udpBacklog 50 The backlog size for theUDP transport

yes

udpPort 123 The UDP port for thisservice.

yes

nbUdpThreads 2 The number of threadused by the UDP serviceIoProcessor

yes

The last six parameters should be used only if one want to set up only a single transport, orwhen UDP and TCP transport don't share the same port.

6.7.4.2. More Information

For help with more advanced configurations, check out our Interoperability Guide [http://cwiki.apache.org/DIRxINTEROP/] .

6.8. DHCP Protocol ProviderThis site is in the process of being reviewed and updated.

6.8.1. IntroductionThe ApacheDS Dynamic Host Configuration Protocol (DHCP) provider implements RFC 2131[http://www.faqs.org/rfcs/rfc2131.html] and RFC 2132 [http://www.faqs.org/rfcs/rfc2132.html] topass configuration information to hosts on a TCP/IP network.

The DHCP provider is implemented plugin into the ApacheDS network layer (MINA). As a plugin,DHCP leverages Apache MINA for front-end services and the Apache Directory read-optimizedbacking store via JNDI for a persistent store.

The ApacheDS DHCP plugin, in conjunction with MINA and the Apache Directory store, providesan easy-to-use yet fully-featured dynamic configuration service. As implemented within the ApacheDirectory, DHCP will provide:

Page 123: ApacheDS Guide

Draft Protocol Providers Draft

© 2003-2010112

The Apache Software Foundation Privacy Policy

• DHCP service (RFC 2131, 2132)

• Vendor extensions (RFC 1497)

• Service Location Protocol (SLP) support (RFC 2608)

• Optional LDAP management

• UDP and TCP Support (MINA)

• Easy POJO embeddability for containers such as Geronimo, JBoss, and OSGi

6.8.1.1. DHCP Notes

• Setting up DHCP and TFTP servers [http://www.linux.com/howtos/Clone-HOWTO/setting-up.shtml]

• PXE using etherboot: HOWTO [http://204.182.52.180/fom-serve/cache/7.html]

• How DHCP works [http://www.j51.com/~sshay/tcpip/dhcp/dhcp.htm]

• RFC 1533 [http://www.faqs.org/rfcs/rfc1533.html] - DHCP Options and BOOTP VendorExtensions

• RFC 1534 [http://www.faqs.org/rfcs/rfc1534.html] - Interoperation Between DHCP and BOOTP

• RFC 3118 [http://www.faqs.org/rfcs/rfc3118.html] - Authentication for DHCP Messages

6.8.2. More InformationFor help with more advanced configurations, check out our Interoperability Guide [http://cwiki.apache.org/DIRxINTEROP/] .

Page 124: ApacheDS Guide

Draft Draft

© 2003-2010113

The Apache Software Foundation Privacy Policy

Chapter 7. Extending the serverWork in progress

7.1. How to write a simple custom partitionfor ApacheDS

Work in progress. Any feedback highly appreciated!

This site was updated for ApacheDS 1.5.5.

On the mailing list, people ask regularly on how to write a custom partition. If you simply plan to addanother suffix to ApacheDS (besides dc=example,dc=com, for instance) in order to store data, it is notnecessary to write any code. You can simply add some lines to the configuration. The following is fordevelopers who plan to implement another storage mechanism than the provided default.

• Section 7.1.1, “What exactly is a partition?”

• Section 7.1.2, “Hello world. A minimal partition”

• Section 7.1.2.1, “The sources”

• Section 7.1.2.2, “Implementing the class HelloWorldPartition”

• Section 7.1.2.3, “Using the partition”

• Section 7.1.2.4, “Verification”

• Section 7.1.3, “To be continued”

7.1.1. What exactly is a partition?

Within ApacheDS, a partition is a physically distinct store for a subset of the entries contained withinthe server. A partition can be implemented using any storage mechanism or can even be backed inmemory. The default storage mechanism for a partition is JDBM [http://jdbm.sourceforge.net/] .

Implementing your own partition is basically implementing the Partition interface from theorg.apache.directory.server.core.partition package. Please note that this is not an easy task.Nevertheless I try to give you a starting point with some simple examples.

7.1.2. Hello world. A minimal partition

Let's start with a minimal partition, the hello world [http://en.wikipedia.org/wiki/Hello_world_program] . Minimal means here, that it is possible to add it to ApacheDS and see it withan LDAP browser. The partition ...

• correctly implements the Partition interface

• is pluggable in the server (embedded and declarative in the configuration)

• is visible for clients like ldapsearch or Apache Directory Studio

• contains one entry, which contains the famous "hello, world" message in an attribute value

Page 125: ApacheDS Guide

Draft Extending the server Draft

© 2003-2010114

The Apache Software Foundation Privacy Policy

• does not support any modification operations like delete, add etc.

• does not take account of filters in search requests, ...

7.1.2.1. The sources

Currently, the sources are checked in here

• http://svn.apache.org/repos/asf/directory/sandbox/szoerner/helloWorldPartition

In order to build it, simply check it out and type "mvn install".

7.1.2.2. Implementing the class HelloWorldPartition

The following UML class diagram depicts the structure of the little example.

Figure 7.1. Hello World UML

In order to be a partition, class HelloWorldPartition implements the corresponding interface fromorg.apache.directory.server.core.partition . It has an association to it's only entry (which will holdthe "hello, world" method). This entry is created in the init life cycle method of the partition, whichlooks like this:

...public void init(DirectoryService core) throws Exception { // Create LDAP DN suffixDn = new LdapDN(suffix); suffixDn.normalize(core.getRegistries().getAttributeTypeRegistry().getNormalizerMapping()); Rdn rdn = suffixDn.getRdn(); // Create the only entry in this partition ServerEntry entry = new DefaultServerEntry(core .getRegistries(), this.suffixDn); entry.put(SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, SchemaConstants.ORGANIZATIONAL_UNIT_OC);

Page 126: ApacheDS Guide

Draft Extending the server Draft

© 2003-2010115

The Apache Software Foundation Privacy Policy

entry.put(SchemaConstants.OU_AT, rdn.getUpValue().toString()); entry.put("description", "hello, world", "a minimal partition"); this.helloEntry = entry;}...

We assume that the suffix starts with "ou=" in order to create an entry of object class organizationalunit. If someone tries to set a suffix which starts with another attribute for the RDN, the setSuffix willthrow an exception.

The Partition interface requires to implement many methods for all the operations a partition shouldsupport (adding, deleting, modifying entries ...). Due to the fact, that this is a read only partition, theimplementation in our case is minimalistic. Here is the delete method as an example.

...public void delete(DeleteOperationContext opContext) throws LdapOperationNotSupportedException { throw new LdapOperationNotSupportedException( MODIFICATION_NOT_ALLOWED_MSG, ResultCodeEnum.UNWILLING_TO_PERFORM);}...

Although this example should be minimal, some methods need more attention. At least if we want tosee the partitiion in an LDAP and not only in the error logs ...

The important methods are hasEntry , lookup and search . The following code is the search method.Please note that it ignores search scopes other than BASE and search filters completely in order tohave simple code.

public EntryFilteringCursor search(SearchOperationContext ctx) throws Exception {

if (ctx.getDn().equals(this.suffixDn)) { switch (ctx.getScope()) { case OBJECT: // return a result with the only entry we have return new BaseEntryFilteringCursor( new SingletonCursor<ServerEntry>(this.helloEntry), ctx); } }

// return an empty result return new BaseEntryFilteringCursor(new EmptyCursor<ServerEntry>(), ctx);}

For the other methods, take a look in the sourcecode [http://svn.apache.org/repos/asf/directory/sandbox/szoerner/helloWorldPartition/src/main/java/org/apache/directory/samples/partition/hello/HelloWorldPartition.java] .

7.1.2.3. Using the partition

7.1.2.3.1. Embedded mode

package org.apache.directory.samples.partition.hello;

import org.apache.directory.server.core.DefaultDirectoryService;import org.apache.directory.server.core.DirectoryService;import org.apache.directory.server.ldap.LdapServer;import org.apache.directory.server.protocol.shared.transport.TcpTransport;

/** * Starts the server with the HelloWorld partition. */public class Main {

public static void main(String[] args) throws Exception {

Page 127: ApacheDS Guide

Draft Extending the server Draft

© 2003-2010116

The Apache Software Foundation Privacy Policy

DirectoryService directoryService = new DefaultDirectoryService(); directoryService.setShutdownHookEnabled(true);

LdapServer ldapServer = new LdapServer(); ldapServer.setDirectoryService(directoryService); ldapServer.setAllowAnonymousAccess(true);

TcpTransport ldapTransport = new TcpTransport(10389); ldapServer.setTransports(ldapTransport);

HelloWorldPartition helloPartition = new HelloWorldPartition(); helloPartition.setSuffix("ou=helloWorld"); helloPartition.init(directoryService);

directoryService.addPartition(helloPartition);

directoryService.startup(); ldapServer.start(); }}

7.1.2.3.2. Adding it to a server.xml file

In order to use the partition in a standard installation of ApacheDS, simply add it to the server.xmlconfiguration. Provide a "native" Spring bean like this.

server.xml<spring:beans xmlns:spring="http://xbean.apache.org/schemas/spring/1.0" xmlns:s="http://www.springframework.org/schema/beans" xmlns="http://apacheds.org/config/1.0">

... <defaultDirectoryService ...> ... <partitions> ... <s:bean id="helloPartition" class="org.apache.directory.samples.partition.hello.HelloWorldPartition"> <s:property name="suffix" value="ou=helloWorld" /> </s:bean> </partitions> ... </defaultDirectoryService>...

Note that the class HelloWorldPartition has to be in the class path of the server. Without, starting theserver leads to a ClassNotFoundException . You can copy the jar file which results from the buildto the lib/ext directory.

7.1.2.4. Verification

After adding the HelloWorldPartition to the directory service like above (embedded or viaconfiguration in server.xml ), you can browse it with an LDAP browser like the one from ApacheDirectory Studio. Here are some screen shots.

Figure 7.2. Hello World LDAP Browser

Page 128: ApacheDS Guide

Draft Extending the server Draft

© 2003-2010117

The Apache Software Foundation Privacy Policy

Figure 7.3. Hello World Entry Editor

Of course using a command line tool works as well ...

$ ldapsearch -h localhost -p 10389 -D "uid=admin,ou=system" -w secret \\ -b "" -s base "(objectclass=*)" namingContextsversion: 1dn:namingContexts: ou=systemnamingContexts: ou=helloWorldnamingContexts: ou=schema$$ ldapsearch -h localhost -p 10389 -D "uid=admin,ou=system" -w secret \\ -b "ou=helloWorld" -s base "(objectclass=*)"

version: 1dn: ou=helloWorldobjectClass: organizationalUnitobjectClass: topdescription: hello, worlddescription: a minimal partitionou: helloWorld$

7.1.3. To be continuedWe plan to add more sophistic examples on this topic in the near feature. Stay tuned on the mailing lists.

Here is an older example on the topic: http://svn.apache.org/viewvc/directory/sandbox/akarasulu/custom-partition

It is outdated, but may still inspire you.

7.2. Implementing a simple customInterceptor

This site was updated for ApacheDS 1.5.5.

The following is for developers who plan to implement their own interceptors in order to extend ormodify the functionality of Apache Directory Server. It contains a simple example as a starting point.

• Section 7.2.1, “What exactly is an interceptor?”

• Section 7.2.2, “Password hash. A simple interceptor”

• Section 7.2.2.1, “The sources”

• Section 7.2.2.2, “Implementing the class PasswordHashInterceptor”

Page 129: ApacheDS Guide

Draft Extending the server Draft

© 2003-2010118

The Apache Software Foundation Privacy Policy

• Section 7.2.2.3, “Using the interceptor”

• Section 7.2.2.4, “Verification”

• Section 7.2.2.5, “Limitations of the example”

• Section 7.2.3, “Further reading”

7.2.1. What exactly is an interceptor?An interceptor filters method calls performed on on the DefaultPartitionNexus just like Servlet filtersdo. The ApacheDS configuration contains a chain of filters performing several tasks. In order toillustrate this, here is the list of interceptors from the default server configuration of ApacheDS 1.5.5

• org.apache.directory.server.core.normalization.NormalizationInterceptor

• org.apache.directory.server.core.authn.AuthenticationInterceptor

• org.apache.directory.server.core.referral.ReferralInterceptor

• org.apache.directory.server.core.authz.AciAuthorizationInterceptor

• org.apache.directory.server.core.authz.DefaultAuthorizationInterceptor

• org.apache.directory.server.core.exception.ExceptionInterceptor

• org.apache.directory.server.core.changelog.ChangeLogInterceptor

• org.apache.directory.server.core.operational.OperationalAttributeInterceptor

• org.apache.directory.server.core.schema.SchemaInterceptor

• org.apache.directory.server.core.subtree.SubentryInterceptor

• org.apache.directory.server.core.collective.CollectiveAttributeInterceptor

• org.apache.directory.server.core.event.EventInterceptor

• org.apache.directory.server.core.trigger.TriggerInterceptor

• org.apache.directory.server.core.journal.JournalInterceptor

Interceptors should usually pass the control of current invocation to the next interceptor by callingan appropriate method on NextInterceptor . The flow control is returned when the next interceptor'sfilter method returns. You can therefore implement pre-, post-, around- invocation handler by howyou place the statement.

Interceptors are a powerful way to extend and modify the server behavior. But be warned. A mistakenlywritten interceptor may lead to a dis-functional or corrupt server.

7.2.2. Password hash. A simple interceptorIn order to demonstrate how to write an interceptor, here is a simple but realistic example. Thefollowing requirement should be fulfilled by an interceptor.

• No user password should be stored in the directory in clear text.

To be more concrete:

• If a userpassword is set by an LDAP client in plain text, a message digest algorithm [http://en.wikipedia.org/wiki/Cryptographic_hash_function] should be applied to the value, and the one-way encrypted value should be stored

Page 130: ApacheDS Guide

Draft Extending the server Draft

© 2003-2010119

The Apache Software Foundation Privacy Policy

• the algorithm should be applied if new entries are created or existing entries are modified (hencemodify and add operations will be intercepted)

• If the value given by the client is already provided in hashed form, nothing happens, and the givenvalue is stored in the directory without modification

7.2.2.1. The sources

Currently, the sources are checked in here

• http://svn.apache.org/repos/asf/directory/sandbox/szoerner/passwordHashInterceptor

In order to build it, simply check it out and type "mvn install".

7.2.2.2. Implementing the class PasswordHashInterceptor

The following UML class diagram depicts the structure of the little example. Classes in white aregiven by Apache Directory Server as extension points. The two gray classes comprise the exampleinterceptor.

Figure 7.4. PasswordHash Interceptor UML

The class HashTools contains two simple methods w.r.t. hashing. isAlreadyHashed detects whether avalue has already been hashed with a known message digest algorithm. applyHashAlgorithm appliesa hash algorithm to a sequence of bytes. See the source code and the unit tests of this class for details,it has not that much to do with the interceptor stuff.

The central class is PasswordHashInterceptor . Every interceptor has to implement the Interceptorinterface from package org.apache.directory.server.core.interceptor . PasswordHashInterceptor doesso by extended the convenience class BaseInterceptor from the same package.

The property hashAlgorithm allows to configure the alhorithm used for hashing the passwords. Itdefaults to MD5 (Message-Digest algorithm 5) [http://en.wikipedia.org/wiki/MD5] . The propertypasswordAttributeName allows configuration of the attribute type which stores the user password. Itsvalue will be hashed if needed. The property defaults to "userPassword", which is quite common andused for instance in the inetOrgPerson [http://www.ietf.org/rfc/rfc2798.txt] object class.

The most interesting methods of the class are add and modify . They intercept the requests ans modifythe attribute values, if needed. See below the complete source code of the class.

package org.apache.directory.samples.interceptor.pwdhash;

import static org.apache.directory.samples.interceptor.pwdhash.HashTools.applyHashAlgorithm;import static org.apache.directory.samples.interceptor.pwdhash.HashTools.isAlreadyHashed;

import java.util.List;

import org.apache.directory.server.core.entry.ClonedServerEntry;import org.apache.directory.server.core.interceptor.BaseInterceptor;import org.apache.directory.server.core.interceptor.NextInterceptor;import org.apache.directory.server.core.interceptor.context.AddOperationContext;import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;import org.apache.directory.shared.ldap.entry.EntryAttribute;import org.apache.directory.shared.ldap.entry.Modification;import org.apache.directory.shared.ldap.entry.ModificationOperation;

public class PasswordHashInterceptor extends BaseInterceptor {

private String hashAlgorithm = "MD5";

private String passwordAttributeName = "userPassword";

Page 131: ApacheDS Guide

Draft Extending the server Draft

© 2003-2010120

The Apache Software Foundation Privacy Policy

public void setHashAlgorithm(String hashAlgorithm) { this.hashAlgorithm = hashAlgorithm; }

public void setPasswordAttributeName(String passwordAttributeName) { this.passwordAttributeName = passwordAttributeName; }

/** * Intercepts the add operation in order to replace plain password values * with hashed ones. */ @Override public void add(NextInterceptor next, AddOperationContext opContext) throws Exception {

ClonedServerEntry entry = opContext.getEntry(); EntryAttribute attribute = entry.get(passwordAttributeName); if (attribute != null) { hashPasswordIfNeccessary(attribute); }

super.add(next, opContext); }

/** * Intercepts the modify operation in order to replace plain password values * with hashed ones. */ @Override public void modify(NextInterceptor next, ModifyOperationContext opContext) throws Exception {

List<Modification> items = opContext.getModItems(); for (Modification modification : items) { ModificationOperation operation = modification.getOperation(); if (operation == ModificationOperation.ADD_ATTRIBUTE || operation == ModificationOperation.REPLACE_ATTRIBUTE) { EntryAttribute attribute = modification.getAttribute(); if (attribute.getId().equalsIgnoreCase(passwordAttributeName)) { hashPasswordIfNeccessary(attribute); } } } super.modify(next, opContext); }

protected void hashPasswordIfNeccessary(EntryAttribute attribute) { try { byte[] password = attribute.getBytes(); if (!isAlreadyHashed(password)) { byte[] hashed = applyHashAlgorithm(hashAlgorithm, password); attribute.clear(); attribute.add(hashed); } } catch (Exception e) { throw new RuntimeException("Password hash failed", e); } }}

7.2.2.3. Using the interceptor

You may use a custom interceptor both in a standard ApacheDS installation and in a server startedembedded.

7.2.2.3.1. Adding it to a standard server installation (server.xml)

In order to get the interceptor installed in a default installation of ApacheDS 1.5.5., just copy the jar-File resulting from the Maven build, which contains the custom classes, to APACHEDS_INSTALLDIR/lib/ext .

After that, add the interceptor to the server.xml file in APACHEDS_INSTALLDIR/conf/ . Make sureto backup the file before your modifications. Within server.xml find the XML elements which list theinterceptors. The easiest way to add a custom interceptor is to add a spring bean (namespace "s"). Youmya set configuration properties to the interceptor as well, if it supports some.

Page 132: ApacheDS Guide

Draft Extending the server Draft

© 2003-2010121

The Apache Software Foundation Privacy Policy

The following fragment shows the interceptor list with the example interceptor added just behindnormalization. For demonstration purposes, the hash algorithm is set to "MD5" (which is the defaultof our interceptor anyway).

...<interceptors> <normalizationInterceptor/> <s:bean class="org.apache.directory.samples.interceptor.pwdhash.PasswordHashInterceptor"> <s:property name="hashAlgorithm" value="MD5" /> </s:bean> <authenticationInterceptor/> <referralInterceptor/> <aciAuthorizationInterceptor/> <defaultAuthorizationInterceptor/> <exceptionInterceptor/> <operationalAttributeInterceptor/> ...</interceptors>...

7.2.2.3.2. Embedded mode

As an alternative, the following Java code starts an ApacheDS embedded in a main method. Thelist of interceptors is complemented with the example interceptor. We insert it exactly behind theNormalizingInterceptor (the position is a little bit tricky to determine).

package org.apache.directory.samples.interceptor.pwdhash;

import java.util.List;

import org.apache.directory.server.core.DefaultDirectoryService;import org.apache.directory.server.core.DirectoryService;import org.apache.directory.server.core.interceptor.Interceptor;import org.apache.directory.server.core.normalization.NormalizationInterceptor;import org.apache.directory.server.ldap.LdapServer;import org.apache.directory.server.protocol.shared.transport.TcpTransport;

/** * Main class which starts an embedded server with the interceptor inserted into * the chain. */public class Main {

public static void main(String[] args) throws Exception {

DirectoryService directoryService = new DefaultDirectoryService(); directoryService.setShutdownHookEnabled(true);

List<Interceptor> interceptors = directoryService.getInterceptors();

// Find Normalization interceptor in chain int insertionPosition = -1; for (int pos = 0; pos < interceptors.size(); ++pos) { Interceptor interceptor = interceptors.get(pos); if (interceptor instanceof NormalizationInterceptor) { insertionPosition = pos; } }

// insert our new interceptor just behind interceptors.add(insertionPosition + 1, new PasswordHashInterceptor()); directoryService.setInterceptors(interceptors);

LdapServer ldapServer = new LdapServer(); ldapServer.setDirectoryService(directoryService); ldapServer.setAllowAnonymousAccess(true);

TcpTransport ldapTransport = new TcpTransport(10389); ldapServer.setTransports(ldapTransport);

directoryService.startup(); ldapServer.start(); }}

Page 133: ApacheDS Guide

Draft Extending the server Draft

© 2003-2010122

The Apache Software Foundation Privacy Policy

7.2.2.4. Verification

Let's check whether our new interceptor does its job! In order to do so, we use Apache DirectoryStudio and connect to the server with the interceptor enabled (see above).

First we create a new entry with the following data, using "New Entry ..." within Studio.

dn: cn=Kate Bush,ou=users,ou=systemobjectClass: personobjectClass: topcn: Kate Bushsn: Bush

Then we add a new attribute userPassword in the entry editor. For the value, a special editor appears:

Figure 7.5. PasswordHash Interceptor PasswordEditor

Select "Plaintext" as the hash method and enter a new password. We selected "secret" (see screen shotabove). After pressing OK, a modify operation is sent to the server, which will be intercepted by ourexample class.

Page 134: ApacheDS Guide

Draft Extending the server Draft

© 2003-2010123

The Apache Software Foundation Privacy Policy

Figure 7.6. PasswordHash Interceptor ModificationLog

After that, the value for userPassword is not "secret", but the MD5 digested value of it.

Figure 7.7. PasswordHash Interceptor EntryEditor

The user Kate Bush is still capable of authenticating with the password "secret", because ApacheDirectory Server supports authentication with passwords hashed with this algorithm. You can verifythis by connecting with Studio and the using "cn=Kate Bush,ou=users,ou=system" as bind DN.

Here it is demonstrated with the help of the ldapsearch command line tool. The result also shows thatthe userPassword value is hashed with MD5.

$ ldapsearch -h localhost -p 10389 -D "cn=Kate Bush,ou=users,ou=system" \\ -w secret -b "ou=users,ou=system" -s one "(objectClass=*)"version: 1dn: cn=Kate Bush,ou=users,ou=systemobjectClass: personobjectClass: topcn: Kate Bushsn: BushuserPassword: {MD5}Xr4ilOzQ4PCOq3aQ0qbuaQ==$

7.2.2.5. Limitations of the example

This example is intended as a demonstration, on how to write your custom interceptor. Don't considerit bullet proof. It has not been tested under production conditions, etc.

At least the following limitation should be mentioned

Page 135: ApacheDS Guide

Draft Extending the server Draft

© 2003-2010124

The Apache Software Foundation Privacy Policy

• The default hash algorithm MD5 is considered weak.

• Exception handling is poor. E.g. if someone configures an unsupported hash algorithm, theinterceptor fails to create an appropriate LDAP error.

• If a multivalued password attribute is used, the interceptor will simply ignore that fact (does notapply to userPassword as of RFC 2256).

7.2.3. Further readingLearn more about interceptors in Section 2.2, “Interceptors” , check out the source code of someimplementations of the Interceptor interface, and/or read the javadoc comments.

Page 136: ApacheDS Guide

Draft Draft

© 2003-2010125

The Apache Software Foundation Privacy Policy

Chapter 8. Partitioning & Replication8.1. Referrals

TODO ...

8.2. ReplicationTODO ...

Page 137: ApacheDS Guide

Draft Draft

© 2003-2010126

The Apache Software Foundation Privacy Policy

Chapter 9. Triggers & StoredProcedures

Work in progress

9.1. Stored ProceduresThis site is in the process of being reviewed and updated.

9.1.1. What are Stored Procedures in LDAP?The closest thing to a Stored Procedure in LDAP is an Extended Operation. This is how the outsideworld would have access to procedures defined within the server. From this we can infer something:stored procedures are static operations. They can also have return values.

9.1.1.1. Java as the Native SP Language

Rather than complicate things with scripting languages and frameworks like BSF to implement storedprocedures we'll keep this first round really simple. Java is a natural fit for us too so I'm not going toworry about leaving scripting languages out of the picture. Also with ClassLoaders we can dynamicallyinstall and load new Java classes carrying stored procedures.

9.1.1.2. Storing Classes within the DIT

Classes will be stored within entries in the DIT. These entries like others can be protected by ACI toprevent exposure. All classes stored in the DIT will not be for stored proc entry points. Some classeswill be supporting classes, and some used to form libraries. So before we start talking about storedprocedures we need to consider code in the DIT and how it might be used.

We already defined a simplistic objectClass and attributeTypes for representing a class within an entry.A very primitive ClassLoader (CL) was able to load classes on demand by searching for them withinthe DIT. We need to go a step further though. Every user will have their own view of the DIT withACI in effect, so every user will need to execute procedures in their own CL. A user's CL needs topull in all classes in the DIT visible to the user. This CL can be used to execute stored procedures.

Thus the user specific CL needs to load the visible classes (seen by a user) as they are needed toexecute procedures. This could really slow things down though. Some caching may be in order herebut how that's to be done properly and efficiently is yet to be determined.

9.1.1.3. Code Security and Class Conflicts

As we pointed out code is stored in the DIT and ACIs are used to control the code entries visible tousers. Hence this changes the classes loaded into different user CLs. Note that multiple versions orcopies of the same class may exist within the server. This is ok. Conflicts can result as they do withstandard fs based classloaders. The fact that each user has its own CL helps limit the collisions.

We proposed some ACIItem extensions to make sure we can easily and efficiently isolate codeacross users. The new creator and notCreator userClasses have been proposed here: ??? . With theseuserClasses we can define a single ACIItem in a subentry at each ACSA with a subtreeSpecificationrefinement that makes javaClass entries only visible to their creators.

Code reuse will also come into the picture here. The administrator may expose some classes as librariesthat users can build on. Making these classes visible to all users may in turn result in some conflicts.

Page 138: ApacheDS Guide

Draft Triggers & Stored Procedures Draft

© 2003-2010127

The Apache Software Foundation Privacy Policy

For example users may load libraries of a newer version. What will be our policy here? Should thispolicy be something that should be decided by the Administrator? Should users be able to overridethis policy?

9.1.1.4. Searching and Search Order for Classes

We are not going to constrain users and administrators to have to maintain classes within a specificregion of the DIT. javaClass entries can reside anywhere within the DIT, within any namingContext.This makes searching for these entries a bit inefficient since the RootDSE must be used and multiplesearches must be conducted on each namingContext until a javaClass is found.

Convensions are good but admins should have options. By default the java subsystem will exhaustthe possibilities. We will allow administrators to configure the java subsystem by specifyinga specific search order for classes. This search order is a list of search operations. Under theou=configuration,ou=system area we can manage this list of operations. Basically the admin canspecify each search operation as a LDAP URL to search under for javaClasses. Perhaps each URL canbe prefixed with an 'insert' directive that defines how it is inserted into the list of search operations.

User profiles can also manage this configuration by inserting their own search operations into the list.The resultant list of search operations is used by the user's ClassLoader to discover classes within theDIT. Users should be able to see the search order of the system so they can override or inject their ownbypass. This may be a good mechanism for users to control situations where libraries and classes inthe system might conflict with their own version. Perhaps the CL search order for the system shouldbe published either in the RootDSE or exposed in the ou=system configuration area.

9.1.1.5. Stored Procedure Call Specification

This is no longer valid

As stated before, a stored procedure is close to an LDAP extended operation. However, we will notregister a new extended operation for each stored procedure. Instead of that, we'll have a genericStored Procedure extended operation where the stored procedure to be called will be specified in theparameter list of the extended operation. (Of course this does not prevent some stored procedures tobe published as standalone extended operations.) Here is the proposed stored procedure specificationin ASN.1 format:

StoredProcedure ::= SEQUENCE { language OCTETSTRING, procedure OCTETSTRING, parameters SEQUENCE OF Parameter}

Parameter ::= SEQUENCE OF { type OCTETSTRING, value OCTETSTRING}

9.1.1.6. Stored Procedure Execution Request Value

??? The wiki is wrong ???

9.1.1.6.1. BER

0x30 LL 0x04 LL abcd [ [ 0x31 LL 0x12 LL abcd 0x30 LL ( 0xc04 LL abcd... [ 0x0A 0x01 0x0[0..2] ] )[ 0x30 LL 0x30 LL [ 0x04 LL abcd ] 0x84 LL abcd ] | [ 0x30 LL 0x30 LL [ 0x04 LL abcd ] 0x84LL abcd ] ]

9.1.1.6.2. The State Machine

??? The wiki is wrong ???

Page 139: ApacheDS Guide

Draft Triggers & Stored Procedures Draft

© 2003-2010128

The Apache Software Foundation Privacy Policy

9.1.1.7. Explanations

The language field is used to specify the implementation language of stored procedure to becalled. This field allows the server to provide any kind or more than one kind of stored procedureimplementations. We'll support compiled Java SPs as default and support forJython is scheduled forafter 1.0 release.

The procedure field is used to specify the fully qualified name of the procedure to be called. Anexample can be "For.Bar.proc".

The parameters field is used to specify a list of parameters (with their types and values ) to begiven to the procedure to be called. Type information is needed to enable maximum implementationgeneralization. Encoding these fields with OCTETSTRING also helps generalization. Interpretingthese fields' values are up to the server. By default we'll require type field to include fully qualifiedclass name of a Java type and we'll require value field to include a string representation of the parametervalue if it's a primitive one and as byte[] if it's a complex Java object.

The return value of stored procedures will be provided by extended operation responses with samesemantics mentioned above.

As an implementation tip, what we're doing here is like adding reflection capability to our serverto call stored procedures. Thinking in terms of Java reflection mechanish helps us better design thesystem here.

According to definitions here, stored procedures in our server will enable users to define and usetheir own standard extended operations. We'll explore new usage scenarios of stored procedures likeTriggers, Task Scheduling in the near future.

Our approach provides independence of any client, any server and any language implementation whichwill make us write a good IETF RFC about the enhancement.

9.1.1.8. Security

http://www.oracle.com/technology/oramag/oracle/03-jul/o43devjvm.html

9.2. LDAP Triggers

9.2.1. IntroductionThis guide serves as an introduction to architectural concepts related to and administration of Triggersin ApacheDS. ApacheDS is the first server to provide Triggers for LDAP like their counterparts inRDBMS world. The Trigger Model in ApacheDS has been carefully designed to be LDAP standardscompliant and to take advantage of powerful aspects of ApacheDS like The Administrative Model.A Trigger basically provides a mechanism to register some sort of action to be fired upon an event.To restate this considering ApacheDS Triggers, Triggers allow you to register Stored Procedureinvocations to be fired upon any change-inducing LDAP operations on some set of selected entries.Triggers also provides some facilities to make them even more usable like allowing to pass requestparameters to stored procedures. To make the most sense of this powerful construct you need to firstunderstand The Administrative Model and have a look at Stored Procedures.

9.2.2. Trigger SpecificationA Trigger can be specified with three basic components: Action Time , Trigger Event and TriggeredAction . According to a Trigger specification, when a tracked Event occurs an Action gets invokedwith respect to the Action Time. For example if an Add operation (Event) is performed, informationrelated to it may be logged with a Stored Procedure (Triggered Action), just After (Action Time) theAdd operation ended. Here is a sample Trigger Specification:

Page 140: ApacheDS Guide

Draft Triggers & Stored Procedures Draft

© 2003-2010129

The Apache Software Foundation Privacy Policy

AFTER Add CALL "Logger.logAddOperation" ($entry,$attributes,$operationPrincipal);

In this example a Stored Procedure named "Logger.logAddOperation" is executed with three operationspecific arguments After an LDAP Add operation is performed. The operation specific arguments willbe discussed later as well as the not-yet-specified set of entries the Trigger is defined on.

9.2.3. Action Time for TriggersApacheDS LDAP Triggers currently support only AFTER action time scheme. An AFTER Triggersis executed just after the tracked event occurs but before the end of request. So before invokinga Triggered Action with respect to a tracked LDAP operation as a Trigger Event, the operation isexecuted essentially. After the Triggered Action is invoked the operation end completely.

TODO: Order of execution of Triggered Actions when there are more than one Triggered Actionswith respect to an Event.

9.2.4. Trigger Events: LDAP OperationsChange inducing LDAP operations can be specified as Trigger Events in a Trigger Specification. Thefollowing are valid identifiers as Trigger Events:

• Modify

• Add

• Delete

• ModifyDN.Rename

• ModifyDN.Export:Base

• ModifyDN.Export:Subtree

• ModifyDN.Import:Base

• ModifyDN.Import:Subtree

9.2.5. Triggered Actions: LDAP Stored Procedures

9.2.6. Planned New Features for TriggersLDAP Triggers support change inducing LDAP operations as Triggering Events. A more granularapproach can be leveraging operation details, especially for the Modify operation.

An Extended Trigger Specification can be as follows:

AFTER Modify WHEN ChangedAttributes or:{ userPassword, sambaNTPassword } CALL "com.mycompany.ldap.utils.sp.Logger:logModifiedEntry" ( $object, $modification );

Page 141: ApacheDS Guide

Draft Draft

© 2003-2010130

The Apache Software Foundation Privacy Policy

Chapter 10. TuningWork in progress

10.1. Performance TuningThis site is in the process of being reviewed and updated.

10.1.1. Balancing Cache w/ Heap Memory IndexingAttributes

The default partition implementation is based on JDBM. By default it may already index somecommon attributes like objectClass and ou for example. However you really want to index attributesthat your applications use frequently in canned queries.

Adding an index on an attribute is pretty simple. The configuration in the server.xml file needs to bealtered before bulk loading data into the server. Otherwise your index will not work properly.

Indices must be configured before loading data into the server. Indices configured after loadingentries into the server will NOT work properly unless they are built using the index buildercommand supplied with the ApacheDS tools command line program. More information on thisin the Building Indices section below.

Indices are configured in the partition configuration section of yourserver.xml. Each partition will have it's own set of indexed attributes.These index configurations reside under the indexedAttributes property ofthe org.apache.directory.server.core.partition.impl.btree.MutableBTreePartitionConfiguration springbean. Here's that section for the stock dc=example,dc=com partition that is configured out of the boxwith ApacheDS.

<property name="indexedAttributes"> <set> <bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"> <property name="attributeId"><value>1.2.6.1.4.1.18060.1.1.1.3.1</value></property> <property name="cacheSize"><value>100</value></property> </bean> <bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"> <property name="attributeId"><value>1.2.6.1.4.1.18060.1.1.1.3.2</value></property> <property name="cacheSize"><value>100</value></property> </bean> <bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"> <property name="attributeId"><value>1.2.6.1.4.1.18060.1.1.1.3.3</value></property> <property name="cacheSize"><value>100</value></property> </bean> <bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"> <property name="attributeId"><value>1.2.6.1.4.1.18060.1.1.1.3.4</value></property> <property name="cacheSize"><value>100</value></property> </bean> <bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"> <property name="attributeId"><value>1.2.6.1.4.1.18060.1.1.1.3.5</value></property> <property name="cacheSize"><value>10</value></property> </bean> <bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"> <property name="attributeId"><value>1.2.6.1.4.1.18060.1.1.1.3.6</value></property> <property name="cacheSize"><value>10</value></property> </bean> <bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"> <property name="attributeId"><value>1.2.6.1.4.1.18060.1.1.1.3.7</value></property> <property name="cacheSize"><value>10</value></property> </bean>

<bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"> <property name="attributeId"><value>dc</value></property> <property name="cacheSize"><value>100</value></property> </bean>

Page 142: ApacheDS Guide

Draft Tuning Draft

© 2003-2010131

The Apache Software Foundation Privacy Policy

<bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"> <property name="attributeId"><value>ou</value></property> <property name="cacheSize"><value>100</value></property> </bean> <bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"> <property name="attributeId"><value>krb5PrincipalName</value></property> <property name="cacheSize"><value>100</value></property> </bean> <bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"> <property name="attributeId"><value>uid</value></property> <property name="cacheSize"><value>100</value></property> </bean> <bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"> <property name="attributeId"><value>objectClass</value></property> <property name="cacheSize"><value>100</value></property> </bean> </set> </property>

As you can see indices are specified using a MutableIndexConfiguration spring bean. Just add oneof these to your existing configuration setting the attributeId to the OID or name of the attribute youwant to index. There is cacheSize parameter used to set the amount of cache on your index as well.Most of the time 100 will suffice no matter how big in capacity your server is.

This number (100) is the number of entries stored in the cache, regardless to their size. Be carefullwhen dealing with huge entries - those which contains jpeg images -

So if I wanted to index the attribute initials all I have to do is append the following xml fragment tothis set of indexed attributes:

<bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"> <property name="attributeId"><value>initials</value></property> <property name="cacheSize"><value>100</value></property> </bean>

That's it. Now queries on initials alone should perform about 50X faster.

Page 143: ApacheDS Guide

Draft Draft

© 2003-2010132

The Apache Software Foundation Privacy Policy

Index