Getting LDAP to work (a solution)

Getting LDAP to work (a solution)

by Lou Delicious -
Number of replies: 25
[this only applies to those running Windows 2003 and Active Directory. If you're a Linux user, this probably won't help...but you're still cool for fighting "the man" and going open source]


Okay --

After about 2 weeks of poring through the forums here, trying various configurations of WAMP (win2k3/apache/mysql/php) and WIMP (win2k3/iis/mysql/php), i finally got Moodle up and running *with* LDAP support.

So, I'd like to save other people the trouble I went through and go over the pitfalls I faced.

This file assumes you are starting from scratch, which might be a good idea. Delete all the old stuff, and start fresh. Then....


1) Get Apache, PHP, and MySQL playing together nicely. I think using an out-of-the-box solution is an extremely easy way to accomplish this, so I used a product called WAMPServer, available at the www.wampserver.com. There are several other products that will do the same thing, so you *do* have a choice. You could use IIS, but I had a horrible time getting PHP going on there, so I scrapped it.


2) Enable LDAP support in PHP by finding your PHP.ini file and uncommenting (getting rid of the ';') the line that says:    
     
;extension=php_ldap.dll


3) Download the LDAP example files from http://adldap.sourceforge.net/ and toss them into a directory on your web server. Take a look at "examples.php" and edit the following near the top of the file:

----------------
//variables, change these Mamatheka
$user="SomeUsername";
$pass="ThePassword";

//some stuff to search for
$lookup_user  = "SomeOtherUsername"; //a user
$lookup_group = "SomeUsergroup"; //a group
----------------

The top two things, the user and password, correspond to what is called a "bind user." To do LDAP Authentication with Active Directory (Windows 2000/2K3), you need to have a valid username/password to access it. Many admins make a bogus account to do this. I did the same. This concept of a "bind user" will present itself later on, when we configure Moodle.

The bottom two things are a User to look up and the corresponsing User Group. The User can be any user in Active Directory. I chose my own account. As for UserGroup, "Users" might not work. I made two new UserGroups in our Active Directory tree -- "Students" and "Teachers." Since I'm a teacher, I put "Teachers" for the group I was searching for.

Save your changes, and then open up the adLDAP.php file. A few lines down, you will see the following:

-------------------------------------------
    // You will need to edit these variables to suit your installation
    var $_account_suffix="@bfsweb.busanforeignschool.org";
    var $_base_dn = "DC=bfsweb,DC=busanforeignschool,DC=org";
   
    // An array of domain controllers. Specify multiple controllers if you
    // would like the class to balance the LDAP queries amongst multiple servers
    var $_domain_controllers = array ("server.bfsweb.busanforeignschool.org");
--------------------------------------------------

Obviously, the Busan Foreign School stuff is specific to my site, so you'll have to supply your own information there. Account Suffix is gonna be whatever the name is at the top of your Active Directory tree -- the name of the domain pretty much. Base DN stands for Base Domain Name, which will be your domain name, again, but with each part between the dots separated out, with DC= in front of it, and each part separated by commas. See the example above, which is much simpler than my explanation sounds.

Lastly, change the domain controllers part to the name of your Domain Server. If your server is called Bob and your domain is called TheZoo.org, then this would be Bob.TheZoo.org . Easy stuff.

Run the examples.php script in your browser, now, and see if it works. If it does, you're good to go. If not, PHP and LDAP aren't playing nice. You'll have to fix your configuration between those programs.


4) Download Moodle.


5) Get another program, which I heard about from another thread on here, called Softerra LDAP Browser, available for free at:

http://www.softerra.com/products/ldapbrowser.php

If you can communicate with your LDAP on here, then you will be able to get it to work with Moodle for sure. Run the program, make a new profile, give in a name, and then type in the name of your LDAP server (the same comp with Active Directory on it), then hit Fetch DNs (and pick the one that looks like something you saw above, when we worked with those PHP scripts). DO NOT click the box for Anonymous Bind. Windows 2003 does not support this, which is why we used the "Bind User" in step 3.

Hit Next.

For User DN, we're gonna put the name of a user (maybe a fake one you created for LDAP purposes). First, let's define some stuff. DN means "distinguished name," which is in the following format:

CN=John Doe,OU=Students,DC=bfsweb,DC=busanforeignschool,DC=org

CN stands for Canonical Name, which is gonna be the name that your users appear with in Active Directory.

This IS *NOT* the name they log in to the domain with.

I didn't realize that, and I banged my head against a wall for weeks trying to figure all this out.

OU is Organization Unit, which is something your Active Directory will have plenty of. As I said before, at my school I used "Students" and "Teachers." You may have something different. This must match the user whom you listed in CN.

We already covered the DC junk...same as before.

Pop all that in, and enter the password of said user.

Hit next.

Hit finish.

If it works, you can see your AD tree pop up, and you can see all kinds of information. If it's not working, make sure your CN, OU, DCs, and Server Name are correct. Mess around with these until you get it right.

6) Finally, go into Moodle. Log in as an admin, and get into your authentication settings. Change it to use LDAP, as opposed to whatever the default is.

Now, the fun part.

As for the settings, only about the top 1/4 of them will apply for us at this juncture. Here's what you should put:

LDAP server settings

ldap_host_url:    ldap://(your server name)   
ldap_version:     3  

Bind settings

ldap_preventpassindb:  Whatever you want      
ldap_bind_dn:    (Distinguished Name [DN] of the Bind User from Step #5)
ldap_bind_pw:   (the password)
      
User lookup settings

ldap_user_type:         MS Active Directory
ldap_contexts:          Where are your users gonna be coming from? What OUs? Remember, I said that at my school I have 2 OUs: "Students" and "Teachers." So, in this box, I put:

ou=Teachers, dc=bfsweb, dc=busanforeignschool, dc=org; ou=Students, dc=bfsweb, dc=busanforeignschool, dc=org

Change this to suit your configuration.


ldap_search_sub:   Yes   (must be changed!)
ldap_opt_deref:       No
ldap_user_attribute:  We talked about the difference between Canonical Names and Login Names before, right? At my school, let's say there's a student named Jane Doe. When she logs into the domain, her Login Name is CrazyMonkey33.

If you put "cn" in the box, or leave it blank, the user will have to type in "Jane Doe" and her password in order to access Moodle.

If you put "SAMAccountName" in the box, the user will have to type in "CrazyMonkey33" and her password in order to access Moodle.

If you play around with the LDAP Browser program we worked with in Step 5, you can find lots of more fun LDAP variables. Ones for givenName, familyName, etc. These will come in handy later on, when you want to automatically fill some of the information fields when the user signs on for the first time. (see the bottom of the Authentication page)

ldap_memberattribute:      (blank) 
ldap_objectclass:  (blank)

Go ahead, save the settings, and try testing a login. It should actually work!

Like I said, it took me about 2 weeks to figure this whole thing out (I was an LDAP virgin), but the sense of accomplishment I felt when actually getting this bad boy to work was something else.



Good luck with your own installations, and thanks for keeping these forums so active. They've been a big help thus far.

Cheers,
-Lou
currently in Busan, South Korea
Average of ratings: -
In reply to Lou Delicious

Re: Getting LDAP to work (a solution)

by Simon Bryan -
Thanks for all that - have now got LDAP against the AD working!! Has taken a couple of days of interrupted work Phatheka kabi

Do you know how I can now force all exisiting users to use the LDAP Authentication as they are all currently looking at POP3?
In reply to Simon Bryan

Re: Getting LDAP to work (a solution)

by Karrie V -

we are using LDAP and AD as well. We got it to work only we get the following error when someoen updates their profile... any idea how to fix it?

Warning: ldap_search(): Search: Invalid syntax in f:\easyphp1-7\www\moodle\auth\ldap\lib.php on line 1329

Warning: ldap_first_entry(): supplied argument is not a valid ldap result resource in f:\easyphp1-7\www\moodle\auth\ldap\lib.php on line 1336

Warning: ldap_search(): Search: Invalid syntax in f:\easyphp1-7\www\moodle\auth\ldap\lib.php on line 1329

Warning: ldap_first_entry(): supplied argument is not a valid ldap result resource in f:\easyphp1-7\www\moodle\auth\ldap\lib.php on line 1336

Thanks!

In reply to Karrie V

Re: Getting LDAP to work (a solution)

by Lou Delicious -
did you get this to work? i think you're gonna want to check you cn and dn values. i had that error for awhile and it was because those values were incorrect. see the original post to learn how to check these.

-L
In reply to Karrie V

Re: Getting LDAP to work (a solution)

by Stuart Mayor -
Sorry to resurrect on old thread, but...

I have been getting similar errors:

Warning: ldap_search(): Search: Invalid syntax in...
Warning: ldap_first_entry(): supplied argument is not a valid ldap resource...

After a bit of digging around I found that the username is not being passed to the function auth_ldap_find_userdn in auth/ldap/lib.php.
I assume this is because we have Moodle set to NOT update the LDAP server with its data.
Adding the line if (isset($username)) { to the beginning of the function and an extra } at the end seems to solve the problem.

In reply to Simon Bryan

Re: Getting LDAP to work (a solution)

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers
If you want all of your currently POP3-authenticated users to use LDAP instead, you can execute the following SQL query in your moodle database (I suppose your moodle users' table is called mdl_user):

    update mdl_user set auth='ldap' where auth='pop3'

If you just want some of the users instead, execute something like this:

	update mdl_user set auth='ldap' where username = 'the-username-I-want-to-chage'

Saludos. Iñaki.
In reply to Lou Delicious

Re: Getting LDAP to work (a solution)

by Babu Melepuram -
great!
thanks a lot lou.
would you please help me in my problem.
i would like an e-mail account is created automatically for the users after authenticated by LDAP.

thanking you in advance
babu
In reply to Babu Melepuram

Re: Getting LDAP to work (a solution)

by Lou Delicious -
that's a tough one...not sure i can help you. what are you using to do email? microsoft exchange?
In reply to Lou Delicious

Re: Getting LDAP to work (a solution)

by Cris Rhea -
A couple of questions for those who have played with Moodle longer...

I'm trying to get Moodle running on a standard Linux configuration. The basic stuff works fine, but I would like to be able to auto-create and authenticate users against our Microsoft AD servers (using LDAP).  While some of the info looks straight-forward, I have two issues/questions:

1. There is no bind user-- in order to look up something in AD LDAP, a user must
use their account to authenticate (i.e., if you send the request including the user's login and password and you get a response, then they gave the correct username/password.)

2. Users should enter their domain login ID, not their common name. On our servers, their domain login should be prefixed with the domain (e.g., to query our AD LDAP server, my login would be "MFAD\crhea").

This is one of the main features that lead me to look into using Moodle... most other "forum type" software allows anybody to register as anything-- not very secure. Moodle's ability to talk to an external LDAP server is key...

Help!

Thanks-

--- Cris

In reply to Cris Rhea

Re: Getting LDAP to work (a solution)

by Simon Bryan -
1. We created a user for this purpose and put them in the administrator group
2. How many domains do you have? If multiple so they 'trust' each other? Moodle will have to be in one domain and looking at one AD server. AFAIK.  Therefore just use the username without the domain for the relevant domain.

We have been using authentication against AD for the last few months with no problems
In reply to Simon Bryan

Re: Getting LDAP to work (a solution)

by Steve Power -
I am not sure the user needs to be in the admins group. I have no admin rights at all in our AD and whilst waiting for a bind user to be created our installation has been using my account to bind. I think all you need is sufficient rights to query the domain to find a user.
In reply to Steve Power

Re: Getting LDAP to work (a solution)

by Cris Rhea -
I'll have to talk to our AD guys...

I'm not an AD admin, so I can't create an account to use for the bind process.

Also, while it would work in testing, it's against our security policy for me to hardcode my login/password into this program.

Our AD guys may have set up an account for this purpose... I'll have to poke around.

With the way our AD environment was set up, I'm not sure this is going to be as seemless a process as you guys have experienced. smile

In reply to Cris Rhea

Re: Getting LDAP to work (a solution)

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers
Tell you AD admins this account can be really low priviledged. In fact, as long as the account has (network) logon rights, everything else can be removed. The password can be as strong as they will, as you will be typing it only once.

If they make the password expirable, make sure they send you the new password everytime they change it Vica

If they are really paranoid, you can set up the LDAP queries via SSL. This is a little bit more complicated to setup, but not rocket science. The OpenLDAP (you said you were running Moodle in Linux) documentation tells you how to set it up in case you need it.

Saludos. Iñaki.
In reply to Cris Rhea

Re: Getting LDAP to work (a solution)

by Simon Bryan -
So put yours in!   big grin at least for testing - the password is encrypted as far as I can tell. So no more of a risk than the services offered by most browsers to remember passwords.

Seriously it is a very low priviledge user has to do nothing more than be able to look up users in the AD
In reply to Cris Rhea

Re: Getting LDAP to work (a solution)

by Cris Rhea -
OK, had generic account created in AD for the bind process... works (sort of)....

I'm going to look into this in the moodle code, but here's a head's up of what the issues are at my company...
  1. Large number of people in AD (nothing magic here).
  2. AD is organized by geographical location-- many buckets for users. Not  as simple as "Students" and "Teachers". It is unrealistic to enumerate all of the locations in the AD tree where someone could be located.
  3. Instead of enumerating all the search bases, the process can be handled in two steps:
  • The first query with the bind user id looks up the person and finds their full DN (will include their location).
  • Remove the CN from the returned DN string-- this is the search base for that specific user.
  • Attempt the login process with the CN and search base set from the full DN of the person.
For example, my LAN ID is "crhea". My full DN in Active Directory is:

cn=CRHEA,OU=Users,OU=MCR,DC=mfad,DC=mfroot,DC=org

Someone working in our Scottsdale, AZ location would have the form:

cn=Someone,OU=Users,OU=MCS,DC=mfad,DC=mfroot,DC=org

We have three large locations and many (>25) small sites.

Just some food for thought on enhancements for future versions....  I'll post code or info after I dig into this further.

--- Cris



In reply to Cris Rhea

Re: Getting LDAP to work (a solution)

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers
In fact, this is what current code is doing for authentication Vica

See it yourserlf in auth/ldap/lib.php, function auth_user_login(), lines 59-75 (moodle 1.5.3+):
    $ldapconnection = auth_ldap_connect();

if ($ldapconnection) {
$ldap_user_dn = auth_ldap_find_userdn($ldapconnection, $username);

//if ldap_user_dn is empty, user does not exist
if(!$ldap_user_dn){
ldap_close($ldapconnection);
return false;
}

// Try to bind with current username and password
$ldap_login = @ldap_bind($ldapconnection, $ldap_user_dn, stripslashes($password));
ldap_close($ldapconnection);
if ($ldap_login) {
return true;
}
}

If you have lots of OUs, you can specify the root of your AD domain and configure ldap_search_sub = 'yes', and moodle will be able to find all your users, no matter how deep inside OUs they are.

We are working like this at my university right now.

Saludos. Iñaki.


In reply to Lou Delicious

Re: Getting LDAP to work (a solution)

by Michael Winter -

Thanks Lou this worked a treat and after many hours trying to get it working with your help i got it to go in a few hours.

I have one problem that is really annoying though. When a student logs in it works fine and I have few fields being filled so they just log straight into the main page. When they go to change anything in their profile it shows a error saying this.

Notice: ldap: Strange! More than one user record found in ldap. Only using the first one. in C:\Inetpub\wwwroot\moodle\auth\ldap\lib.php on line 830.

On that line in the file is this.

  828     $user_entry = auth_ldap_get_entries($ldapconnection, $user_info_result);
  829      if (count($user_entry)) {
   830       trigger_error("ldap: Strange! More than one user record found in ldap. Only using the first one.");
  831      }

Any ideas ? I am not a programmer so makes no sense to me. Have also attached a screenshot of it.

This goes away after a few seconds and still makes the change. So just want to get rid of it coming up.

Attachment ldap_error.jpg
In reply to Lou Delicious

Re: Getting LDAP to work (a solution)

by James Bromley -

One more thing that might save someone some time, If you are trying to use the feature to automatically assign creators and you have changed the ldap_user_attribute then you also need to change ldap_memberattribute. In my case we are using SAMAccountName in ldap_user_attribute so I had to put member.SAMAccountName in ldap_memberattribute.

James Bromley

Leavenworth Kansas

In reply to Lou Delicious

Re: Getting LDAP to work (a solution)

by John Hiles -

I seem to have created a bind user and successfully connected to AD. Excuse me for being a bit of a novice... this is probably obvious to the techies... but I don't seem to be able to show the test information.below I have attached images for the browser result, the AD tree with the user 'HilesJ' showing the location, and the entry in the examples.php file.

I have tried a few variations but to no avail. I am sure this is due to a lack of understanding of container groups etc on my part. any help gratefully recieved!

Cheers, John

Attachment ldap.gif
In reply to John Hiles

Re: Getting LDAP to work (a solution)

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers
In this particular case, 'Staff' is not a group, but what's called an 'Organizational Unit' (OU for short). You need to specify a regular user group (either Global or Local). They can be identified by their icon: a couple of people Mamatheka

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

Re: Getting LDAP to work (a solution)

by John Hiles -

Thankyou, You're right.  the image I posted showed an OU but there is also a global user group called 'staff' of which the user 'HilesJ' is a member (another image attached to show this).

I assume that the bind user 'binduser' is binding OK because I get the 'authenticated OK' result. Any ideas why it should be that the lookup user or group is failing? I have installed WAMP on a win2003 sever and followed the instructions above to the letter.

Cheers, John

Attachment ldap2.gif
In reply to John Hiles

Re: Getting LDAP to work (a solution)

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers
No idea at all, as I don't know what PHP code you are running to test all of this Phatheka kabi (I suspect it has nothing to do with Moodle)

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

Re: Getting LDAP to work (a solution)

by John Hiles -
you're right, Nothing to do with moodle (that is the next step). I am following Lou's instructions; ie. fresh install of WAMP, download example PHP files, get LDAP and PHP talking properly. I'm up to step 3. bind user is authenticating but user details search not working.
In reply to Lou Delicious

Re: Getting LDAP to work (a solution)

by Phil Rand -
Nice write-up, Lou!

I had to discover most of this stuff for myself when I integrated our Blackboard site with AD a few years ago, and I had forgotten how frustrating it was.

One more tip:

The domain controller (DC) servers on our campus change names and IP addresses from time to time as old hardware is replaced, and other things happen. It doesn't happen all that often, but having a hard-coded array of specific server names in my Blackboard or Moodle LDAP configurations would mean updating them every time the AD managers change a DC. Well it turns out that AD maintains round-robin DNS records for the domain controllers under the overall domain name. In my case, our AD domain is "spu.local" (not visible from the Internet), so if I set ldap_host_url to "ldap://spu.local", everything just works, including when a DC happens to be down for some reason, and I never have to change it.
In reply to Phil Rand

Re: Getting LDAP to work (a solution)

by Phil Rand -
Correction: You need a trailing slash, so my ldap_host_url is really "ldap://spu.local/".