Rails and LDAP gotchas

I’ve spent some time over the last few days trying to access a Microsoft Active Directory (AD) using LDAP from a Rails app. Although there are some libraries and a few blog posts, this is still a very painful thing to do.

Here’s some things I worked through so you don’t have to.

LDAP paths are location dependent, but not case sensitive

Not a Ruby or Rails issue, but something you need to know – “dc=foo,dc=com” is not the same as “dc=com,dc=foo”. However, DC=Foo,DC=com is the same as dc=foo,dc=com

Pre-built Windows ruby-ldap needs no other LDAP libraries

Chris Scharf has built the ruby ldap libraries for Windows Although the ruby-ldap site says the code relies on other libraries, on Windows, that code is built in.

Here’s some ruby-ldap code that works with my AD server:

require 'ldap'

conn = LDAP::Conn.new( '<domain-server>', 389 )
conn.set_option( LDAP::LDAP_OPT_PROTOCOL_VERSION, 3 )
conn.bind( '<domain>\<username>', '<password>' ) do |conn|

  base = 'ou=Users,ou=<container>,dc=<domain>,dc=local'

  results = conn.search2(base, LDAP::LDAP_SCOPE_SUBTREE, '(cn=*)')
  results.each { |entry| puts "#{entry['dn']}: #{entry['telephoneNumber']}" }

end

Note: I’m using a Small Business Server, and the container for me is MyBusiness. Also, my full domain name is .local.

Most ActiveLDAP document is wrong

ActiveLDAP is getting closer to ActiveRecord in the way it works, and a bunch of the initialization code has changed to do this, but the documentation is not entirely correct. I have version 0.8 and here’s what I know:

  • Use ActiveLdap::Base.establish_connection to setup the connection
  • :password can now be used instead of :password_block
  • :user isn’t yet used (but is documented) – use :bind_as instead

Here’s my code from environment.rb:

require 'active_ldap'
ActiveLdap::Base.establish_connection(
  :host => '<domain-server>',
  :port => 389,
  :base => 'dc=<domain-name>,dc=local',
  :bind_format => '%s',
  :bind_dn => '<domain-name>\\<username>',
  :password_block => Proc.new { '<password>' },
  :allow_anonymous => false
)

ActiveLDAP has some bugs in a Rails app

There are some bugs in ActiveLDAP 0.8 that I had to work around

Implement to_param

If you implement in your model code:

def to_param
  id
end

Then the Rails scaffold code will work great!

Schema processing broke for me

At line 44 of ActiveLDAP’s schema.rb file, I had to update to this to stop the code crashing:

      while @entries[group] && schema = @entries[group].shift

The DN value for saving is broken

I poked around and commented out some code, but I really didn’t understand what I was doing! Part of my confusion is that ActiveLdap::Base has two implementations of the base method that interact weirdly. The problem is that the base part of the DN was being added twice, and the DN attribute name (in my case CN) was on the front of the string. Here’s an example of what I was seeing:

cn=cn=<my name>,ou=Users,ou=MyBusiness,dc=<domain>,dc=local,ou=Users,ou=MyBusiness,dc=<domain>,dc=local

The string that did work was:

cn=<my name>,ou=Users,ou=MyBusiness,dc=<domain>,dc=local

nTSecurityDescriptor isn’t supported

After getting past the DN string building, this was my next problem with save (I actually disabled validation to get here, as the validation does insist this is needed)

Ok, so this is mostly the fault of AD, but if you want to save changes back to AD, then you need to be able to get the nTSecurityDescription attribute for your objects. It seems that AD has implemented an extension to retrieve this attribute, but I have no idea how to do that.

What else can go wrong?

I was planning on being able to build a live search against my users in the AD using LDAP, but the performance sucks, even for only a dozen users, it takes over a second on my unloaded server with everything in memory.

Posted by Tom Thu, 01 Mar 2007 04:43:52 GMT


Can Rails learn how to release software?

Mathew has an interesting post here about the problems with Rails 1.2, and the underlying issue of the Rails Core team not releasing software correctly.

I noticed the start of this with the 1.1.4 to 1.1.6 update (via a quick stop at 1.1.5). Looking at the change sets between the minor version changes, it was clear that we weren’t getting just a security update, but a few cool new features too. Ben and I talked about it at the time, and then Ben went on to blog about the issues

I seems that the situation hasn’t changed yet.

Apparently, DHH’s views on change are along the lines of ‘tough, this is the way I work, live with it’.

These problems haven’t affected me personally yet, but as more and more people use Rails, more will get screwed by the process and will head off back to their current platforms with tales of woe that discourage others from trying out Rails.

That would be a shame for all concerned.

Posted by Tom Mon, 19 Feb 2007 05:31:58 GMT


I have a new job!

As of this afternoon, I have a new employer. I will be starting work as a programmer at Zipper Interactive in Redmond on the 26th.

I talked with a bunch of people, and didn’t get around to talking with a bunch more, but the completely different environment of a game development company was too tempting to pass up. There’s a lot of Rails development going on in Seattle, not all of it publicly known.

Now I can take a week off without worrying about mortgage payments and job interviews.

Posted by Tom Sat, 17 Feb 2007 07:21:32 GMT


Microsoft Puzzlehunt Atlantis finished

Our team – the Dirty Smackmasters – convened for the 10th Microsoft Puzzlehunt (Puzzlehunt A). This year was an Atlantis theme, and we did a little better than last time – we’ll probably be in the low 30’s our of 75 when the results come out. We solved all but 14 puzzles, and we had about 3 or 4 that we were really close on.

This year, we made great progress at the start, and someone has a screenshot of the standings page to show us in 2nd! I like it when the first puzzles allow you to make progress. One year, we solved nothing in the first 4 hours. This is a good way to make you feel stupid.

One tip to anyone making puzzles – don’t use pizza! This year, one of the puzzles involved the layout of olives on a delivered pizza. Our olives had all moved by the time we received it, so we had no chance to solve this until we got a photo of the expected layout. We wasted so much time on this, and then didn’t have enough time to solve it once we got the correct layout.

Once again, we had too much bad food, but we did have a good time. For the first time, I didn’t sleep at all, and then crashed at 7 on Sunday evening for 12 hours!

Update: Is seems we did finish 29th!

Microsoft Puzzlehunt has a Wikipedia entry (hopefully not edited by someone involved to avoid the Wikipedia editor’s wrath)

Here’s my comments from Puzzlehunt 9

Posted by Tom Mon, 12 Feb 2007 18:59:35 GMT


4 1/2 Rails plugins I use in every project

Any time I’m starting a Rails project, I pick which base plugins I’m going to need to get the job done. Here are the ones I use the most.

SQL Session Store

This is Stefan’s implementation of the SQL session store bypassing ActiveRecord for performance. Wasting cycles on loading the session is not what I want my servers to be spending their time on.

Exception Notification

We all want to know when our production servers are having problems. The Exception Notification plugin sends you mail when exceptions occur. One note: Routing errors are not caught by this plugin, which may be important for you to catch.

Acts As Slugable

Put the title of your model into the URL for that model, not just its ID. This is great for SEO purposes, and is easier to read when looking at urls.

Obie just wrote about how to do this manually

Action Cache

Shameless plug! You can’t run a production web site without some sort of caching of page results. Page caching is the best, if your site has pages that can use this form of caching. Action caching is the next best, and my action_cache plugin extends the functionality of action caching (and works around bugs that can be annoying)

Acts As Authenticated

Not really a plugin, once the Acts As Authenticated generator has been run, the plugin can be deleted (hence the 1/2). The generated code has issues when you start adding extra functionality from the wiki, but the basics get you going pretty quickly.

Posted by Tom Thu, 08 Feb 2007 04:27:24 GMT


2 Best Firefox plugins for Rails developers

Usually these lists are 10 best, but really, for Rails developers, there are only two plugins you really need.

DevBoi plugin, with Rails addon

The DevBoi plugin adds a sidebar with documentation lookup for HTML, CSS, DOM and Javascript.

The Rails addon pack gives you Rails and Ruby documentation too. Ctrl-F9 (on Windows) brings up the sidebar.

I can’t work without this plugin.

Install it from here: http://www.martincohen.info/products/devboi/

Web Developer plugin

This plugin allows you to view all sorts of useful information about the current page. When you’re building pages, and nothing seems to be working, the information this plugin provides is invaluable.

Get the Web Developer plugin here: https://addons.mozilla.org/firefox/60/

Posted by Tom Mon, 05 Feb 2007 05:38:38 GMT


Dreamhost, Rails and locally installed Gems

I followed the instructions for installing Collaboa on Dreamhost, which includes building and installing local versions of everything interesting – Rails, Subversion, FastCGI, Gems.

The environment can be setup in the .bash_profile, .bashrc and .gemrc files to allow all the tools find these locally installed versions. .bashrc is claimed to be the place for non-interactive apps to get their configuration setup. It seems not, at least for the Dreamhost configuration.

After trying all the tricks in the book to get my Rails app running under FastCGI, I eventually worked out what was missing—my app wasn’t picking up the locally installed Gems.

To make this work, I added the following lines to my dispatch.fcgi file:

ENV['RAILS_ENV'] = 'production'
ENV["GEM_HOME"]="/home/<username>/.gems"
ENV["GEM_PATH"]="/usr/lib/ruby/gems/1.8:/home/<username>/.gems"

After killing the existing processes, my app started working as expected. Woot!

I also added Todd’s new Dreamhost Plugin to the app to help improve reliability.

Posted by Tom Sat, 03 Feb 2007 08:39:31 GMT