ruby-activeldap requires ruby-ldap and ruby-log4r (hah @ log4r). On Activeldap 0.7.4 via debian etch packages:
Remember that AD doesn’t like anonymous binds:
require 'activeldap'
ActiveLDAP::Base.connect(
:host => "ad.example.org",
:base => "dc=ad,dc=example,dc=org",
:bind_dn => "cn=ldapbind,ou=service,dc=ad,dc=example,dc=org",
:password => "password",
)
/usr/lib/ruby/1.8/activeldap/base.rb:312:in `connection': Unable to retrieve schema from server (plain) (ActiveLDAP::ConnectionError)
This error is deceiving though. I noticed via wireshark that it was trying to bind as ‘cn=username,dc=localdomain’, failing, and trying an anonymous bind, at which point AD was letting it search that weird referral land that typically breaks other ldap searches. After adding:
:allow_anonymous => false
I got:
/usr/lib/ruby/1.8/activeldap/base.rb:1225:in `do_bind': Invalid credentials (LDAP::InvalidCredentials)
Using this worked:
ActiveLDAP::Base.connect(
:host => "ad.example.org",
:base => "dc=ad,dc=example,dc=org",
:bind_format => "cn=%s,ou=service,dc=ad,dc=example,dc=org",
:user => "ldapbind",
:password => "password",
:allow_anonymous => false
)
I’ve lost the class block using ldap_mapping I was using, but you could do things like:
class User < ActiveLdap::Base
ldap_mapping :dn_attribute => 'uid', :prefix => ""
end
user = User.new("myusername")
puts user.mail
Awesomely enough you have to pay strict attention to what version of Activeldap you’re using. in Later versions ActiveLDAP becomes ActiveLdap and the Base.connect method becomes Base.establish_connection and works a little differently (using Activeldap 0.10.0 via gem). dnattr used with ldap_mapping becomes dn_attribute. ri is your friend here. Something like this works:
#!/usr/bin/ruby
# requires ruby-activeldap (libactiveldap-ruby1.8)
# ruby-ldap (libldap-ruby1.8) ruby-log4r (liblog4r-ruby1.8)
# this particular syntax requires ruby-activeldap 0.10.0
# rubygems is required because I installed via gem. I don't know why.
# Bryan McLellan
require 'rubygems'
require 'active_ldap'
ActiveLdap::Base.establish_connection(
:host => "ad.example.org",
:base => "dc=ad,dc=example,dc=org",
:bind_dn => "cn=ldapbind,ou=service,dc=ad,dc=example,dc=org",
:password => "password",
)
class User < ActiveLdap::Base
ldap_mapping :dn_attribute => 'uid', :prefix => 'ou=MyUsers, :classes => ["user"]
end
user = User.find("myusername")
puts user.mail
You need classes to tell activeldap what schema to load. Standard classes are things like [‘top’, ‘account’, ‘posixAccount’]. You can list multiple schema’s in an array like I just did. I found user by ‘puts user.attribute_names’ and looking for the attribute I wanted. Note also that we’re using User.find instead of User.new. Previously User.find didn’t contain any attributes, now it does, whereas User.new will have empty attributes because it is in fact creating a new user class as one would expect (albeit in memory).
I’m going to post this as WP like to destroy my PRE blocks, and I haven’t looked for a solution yet.