Multiple LDAP servers in auth/ldap plugin in 3.x

Multiple LDAP servers in auth/ldap plugin in 3.x

by Damian Kaliszan -
Number of replies: 15
Hi,

Despite some messages on this thread already appeared in this forum, this is still not clear to me if we can use multiple LDAP servers url in the plugin/auth/ldap web form for users synchronisation task.
Code analysis says sync_users task calls only once ldap_connect (which, in turn, calls ldap_connect_moodle). Then, inside ldap_connect_moodle there's a loop on urls which .... doesn't do much...
Could you clear to me if multiple ldap urls are enabled and - if not - how to make them work?

Best regards,
Damian
PSNC


Average of ratings: -
In reply to Damian Kaliszan

Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Emma Richardson -
Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Plugin developers

You can use multiple urls for the same AD as a failover.  If you want to authenticate from two different domains, then you need to clone the plugin and set up two versions, one for each domain.  See this (very lengthy) forum post https://moodle.org/mod/forum/discuss.php?d=74279 where Inaki posts all the patches that make this process a lot easier.

In reply to Emma Richardson

Odp: Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Damian Kaliszan -

Thank yousmile I succeeded this one some time ago and currently have two copies of same plugin.

I have two further questions:

1/ How to sync users from second LDAP too? (for regular sync I use the following command: php admin/tool/task/cli/schedule_task.php --execute=\\auth_ldap\\task\\sync_task)


2/ This is more dev question.

 In user profile I created addition field called "Group" (it has 2 possible values).

During sync (on clear users table), based on DN  or LDAP url I assign users to particular group. This one I can do in auth.php in section starting with "/// User Additions". I'm unable to do the same when given user already exist (in user table) and sync process needs to check/update group based on DN again.

The question is how to enforce to enter the section " if ($do_updates and !empty($updatekeys))" and make it  to check if user Group has change? (i.e. LDAP admin changed user DN on some purpose).

In other words every time I call sync I need to change user DN for any update/change.


Hope my quesion is clearsmile

p.s. this piece of code is in charge of adding field key to update keyss

/// User Updates - time-consuming (optional)
        if ($do_updates) {
            // Narrow down what fields we need to update
            $all_keys = array_keys(get_object_vars($this->config));
            $updatekeys = array();
            foreach ($all_keys as $key) {
                 
                if (preg_match('/^field_updatelocal_(.+)$/', $key, $match)) {
                    // If we have a field to update it from
                    // and it must be updated 'onlogin' we
                    // update it on cron
                     echo "KEY=".$key.", MATCH=".$match[1]."; onlogin=".$this->config->{$match[0]}."\n";
                    if (!empty($this->config->{'field_map_'.$match[1]})
                         and $this->config->{$match[0]} === 'onlogin') {
                        array_push($updatekeys, $match[1]); // the actual key name
                      
                    }
                }
            }

In reply to Damian Kaliszan

Re: Odp: Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Emma Richardson -
Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Plugin developers

For your first question, you just run the sync from the same folder in your second ldap plugin folder.

In reply to Damian Kaliszan

Odp: Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Damian Kaliszan -

Hmm...

The problem is I can call (original) sync task from any folder I want but I have to point the path to schedule_task.php in the execution command .

In any case the original ldap sync is called. It is because the command php admin/tool/task/cli/schedule_task.php --execute=\\auth_ldap\\task\\sync_task doesn't contain any additional information, such as path to the task to be executed. It's designed to call original ldap sync.



In reply to Damian Kaliszan

Re: Odp: Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Emma Richardson -
Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Plugin developers

Oh, so you are wanting it to run automatically from scheduled task?  I don't think that is possible.  I would suggest setting up a cron script on the server that will run the sync for the second ldap folder.  Otherwise, you are going to have to hack code...

In reply to Emma Richardson

Odp: Re: Odp: Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Damian Kaliszan -
Yes, this is what I tend to...
However, I have also problems to follow the second (deprecated)way of sync.

moodle@moodle:~/moodle/auth/ldap_other/cli$ php sync_users.php
[AUTH LDAP_OTHER] The users sync cron has been deprecated. Please use the scheduled task instead.
[AUTH LDAP_OTHER] The scheduled task sync_task is enabled, the cron execution has been aborted.

When you look into sync_users.php script, despite changing $authtype from 'ldap' to 'ldap_other' the following part of the code still wants to get the previous task

$taskdisabled = \core\task\manager::get_scheduled_task('auth_ldap\task\sync_task');


Regards,
Damian
In reply to Damian Kaliszan

Re: Odp: Re: Odp: Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Emma Richardson -
Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Plugin developers

To run it manually, you have to disable the scheduled task.  Then you will still get the deprecated warning but it will run.

 

In reply to Emma Richardson

Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Damian Kaliszan -
Ok. I disabled the scheduled task in server/scheduled task in the server section. Then..
moodle@moodle:~/moodle/auth/ldap_other$ php ./cli/sync_users.php
[AUTH LDAP_OTHER] The users sync cron has been deprecated. Please use the scheduled task instead.
PHP Fatal error:  Call to a member function get_disabled() on a non-object in /home/moodle/moodle/auth/ldap_other/cli/sync_users.php on line 67

Fatal error: Call to a member function get_disabled() on a non-object in /home/moodle/moodle/auth/ldap_other/cli/sync_users.php on line 67
This is because, line 66 looks like this

$taskdisabled = \core\task\manager::get_scheduled_task('auth_ldap_other\task\sync_task');

It tries, anyway, to get scheduled task of the plugin. As I mentioned earlier in db/tasks.php I already defined:
$tasks = array(
    array(
        'classname' => 'auth_ldap_other\task\sync_task',
        'blocking' => 0,
        'minute' => '0',
        'hour' => '0',
        'day' => '*',
        'month' => '*',
        'dayofweek' => '*',
        'disabled' => 0
    )
);
In classes/task/sync_task.php I changed namespace to
namespace auth_ldap_other\task;
and the rest as in th attached file. What else needs to be changed to make the sync task in duplicated plugin work?

In reply to Damian Kaliszan

Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Emma Richardson -
Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Plugin developers

I am sorry - I should have read more carefully.  Run the task from auth/ldap/cli/sync_users.php, not from the scheduled tasks.  The script is actually found in that folder.  For your duplicated instance, run it from auth/"yournewldap"/cli/sync_users.php

In reply to Emma Richardson

Odp: Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Damian Kaliszan -
OK, that was not the case. I had to create manually a record related to new ldap syn task in task_scheduled table in the database. After this step I am able to run both scheduled task for all ldaps as well as sync_users.php script (the latter searches for scheduled task anyway).
In reply to Damian Kaliszan

Re: Odp: Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Emma Richardson -
Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Plugin developers

Oh, very cool.  I had not even thought of trying that but then I rarely need to run the sync for my second ldap server so I tend to just run it manually when I need that.  Glad you got it working despite my wrong directions!!  wink

In reply to Emma Richardson

Odp: Re: Odp: Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Damian Kaliszan -

No problem.

Anyway it's interesting how you got it working without any changes in the code (related to ldap plugin name change)  and relevant update in the database. 

Additionally,  script can be  ran from any folder but the path to it must be included in the execution command.


Regards, Damian smile

In reply to Damian Kaliszan

Re: Odp: Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Olumuyiwa Taiwo -
Picture of Plugin developers

You said:

>  I had to create manually a record related to new ldap syn task in task_scheduled table in the database

Changing Moodle database manually is generally a very bad idea and can have serious consequences, especially during upgrades. Consider creating a custom plugin instead.


In reply to Olumuyiwa Taiwo

Odp: Re: Odp: Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Damian Kaliszan -
Yes, I'm aware of that but I couldn't find any better way to make the plugin working, in the scope of task sync.
Both methods ( current using scheduled task and deprecated calling directly cli/sync_users.php failed due to aforementioned reasons.
(get_scheduled_task function calls $DB->get_record searching for a record containg new classname of a plugin).

If you could point a better (proper) way I would appreciate thissmile

Regards,
Damian
In reply to Damian Kaliszan

Re: Odp: Re: Odp: Re: Multiple LDAP servers in auth/ldap plugin in 3.x

by Olumuyiwa Taiwo -
Picture of Plugin developers

Did you remember to bump the version number of your ldap_other plugin after creating the scheduled_task class? 

See https://docs.moodle.org/dev/Task_API

You have to do that every time you make changes to the code in order for it to be picked him the DB.