TRIVIAL-LDAP is a one file, all Common Lisp client implementation of
parts of RFC 2261.
WARNING: This is beta software. While I believe the API
documented below is correct it is subject to change. Also, do
not run execute the example.lisp program against a production LDAP
directory, it will delete your entries.
Introduction This LDAP client came about as a result of
some functionality I required for a different project altogether.
As a result it provides functionality that is general enough but
probably not in typical low-level API fashion. (For instance, a
"real" LDAP library would probably tackle the BER encoding
separately.) However, as there is a lack of Common Lisp LDAP
clients out there I thought I'd share.
I am open to both requests for features and suggestions for
improving my Lisp code. There are features I will be implementing
in the short term but for the sake of not creating false
expectations neither a comprehensive list nor timeframe is
You can reach me at email@example.com.
- 2009-10-23 (v0.92)
- Applied a patch supplied by Faré to provide support for
- 2009-08-16 (v0.91)
- Applied a patch supplied by Nick Dannenberg to fix UTF-8
handling for SBCL and CCL. My sincerest appreciation for taking
the time to generate and send the patch along!
- 2009-03-12 (v0.90)
- Applied patches kindly provided by Slawek Zak.
Thanks to Slawek for taking the time to send the patches!
- Enable UTF-8 encoding for Allegro.
- Fixed a compilation failure on Allegro where a number
of constants were not properly defined.
- Fixed the dosearch macro for cases where the LDAP
variable is lexical.
- 2007-01-12 (v0.80)
- Converted from trivial-socket to usocket: indications
were that trivial-socket has been deprecated.
- Added support for SSL with CL+SSL. Setting the ldap
sslflag to T or
port slot to 636 will force an encrypted
connection. Do note that this is not TLS, just ldaps://
... I don't require TLS; if you do, drop me a line.
- Added functionality to ease the pain of short slapd
idletimeouts. The ldap object
reuse-connection may be set to NIL (the
default) to not attempt reopening connections, T to reopen
the connection before each request, or TRIVIAL-LDAP:REBIND
if the connection should be opened and a bind message sent
before each request (except, of course, the bind request
- A couple of documentation and logic bugs were corrected
Acknowledgments I would like to thank Zach Beane for his
many helpful comments and suggestions. Thanks also to Ed Symanzik
for pointing out a number inconsistencies in the code and
License TRIVIAL-LDAP is distributed under the Clarified
Artistic License, a copy of which is included in the downloadable
Requirements TRIVIAL-LDAP has been tested under OpenMCL 1.0
(OS X/PPC), SBCL 0.9.7 (OS X/PPC), and SBCL 1.0 (OS X/Intel).
I would assume any CL that is supported by usockets and CL+SSL
would have no issues with this code. If you encounter problems
let me know.
Two external packages, usocket and CL+SSL, are required.
CL+SSL itself requires trivial-gray-streams, flexi-streams, and
cffi. These may be downloaded from:
The trivial-gray-streams project is part of the CL+SSL project.
(Note: to get CL+SSL working on OS X/Intel it was necessary to
re-compile openssl with the -m64 flag.)
Missing functionality, as specified by RFC 2251, includes:
I do not require this functionality myself, but if there was
interest I would consider augmenting TRIVIAL-LDAP with some of
this missing functionality.
- UTF-8 is not implemented for all CL implementations
- SASL authentication is not implemented
- controls are not implemented
- extended DN searches are not implemented
- referrals are not followed
- extended request/response is not implemented
LDAP object and associated methods.
new-ldap &key (host "localhost")
(port 389) user pass base debug [function]
- Return an LDAP object.
- Get/set the host slot value of
ldap-object. Slot value will be a string.
port ldap-object [method]
- Get/set the port slot value of
ldap-object. Slot value will be an integer. If the sslflag slot
is NIL, defaults to 389; if sslflag slot is T, defaults to 636.
If the port parameter is manually set to 636 an SSL connection is
used unless the sslflag is explicitly set to nil.
user ldap-object [method]
- Get/set the user DN to bind as. Slot
value will be a string.
pass ldap-object [method]
- Get/set the simple password to bind with.
Slot value will be a string.
base ldap-object [method]
- Get/set the default base DN for searches.
Slot value will be a string.
- Get/set the debug flag. Slot value will be T or NIL. When
value is T debug output will be written to *debug-io*.
- Get/set the SSL flag. When T the default port is 636 and a
CL+SSL stream is used. Defaults to nil. Note that if the port
slot is explicitly set to 636 an SSL connection is used unless the
sslflag slot is set to nil explicitly.
- Get/set the reuse-connection slot parameter. When T re-open
the stream before each reqest; when LDAP:REBIND open the stream
and send an (ldap:bind ldap-object) message; when nil, don't do
anything special. Set to NIL by default.
Entry object and associated methods
new-entry dn &key (attrs ())
(infer-rdn t) [function]
- Return a new entry object with the DN specified.
attrs, if specified, will be an alist of
attribute/value pairs. If
infer-rdn is T the RDN
attribute and value will be appended to the attribute list.
- Return the DN value for entry-object.
- Return the RDN value for entry-object
- Change the RDN (and therefore DN) of an
entry-object. The RDN attribute and value will be updated in the
attribute list. No LDAP directory transactions will take place.
- Return the list of attribute symbols
belonging to entry-object
- Return a list of values associated with
attr. Return NIL if the attribute does
not exist. If a list of attributes is passed, return a list of
lists of values.
add-attr entry-object attr
- Add the specified attribute with the value
or values specified to the entry object's attribute list. Returns
the entire list of attributes/values. No LDAP directory transactions
will take place.
del-attr entry-object attr
&optional values [method]
- Delete the specified attribute (or values
for attribute) from the entry object's attribute list. Returns
the entire list of attributes/values. No LDAP directory
transactions will take place.
replace-attr entry-object attribute
- Replace current attribute values with
values specified. Returns the entire list of attributes/values.
No LDAP directory transactions will take place.
- Return an LDIF representation of entry (as a string).
NB: Methods below that are specialized first on ldap-object will
return three values: T/NIL indicating success or failure, the LDAP
response code (these are exported from the TRIVIAL-LDAP package as
symbols), and third, any response message received from the LDAP
directory server (as a string).
Methods specialized first on entry-object will return T (or T/NIL
in the case of compare) and will throw an ldap-response-error if a
response from the LDAP directory server is other than succesful.
dn-or-entry can be either an entry-object or a DN string.
dn is a string. Generally if the method only requires the DN
either the entry or the DN will be acceptable arguments.
- Send a bind request to the LDAP directory server.
- Send an unbind request to the LDAP
directory server and close the stream.
- Send an abandon request to the LDAP
directory server and purge any data on the stream waiting to be
add ldap-object entry-object
add entry-object ldap-object
- Add an entry described by entry-object to
the directory specified by ldap-object.
delete dn ldap-object
- Delete entry from directory specified by
dn-or-entry may be an entry object or a
moddn ldap-object dn-or-entry
new-rdn &key delete-old new-sup [method]
moddn entry-object ldap-object
new-rdn &key delete-old new-sup
moddn dn ldap-object new-rdn &key
- Modify the RDN specified by
dn-or-entry to the replacement RDN
dn-or-entry may be either an
entry object or DN string. If an object is specified, the DN and
attribute associated with the RDN slot values are modified as well
as the directory specified by ldap-object.
compare ldap-object dn-or-entry
attribute value [method]
entry-object ldap-object attribute value
- Send a compare message to the directory
server asserting that entry-obj (or DN) has an attribute
attribute with a value
either T or NIL (as the only argument or as the first argument)
indicating a return code of compareTrue or compareFalse.
modify ldap-object dn-or-entry
modify entry-object ldap-object
- Modify the entry specified by
list-of-mods is a list of (type attribute value)
triples. Type will be one of ldap:add, ldap:delete, or
search ldap-object filter &key base
(scope 'sub) (deref 'never) (size-limit 0) (time-limit 0)
types-only attributes [method]
- Search the directory specified by
filter is an LDAP filter (as a string).
The outer parens on the filter are optional. The search base
defaults to the base slot-value of the ldap-object. This method
returns T or NIL, indicating results pending or not, respectively.
- After an ldap:search is executed, this
method can be used to return each of the entry objects that search
resulted in. next-search-result will return NIL if no more
results are available.
dosearch var search-form &body
- Execute the ldap:search provided as
search-form and iterate through the results binding
each resulting entry object to
var before evaluating
body. Returns the number of entries processed.
NB: If the body of the loop involves LDAP transactions it
is probably best that a difference LDAP instance be employed.
- Prints the results of a search in LDIF.
This macro is probably most useful in an interactive setting.
ldap-search-args are passed directly to the search
method described above.
Last modified: Sat Jan 13 09:01:44 EST 2007