Jumping over LDAP hurdles

LDAP is nothing new, but until recently I had never had the need to create LDAP lookups from an application to a directory server. Most of today’s platforms are usually LDAP compliant and handle this themselves, thereby abstracting developers and administrators from the LDAP server internals. Under normal circumstances you just have to read the platform/framework configuration documentation, create a system account for the application to use to bind to the LDAP server, and the platform takes care of the rest itself… well more or less :-).

Context

In the past I have read a lot about LDAP, and for some reason I had got the idea in my head that working with LDAP was difficult. In practice it turned out to be pretty simple once you got past a few hurdles. The ASP.NET application I was maintaining needed to switch from LDAP services supplied by Lotus Domino to Microsoft Active Directory. The application was using Active Directory for user authentication, but for all the other services it was using the LDAP directory supplied by Lotus Domino. There were historic reasons why this was the case, but it didn’t make sense anymore. To make matters worse, the data in two directory services were not synchronized so users were complaining that their user data was displayed incorrectly in the application UI. Of course this was true since it was being read from a mix of directory servers.

From my brief experience from working with this technology there are three basic hurdles you need to jump over to get something working.

Binding

The first thing you need to do is bind to a LDAP directory which is LDAP jargon for authenticating to the LDAP server. It sounds simple enough… However, when creating a URL I usually write the protocol specifier using lowercase characters. Doing this was giving me a very cryptic error from the Microsoft .NET runtime since I was using a protocol specifier that looked similar to ldap://server/query… Luckily Google was my friend on this occasion and I soon found out why I was getting complaints from the .NET runtime environment. It seems the .NET System.DirectoryServices.DirectoryEntry class does not like the protocol specifier in lowercase characters when connecting with Active Directory, so ldap:// has to be converted to LDAP:// which I still find to be a bit strange. Is this a platform specific bug? I could not find any information in any LDAP documentation that specifies that this is necessary…

Directory structure

The next thing to do is get familiar with your specific directory structure. I used the free Softerra LDAP browser to help me here. It will let you query the directory and display the results. It will also let you traverse the tree using the GUI which is useful to get a feel for the LDAP tree. Your tree will probably be site specific and you will need to know where to look to create a meaningful and efficient LDAP query. For lookup efficiency you should avoid starting your query at the directory’s root node. I was working for a large enterprise with thousands of users and groups. Starting a query at the wrong place would kill performance. In my case I was using an auto-complete function on the UI to call upon a backend lookup service so it had to be fast.

LDAP query syntax

Building the LDAP query is where you probably will spend most of your time. The query syntax itself may seem difficult to read at first, but you get used to it fast. If you’ve ever worked with a scientific calculator then I guess you can think of it working much that same way, only backwards :-). So to find an object that has objectclass=person and a shortname attribute starting with “joe” you could write (&(objectclass=person)(shortname=joe*)). The “&” works as a logical AND and the objectclass is the LDAP object type to return (there are other types of standard LDAP objects). Also note the wildcard. To expand our search example to find people with a shortname starting with “joe” or “kent”, the query could be written as (&(objectclass=person)(|(shortname=joe*)(shortname=kent*))). Notice the “|” symbol for the logical OR. Also note the parenthesis in the query limiting the AND and OR functionality. It may be hard to read at first. This is where a LDAP query tool as mentioned above may come in handy when testing your query.

Advertisements

Remember me? I’m your old C++ code…

Just recently I was called upon to fix some code that I had written while working as a consultant “way back” in 1998. It’s not that long ago really, but a lifetime in software developer years. At the time I was fresh out of university so this was my first proper assignment as a professional. I was the sole developer on this project and the code was written in C++ using the Lotus Notes/Domino C++ API. This was kind of the norm back then.

In essence this old code was broken in to four programs. They were all server based batch type jobs, run at scheduled intervals. Their common goal was to maintain the people groups in the Lotus Notes Name & Address book to reflect the structure of the organization (which was, and still is, a large organization). That means creating new groups, removing empty groups and adding/moving group members to and from groups. For a user to gain access to the Lotus Domino servers (for mail and other databases) you had to be a member of a group in the hierarchy, since only the top node (and thereby it’s children) was granted access to the servers. The groups were also used as mailing groups to parts of the organization. It would be kind of “critical” for a user if the program made a mistake and it goes without saying that with so much application business logic you wouldn’t choose C++ for this type of task today.

I was amazed that these old programs were still running!! Sure, one program had been altered by someone else a few times some years ago, but the remaining three were running just as I last compiled them back in October of 1999. I thought that was kind of fun and also made me a bit proud. Of course, I believe there are two reasons why this code has run unaltered for so long:

  1. It was written properly and there was no need to alter it
  2. Nobody understood the source code and therefore dared not make a change

I choose to believe reason one. I guess that’s a shocker! However, I was actually able to confirm this fact when I started to work with the source code once again after all these years. It was tidy and easy to read, although I was amazed just how much of the C++ syntax was now strange to me after many years of programming Java, Python and C#. I would not have made all the same choices that I did back then regarding the architecture, but in general I was kind of impressed. There was also valid documentation, written by me, which I found very useful when trying to get back in to the problem mindset. Not bad!! 🙂

It was strange to use Visual C++ 6.0 again which was the IDE/compiler I worked with originally. I did actually try to upgrade the project to Visual Studio 2008, but the Visual Studio C++ compiler wouldn’t compile the original source code so in the end I gave up trying. It was never part of the new assignment and the C++ syntax was just too unfamiliar to me. The customer didn’t care so I stuck to VC++ for the time being. Maybe in the future if I get the opportunity again I will give it another attempt.

Of course, it goes without saying that the actual source code – released in 1999 – was lost, but luckily enough I found a copy on a CD-ROM at home, which was a relief. It made the job a lot easier, but I guess it also shoots to bits my reason one (above) a bit 🙂