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 McLellanrequire '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.