Ldap -> External DB failthrough

Ldap -> External DB failthrough

by CG G -
Number of replies: 7

I have a scenario with a multi-domain forest with some users in it via Active Directory. 

From my reading here, using the GC port and forest address in the LDAP configuration should provide read access to the entire forest, so that takes care of my first possible issue. 

We also have a MySQL database with ALL users, including those contained in AD. This database does not contain passwords for our AD users, but does have passwords for users that are not in AD. 


We need to have authentication for all users in Moodle. So my question is this:


If I setup LDAP as the first authentication method (below internal for my moodle admin accounts), then the external SQL database below that, will Moodle "fail through" the LDAP plugin if it does not find any users matching the passed username and then check via the second database?


Thanks for any help you can offer. This entire Moodle community forum is outstanding for support!



Average of ratings: -
In reply to CG G

Re: Ldap -> External DB failthrough

by Leon Stringer -
Picture of Core developers Picture of Particularly helpful Moodlers

Yes, but I'd recommend thinking through the work flow and using a test site to make sure it works as expected.

For example, with both auth_ldap and auth_db enabled and attempted in that order if an AD user which doesn't already exist in Moodle attempts to log in with a password which doesn't match their AD password the authentication will then be attempted using auth_db. If that were to succeed the user would now be an External Database user so would never authenticate against AD, unless manually changed by the Moodle admin.

If the database never holds passwords for AD users then presumably this couldn't (or shouldn't!) happen.

You may also want to think about syncing the users from the external sources. It's often useful to have the users populated in Moodle so they can be enrolled on courses ahead of their first login, but it will be important to make sure the users you want to authenticate with each specific service are created with the correct authentication method so AD users are authenticated by auth_ldap and database users are authenticated by auth_db. From your description it may be possible to use a database view which only returns those users with a password so that Moodle only sees users in the database that will be authenticated by the database.

I hope this makes sense!

Average of ratings: Useful (2)
In reply to Leon Stringer

Re: Ldap -> External DB failthrough

by CG G -
That does make sense, thank you for the info. I'll be testing out the fail-through to see if it works as intended. 

For syncing users, isn't that the Enrolment method in the Moodle documentation? I didn't realize there was a way to specify which authentication method each user needs to use in that. 
In reply to CG G

Re: Ldap -> External DB failthrough

by Emma Richardson -
Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Plugin developers
Just make sure that your users are not already in Moodle. In which case, you would need to change their authentication method to ldap or database.
In reply to CG G

Re: Ldap -> External DB failthrough

by Leon Stringer -
Picture of Core developers Picture of Particularly helpful Moodlers

Both the External Database and LDAP Server plugins have a scheduled task which can keep the relevant user details up-to-date. If enabled the scheduled task would query the authentication source – the AD server or database server in this instance – and add the returned users to Moodle if they don't already exist or update user profiles (first name, last name, etc.).

It looks like the External Database documentation is out of date: instead of running sync_users.php this is now all managed on the Scheduled Tasks page (\auth_db\task\sync_users and \auth_ldap\task\sync_task), these are then run by the site cron.

Again, there are a couple of things to think through such as what happens to users in Moodle when they're no longer returned by the authentication source (delete them in Moodle, suspend them or do nothing?). Also with AD it's important to get the look-up criteria (contexts or group membership) correct otherwise you end up with a Moodle full of Windows system accounts and other AD users you didn't want to synchronise.

In reply to Leon Stringer

Re: Ldap -> External DB failthrough

by CG G -
Thanks for that.


Now onto my next question regarding authentication:

I've tested LDAP, which works, including through our global catalog (thanks Emma from a previous post!)

I've tested our MySQL external database, and that also works, with one issue. The passwords in that database were put in the user table using the PASSWORD (string) function in MySQL. This isn't MD5, SHA-1, or any other hash that is available in Moodle. If I copy the actual encoded password string, select plain text in Moodle for the password encoding, then log in, it works fine. MD5 and SHA-1 doesn't work, because MySQL doesn't use those encoding methods for storing passwords using the PASSWORD (string) function.

I've tested the password using external encoders. MD5 and SHA-1 don't work, but encoding via the MySQL PASSWORD() hash matches what I have in the database exactly.

Short of adding another field for MD5 or SHA-1 encoded passwords in the database, do I have any other options for using the native MySQL PASSWORD() encoded hashes? Is there a way to tell Moodle to encode the passwords using that MySQL function?
In reply to CG G

Re: Ldap -> External DB failthrough

by Leon Stringer -
Picture of Core developers Picture of Particularly helpful Moodlers

If I've understood correctly then Moodle can't use this database for authenticating users. You could still use it to manage users and their profile data. You could then manage a process to change affected users' passwords, perhaps using Password format = "Internal" in Moodle. But if the database is being used for authentication with other systems then this may be an issue as users would have one password for Moodle and another for other systems.

Another option could be to change Moodle adding support for this password format. You'd need to edit two files, first auth/db/settings.php to add a new $passtype[] element (line 98 in Moodle 3.8):

    $passtype["mysqlfunction"]    = "MySQL Function";

Then edit auth/db/auth.php to handle this new type (line 141):

            } else if ($this->config->passtype === 'mysqlfunction') {
                $authdb = $this->db_init();
                $rs = $authdb->Execute("SELECT PASSWORD('$extpassword') AS password");
                $password_function = $rs->fields['password'];
                $authdb->Close();
                return ($fromdb === $password_function);
            } else {

This would add "MySQL Function" to the plugin's Password format field. It seems to work correctly in my tests.

Caveats:

  • Modifying Moodle isn't generally recommended, changes may delay updates being installed and the changes must be re-applied as part of the update.
  • When you modify Moodle it's more difficult to get support, either in these forums or elsewhere, as your Moodle doesn't match anyone else's.
  • MySQL's PASSWORD() has been deprecated for some time and has been removed from MySQL 8.0 so ideally plan to move away from this regardless of what you do.

But this change may be an option for you in the short term.

Average of ratings: Useful (2)
In reply to Leon Stringer

Re: Ldap -> External DB failthrough

by CG G -

Outstanding!


I've made the modifications and tested them. Everything is working as intended. 


We are running a legacy external DB that is heavily used for a number of other internal custom applications. Once we upgrade that to a newer version of MySQL and transition all the other applications in the process, we can then switch over to using SHA-1 and I will not need the modified code any longer. 


Thank you so much for the help. Your help is exactly what makes this community so great.