From 0fe17585726b35cfcfaf0f4f8e29cbacf8e878eb Mon Sep 17 00:00:00 2001 From: sshambar Date: Wed, 19 Feb 2020 14:12:39 -0800 Subject: [PATCH] Add SASL PLAIN authentication support (#92) Adds a new sasl mech 'plain' which converts all simple authentication methods to SASL PLAIN. NOTE: doesn't use auth_type 'sasl' as credentials may come from login form, stored in cookies etc... --- config/config.php.example | 9 +++++++-- lib/ds_ldap.php | 26 +++++++++++++++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/config/config.php.example b/config/config.php.example index e375d27..a5377f3 100644 --- a/config/config.php.example +++ b/config/config.php.example @@ -341,11 +341,16 @@ $servers->setValue('server','name','My LDAP Server'); /* Enable SASL authentication LDAP SASL authentication requires PHP 5.x configured with --with-ldap-sasl=DIR. If this option is disabled (ie, set to false), then all other sasl options are ignored. */ -// $servers->setValue('login','auth_type','sasl'); +# $servers->setValue('login','auth_type','sasl'); -/* SASL auth mechanism */ +/* SASL GSSAPI auth mechanism (requires auth_type of sasl) */ // $servers->setValue('sasl','mech','GSSAPI'); +/* SASL PLAIN support... this mech converts simple binds to SASL + PLAIN binds using any auth_type (or other bind_id/pass) as credentials. + NOTE: auth_type must be simple auth compatible (ie not sasl) */ +# $servers->setValue('sasl','mech','PLAIN'); + /* SASL authentication realm name */ // $servers->setValue('sasl','realm',''); # $servers->setValue('sasl','realm','EXAMPLE.COM'); diff --git a/lib/ds_ldap.php b/lib/ds_ldap.php index 4352414..6107552 100644 --- a/lib/ds_ldap.php +++ b/lib/ds_ldap.php @@ -195,7 +195,7 @@ class ldap extends DS { # If SASL has been configured for binding, then start it now. if ($this->isSASLEnabled()) - $bind['result'] = $this->startSASL($resource,$method); + $bind['result'] = $this->startSASL($resource,$method,$bind['id'],$bind['pass']); # Normal bind... else @@ -588,6 +588,8 @@ class ldap extends DS { * Users may configure phpLDAPadmin to use SASL in config,php thus: * * $servers->setValue('login','auth_type','sasl'); + * OR + * $servers->setValue('sasl','mech','PLAIN'); * * * @return boolean @@ -596,8 +598,11 @@ class ldap extends DS { if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs); - if ($this->getValue('login','auth_type') != 'sasl') - return false; + if (! in_array($this->getValue('login','auth_type'), array('sasl'))) { + // check if SASL mech uses login from other auth_types + if (! in_array(strtolower($this->getValue('sasl', 'mech')), array('plain'))) + return false; + } if (! function_exists('ldap_sasl_bind')) { error(_('SASL has been enabled in your config, but your PHP install does not support SASL. SASL will be disabled.'),'warn'); @@ -615,7 +620,7 @@ class ldap extends DS { * * @todo This has not been tested, please let the developers know if this function works as expected. */ - private function startSASL($resource,$method) { + private function startSASL($resource,$method,$login,$pass) { if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs); @@ -625,8 +630,8 @@ class ldap extends DS { if ($method == 'anon') return false; - # At the moment, we have only implemented GSSAPI - if (! in_array(strtolower($this->getValue('sasl','mech')),array('gssapi'))) { + # At the moment, we have only implemented GSSAPI and PLAIN + if (! in_array(strtolower($this->getValue('sasl','mech')),array('gssapi','plain'))) { system_message(array( 'title'=>_('SASL Method not implemented'), 'body'=>sprintf('%s: %s %s',_('Error'),$this->getValue('sasl','mech'),_('has not been implemented yet')), @@ -635,8 +640,15 @@ class ldap extends DS { return false; } + if (strtolower($this->getValue('sasl','mech')) == 'plain') { + return @ldap_sasl_bind($resource,NULL,$pass,'PLAIN', + $this->getValue('sasl','realm'), + $login, + $this->getValue('sasl','props')); + } + if (! isset($CACHE['login_dn'])) - $CACHE['login_dn'] = is_null($this->getLogin($method)) ? $this->getLogin('user') : $this->getLogin($method); + $CACHE['login_dn'] = $login; $CACHE['authz_id'] = '';