Tuesday, June 30, 2009

Active Directory Hell

I've spent a number of years playing at knowing a thing or two about LDAP but I've managed to avoid spending any worthwhile time playing with Active Directory.

Now, the observant amongst you will notice that I succeeded in writing a sentence that included LDAP and Active Directory. Active Directory is merely LDAPpy, for want of a better word (though now I've written it, I'm quite pleased with the way it looks and sounds).

Today, I had to work out how to write an attribute into an Active Directory instance. Trivial. At least, I thought it would be trivial. The attribute is a schema extension and is used to store a binary representation of a GUID. GUIDs are things I can handle... a lengthy string of HEXish characters! What could be easier.

Well, things are never straightforward. I have some VBScript which details how the GUID should be "manipulated" by taking the two characters starting at position 7, then the two characters starting at position 5, etc., etc. The resulting string of two character hex codes is still quite lengthy but quite jumbled from the original GUID. But here is where the fun begins. This attribute is of type java.lang.String (according to the schema) but is actually a binary object! The VBScript opens an ADODB.stream object (of type text) into which it places the ChrB representations of the HEX codes. It then strips of the UTF-8 marker and rereads the stream as a binary object before putting it into the directory.

Why? I have no idea other than someone said their application performed better if it was done that way!

Now... how do you create a stream object of type text, split of the UTF-8 marker then commit the resulting stream as a binary object from within Java?

I struggled, I can tell you. And my dear old friend Google wasn't being much help. In exasperation, I decided to test that I wasn't banging my head off a brick wall. My AD instance already had examples of accounts with these particular attributes populated by the VBScript routine. I was able to extract this data using IBM Tivoli Directory Integrater and inspect each byte. I was then able to determine exactly how the binary value was being created and recreated the object in code.

However, committing this object to AD failed with some kind of attribute constraint. I was mystified. After much scratching of the head, I decided to create an Assembly Line with the following 2 connectors:
  1. Lookup AD for a particular user entry
  2. Update the same user entry in AD with the attribute values retrieved in step 1

In other words, try to update the AD object with the same values that it already has.

It failed. Attribute Constraint! So, by merely reading some data and writing it directly back to the source, I managed to generate an attribute constraint error.

I may give up... I'm not happy with the way AD behaves and I'm certainly unhappy with the VBScript. I suspect the fact that the attribute is defined as a String but is storing a binary object is the route of all the evil. So today has ended on a low... no resolution as yet to a problem which I suspect may not be solved by conventional methods.

No comments: