Activeldap

Obviously I am missing something and I don’t know what it is…

I am following the instructions at
http://rubyforge.org/docman/view.php/381/114/activeldap_rb.html

and also here…
http://wiki.rubyonrails.org/rails/pages/HowtoAuthenticateViaLdap

my model looks exactly like this…
class LdapUser < ActiveRecord::Base

ldap_mapping :dnattr => ‘uid’, :prefix => ‘People’, :classes =>
[‘top’,‘account’]
#belongs_to :groups, :class_name => ‘Groups’, :foreign_key =>
‘memberUid’, :local_key => ‘uid’

def self.login(username, password)
begin
ActiveLDAP::Base.connect(
:host => “srv1.azapple.com”,
:port => 389,
:base => “dc=azapple,dc=com”,
:bind_format => “uid=#{username},ou=People,dc=azapple,dc=com”,
:password_block => Proc.new { password },
:allow_anonymous => false
)
ActiveLDAP::Base.close
return true
rescue ActiveLDAP::AuthenticationError
return false
end
end

end

which makes sense to me since this works…
$ ldapsearch -x -h srv1.azapple.com -W
-D ‘uid=craig,ou=People,dc=azapple,dc=com’
-b ‘dc=azapple,dc=com’ ‘(uid=craig)’

but the web page gives me this error about the ldap_mapping…

NoMethodError in Login#login
undefined method `ldap_mapping’ for LdapUser:Class

RAILS_ROOT: script/…/config/…

Application Trace | Framework Trace | Full Trace
/usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/base.rb:991:in
`method_missing’

and it seems that no matter what I put into the ldap_mapping line in my
model, the error is the same.

Hints?

Craig

my model looks exactly like this…
class LdapUser < ActiveRecord::Base

You want LdapUser to be a subclass of ActiveLDAP::Base, not
ActiveRecord::Base.

On Sun, 2006-03-26 at 16:46 -0700, Grant Hollingworth wrote:

my model looks exactly like this…
class LdapUser < ActiveRecord::Base

You want LdapUser to be a subclass of ActiveLDAP::Base, not
ActiveRecord::Base.


good catch - that’s been making me crazy - thanks

Craig

Did you install the gem or from source? I think if it’s from a gem you
may
need something like this:

require ‘rubygems’
require_gem ‘ruby-activeldap’

I install from source, so the require ‘activeldap’ works for me

jro@inferno:~$ irb
irb(main):001:0> require ‘activeldap’
=> true

-j

Yes, I did install the gem…

$ ruby script/console
Loading development environment.

require “rubygems”
=> false

require_gem “ruby-activeldap”
=> true

require “app/controllers/application.rb”
=> true

require “app/models/ldap_user.rb”
=> true

mytest = LdapUser.login(“craig”, “MY-REMOVED-PASSWORD”)
=> false

require “rubygems” fails - perhaps not meaningful

still significantly, I see the connect and then the close, but never a
bind attempt in my slapd logs…

Mar 27 09:01:04 srv1 slapd[30353]: conn=2835 fd=12 ACCEPT from
IP=192.168.2.10:42993 (IP=0.0.0.0:389)
Mar 27 09:01:04 srv1 slapd[30353]: conn=2835 fd=12 closed

whereas binds are clearly obvious in the logs (binds from other ‘client’
applications)

Craig

On Sun, 2006-03-26 at 16:46 -0700, Grant Hollingworth wrote:

my model looks exactly like this…
class LdapUser < ActiveRecord::Base

You want LdapUser to be a subclass of ActiveLDAP::Base, not
ActiveRecord::Base.


this solved my syntax issues with things like ldap_mapping but I am
still struggling to connect and have simply shifted to trying to connect
from console and still struggling…

First note, I am reasonably adept at ldap - from the command line, I can
connect no problem…

$ ldapsearch -x -h srv1.azapple.com
-D ‘uid=craig,ou=People,dc=azapple,dc=com’
-b ‘dc=azapple,dc=com’ -W ‘(uid=craig)’
Enter LDAP Password:

extended LDIF

LDAPv3

base <dc=azapple,dc=com> with scope sub

filter: (uid=craig)

requesting: ALL

craig, People, azapple.com

dn: uid=craig,ou=People,dc=azapple,dc=com
…snip…you get the idea…

I have identical type bind configured in “app/models/ldap_user.rb”

ldap_mapping :dnattr => ‘uid’,
:prefix => ‘ou=People’,
:classes => [‘top’,‘posixaccount’]

def self.login(login, password)
begin
ActiveLDAP::Base.connect(
#:logger => log4r_obj,
:host => “srv1.azapple.com”,
:port => 389,
:base => “dc=azapple,dc=com”,
:bind_format => “uid=#{login},ou=People,dc=azapple,dc=com”,
:password_block => Proc.new { password },
:allow_anonymous => false,
:try_sasl => false
)
ActiveLDAP::Base.close
return true
rescue ActiveLDAP::AuthenticationError
return false
end
end

then the console…
[craig@lin-workstation trunk]$ ruby script/console
Loading development environment.

require “activeldap”
=> false
require “app/controllers/application.rb”
=> true
require “app/models/ldap_user.rb”
=> true
mytest = LdapUser.login(“craig”, “MY-REMOVED-PASSWORD”)
=> false

One other thing of note…I have tried putting into following into
environment.rb …

config.frameworks -= [ :active_record ]

but it seems to make no difference either way (whether commented out or
not)

So - I’m wondering…why I get a ‘false’ from my first console line of
‘require “activeldap”’ ?

and more importantly, why won’t it authenticate? slapd logs show the
connection but the bind isn’t attempted.

Craig

The documentation of both gems, ruby-activeldap and log4r suggest that I
need to execute
require “rubygems” but all I get is false on this…

I got confused by the same thing. False means it’s already loaded. If
the load failed, Ruby would raise a LoadError exception.

Explanation:
http://rubyforge.org/pipermail/rubygems-developers/2005-September/001746.html

gem install rubygems

If you have ‘gem’, RubyGems is already installed.

Maybe I’m wrong and rubygems error is significant…

I don’t get it.

The documentation of both gems, ruby-activeldap and log4r suggest that I
need to execute

require “rubygems” but all I get is false on this…

so I tried…at any rate, the ruby-activeldap connects to my ldap server
but never bothers trying to bind to it - despite having what I believe
is a simple connection script (below)

Craig

the following is the results of my efforts to enable ‘require
“rubygems”’ to work…

gem install rubygems

Attempting local installation of ‘rubygems’
Local gem file not found: rubygems*.gem
Attempting remote installation of ‘rubygems’
Updating Gem source index for: http://gems.rubyforge.org
ERROR: While executing gem … (Gem::GemNotFoundException)
Could not find rubygems (> 0) in the repository
You have new mail in /var/spool/mail/root
[root@lin-workstation activeldap]# gem list

*** LOCAL GEMS ***

actionmailer (1.1.5)
Service layer for easy email delivery and testing.

actionpack (1.11.2)
Web-flow and rendering framework putting the VC in MVC.

actionwebservice (1.0.0)
Web service support for Action Pack.

activerecord (1.13.2)
Implements the ActiveRecord pattern for ORM.

activesupport (1.2.5)
Support and utility classes used by the Rails framework.

log4r (1.0.5)
Log4r is a comprehensive and flexible logging library for Ruby.

model_security_generator (0.0.9)
[Rails] Model security and authentication generator.

postgres (0.7.1)
The extension library to access a PostgreSQL database from Ruby.

rails (1.0.0)
Web-application framework with template engine, control-flow layer,
and ORM.

rake (0.7.0, 0.6.2)
Ruby based make-like utility.

ruby-activeldap (0.6.0)
Ruby/ActiveLDAP is a object-oriented API to LDAP

sources (0.0.1)
This package provides download sources for remote gem installation

Craig

On Mon, 2006-03-27 at 13:43 -0500, [email protected] wrote:

The documentation of both gems, ruby-activeldap and log4r suggest that I
need to execute

require “rubygems” but all I get is false on this…


This is a little confusing, but require returns false if you try to require
a library that has already been loaded.

I’ve seen that - just usually the first time when I open a console and
require, it returns true and subsequent efforts would be false.
Apparently, it is as Grant suggests, rubygems is automatically activated
in which case, all attempts to ‘require “rubygems”’ are superfluous and
probably relate to pre-1.0.0 rails

Anyway, I am going to restate my problem with activeldap since I can
articulate it better with each wasted hour I spend trying to make it
work…

$ ldapsearch -x -h srv1.azapple.com
-D ‘uid=craig,ou=People,dc=azapple,dc=com’
-b ‘dc=azapple,dc=com’ -W ‘(uid=craig)’
Enter LDAP Password:

extended LDIF

LDAPv3

base <dc=azapple,dc=com> with scope sub

filter: (uid=craig)

requesting: ALL

craig, People, azapple.com

dn: uid=craig,ou=People,dc=azapple,dc=com
…snip…you get the idea…

I have identical type bind configured in “app/models/ldap_user.rb”

class LdapUser < ActiveLDAP::Base

ldap_mapping

def self.login(login, password)
begin
ActiveLDAP::Base.connect(
:host => “srv1.azapple.com”,
:port => 389,
:base => “dc=azapple,dc=com”,
:bind_format => “uid=#{login},ou=People,dc=azapple,dc=com”,
:password_block => Proc.new { password },
:allow_anonymous => false,
:try_sasl => false
)
ActiveLDAP::Base.close
return true
rescue ActiveLDAP::AuthenticationError
return false
end
end
end

BUT in the Console…

$ ruby script/console
Loading development environment.

require_gem “ruby-activeldap”
=> true
require “app/models/ldap_user.rb”
=> true
mytest = LdapUser.login(“craig”, “MY-REMOVED-PASSWORD”)
=> false

and though it will connect to the ldap server, it never attempts to bind
to the ldap server as me or anyone (according to the ldap server logs).

Craig

The documentation of both gems, ruby-activeldap and log4r suggest that I
need to execute

require “rubygems” but all I get is false on this…

http://rubyforge.org/pipermail/fxruby-users/2005-June.txt
From: lyle at knology.net
> require ‘rubygems’
> false

This is a little confusing, but require returns false if you try to 

require
a library that has already been loaded.

Have you mailed the maintainer? I think his email address is in the
README or, at least, all over the docs. The main post on his blog for
ActiveLDAP is:

http://dataspill.org/pages/projects/ruby-activeldap

I’ve had issues with ActiveLDAP before and he was very helpful. He
might be able to determine what the issue is.

My question is, have you tried to authenticate with just Ruby::LDAP?
It would be interesting to see if the problem lies there and not in
ActiveLDAP (or vice-versa). Obviously, authentication works, but
something’s mucking it up.

Sean

On Tue, 2006-03-28 at 15:23 -0500, Sean H. wrote:

Have you mailed the maintainer? I think his email address is in the
README or, at least, all over the docs. The main post on his blog for
ActiveLDAP is:

http://dataspill.org/pages/projects/ruby-activeldap

I’ve had issues with ActiveLDAP before and he was very helpful. He
might be able to determine what the issue is.


I thought I did…I emailed Ian Caliban but his was the Ruby::LDAP and
that I guess is not the activeldap package. I got no answer :wink:

Thanks for forcing me to look again - I am tearing my hair out. I’ve
aged 4 years in the past 4 days :wink:

it was easier to learn LDAP than to get this little module going.

My question is, have you tried to authenticate with just Ruby::LDAP?
It would be interesting to see if the problem lies there and not in
ActiveLDAP (or vice-versa). Obviously, authentication works, but
something’s mucking it up.


I have to figure out how to do that - I don’t know that I’ve been able
to figure out where the Ruby::LDAP stops and activeldap starts

=> true

I have updated to Rails 1.1
stuck here.


Thanks

Craig

I really need this to work - and I can’t make it work regardless of how
I simplify…

require_gem “ruby-activeldap”
=> false
require “app/models/ldap_user.rb”
=> true
mytest = ActiveLDAP::Base.connect(:host => “srv1.azapple.com”,
:port => 389,
:base => “dc=azapple,dc=com”,
:bind_format => “cn=root,dc=azapple,dc=com”,
:password_block => Proc.new{ “MY-REMOVED-PASSWORD” },
:try_sasl => false, :allow_anonymous => false )
ActiveLDAP::AuthenticationError: All authentication mechanisms failed

from ./script/…/config/…/config/…/lib/activeldap/base.rb:1196:in
`do_bind’

from ./script/…/config/…/config/…/lib/activeldap/base.rb:1168:in
`do_connect’

from ./script/…/config/…/config/…/lib/activeldap/base.rb:227:in
`connect’
from (irb):11

that is my rootbinddn - I have absolutely no problem connecting to ldap
server with this same host/port/bind/password/no-sasl combo

I have updated to Rails 1.1
I now get false reply to the following…
require “activeldap”
require_gem “ruby-activeldap”

and removing/reinstalling gem ruby-activeldap doesn’t change that.

More importantly - still the logs on the ldap server show the connection
being made but no attempt to ‘bind’ is made whatsoever.

I really need help with this. This is now the 4th day I have remained
stuck here.

Thanks

Craig

On Tue, 2006-03-28 at 17:35 -0500, Sean H. wrote:

PASS = “”
def initialize (host = LDAP_HOST, version = PROTOCOL_VERSION)

See if you can get something like that going.


I’m playing with this but it ain’t rails and I’m starting to figure
rails out but ruby code is still not entirely clear to me…nor is the
environment to use it. I started using script/console from my
application and then figured it was probably smarter to use irb.

I ended up hitting a wall about here…

results = conn.search2(MyLDAP::PEOPLE_DN, LDAP::LDAP_SCOPE_SUBTREE,
filter, attrs)
LDAP::ResultError: No such object
from (irb):14:in `search2’
from (irb):14
from /usr/lib/ruby/1.8/rdoc/markup/simple_markup/inline.rb:150

which was disappointing since I thought I was getting to it…with only
a few missteps but this told me that I didn’t know what I was doing
because I wasn’t sure that this command above related to the other
section where initialize and bind were defined and other than the
original ‘include’ statement, it doesn’t seem to me that the parts
connect to each other, let alone the LDAP server.

I did write an email to Will Drewry (I think was his name), packager for
activeldap…and I pray that he takes the time to look at it my issue -
I hope I made it simple enough for him. The LDAP integration is less
than optimal.

Craig

For the moment, throw ActiveLDAP out.

Here’s a (modified) class I built to work with our LDAP:

require “ldap”
include LDAP

class MyLDAP < LDAP::Conn

DN = “uid=ldapmanager,dc=company,dc=com”
PASS = “”
BASE_DN = “dc=company,dc=com”
PEOPLE_DN = “ou=people,dc=company,dc=com”
LDAP_HOST = “ldap.company.com
LDAP_PORT = 389
PROTOCOL_VERSION = 3

Create a new LDAP connection object with a default

host of ldap.company.com

Override this by setting host in the method call.

Returns a connection object.

def initialize (host = LDAP_HOST, version = PROTOCOL_VERSION)
super( host, LDAP_PORT )
set_option( LDAP::LDAP_OPT_PROTOCOL_VERSION, version )
return self
end

Bind as the root dn unless specified otherwise.

def bind(dn = DN, pass = PASS)
super( dn, pass )
end
end

Then I use it like this (sort of–that’s a big data return on the
filter):

require “myldap”
conn = MyLDAP.new.bind
attrs = %w{uid sn givenname cn}
filter = “objectClass=*”
results = conn.search2(MyLDAP::PEOPLE_DN, LDAP::LDAP_SCOPE_SUBTREE,
filter, attrs)
p results

See if you can get something like that going.

Sean

On Wed, 2006-03-29 at 00:59 -0500, Sean H. wrote:

than optimal.

Will has been great and patient with me. I did eventually have to
drop ActiveLDAP from my project due to a schema clash with the schema
for our calendar server. The error was in (I believe) Ruby::LDAP, not
ActiveLDAP, but since ActiveLDAP uses Ruby::LDAP and needs to see all
the schemas, I couldn’t reliably work around it.


Sean

Will never did write me back but it is of little consequence now. Ian
(Ruby::LDAP) did write me back finally this morning and said that he
thought that Will was in the process of moving from the US to Ireland.
Since I already had things sort of working following your direction, I
didn’t belabor the point.

I have been able to make it thoroughly work within irb and have even
made it into working rails code and have only a few snags left to deal
with but it definitely allows me to launch the rails application without
a connection, to bind when I need to authenticate a user and then
finally, I used the login (after success) to tie into my ActiveRecord
based ‘users’ table where I intend to keep the role based access
information and not bother with sustaining an LDAP connection.

Your help was awesome. I just needed to forget about activeldap.

What I think I finally determined was that activeldap wasn’t suitable
for my needs either and the wiki page is very misleading
(HowToAuthenticateWithLDAP) since it is really isn’t about
authentication at all, it’s about one sustained bind to LDAP - and once
bound, an ‘unbind’ breaks the application entirely.

Just thought I would sound back on this and expect that I will try to
put something useful on the rails wiki when I get settled on the
structure.

Craig

Hmm.

I ended up hitting a wall about here…

results = conn.search2(MyLDAP::PEOPLE_DN, LDAP::LDAP_SCOPE_SUBTREE,
filter, attrs)
LDAP::ResultError: No such object
from (irb):14:in `search2’
from (irb):14
from /usr/lib/ruby/1.8/rdoc/markup/simple_markup/inline.rb:150

Before you try the search, try this:

conn.bound?

I should have put that in there. That’ll tell you if you’re binding.
If not, maybe we’ve found your issue.

I did write an email to Will Drewry (I think was his name), packager for
activeldap…and I pray that he takes the time to look at it my issue -
I hope I made it simple enough for him. The LDAP integration is less
than optimal.

Will has been great and patient with me. I did eventually have to
drop ActiveLDAP from my project due to a schema clash with the schema
for our calendar server. The error was in (I believe) Ruby::LDAP, not
ActiveLDAP, but since ActiveLDAP uses Ruby::LDAP and needs to see all
the schemas, I couldn’t reliably work around it.

Sean

Awesome! Glad it’s working!

I had almost the same experience with ActiveLDAP. I had it working at
one point, but just in a simple way, not with any relations. After
wrestling for some time and then coming up against schema validation
errors, I couldn’t go any further. Hence, good ol’ Ruby::LDAP.

I think I’d be able to work with ActiveLDAP (forgetting about the
validation errors) to build something along the lines of phpLDAPadmin,
but the roadblocks I kept hitting trying to integrate it into a Rails
project were too much to overcome without documentation.

That said, it’s still 0.6, not 1.0+, so that’s to be expected. I
really like the library and I especially like the idea and simplicity
of it, but it’s just not “there” enough for my needs.

Sean