ubc / iPeer

Peer Evaluation System
http://ipeer.ctlt.ubc.ca
Other
17 stars 18 forks source link

Active Directory authentication issues #635

Closed dramaley closed 4 years ago

dramaley commented 4 years ago

Hello! I've recently moved our iPeer from a RHEL 7 to a Debian 10 server. The new server has PHP 7, which allowed me to update iPeer to version 3.4.4 with CakePHP-Guard-Plugin 1.0.5. It all seems to be running just fine.

The next change is to authentication though. Our iPeer currently authenticates to a standard LDAP server which is scheduled for removal later this year. So I need to change it to authenticate against Active Directory. We have the same users in AD as the standard LDAP, so it should be a simple matter of changing the configuration in app/config/guard.php, right?

Here is the configuration that goes to the old server; i'm going to obscure the credentials but it does work: $config['Guard.AuthModule.Ldap'] = array( 'host' => 'ldaps://eds.drake.edu', 'port' => 636, 'serviceUsername' => '[SECURED]', // username to connect to LDAP 'servicePassword' => '[SECURED]', // password to connect to LDAP 'baseDn' => 'ou=people,dc=drake,dc=edu', 'usernameField' => 'uid', 'attributeSearchFilters' => array( // 'uid', ), 'attributeMap' => array( // 'username' => 'uid', ), 'fallbackInternal' => true, );

That works just fine. And this gets written to app/tmp/logs/debug.log: 2020-03-09 14:18:40 Debug: Using LDAP Authentication module 2020-03-09 14:18:41 Debug: redirecting to /

Nothing is written to app/tmp/logs/error.log.

Now, i tried to change guard.php to point to our Active Directory: $config['Guard.AuthModule.Ldap'] = array( 'host' => 'ldaps://drake.edu', 'port' => 636, 'serviceUsername' => '[SECURED]', // username to connect to LDAP 'servicePassword' => '[SECURED]', // password to connect to LDAP 'baseDn' => 'dc=drake,dc=edu', 'usernameField' => 'sAMAccountName', 'attributeSearchFilters' => array( // 'uid', ), 'attributeMap' => array( // 'username' => 'uid', ), 'fallbackInternal' => true, );

And that does not work. Any ideas? I have confirmed using the ldapsearch command that all the information is accurate, and I can use those credentials to perform searches, so I know all the values are correct.

I see different things in the logs though. In app/tmp/logs/debug.log: 2020-03-09 14:16:51 Debug: Using LDAP Authentication module

And in app/tmp/logs/error.log: 2020-03-09 14:16:51 Warning: Warning (2): ldap_search(): Search: Operations error in [/srv/www/ipeer/html/app/plugins/guard/controllers/components/ldap_module.php, line 58] 2020-03-09 14:16:51 Error: Fatal Error (256): Unable to perform LDAP seach with base DN dc=drake,dc=edu and search sAMAccountName=000214567. in [/srv/www/ipeer/html/app/plugins/guard/controllers/components/guard.php, line 325]

kitsook commented 4 years ago

Hard to tell from the log as it doesn't print out the exact LDAP error. The binding call seems passed so the system authentication part should be fine.

Try printing out ldap_error($ds) as part of the log within the if block in app/plugins/guard/controllers/components/ldap_module.php

https://github.com/xcompass/CakePHP-Guard-Plugin/blob/96d815561a6c3fb77982f080c6e6b7fea1b5042a/controllers/components/ldap_module.php#L58-L63

When you try with ldapsearch command, did you use the same base DN dc=drake,dc=edu and filter sAMAccountName=000214567?

I am thinking could it be the filter syntax? Try to change the filter in the ldap_search call

'(&(objectCategory=person)('.$this->usernameField.'='.$this->data[$this->guard->fields['username']].'))'

reference: https://stackoverflow.com/questions/6507492/get-samaccountname-from-ldap-using-php

dramaley commented 4 years ago

Hello and thank you for the response! I added a debug statement at the spot you indicated. Got this in the logs: 2020-03-16 14:32:16 Debug: Operations error

"Operations error" sounds kind of vague, but I Googled it and ended up finding this page which mentions that. One of the suggestions in that thread was to add: ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);

That worked!

I have no idea if i added it in a good place though; I don't work in PHP and so don't know how the error trapping really works. For now I just added that after the LDAP_OPT_PROTOCOL_VERSION line. I've attached a patch file with the addition (though had to add a .log extension to get this forum to accept it). Is that an OK spot to add the extra line of code, or does it need more? ldap_module.patch.log

kitsook commented 4 years ago

Hi @dramaley. Thanks for letting us know your findings. Yes, it is OK to set LDAP_OPT_REFERRALS after LDAP_OPT_PROTOCOL_VERSION. You wanted to set these options before calling ldap_bind.

So it seems that in your environment, the AD server tried to refer your requests to another server. But that referred server probably doesn't support your search query and hence you got the "operations error". By disabling the LDAP_OPT_REFERRALS option, your query will be send to the original server.

dramaley commented 4 years ago

This is working, and I've made notes that my environment requires this extra line of LDAP_OPT_REFERRALS code so we can make sure to keep that when we do updates. Thank you for the help!