I move here the sub-thread regarding LDAP groups and roles, first generated under the "Authentication only LDAP module" thread. Just to make some sense sorting the different issues.

This topic was first started by deanypop, when he requested this feature:

Drupal/ldap-auth-module should check LDAP users to see if they have LDAP groups that match Drupal roles, and grant access to those roles within drupal.

A first draft of the solution was commited to the CVS tree, as a module release for Drupal 4.6.0, on 5/Oct/2005. It was intended to work as follows:

When a user logs in, the module checks the settings concerning the groups (those in the "From LDAP groups to Drupal roles" section), and signs the user in any existing roles with the same name.

So, for example, say that a LDAP user has a multivalued attribute named "group", its values are "admins", "users" and "bosses". Drupal (actually, this LDAP module) is instructed, through the settings, to read that multivalued attribute and understand its values as roles.

Say now that the Drupal installation has several roles configured, named "admins", "users" and "gods". At login, the user will be included in those roles matching values for that multivalued attribute. Therefore, the user will have the "admins" and "users" roles, and not the "bosses" or "gods" roles.

Well, I hope this one is understandable or, at least, that we are converging into a common vocabulary.

Then, rla contributed his twopence with the next lines and then a patch sent to me privately:

Regarding the groups from LDAP; Active Directory returns the groups a person belongs to as a full CN, often a long string. For example, one of our groups looks like this:

CN=DeptTST,OU=Departmental,OU=Groups,DC=myorg,DC=mytld

this is too long a string for Drupal's role names (I think the db limits it to 32 characters). I wonder if it would be possible to provide a regular expression for extracting the group name? For example, I'd like the Drupal role to be "DeptTST".

Also, what happens if the person is removed from the LDAP group? Do they get removed from the Drupal role next time they log in or do they keep it? Seems like this would be tricky. How would you know if the role is derived from a LDAP group or one assigned outside LDAP?

Maybe having a LDAP group/Drupal role mapping table (like the attribute mappings) would solve both problems? You could map the long group name to short Drupal name and loop over the list of mappings to decide which ones to remove the user from if they no longer belong to that LDAP group.

Comments

pablobm’s picture

After giving a try to rla's patch, thinking about it, pondering possibilities, trying to make things easy and straightforward and procrastinating a lot between each couple of steps...

I have come up with what I think may be the adecuate solution. It relies once again in conf.php to tell what should be mapped and what not, and how. It also provides the option to deny roles according to LDAP updates.

This time, roles doesn't need to be created in advance: the module will create them, but don't forget to specify the mappings on conf.php!!.

Here I leave it, before committing to CVS, so we can get to some agreement before making anything official.

rla’s picture

Seems to work great for direct group membership.

One thing that I notice is that is more a problem with LDAP than this module, but would be nice to solve involves heirarchical group membership. If a user is a member of a group and that group is a member of another group the containing group does not show up listed under the user's group attributes. Only the groups for which the user is a direct member show up. So, for instance you have a user "Joe" who is in the group "Faculty" and "Faculty" is a member of "Employees". While Joe is technically a member of Employees, he is not a direct member of Employees and Employees will not be in the array of groups when we query for Joe's LDAP attributes. There must be a way to directly test for the user's membership in a particular group.

pablobm’s picture

Mmmm, to me that sounds more like an issue that should be solved out of ldap_integration module. Perhaps as changes to Drupal's core or maybe as a new module.

This is something that should be investigated. I'll try to devote some minutes to it.

rla’s picture

phpBB has a LDAP module that does the deep group search, as does Moodle. I will try and look at the code in those. Maybe some hints there.

muzza’s picture

Hi Guys,

I too would like to be able my LDAP groups map to Drupal roles but the current state of the module doesn't appear to do this. If there is a newer version that might, please let me know and I will try it out. In my LDAP schema, the user's group membership is not stored in the user's LDAP attributes. Rather the user's membership of a group is stored as their userid in a Posix LDAP group, ie I use a group DN like
"cn=mygroup,ou=groups,dc=mydomain,dc=net" and the users in the group are stored as memberUid attributes. This maps pretty well to the UNIX scheme of havings user entries in the /etc/group file. Is there any chance of this type of setup working in the near future? In my case a search for the userid through "cn=*,ou=groups,dc=mydomain,dc=net" would give the list of groups the user is a member of.

Murray

muzza’s picture

Sorry, I meant search "memberUid=*,ou=groups,dc=mydomain,dc=net"

lewiz’s picture

I have yet another slightly different set-up. My users are assigned a gidNumber as part of their posixAccount. This always maps to the users group.
Extra groups are defined as follows:

cn=admin,ou=Group,dc=domain,dc=com

This is a groupOfNames, which has a multi-value member field:

uid=fred,ou=People,dc=domain,dc=com

It would be really great if I could incorporate this somehow. Naming the Drupal role "admin" is no problem, but "Administrator user" would fit in better.

Thanks a lot.

muzza’s picture

Hi Lewiz,

I just realised you are using basically the same setup as me. Our Posix secondary groups are stored in LDAP as:

cn=group_name,ou=group_container,dc=domain,dc=com

eg cn=admin,ou=groups,dc=domain,dc=com

and the uid's who are members of that group are stored are attributes, in my case:

memberUid=msmith
memberUid=rjones
.
.

In your case you use appear to use uid instead of memberUid. Obviously this attribute would need to be customizable if this way of doing things was implemented in the module. I think this is a pretty standard way of storing secondary Posix groups in LDAP so I hope the LDAP Integration module will support this group setup some time in the near future. At least we have two votes for it :-)

Murray

pablobm’s picture

Status: Active » Needs review

OK guys. I just added initial support for this POSIX groups feature. Have a look at the CVS and give me some feeback, please.

Don't forget the mappings at conf.php.

muzza’s picture

Great. I will test it out and get back to you shortly.

Thanks

Murray

muzza’s picture

Hi Pablo,

I tried the patch but it doesn't work for me. I selected the "Groups exist as LDAP entries where a multivalued attribute contains the members" and put the entry below in the "Entries containing groups" box.

cn=staff,ou=groups,dc=mydomain,dc=net

I had already created a staff role in my Drupal server but when I login as myself being an LDAP user and member of the LDAP staff group I get the error below:

warning: Invalid argument supplied for foreach() in /srv/www/htdocs/modules/ldap_integration.module on line 336.

warning: Cannot modify header information - headers already sent by (output started at /srv/www/htdocs/includes/common.inc:384) in /srv/www/htdocs/includes/common.inc on line 192.

From the error above I would assume I have to add some sort of Drupal role to LDAP group mappings in the conf.php file. If so, what is the syntax required?

Thanks

Murray

pablobm’s picture

Sorry for my late replays lately. I'm too busy these days and have not much chance to work in this module, but I really want to get rid of the growing issues queue, starting from this one.

I spotted a bug in my last code, I can't understand how it could work in my tests. Anyway, there's still a problem: does "memberUid" hold UIDs like 1000,1001,1002,1003? or does it hold CNs, like "muzza","pablobm"?.

Now I realize that the former must be the case, whereas I thought it was the latter. This creates new implications, as might be preferable to have options to say:

  1. which is the attribute from users that groups store
  2. which is the multiattribute where groups store it

Or is it always like "uid" for the first and "memberUid" for the second?. If so, no additional preferences would be needed and things would be a whole lot simpler.

Please confirm this ASAP. I promise I will scratch some time from my sleep hours in order to get this done.

muzza’s picture

Hi Pablo,

The memberUids in the group entry are definitely names - not their uid number.

Regards

Murray

pablobm’s picture

Beautiful then. Here I attach a new patched version.

Once installed, go to the "Groups and roles" section in the preferences page, check the "Groups exist as LDAP entries where a multivalued attribute contains the members" box, and enter the groups' DNs below, just like "cn=Admins,dc=pablobm,dc=com", or whatever.

Then go to modules/ldap_integration/conf.php and edit the values for the $GLOBALS['ldap_group_role_mappings'] variable. The first one of the commented examples is the case here: group DN as key and drupal role as value.

For example, a value like:

$GLOBALS['ldap_group_role_mappings'] = array(
   'cn=Admins,dc=myorg,dc=mytld' => 'Admin',
   'cn=Posters,dc=myorg,dc=mytld' => 'Poster',
);

Will give the roles 'Admin' and 'Poster' to users in LDAP groups 'cn=Admins,dc=myorg,dc=mytld' and 'cn=Posters,dc=myorg,dc=mytld', respectively.

Hope it works now.

muzza’s picture

Hi Pablo,

That seems to work now. I can add and remove users from the LDAP group and the roles are added and denied as expected (I have the group role signoff section enabled) . Just a minor comment - the memberUid attribute probably shouldn't be hard-coded as other sites may use a different attribute.

Thanks

Murray

pablobm’s picture

Great!. I'll add a preference for the attribute as you say, but at least now things start to work.

Thanks for your patience.

pablobm’s picture

Status: Needs review » Fixed

This seems to be solved now. Tagging as "fixed" before closing.

Anonymous’s picture

Status: Fixed » Closed (fixed)