========================================================================= JavaLDAP - An LDAP server written in Java (c) 2000 Clayton Donley All Rights Reserved http://javaldap.sourceforge.net/ ========================================================================= LICENSE ------- This software can be distributed and modified under the terms of the GNU Public License (GPL). REQUIREMENTS ------------ The Xerces J XML parser is required for DSML Schema support. You can retrieve the source from the http://xml.apache.org/. The BER encoder/decoder classes required can be found in IBM's SNACC for Java compiler on Alphaworks (www.alphaworks.ibm.com) or in IBM's JNDI LDAP provider. Either should work. People wishing to use the JDBC backend need a JDBC driver for their database. INTRODUCTION ------------ The JavaLDAP Server acts as an LDAP protocol engine that can provide access to information from a variety of sources to an LDAP-capable client. A memory backend is mostly functional, while a JDBC backend is now available that allows a database to be used as a data source. Schema checking works at the object class level and LDAP schema can be loaded from Directory Services Markup Language (DSML) files, as described at http://www.dsml.org/. Access control is now supported and mostly compliant with the latest Internet Draft published by the IETF's LDAPEXT working group. You can find more about this at the IETF site at http://www.ietf.org/. A big focus in this release was on streamlining performance. Buffered IO streams are now used as well as a few other network enchancements. On a Pentium III laptop with the memory backend, it is possible to load 10,000 entries in 10 seconds over LDAP (not a special bulk loading tool) and the DirectoryMark benchmark (www.mindcraft.com) with equality and presence searches does around 1000 operations per second. Work needs to be done to streamline the JDBC backend, as its performance is not even close on the same class of machine. INSTALLING ---------- Unpack the archive and change into the top directory. Edit the paths at the top of the 'javaldap.sh' or 'javaldap.bat' file. Edit javaldap.prop to set the port number and paths to other configuration information. This is also where you will set the superuser's information and information for the JDBC backend if necessary (that config will be moved to backends.prop in the next snapshot). Edit backends.prop to change or add any top-level naming context and the class implementing Backend that will manage that context. Edit acls.prop as necessary if you want non-root users to have access to things. It fully supports the current IETF internet draft for LDAP access control with the following exceptions: o Authentication type is ignored o Only authzid-dn, this, and public are supported subject types o ACLs can not yet contain both grant and deny permissions Now 'javaldap.sh' or 'javaldap.bat'. The server will start on port 10389. Change the port to 389 if you want the LDAP default and have appropriate permissions on your system. GENERAL DESIGN -------------- The classes under org.javaldap.ldapv3 were generated by the IBM Snacc for Java compiler. These classes mostly instantiate information objects that can be encoded/decoded using Basic Encoding Rules (BER). Some changes were made from the original generated output in order for everything to work. The stuff under org.javaldap.server does everything not involved with the actual encoding/decoding of LDAP transmissions. This includes the following packages: o org.javaldap.server.acl Contains the ACL class and the ACLChecker class. The later is responsible for initializing and checking access controls on the directory based on the acls.prop file. At this time the server needs to be restarted in order to reread acls.prop if that file is changed. o org.javaldap.server.backend Contains the abstract Backend class and a number of classes that realize that class. The BackendHandler figures out which backend to use based on the 'backend.prop' file. o org.javaldap.server.operation Contains the classes that handle each LDAP operation. These classes are responsible for taking a request message and sending back one or more response messages. These classes may do some of their own work, but pass anything related to backend information back to the BackendHandler. o org.javaldap.server.schema Includes a class for ObjectClass and AttributeType, the SchemaChecker class, and a few classes for parsing a file containing DSML schema definitions. o org.javaldap.server.syntax Currently only contains the DirectoryString class. Will add more to support other syntaxes as AttributeTypes are used in any real manner by the schema subsystem. o org.javaldap.server.util Contains exceptions and utilities for parsing distinguished names. o org.javaldap.btree The simple memory-based B-Tree used by the memory backend. Some important classes also exist in the org.javaldap.server package itself. o LDAPServer - Basically starts a new ServerSocket and listens for new connections. Starts a new ConnectionHandler thread for each new incoming connection. o ConnectionHandler - Creates a new connection object that holds information about the current connection. Loops on getting and answering requests. o Connection - Holds information about the socket being used and the MessageHandler for this connection. o MessageHandler - Holds information on the BER encoder/decoder object that will be used to encode/decode all LDAP messages. The getNextRequest method calls the low-level decoder to retrieve the next LDAPMessage. The sendResponse method actually encodes the response LDAPMessage. The answerRequest method actually checks the type of message that has been retrieved, and calls a 'doXXXX' method with the request data. The doXXXX methods will instantiate new Operation classes and send them call them as appropriate. o Entry - Subclassed from Hashtable. Basically a Hashtable with Vector values. Each Entry also has a name (DN) and a base. o EntryChange - Contains the changes to be performed on a particular entry. Used in the modify operation. o EntrySet - This is an interface implemented by GenericEntrySet and JDBCEntrySet that knows how to read the next result generated by the backend. This way we don't have to read all results into memory in advance and return them as a Vector or other such object. Here are some of the important classes in the backend package. o BackendHandler - A class using a singleton pattern that is used by all threads to communicate with the various backends. It will select a single backend based on the base or entry name when doing change operations. Multiple backends may be selected for searches. At the moment, the BackendHandler also has a Hashtable that maps various root contexts to an instance of a class implementing Backend. o Backend - An abstract class that is implemented by all backends. o BaseBackend - Realizes the Backend abstract class, but simply returns errors for all operations. Useful superclass for backends that only allow searches - BackendSchema for example. o BackendMemory - A simple backend that implements a simple Hashtable with Entry values. Substring searches and NOT searches are not implemented, but everything else should work. o BackendJDBC - A backend that uses a particular set of database tables to persist information in a way that is easy to use with LDAP. A separate BackendDB will offer a mapping layer so that existing databases can be used. o BackendSchema - Returns the schema as an LDAP entry. Currently only returns object classes, though pretty simple to add other things. o BackendRoot - Returns information about the LDAP server, such as the root context and other information. FUNCTIONAL LIMITATIONS ---------------------- - Only simple authentication is supported and passwords are stored in clear text on the server (though ACLs allow us to restrict who can see this over LDAP). Need to add support for SHA and CRYPT password storage at a minimum and SASL authentication mechanisms. - A few limitations with ACLs, as described earlier, with the ACLChecker. New operations and root attributes described in Internet Draft are not yet implemented. Also should make ACLs changable/viewable via LDAP protocol. - Need to make some of the exception handling more consistent. Sometimes we throw DirectoryExceptions, while other times we return LDAP result codes. - Need better performance in BackendJDBC. Works miserably with HSQL and other Java RDBMSes. - Need to work with the Cryptix folks to help them with their ASN.1 kit. They are rewriting it and I'd like to spend some time to help them add BER encoding to the class. Until then we'll continue to use the IBM ASN.1 encoder/decoder. SAMPLE SESSION -------------- Here was a sample session using the OpenLDAP tools to manipulate the directory. [donley@claytond tools]$ ./ldapadd -p 10389 dn: cn=Test,o=javaldap,c=US objectclass: organizationalPerson cn: Test sn: Test adding new entry cn=Test,o=javaldap,c=US [donley@claytond tools]$ ./ldapsearch -p 10389 "objectclass=*" -L dn: cn=Test,o=javaldap,c=US objectclass: person objectclass: top objectclass: organizationalPerson cn: Test sn: Test [donley@claytond tools]$ ./ldapmodify -p 10389 dn: cn=Test,o=javaldap,c=US changetype: modify add: title title: CEO modifying entry cn=Test,o=javaldap,c=US [donley@claytond tools]$ ./ldapsearch -p 10389 "objectclass=*" -L dn: cn=Test,o=javaldap,c=US title: CEO objectclass: top objectclass: person objectclass: organizationalPerson cn: Test sn: Test