LDAP AD creators

LDAP AD creators

by Tim Howarth -
Number of replies: 30
(Using Windows 2003/IIS 6)

Having spent some time trying to work out why Moodle 1.53 was not automatically assigning people (by group membership) as course creators, it looks like something is wrong in auth\ldap\lib.php.

According to bugid 3931 it should work in 1.53 but I couldn't make it, having searched here and found references to "memberOf" as the the required value for ldap_memberattribute, I tried this, no luck.

Eveantually I found in lib.php
function auth_ldap_getdefaults

which (for 'ad') also sets ldap_memberattribute to "memberOf"
and sets ldap_memberattribute_isdn to 0.

For the purpose of group membership checking in auth\ldap\lib.php these are incorrect (AFAIUI).

"memberOf" is a property of a user object, i.e. memberOf cn=xyz (etc.) group

The property required for looking at a group to find members is simply "member".

Also, when looking at groups for members, the members are stored as distinguished names (e.g. cn=Jim Smith,ou=peeps,dc=home,dc=local) not just username (e.g. SmithJ). So for Active Directory, ldap_memberattribute_isdn should be 1.

Have I missed something somewhere, or are the default values used elsewhere and is changing them to what I believe they should be, going to break something ?

ATM there's not public/visible way to set ldap_memberattribute_isdn, shouldn't this be configurable on the LDAP authentication page ? - I can't see how any(normal)body could have this feature working on Windows servers.

Have I missed something ?

Tim
Average of ratings: -
In reply to Tim Howarth

Re: LDAP AD creators

by Martín Langhoff -
> Have I missed something ?

Nope. We need your help testing things on AD. So far, the programmers working on Auth/LDAP and Enrol/LDAP have Moodle installs running with OpenLDAP or eDirectory. So the accuracy of our AD settings isn't really that good sad

That changes quickly as soon as someone can post a good patch here (is that a hint or something?) wink Have you been able to get it going against AD? Can you post a good unified diff against 1.5.3+ showing the minimal changes required for it to work?
In reply to Tim Howarth

Re: LDAP AD creators

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
"memberOf" is a property of a user object, i.e. memberOf cn=xyz (etc.) group
The property required for looking at a group to find members is simply "member".

Oops!. My fault. It was me who proposed that change (member->memberOf) a couple of months ago. I thought it was used to test membership of users, not to list users belonging to a group. I was obviously wrong.

I have also verified that members are indeed DN values (with ADSI Edit), as Tim says.

Martin, would you please revert that change? (I have attached a diff that reverts the change and makes ldap_memberattribute_isdn = 1 for AD).

Tim, as for the setting of ldap_memberattribute_isdn, you could add something like this to you config.php file in the meanwhile:
$CFG->ldap_memberattribute_isdn = 1;
Saludos. Iñaki.
In reply to Iñaki Arenaza

Re: LDAP AD creators

by Martín Langhoff -
Grumble. I don't have AD to test so I'm in your hands guys mixed

Tim -- can you confirm that vanilla 1.5.3 with Iñaki's patch does the trick for you? I will only merge the fix when I hear from both of you that it works...
In reply to Martín Langhoff

Re: LDAP AD creators

by Tim Howarth -
Yes, a straight 1.53 with the changes in the patch sorts out the creators from AD problem.

For future reference, is there a way to apply patches (I just made the changes by hand) - in Windows land ?
In reply to Martín Langhoff

Re: LDAP AD creators

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
I don't use ldap creators at all. But if you tell me how to test it, I can setup a test machine (vmware is your friend wink) and test it.

Saludos. Iñaki.
In reply to Iñaki Arenaza

Re: LDAP AD creators

by Tim Howarth -
Thanks, have done it simply by tweaking ldap\lib.php. Though for future useability it would be easier if it could be set along with the property for group member.

If the defaults section (of ldap\lib.php) can be guaranteed to be correct for all choices of server, then there would be no need to set either value indvidually.
In reply to Tim Howarth

Re: LDAP AD creators

by Grant Frazer -

This was an extremely helpful post!  I have been testing the moodle system from various operating systems against our MS AD tree and the whole process of course creators was puzzling me due to its lack of operation.  I performed the simple change to the lib.php and all of sudden my teachers were able to automatically become course creators.

Bravo chaps!

In reply to Grant Frazer

Re: LDAP AD creators

by Matt Gibson -

Hi,

I'm using a similar setup - moodle on windows server 2003 and MS AD for LDAP lookups. We can get the lookups to work, but the course creator thingy is stubbornly dead. It even reverts any manual changes that are made. Our teachers are in ou=teachers,ou=staff,dc=pmsnet,dc=internal and that's ok for the sign-on, but is this the same thing that should be put into the course creators box? We apparently can only make security groups and distribution groups, not posixgroups as mentioned in the moodle docs page. Checking my member attributes on the AD server, I'm in cn=staff,dc=pmsnet,dc=internal but this doesn't work either. It also doesn't work with ldap_memberattribute set to memberOf and/or

set in config.php.

Could anyone advise on how to get this to work? It's driving me nuts (not to mention the rest of the IT team).

Thanks,

Matt

In reply to Matt Gibson

Re: LDAP AD creators

by Matt Gibson -

Found the soultion!

the correct group procedure using MS AD is to create a security group, add the people, and then list all of the OUs, preceded by the security group e.g.

cn=Staff-creators,ou=teachers,ou=staff,dc=pmsnet,dc=internal; cn=Staff-creators,ou=admin,ou=staff,dc=pmsnet,dc=internal

hope that saves someone some hassle.

Matt

In reply to Matt Gibson

Re: LDAP AD creators

by James Bromley -
I am in 1.6 verifying creators from ms-ad 2003 security group. I had this working in 1.53 but I had to modify the default value of member attribute. Now that I have migrated to 1.6 I seem to have a completely diffrent problem. First of all I was previously able to specify that username was samaccountname and that member of was member.samaccountname this no longer works. so I went back to defaults. my username is samaccountname (yea I know that is not default) and my member of is member. (confused yet?)    Line 1262 in /auth/ldap/lib.php returns no results for this arrangement. the line is "$search = @ldap_read($ldapconnection, $group,  '('.$CFG->ldap_memberattribute.'='.$username.')', array($CFG->ldap_memberattribute));" $ldapconnection, $group, and array($CFG->ldap_memberattribute) works ok, the filter or '('.$CFG->ldap_memberattribute.'='.$username.')' returns nothing to the query. There are a few things I would like to point out. $username at this point is actually dn for the user not samaccount name (this is good because this is what is in the member information.) phpldapadmin exports member of a security group as one field terminated by |. ldap_read gets member back as an array. I had to make a few things diffrent for my instilation to work. However this would be slow in an enviroment with lots of members to the group and/or lots of diffrent creator groups. I changed my filter to be (objectclass=*) and replace lines 1266 - 1269 with this:  for ($i = 0; $i<$info[0]["member"]["count"];$i++) {
        if ($info[0]["member"][$i] === $username){
        $result = true;
        }
      }

I wanted to report this as a bug, but I ultimatly was unable to determine if it was an issue with my setup or the code. Attched is my modified lib.php
In reply to James Bromley

Re: LDAP AD creators

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
I guess it's an issue with your setup. I have just setup a 1.6 test site, using a W2K3 A.D. with ldap creators and It Just Works(tm).

Saludos. Iñaki.
In reply to Iñaki Arenaza

Re: LDAP AD creators

by James Bromley -

Here are my settings: I if you see discrepancies from yours that may affect this please let me know…

ldap_host_url:

ldap://myserver.mydomain.com/

ldap_version:

3

ldap_preventpassindb:

Yes

ldap_bind_dn:

cn=moodlebind,ou=Tech Center,dc=mydomain,dc=com

ldap_bind_pw:

********

ldap_user_type:

MS DctiveDirectory

ldap_contexts:

ou=Tech Center,dc=mydomain,dc=com

ldap_search_sub:

No

ldap_opt_deref:

No

ldap_user_attribute:

SAMAccountName

ldap_memberattribute:


ldap_objectclass:


Force change password:

No

Use standard Change Password Page:

No

ldap_expiration:

No

ldap_expiration_warning:

10

ldap_exprireattr:


ldap_gracelogins:

No

ldap_graceattr:


ldap_create_context:


ldap_creators:

CN=Domain Admins,OU=Tech Center,DC=mydomain,DC=com

 

mysqlversion 5.0.19

phpversion  4.3.10

php_extensioniconv is enabled OK

php_extensionmbstring is enabled OK

Moodle 1.6 (2006050506)

 

Thank you for taking the time to look at this information.

 

James Bromley

In reply to Iñaki Arenaza

Re: LDAP AD creators

by James Bromley -

Ok, I get the idea it Just Works(tm) for you but it is not just working for me or I would not of gotten here... Please help me to find what I have not done that you have (or I did that you did not) that caused mine to Just Not Work this time. (Please excuse my sarcasm)

I am thinking a difference in the PHP setup or something that was not allowing it to enumerate the array of members. Please help me work through this issue. The work around I implemented is only a band-aid.

 

Thank you for your help!

James Bromley
In reply to James Bromley

Re: LDAP AD creators

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
The only differences between your setup and mine are:
  1. My W2K3 A.D. domain was upgraded from an existing NT Domain instead of being a fresh install. I don't think this makes any difference.
  2. I'm mapping 'sAMAccountName' into 'ID Number' (I've just removed this mapping, deleted it from the users' profiles and logged in again, and it works too).
  3. My creator groups don't have any spaces in their CN's and sAMAccountName's (I'm right now testing with a new group with spaces just to see if it makes any difference. And it doesn't, it works like a charm too.).
  4. I'm using multiple user contexts with ldap_search_sub = yes. I don't think this could make a difference (your setup is simpler, so there is even less room for error).
  5. My Moodle 1.6 test site was installed from scratch, not upgraded from 1.5.x. This could or could not make a difference (I have not had a look at the code). It has not been migrated to UTF-8, by the way.
My test site is running with mysql 4.0.24 (I know this is officially not supported for 1.6, but it works for my test site with just latin1 content), PHP 4.3.10 and apache 1.3.x on Linux.

Just to make sure, is your LDAP creator group a global security group?

Saludos. Iñaki.
In reply to Iñaki Arenaza

Re: LDAP AD creators

by James Bromley -

Yes, cn=nbecmoodlecreator,ou=STAY,ou=Alternative,ou=Administration,dc=mydomain,dc=com is a Global Security Group. You mentioned spaces, neither my creator group or my samaccountname has spaces in it, some of our ou's do. A lot of our samaccountnames's contain a period though. I would not think this to matter. We are using the same version of PHP, and I would not think mysql to matter. The only difference left I see is IIS/MS for the web server vs. apache/linux. Also not on the top of my list for differences. I did upgrade from 1.5.3 to 1.6. I also am running a AD that was migrated from an nt domain. I just tried copping my auth/ldap/lib.php from the 1.6 install to my site and it stopped working. (just in case it did not get copied over when I upgraded.) I am really at a loss I do not see a large difference in our setup's that would be causing this problem... I appreciate your time with this...



James

In reply to James Bromley

Re: LDAP AD creators

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
This is really strange. Could you please add the following lines (the ones in blue) to your auth/ldap/lib.php file and paste here the result? (have a look at the page source, as the message is inside an html comment block)

       //echo "Checking group $group for member $username\n";
        echo "<!--\n";
echo "group: $group \n";
echo "filter: (".$CFG->ldap_memberattribute."=".$username.")\n";
echo "attribs: \n";
print_r ($attribs);
echo "-->\n";
$search = @ldap_read($ldapconnection, $group,  '('.$CFG->ldap_memberattribute.'='.$username.')',  array($CFG->ldap_memberattribute));
Saludos. Iñaki.
In reply to Iñaki Arenaza

Re: LDAP AD creators

by James Bromley -

group: CN=Domain Admins,OU=Tech Center,DC=mydomain,DC=com
filter: (member=CN=Bromley\, James,OU=Tech Center,DC=mydomain,DC=com)
attribs:

group: cn=nbecmoodlecreator,ou=STAY,ou=Alternative,ou=Administration,dc=mydomain,dc=com
filter: (member=CN=Bromley\, James,OU=Tech Center,DC=mydomain,DC=com)
attribs:

Above are the results, The first one should of been a match... if I look in phpLDAPadmin at the members of Domain Admins the following is shown...
CN=Bromley\, James,OU=Tech Center,DC=mydomain,DC=com

I am lost, I keep wanting to run to the filter... but I can not put my finger on it...

Thank you for your help with this, Let me know what you think...

James Bromley
In reply to James Bromley

Re: LDAP AD creators

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
Ok, let's dig a little bit further. What do you get if you add the lines in blue? (some are the same as the previous time):
       //echo "Checking group $group for member $username\n";
        echo "<!--\n";
echo "group: $group \n";
echo "filter: (".$CFG->ldap_memberattribute."=".$username.")\n";
echo "attribs: \n";
print_r (array($CFG->ldap_memberattribute));
$search = @ldap_read($ldapconnection, $group,  '('.$CFG->ldap_memberattribute.'='.$username.')',  array($CFG->ldap_memberattribute)); print_r ($search); if (!empty($search) AND ldap_count_entries($ldapconnection, $search)) { $info = auth_ldap_get_entries($ldapconnection, $search); print_r ($info); if (count($info) > 0 ) { // user is member of group $result = true; break; } } echo "-->\n";
Saludos. Iñaki.


In reply to Iñaki Arenaza

Re: LDAP AD creators

by James Bromley -
Results:

group: CN=Domain Admins,OU=Tech Center,DC=mydomain,DC=com
filter: (member=CN=Bromley\, James,OU=Tech Center,DC=mydomain,DC=com)
attribs:
Array
(
    [0] => member
)

group: cn=nbecmoodlecreator,ou=STAY,ou=Alternative,ou=Administration,dc=mydomain,dc=com
filter: (member=CN=Bromley\, James,OU=Tech Center,DC=mydomain,DC=com)
attribs:
Array
(
    [0] => member
)

I double checked I did put the "print_r ($info);" in it did not print I assume because $search was empty.


James
In reply to James Bromley

Re: LDAP AD creators

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
After nearly 45 minutes trying to reproduce it, I have finally done it smile The problem lines in the ',' character you have in your CN. ',' is the "path" separator in LDAP, so you have to quote it.

auth_ldap_get_userdn() returns the right value (as your print_r shows), but don't ask my why, OpenLDAP libraries[1] want that quote with a double backslash.

So with a CN of:

      CN=Bromley\, James,OU=Tech Center,DC=mydomain,DC=com

the search fails, but with:

      CN=Bromley\\, James,OU=Tech Center,DC=mydomain,DC=com

the search is successful and you get your prize smile

This is why I wasn't having the problem: none of my CN have ',' in them (in fact, they are just alphanum character strings).

So the magic incantation is adding the following line (the one in blue):

    if ($CFG->ldap_memberattribute_isdn) {
        $username=auth_ldap_find_userdn($ldapconnection, $username);
    }
    if (! $username ) {
        return $result;
    }

    $username = preg_replace ('/\\\\,/', '\\\\\\\\,', $username);
    $groups = explode(";",$groupdns);

At least it works in the tests I have done here. Maybe we should file a bug with this info if it works in your environment.

Saludos. Iñaki.

[1] I have tested this using the command line version of ldapsearch, and you need the same double backslash syntax there too.
Average of ratings: Useful (1)
In reply to Iñaki Arenaza

Re: LDAP AD creators

by James Bromley -
Yea! This does fix my problem; it is defiantly due to the escaped charter. Very diligent work! I really appreciate your assistance. Do you want me to open the bug report for this or will you?

 

Thank you again for your support,

 

James Bromley

In reply to James Bromley

Re: LDAP AD creators

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
Do you want me to open the bug report for this or will you?

It was you who found the bug, so it yours smile. When you open it, put a link to this thread to help understand and fix it, please.

Saludos. Iñaki.
In reply to James Bromley

Re: LDAP AD creators

by Colin Mackinlay -

Wow - this thread almost fixed my identical problem. But not quite.

LDAP user authentication is working fine. My user is a member of Moodle Creators and Domain Admins and I've tried both of these in the LDAP setup. Nothing has a comma in it and I've made the change to config.php too.

Brand new moodle, php5 and mysql5.

Is it worth me making the various changes in blue from earlier in the thread to see what info I get?  I will anyway!

Colin

 

 

In reply to Colin Mackinlay

Re: LDAP AD creators

by Colin Mackinlay -

Doh! Should have taken my own advice and tried the "blue script" first. All working fine now. The script showed that my moodle creators security group had been created in security groups rather than within staff. Sorted this, removed the other mods and all works absolutely brilliantly.

Thanks for all the work you guys already did as this sorted the bulk of the issue.

Colin

In reply to Iñaki Arenaza

Re: LDAP AD creators

by James Bromley -
Ok, a little bit more thought although this is a syntax problem in moodle ultimately is this a bug with PHP?

The PHP function ldap_get_dn near line 1386 is responsible for returning the dn with the comma escaped with only one backslash which is not compatible with the filter for ldap_read? I wonder if a different version of PHP makes any difference.

My last question is should this be a few lines higher up in the code would we want to perform this to every username or only to usernames that are dn’s? If so change:   

if ($CFG->ldap_memberattribute_isdn) {

        $username=auth_ldap_find_userdn($ldapconnection, $username);

    }

    if (! $username ) {

        return $result;

    }

$username = preg_replace ('/\\\\,/', '\\\\\\\\,', $username);

    $groups = explode(";",$groupdns);

 

To

 

    if ($CFG->ldap_memberattribute_isdn) {

        $username=auth_ldap_find_userdn($ldapconnection, $username);

$username = preg_replace ('/\\\\,/', '\\\\\\\\,', $username);

    }

    if (! $username ) {

        return $result;

    }

    $groups = explode(";",$groupdns);

 


Thank you,
James Bromley

In reply to James Bromley

Re: LDAP AD creators

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
My last question is should this be a few lines higher up in the code would we want to perform this to every username or only to usernames that are dn’s?

In fact, I would change it to:
    if ($CFG->ldap_memberattribute_isdn) {
        $username=auth_ldap_find_userdn($ldapconnection, $username);
        if (! $username ) {
            return $result;
        }
        $username = preg_replace ('/\\\\,/', '\\\\\\\\,', $username);
    }

The only way $username can be empty at this point is if we can't find the user DN (we already tested before that $username was not empty), so testing it after the ldap_memberattribute_isdn test is "useless".

Thus we only do the 'quoting' if $username should be a DN and we really found that DN in the LDAP server.

Saludos. Iñaki.
In reply to Iñaki Arenaza

Re: LDAP AD creators

by Phil Rand -
Fixed it for me too, Moodle 1.7, auth/ldap/lib.php,v 1.83.2.2.