Recently in Virtual-LDAP Category

You have your new shiny application, and LDAP server on the other side. Easy as pie. What can go wrong?

  • you use e-mail as login, and application assumes that logins don't have domain in them and allows you embedding of whole login into DN
  • application can import various interesting fields using LDAP, but you have data somewhere else, and it doesn't really belong into your LDAP
  • you need to provide subset of data in your database as LDAP server to application

I had written about my saga with LDAP about augmenting LDAP search responses and exposing RDBMS data as LDAP server. But today, I added rewrite of bind, so now I can use unmodified Koha, and all needed quirks for my AAI@EduHr schema are outside application.

This made my attempt to virtualize LDAP almost complete so I created a project page on Ohloh. I will write small updates about status there, so If any of this is interesting to you, hop over there.

Have you ever wondered how exactly LDAP groups work? Well, I did last week and here are my findings...

LDAP for Rocket Scientists description of LDAP groups was first one around which I can wrap my mind. However, it has small error so I will reproduce corrected version here:

# LDIF fragment to create group branch under root

dn: ou=groups,dc=example,dc=com
objectclass:organizationalunit
ou: groups
description: generic groups branch

# create the itpeople entry

dn: cn=itpeople,ou=groups,dc=example,dc=com
objectclass: groupofnames
cn: itpeople
description: IT security group
# add the group members all of which are 
# assumed to exist under people
member: cn=road runner,ou=people,dc=example,dc=com
member: cn=micky mouse,ou=people,dc=example,dc=com
Ok, so we need to make two objects in LDAP directory to create single group.
But, where did groupofnames came from?

Warning: rant ahead! I had idea that whole point of very strict schema checking in LDAP is to have single way of defining entities in directory. Did we got there? Let's see data from IBM Technote:

server person group
objectclassnameunique objectclass member attribute nameunique
Lotus Domino LDAP Directory organizationalPerson cn mail groupOfNames member cn description
Netscape Directory Server organizationalPerson cn mail groupOfUniqueNames uniquemember cn description
Microsoft Exchange 5.5 organizationalPerson cn mail groupOfNames member cn description
Microsoft Active Directory organizationalPerson userPrincipalName cn group member cn description

Right... I can clearly see why strict LDAP schema was good idea.

Let's assume that we have two systems, one which support LDAP user accounts and other system, based on relational database (Koha, in this example) which has user information which you would like to expose using LDAP for first system.

We could export all data required into institution LDAP, but that would push a lot of junk which is really required only by one application. Worse yet, some of that data is somewhat sensitive because it include serial numbers (SID) and data from RFID cards.

But, since application supports LDAP and we have Net::LDAP::Server it should be easy! And it really is.

LDAP server accessing Koha database using DBI is really converter of LDAP search query into SQL where syntax which is than appended to initial select which returns attribute values for LDAP entry which will be returned for search request.

This small example will hopefully be useful to other people who would like to integrate two systems by exposing user data via LDAP protocol. Just remember that pushing real valid usable data back to LDAP always makes more sense if that data is useful for current or future systems...

PerlMonks has node with this annoucement, so you might want to comment there if it's in interest of general perl comunity

This weekend I worked on LDAP mungling: we needed to roll-out Koha with LDAP support, but at the same time, central LDAP server didn't have all data (date of birth, gender and address) needed for full entry about user in Koha. We had those data available as CSV export from other systems.

There are many ways to tackle this problem from modifying Koha LDAP support (which I was somewhat reluctant to do) to importing data back into LDAP. However, none of those things can be done in just one day, so I decided to write small LDAP proxy which will do data marging for me.

I started with Net::LDAP::Server based solution implemented by LDAP::Virtual module, but soon I stumbled upon problem of compareRequest which I couldn't implement correctly. Since it's required for login this was show-stopper.

After a bit of searching, I found simple-proxy.pl which is part of Net::LDAP. This is simpler script which operates directly on sockets and ASN encoding of entries. It's very useful in debugging, so I decided to re-implement modification of searchResEntry from LDAP server as ldap-rewrite.pl with following changes:

  • augment LDAP entry with data from YAML file (with configurable prefix for attribute names)
  • support SSL to upstream LDAP server
  • expand attributes with multiple values into separate attribute for each occurrence (to enable easy import of second value from attribute address using something like address_1 (it's 0 based, same as perl arrays)
  • generate additional attributes using concatenation of prefix: from data and attribute name (to get hrEduPersonUniqueNumber_JMBG from attribute hrEduPersonUniqueNumber which has JMBG: 1234567890 as value)

To keep it really KISS I used yaml files named as dn (for example, uid=dpavlin,dc=example,dc=com.yaml) for simple, human readable file fromat. This enabled me to separate data-mungling part into csv2yaml.pl. In this script, I converted values from CSV delimited by # into separate attributes, detect phone numbers which are mobile or fixed and do other tweaks (like gender mapping). YAML files are also nice if I want to implement audit trail of changes: I can just import them all into git and be done with it.

For future versions, I can envision that overlay data can also be fetched from database, so I can add additional attributes to LDAP entries directly from Koha database. This will be useful when connecting with copiers which require LDAP with card number for each user which isn't available in upstream LDAP directory.

Not bad for 4k of perl code :-) I hope this will help you use LDAP as directory for different data as opposed to just login service. Don't forget to push all useful data back to LDAP server, so that all application can take benefit from it without need to worry about source data format.

About this Archive

This page is an archive of recent entries in the Virtual-LDAP category.

Sack is the previous category.

Z39.50 is the next category.

Find recent content on the main index or look in the archives to find all content.

Pages

  • pics
OpenID accepted here Learn more about OpenID
Powered by Movable Type 5.04