activeLDAP - ldap_mapping - wildcard

Hi,

I’ve a problem and I don’t know if it is solvable with activeLDAP. Here
is an example of the tree structure of our LDAP server. The structure
isn’t exactly like that, but is similare and I can already access almost
any informations of a user when I’m logging as this user. The probleme
come when using the belong_to, has_many and ldap_mapping has you will
see in the rest of this message.

-localhost
|
-groups
||
|-group01
|||
||-subgroup01
||-subgroup02
||-subgroup03
||
|-groupe02
||
|-groupe03
|
-users
||
|-labo01
|||
||-user01
||-user02
||
|-labo02
|||
||-section01
||||
|||-user03
|||-user04
|||
||-section02
||||
|||-user05

I have 2 corresponding classes

#this class of LdapUser work as long as the user is found directly under
“labo01”
class LdapUser < ActiveLDAP::Base

ldap_mapping :dnattr => 'cn' , :prefix => 'ou=labo01,ou=users', 

:classes => [‘top’,‘hostObject’, ‘person’, ‘shadowAccount’,
‘posixAccount’, ‘postfixAccount’]

has_many :groups,
	:class_name => 'Groups',
	:foreign_key => 'memberUid',
	:local_key => 'cn'

end

#this class of Groups work as long as the group is found directly under
“groups”
class Groups < ActiveLDAP::Base

ldap_mapping :dnattr => 'cn' , :prefix => 'ou=groups', :classes => 

[‘top’,‘posixGroup’]

has_many :ldapusers,
	:class_name => 'LdapUser',
	:local_key => 'memberUid' ,
	:foreign_key => 'cn'

end

A group can have 0 to N users and a users can be in 0 to N groups.
Everything under “groups” is a group with a variable “memberUid” that
reference a user under “users”. This way, as an example, user03 can be
in group03 and subgroup01 and group03 may have user01, user03 and user05
in it. If I ask ruby-activeldap about the groups where the user01 is, it
will answer only group03, ignoring the fact that subgroup01 is also a
group. The other way arround, if I ask the members of a groupe like
group03, I will only get user01.

The problem is that I would need a kind of wildcard in the ldap_mapping
call to set the prefix. To define a group I would write something like

ldap_mapping :dnattr => ‘cn’, :prefix => ‘*,ou=groups’ where * could be
nothing

because I know that everything under ou=groups is a group and for the
LdapUser

ldap_mapping :dnattr => ‘cn’, :prefix => ‘*,ou=users’ where * could be
nothing

because I know that everything under ou=users is a user.

I know I could write every user under “ou=users”, but I have a pretty
large amount of user on this ldap server and also a large amount of
groups. So putting everything under a same root isn’t really an option.

Is having a wildcard in a ldap_mapping possible? If so, how? If not, How
could I solve my problem?

Thanks for your help,

Marc-Alexandre Nolin

Anybody have an idea or a suggestion about the probleme stated above?

Also, I have another question: I’m currently able to connect on the ldap
server with activeLDAP. The sys admin have been kind enough to open me a
port not securise with SSL, but for the production machine, I will need
to connect on the ldapS server. But for now the connect() fonction of
activeLDAP don’t seem to work.

Is there a parameters where I can specify that the server is ldapS?
(just changing the port to use the ssl secure ldaps don’t work)

Thanks,

Marc-Alexandre Nolin

Hi Marc-Alexandre,

Sorry for the immense delay in responding! For these sorts of nested
structures, I’ve used factories for generating classes as you describe
on the fly. I have a helper function in ActiveLDAP as a sample –

ActiveLDAP::Base.create_object( :class => “User01”, :dnattr => “uid”,
:classes => [‘top’,‘posixAccount’], :base => [‘ou=User01’], :has_many
=> [[:ldapusers, {‘local_key’ => ‘memberUid’, ‘class_name’ =>
‘LdapUser’, ‘foreign_key’ => ‘cn’}]]
)

However, this is broken in release 0.6.0 (but is fixed in CVS).

To avoid the hackery of the above method, you can also just create a
class factory:
def UserFactory(username)
a = Class.new(ActiveLDAP::Base)
a.class_eval(“ldap_mapping :dnattr => ‘cn’ , :prefix =>
‘ou=#{username},ou=users’, :classes => [‘top’,‘hostObject’, ‘person’,
‘shadowAccount’, ‘posixAccount’, ‘postfixAccount’]”)
return a
end

User01 = UserFactory(“labo1”)
user = User01.new(‘subuser01’)

I know this isn’t as convenient as wildcards. I’ll consider how it
could be done sanely with wildcards. Of course, I accept patches :wink:

That aside, SSL and TLS support have been in ActiveLDAP since the
beginning. I am about to roll out a new release (in CVS now) which
make it clearer on how to use SSL, TLS and plain/no-encryption. It
will be used as follows:

ActiveLDAP::Base.connect(…, :method => :ssl, …)

The options for :method are :ssl, :tls, and :plain. It defaults to
:plain.

For all previous versions, TLS and SSL were always attempted, but you
would have needed to specify the port with :port => 636 if that’s
where the ldaps server is. (This is still true with the :method
option in CVS).

I hope this helps and feel free to send more
questions/comments/complaints my way.

/wad

Thanks,

I wasn’t expecting an answer anymore so I made suggestion about change
in the LDAP structure and they were accepted. So now everything work
fine :slight_smile:

But I will keep you answer if the need to have subcategories under
ou=names come back again. Currently, the number or person under
ou=names are in hundred, so this is still managable but possibilities
are that my web site will also be use with a local university LDAP in a
not so far futur and having subcategories under ou=names might be useful
for 40 000 users !

For the SSL part, I think that problem might be related that our
development server don’t have a valid certificate. The validation juste
hang there. For now, everything work in plan text validation, but I will
come back here if I get the same problem with the production server.

Thanks agains !

Marc-Alexandre

Will Drewryâ?¢ wrote:

Hi Marc-Alexandre,

Sorry for the immense delay in responding! For these sorts of nested
structures, I’ve used factories for generating classes as you describe
on the fly. I have a helper function in ActiveLDAP as a sample –

ActiveLDAP::Base.create_object( :class => “User01”, :dnattr => “uid”,
:classes => [‘top’,‘posixAccount’], :base => [‘ou=User01’], :has_many
=> [[:ldapusers, {‘local_key’ => ‘memberUid’, ‘class_name’ =>
‘LdapUser’, ‘foreign_key’ => ‘cn’}]]
)

However, this is broken in release 0.6.0 (but is fixed in CVS).

To avoid the hackery of the above method, you can also just create a
class factory:
def UserFactory(username)
a = Class.new(ActiveLDAP::Base)
a.class_eval(“ldap_mapping :dnattr => ‘cn’ , :prefix =>
‘ou=#{username},ou=users’, :classes => [‘top’,‘hostObject’, ‘person’,
‘shadowAccount’, ‘posixAccount’, ‘postfixAccount’]”)
return a
end

User01 = UserFactory(“labo1”)
user = User01.new(‘subuser01’)

I know this isn’t as convenient as wildcards. I’ll consider how it
could be done sanely with wildcards. Of course, I accept patches :wink:

That aside, SSL and TLS support have been in ActiveLDAP since the
beginning. I am about to roll out a new release (in CVS now) which
make it clearer on how to use SSL, TLS and plain/no-encryption. It
will be used as follows:

ActiveLDAP::Base.connect(…, :method => :ssl, …)

The options for :method are :ssl, :tls, and :plain. It defaults to
:plain.

For all previous versions, TLS and SSL were always attempted, but you
would have needed to specify the port with :port => 636 if that’s
where the ldaps server is. (This is still true with the :method
option in CVS).

I hope this helps and feel free to send more
questions/comments/complaints my way.

/wad