Net::Ldap question

Hello, I'm trying this plugin in a rails app and think I need some help.
What I want to do is authenticate some user, I don't need to do any queries or
search in LDAP. I have this method:

     def self.initialize_ldap_con(identifier, password)
       hsh = {:host => AppConfig.ldap_server_host, :port => AppConfig.ldap_server_port}
       hsh[:base] = AppConfig.ldap_server_tree_base
       hsh[:auth] = { :method => :simple, :username => identifier, :password => password }
       Net::LDAP.new( hsh )
     end

And get this object as result:

#<Net::LDAP:0xb77a72c4 @auth={:username=>"eduardo", :password=>"********", :method=>:simple}, @host="ldapserver", @encryption=nil, @port=389, @base="ou=company,c=es", @verbose=false, @open_connection=nil>

What does mean :method? Which methods could I choose?
What does mean @open_conection=nil? Does it mean that connection is not open?
How could I set an encryption method (I guess I could with :method option)?

Sorry I forgot to say how I try to authenticate the user:

     def self.authenticate(identifier, password)
       if identifier.to_s.length > 0 and password.to_s.length > 0
         ldap_con = initialize_ldap_con(identifier, password)
         p ldap_con
         if ldap_con.bind
           true
         else
           false
         end
       end
     end

but I never get true after calling bind method.
I know our LDAP server use MD5 encryption method, is this library capable of authenticate using this
encryption?, is there any library I could use to do what I want?

Hehe, sorry again. I've reading documentation of this library and already know
about method option. But I still don't get authenticated, I get this error from
the library (using get_operation_result):

#<OpenStruct message="No Such Object", code=32>

Does it mean that I get connected to Ldap but the user wasn't found? or I didn't connect at all?

Are you using the latest version of Net::LDAP?

Try this very simple code, apart from Rails:

ldap = Net::LDAP.new( :host => ldap_server_ip_address, :port =>
ldap_server_port, :auth => {:method => :simple, :username =>
"eduardo", :password => ****} )
p ldap.bind

32 is a very unusual result from an LDAP bind. It may mean that your
server requires SASL authentication, which is partly supported in the
very latest versions of Net::LDAP.

···

On 12/13/06, Eduardo Yáñez Parareda <eduardo.yanezNOSPAM@nospamgmail.com> wrote:

Hehe, sorry again. I've reading documentation of this library and already know
about method option. But I still don't get authenticated, I get this error from
the library (using get_operation_result):

#<OpenStruct message="No Such Object", code=32>

Does it mean that I get connected to Ldap but the user wasn't found? or I didn't connect at all?

Are you using the latest version of Net::LDAP?

Yes, I installed 0.0.4 version.

Finally I got to be authenticated, but I had to make the user's DN. Anyway, I tried to use bind_as method
since the documentation says it search before for the username to make the DN,
but when I used it I received a 'Size limit exceeded' error, so for now I use bind method, although it's a bit ugly to have to make the DN.

What is the LDAP server? Active Directory often allows you to bind as
a user name. Most other directories require a full DN. I don't like
the Size limit exceeded error. Can you show an example of the bind_as
call that you are using?

···

On 12/14/06, Eduardo Yáñez Parareda <eduardo.yanezNOSPAM@nospamgmail.com> wrote:

> Are you using the latest version of Net::LDAP?

Yes, I installed 0.0.4 version.

Finally I got to be authenticated, but I had to make the user's DN. Anyway, I tried to use bind_as method
since the documentation says it search before for the username to make the DN,
but when I used it I received a 'Size limit exceeded' error, so for now I use bind method, although it's a bit ugly to
have to make the DN.

The LDAP server is from Netscape, don't know exactly which version is it.

the Size limit exceeded error. Can you show an example of the bind_as
call that you are using?

Yes, of course. This is the module I use to authenticate with bind_as:

   require 'net/ldap'

   module LDAP
     # If login succeeds returns true
     # If login fails returns false
     def self.authenticate(identifier, password)
       if identifier.to_s.length > 0 and password.to_s.length > 0
         ldap_con = initialize_ldap_con(identifier, password)
         if ldap_con.bind_as
           true
         else
           p "ERROR => #{ldap_con.get_operation_result}"
           false
         end
       end
     end

     private

     def self.initialize_ldap_con(identifier, password)
       setup = {:host => AppConfig.ldap_server_host,
                :port => AppConfig.ldap_server_port,
                :base =>AppConfig.ldap_server_tree_base }
       setup[:auth] = { :method => :simple, :username => identifier, :password => password }
       Net::LDAP.new(setup)
     end
   end

However, this doesn't work when I use bind, first I had to make the DN.

You may have misunderstood how Net::LDAP#bind_as works. Go back and
re-read the rdocs. You have to first supply a known account
(identified by a DN), perhaps that of an administrator. What #bind_as
does is to call #bind as the admin account, and then query the
#bind_as username's DN. It then rebinds as the #bind_as user's DN.
This is more or less the standard way to authenticate users against
LDAP directories.

···

On 12/14/06, Eduardo Yáñez Parareda <eduardo.yanezNOSPAM@nospamgmail.com> wrote:

The LDAP server is from Netscape, don't know exactly which version is it.

> the Size limit exceeded error. Can you show an example of the bind_as
> call that you are using?

Yes, of course. This is the module I use to authenticate with bind_as:

   require 'net/ldap'

   module LDAP
     # If login succeeds returns true
     # If login fails returns false
     def self.authenticate(identifier, password)
       if identifier.to_s.length > 0 and password.to_s.length > 0
         ldap_con = initialize_ldap_con(identifier, password)
         if ldap_con.bind_as
           true
         else
           p "ERROR => #{ldap_con.get_operation_result}"
           false
         end
       end
     end

     private

     def self.initialize_ldap_con(identifier, password)
       setup = {:host => AppConfig.ldap_server_host,
                :port => AppConfig.ldap_server_port,
                :base =>AppConfig.ldap_server_tree_base }
       setup[:auth] = { :method => :simple, :username => identifier, :password => password }
       Net::LDAP.new(setup)
     end
   end

However, this doesn't work when I use bind, first I had to make the DN.

The LDAP server is from Netscape, don't know exactly which version is it.

the Size limit exceeded error. Can you show an example of the bind_as
call that you are using?

Yes, of course. This is the module I use to authenticate with bind_as:

   require 'net/ldap'

   module LDAP
     # If login succeeds returns true
     # If login fails returns false
     def self.authenticate(identifier, password)
       if identifier.to_s.length > 0 and password.to_s.length > 0
         ldap_con = initialize_ldap_con(identifier, password)
         if ldap_con.bind_as
           true
         else
           p "ERROR => #{ldap_con.get_operation_result}"
           false
         end
       end
     end

     private

     def self.initialize_ldap_con(identifier, password)
       setup = {:host => AppConfig.ldap_server_host,
                :port => AppConfig.ldap_server_port,
                :base =>AppConfig.ldap_server_tree_base }
       setup[:auth] = { :method => :simple, :username => identifier, :password
=> password }
       Net::LDAP.new(setup)
     end
   end

However, this doesn't work when I use bind, first I had to make the DN.

You should be able to search for a user and get back a dn if your ldap
server is setup for anonymous searching. For this example I'll filter
against the uid value in a ldap tree. Here is an example.

def search(name)
    Ldap_con = Net::LDAP.new( :host => '<ldap server>', :port => <ldap

, :auth => { :method => :simple, :username => '', :password => '' },

:encryption => { :method => :simple_tls } )

  filter = Net::LDAP::Filter.eq("uid", name)
  treebase = '<Your treebase values>'
  ldap_con.search( :base => treebase, :filter => filter) do |entry|
    return entry.dn
  end
end

Then you can authenticate like this.

def authenticate(dn, password)
  ldap_con = initialize_ldap_con(dn, password) #Your ldap initialize method
  if ldap_con.bind
    return true
  else
    return false
  end
end

···

On 12/14/06 10:18 AM, "Eduardo Yáñez Parareda" <eduardo.yanezNOSPAM@NOSPAMgmail.com> wrote:

Thanks a lot to Francis and David, finally I got it. Since I don't have an administration account,
I made an anonymous search to find the DN, as David told me, and now it works without having to do
strange things :). Thanks to both again.

David's points are quite true, however the Net::LDAP#bind_as method is
intended to encapsulate the same technique. Now that you have it
working, I'd be very grateful if you tried #bind_as and see if it also
works for you.

···

On 12/19/06, Eduardo Yáñez Parareda <eduardo.yanezNOSPAM@nospamgmail.com> wrote:

Thanks a lot to Francis and David, finally I got it. Since I don't have an administration account,
I made an anonymous search to find the DN, as David told me, and now it works without having to do
strange things :). Thanks to both again.

David's points are quite true, however the Net::LDAP#bind_as method is
intended to encapsulate the same technique. Now that you have it
working, I'd be very grateful if you tried #bind_as and see if it also
works for you.

Hello, I've tried it, although before I read the documentation again more slowly :),
and it worked right. What I don't understand is why whether you try to 'bind_as'
with :method => :anonymous it doesn't work, and you have to put :method => :simple
with blank username and password.

The final code is:

require 'net/ldap'

module LDAP
     # If login succeeds returns true
     # If login fails returns false
     def self.authenticate(identifier, password)
       if identifier.to_s.length > 0 and password.to_s.length > 0
         ldap_con = initialize_ldap_con(identifier, password)
         if ldap_con.bind_as(:base => AppConfig.ldap_server_tree_base,
                             :filter => "(uid=#{identifier})",
                             :password => password)
           true
         else
           false
         end
       end
     end

     private
     def self.initialize_ldap_con(identifier, password)
       setup = {:host => AppConfig.ldap_server_host,
                :port => AppConfig.ldap_server_port,
                :base =>AppConfig.ldap_server_tree_base }
       setup[:auth] = { :method => :simple, :username => '', :password => '' }
       Net::LDAP.new(setup)
     end
   end

Although I'm going to change it in order to obtain user's information like e-mail or so after authentication.

Thanks. It's possible that either #bind or #bind_as (or both) are
mishandling the :anonymous auth method. I'll have a look.

···

On 12/19/06, Eduardo Yáñez Parareda <eduardo.yanezNOSPAM@nospamgmail.com> wrote:

> David's points are quite true, however the Net::LDAP#bind_as method is
> intended to encapsulate the same technique. Now that you have it
> working, I'd be very grateful if you tried #bind_as and see if it also
> works for you.

Hello, I've tried it, although before I read the documentation again more slowly :),
and it worked right. What I don't understand is why whether you try to 'bind_as'
with :method => :anonymous it doesn't work, and you have to put :method => :simple
with blank username and password.

The final code is:

require 'net/ldap'

module LDAP
     # If login succeeds returns true
     # If login fails returns false
     def self.authenticate(identifier, password)
       if identifier.to_s.length > 0 and password.to_s.length > 0
         ldap_con = initialize_ldap_con(identifier, password)
         if ldap_con.bind_as(:base => AppConfig.ldap_server_tree_base,
                             :filter => "(uid=#{identifier})",
                             :password => password)
           true
         else
           false
         end
       end
     end

     private
     def self.initialize_ldap_con(identifier, password)
       setup = {:host => AppConfig.ldap_server_host,
                :port => AppConfig.ldap_server_port,
                :base =>AppConfig.ldap_server_tree_base }
       setup[:auth] = { :method => :simple, :username => '', :password => '' }
       Net::LDAP.new(setup)
     end
   end

Although I'm going to change it in order to obtain user's information like e-mail or so after authentication.