« Hewitt is Right, Arment is Wrong | Main | Interview with »

Zetetic.Ldap - Bringing LDAP + LDIF tools to .NET

We’ve just released the Zetetic.Ldap library to github, which makes it, to the best of our collective knowledge, the first and therefore most kickin’est .NET library for working with RFC 2849 LDIF, LDAP schema, and LDAP entry change tracking.

LDIF: This file format is still the best and most universal way to move data in or out of directory systems like OpenLDAP, Active Directory, Fedora or Red Hat Directory Server, etc. Zetetic.Ldap makes it easy to write and read directory entries with LDIF.

LdifWriter ldif = new LdifWriter(@"c:\temp\stuff.ldif"); 
ldif.BeginEntry("cn=joe cool,o=zetetic");
ldif.WriteAttr("givenName", "joe");
ldif.WriteAttr("jpegPhoto", File.ReadAllBytes(@"c:\temp\joe-photo.jpeg");
ldif.WriteAttr("dateCreated", DateTime.Now);

Zetetic.Ldap knows how to format binary data, dates, and long fields in the proper way — you don’t have to mess with it!

The same is true for reading entries out of an LDIF file.

LdifEntryReader ldif = new LdifEntryReader(@"c:\temp\stuff.ldif"); 
for (Entry entry = ldif.ReadEntry(); entry != null; entry = ldif.ReadEntry())
Console.WriteLine("Found: {0}", entry.DistinguishedName");

We’ve also included a command-line pivoter program that transforms LDIF files into tab-delimited files, for easy loading into Excel, RDBMS, or what-have-you. This can be incredibly useful for analyzing the data in your directory.

Change tracking: Normally, if you’re using Microsoft’s System.DirectoryServices.Protocols classes, you’ve got to manage the concept of preparing specific LDAP modification commands yourself. It can get pretty complicated, and sometimes you have to resort to trial-and-error to learn the right way to delete an attribute, for example, or rename or move an entry. Zetetic.Ldap provides a wrapper around this complexity, and will track your changes until you’re ready to send them to the server.

MutableEntry entry = MutableEntry.CreateUncommitted("cn=frank grimes,o=snpp", "person");
entry.SetAttr("sn", "Grimes");

MutableEntry entry = new MutableEntry(mySearchResult);

Schema: This part is a little more abstract. Directory servers contain an area that describes the allowable objectClasses (types) and attributes (fields), and those attributes have syntaxes (like string, number, date, etc.). The classes in Zetetic.Ldap.Schema help you work with these data programmatically, so you can quickly discover what the server supports. Moreover, you can find out what kind of value (syntax) each attribute uses conceptually, without delving into the world of OIDs.

Here’s a snippet from the project’s unit tests, showing how to export the basic objectClass definitions from a Microsoft LDAP server.

ISchemaInfo target = new AdsSchemaInfo();
using (LdapConnection conn = new LdapConnection("localhost:20389"))

foreach (ObjectClassSchema o in target.ObjectClasses)
System.Console.WriteLine("oc: {0}", o);
foreach (AttributeSchema a in o.MustHave)
System.Console.WriteLine(" must: {0} as {1}", a, a.LangType);

foreach (AttributeSchema a in o.MayHave)
System.Console.WriteLine(" may : {0} as {1}", a, a.LangType);

We also included some helpers to manage parsing special attributes like GUIDs, or “pwdLastSet” and “accountExpires,” which are usually treated like DateTimes, but stored as 64-bit integers, sometimes outside the range of what DateTime can handle—I always enjoy telling people, “Oh, it’s simply the number of 100-nanosecond intervals since January 1, 1601 UTC!”

So anyway, when you find yourself working with LDAP or LDIF on .NET, grab the release at github, and drop us a line, we’d love to know how you like it.

Reader Comments

There are no comments for this journal entry. To create a new comment, use the form below.

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>