DSMLGateway is an xml-rpc server. DSML is an XML markup language
for LDAP (directory) content. At this point, it can represent directory
entries (data) and schema, but it does not yet have a query mechanism.
Queries must still be formulated and executed natively with LDAP.
The 1.0 specification of DSML was developed by a number of companies,
including Bowstreet, IBM, Netscape, Microsoft, Novell, and Oracle, and
submitted to OASIS 12/7/1999. Continued development will happen in OASIS.
Read about DSML at http://www.dsml.org.
Directories are primarily used to store information about users, for
purposes of authentication and for querying user profiles. Read about LDAP
deployment in Understanding
and Deploying Ldap Directory Services and about programming LDAP
in
LDAP
Programming with Java.
Data in LDAP is stored as hierarchically organized entries. Generally,
a single entry contains all the information (attributes) for a particular
user, although a deployment may split up the information into multiple
entries. A standard LDAP command-line search program reports the results
in LDIF (Lightweight Directory Interchange Format), for example:
java LDAPSearch -b "o=mcom.com" "uid=scarter"
dn: uid=scarter, ou=People, o=mcom.com
cn: Sam Carter
sn: Carter
givenname: Sam
objectclass: top
ou: Accounting
l: Sunnyvale
uid: scarter
mail: scarter@mcom.com
telephonenumber: +1 408 555 4798
facsimiletelephonenumber: +1 408 555 9751
roomnumber: 4612
The format has each attribute name followed by a colon and a value. If an attribute has multiple values, there is a line for each one. In DSML, the format would be:
java LDAPSearch -X -b "o=mcom.com" "uid=scarter"
<dsml:dsml xmlns:dsml="http://www.dsml.org/DSML">
<dsml:directory-entries>
<dsml:entry dn="uid=scarter, ou=People,
o=mcom.com">
<dsml:attr name="cn">
<dsml:value>Sam
Carter</dsml:value>
</dsml:attr>
<dsml:attr name="sn">
<dsml:value>Carter</dsml:value>
</dsml:attr>
<dsml:attr name="givenname">
<dsml:value>Sam</dsml:value>
</dsml:attr>
<dsml:objectclass>top</dsml:objectclass>
<dsml:objectclass>person</dsml:objectclass>
<dsml:objectclass>organizationalPerson</dsml:objectclass>
<dsml:objectclass>inetOrgPerson</dsml:objectclass>
<dsml:attr name="ou">
<dsml:value>Accounting</dsml:value>
<dsml:value>People</dsml:value>
</dsml:attr>
<dsml:attr name="l">
<dsml:value>Sunnyvale</dsml:value>
</dsml:attr>
<dsml:attr name="uid">
<dsml:value>scarter</dsml:value>
</dsml:attr>
<dsml:attr name="mail">
<dsml:value>scarter@mcom.com</dsml:value>
</dsml:attr>
<dsml:attr name="telephonenumber">
<dsml:value>+1
408 555 4798</dsml:value>
</dsml:attr>
<dsml:attr name="facsimiletelephonenumber">
<dsml:value>+1
408 555 9751</dsml:value>
</dsml:attr>
<dsml:attr name="roomnumber">
<dsml:value>4612</dsml:value>
</dsml:attr>
</dsml:entry>
</dsml:directory-entries>
</dsml:dsml>
Authenticate is straightforward and could have been easily implemented without changes to the Userland xml-rpc code. You send a username and password and the server returns success or failure.
Search is a different story. A directory search could return hundreds or thousands or millions of results. Having the server accumulate all these results and then send them back to the client as the return value of the method call would just not work. So for this, the server returns results in a streaming way as soon as each result is available (from the directory, which also supplies results in a streaming way) and the client must process them as they arrive. That required major changes on both the server and the client side. The client registers a ResultListener with the xml-rpc client implementation to receive results as they arrive.
The prototype includes a modified xml-rpc Web server, so it's ready
to run from the command-line.
You start up the xml-rpc server with options to tell it where the LDAP server is and what its base DN is (the top of the data tree where there is user information):
java WebServer
Usage: java WebServer -b LDAPBASE [-h LDAPHOST]
[-p LDAPPORT] [-w WEBPORT] [-D]
Defaults: LDAPHOST=localhost, LDAPPORT=389,
WEBPORT=8080, no debug
Example: java WebServer -b "o=airius.com"
-h ldap.airius.com -p 3890 -w 8000 -D
java WebServer -b "o=airius.com"
started web server on port 8080
DsmlClient client = new DsmlClient
(url);
Vector v = new Vector ();
v.addElement( args[ind++] );
v.addElement( args[ind++] );
Object res = client.execute ("dsml.authenticate",
v);
System.out.println( "Result: " + res
);
DsmlClient requires the HTTP URL of the xml-rpc server. The arguments are a user ID and a password. The result is a string: "OK" or "Failed".
Search requires a little more, since it processes streaming results instead of a return value:
DsmlClient client = new DsmlClient
(url);
client.setResultListener( new ResultPrinter()
);
Vector v = new Vector ();
v.addElement( args[ind++] );
Object res = client.execute ("dsml.search",
v);
// The results were streamed back,
so res only contains the final
// result
/**
* Implementation to print out results
as they arrive. For LDAP
* searching, it is called once for
each returned entry.
*/
class ResultPrinter implements ResultListener
{
public void result( Object o ) {
System.out.print( o.toString() );
System.out.flush();
}
Search takes an LDAP search expression as argument, for example:
"objectclass=person" for all users
"sn=carter" for all users with the last name carter
"cn=sam*" for users with names starting with "sam" (case-insensitive)
"(&(givenname=sam)(l=mountain view))" for users named "sam"
living in "mountain view"
The method currently does not take credentials as an argument, so the
assumption is that the directory allows anonymous searches (which is not
always the case, but is quite common). Another desirable future extension
would be to allow specifying which attributes to return for each user,
rather than returning all possible attributes for each result. The prototype
always does a subtree search from the specified starting point (when starting
the server). LDAP allows specifying a one-level search as well, but that
was considered unimportant for this prototype.
authenticate
java Authenticate
Usage: java Authenticate [-D] ServerURL USERNAME
PASSWORD
search
java Search
Usage: java Search [-D] ServerURL SEARCHEXPRESSION
Rob Weltman
robw@worldspot.com