I recently did a bit of work with the Ruby Net::LDAP library, and found it to be very useful. When working with LDAP attributes that store binary data, however, I have just one word of advice: arrays!
The Net::LDAP library makes it easy to add and update attributes for entities in your LDAP. The modify method takes an array of operations to perform as one of its arguments, and according to the documentation, each operation is also an array, with the following three elements:
an operator: must be :add, :replace, or :delete an attribute name: the attribute name (string or symbol) to modify a value: either a string or an array of strings
So when updating the email address for an entity, the operation array would look something like this:
ops = [[:replace, :mail, "email@example.com"]] ldap.modify( :dn => "uid=xxx,ou=people...", :operations => ops )
Now consider the case of storing images in your LDAP, using a jpegPhoto attribute. That attribute stores the image as binary data, so the operation array would need a binary string as its third element. To achieve this, I used the following block of code:
img = File.open("path/to/image.jpg", "rb") { |f| f.read } ops = [[:replace, :jpegPhoto, img]] ldap.modify( :dn => "uid=xxx,ou=people...", :operations => ops )
Using this operation array, however, the modify method was failing for me every time. And the message returned by the get_operation_result method always stated “Attribute or Value exists,” even for records where I was sure that no jpegPhoto attribute was present.
After much searching around in vain for an explanation as to why the modify operation was failing, I ended up back at the Net::LDAP documentation for the modify method (quoted above). And noticing that the third element in the operation array could be either a string or an array of strings, I decided to try:
img = File.open("path/to/image.jpg", "rb") { |f| f.read } ops = [[:replace, :jpegPhoto, [img]]] ldap.modify( :dn => "uid=xxx,ou=people...", :operations => ops )
And sure enough, it worked. Note the subtle difference on the second line: the value being assigned to the jpegPhoto attribute is an array that contains exactly one element, the binary string, instead of just the binary string itself — that makes all the difference. And after a little testing, I realized this is true across the board; whenever you’re working with a binary string, you’ll save yourself a lot of headaches if you always remember to place it in an array before using it in an LDAP operation.
Leave a message
08-22-2008
Frederic says:
This is a lifesaving post.
Thanks a lot for sharing your experience !