From be2ac5f1c936f17e2879636ac9e913f0e4c4ad02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Guillot?= Date: Tue, 19 Aug 2014 16:26:07 -0700 Subject: [PATCH] Add multiple LDAP binding type --- app/Auth/Ldap.php | 17 ++++++- app/common.php | 1 + config.default.php | 8 ++- docs/ldap-authentication.markdown | 85 +++++++++++++++++++++++++++++-- 4 files changed, 104 insertions(+), 7 deletions(-) diff --git a/app/Auth/Ldap.php b/app/Auth/Ldap.php index bb17653d4..97d4d0e3a 100644 --- a/app/Auth/Ldap.php +++ b/app/Auth/Ldap.php @@ -96,8 +96,21 @@ class Ldap extends Base ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0); - if (! @ldap_bind($ldap, LDAP_USERNAME, LDAP_PASSWORD)) { - die('Unable to bind to the LDAP server: "'.LDAP_SERVER.'"'); + if (LDAP_BIND_TYPE === 'user') { + $ldap_username = sprintf(LDAP_USERNAME, $username); + $ldap_password = $password; + } + else if (LDAP_BIND_TYPE === 'proxy') { + $ldap_username = LDAP_USERNAME; + $ldap_password = LDAP_PASSWORD; + } + else { + $ldap_username = null; + $ldap_password = null; + } + + if (! @ldap_bind($ldap, $ldap_username, $ldap_password)) { + return false; } $sr = @ldap_search($ldap, LDAP_ACCOUNT_BASE, sprintf(LDAP_USER_PATTERN, $username), array(LDAP_ACCOUNT_FULLNAME, LDAP_ACCOUNT_EMAIL)); diff --git a/app/common.php b/app/common.php index f92e3ddb6..6b5bc7293 100644 --- a/app/common.php +++ b/app/common.php @@ -62,6 +62,7 @@ defined('LDAP_AUTH') or define('LDAP_AUTH', false); defined('LDAP_SERVER') or define('LDAP_SERVER', ''); defined('LDAP_PORT') or define('LDAP_PORT', 389); defined('LDAP_SSL_VERIFY') or define('LDAP_SSL_VERIFY', true); +defined('LDAP_BIND_TYPE') or define('LDAP_BIND_TYPE', 'anonymous'); defined('LDAP_USERNAME') or define('LDAP_USERNAME', null); defined('LDAP_PASSWORD') or define('LDAP_PASSWORD', null); defined('LDAP_ACCOUNT_BASE') or define('LDAP_ACCOUNT_BASE', ''); diff --git a/config.default.php b/config.default.php index 6206f37e9..89ba033e7 100644 --- a/config.default.php +++ b/config.default.php @@ -55,10 +55,14 @@ define('LDAP_PORT', 389); // By default, require certificate to be verified for ldaps:// style URL. Set to false to skip the verification. define('LDAP_SSL_VERIFY', true); -// LDAP username to connect with. NULL for anonymous bind (by default). +// LDAP bind type: "anonymous", "user" (use the given user/password from the form) and "proxy" (a specific user to browse the LDAP directory) +define('LDAP_BIND_TYPE', 'anonymous'); + +// LDAP username to connect with. null for anonymous bind (by default). +// Or for user bind type, you can use a pattern: %s@kanboard.local define('LDAP_USERNAME', null); -// LDAP password to connect with. NULL for anonymous bind (by default). +// LDAP password to connect with. null for anonymous bind (by default). define('LDAP_PASSWORD', null); // LDAP account base, i.e. root of all user account diff --git a/docs/ldap-authentication.markdown b/docs/ldap-authentication.markdown index 989ee24d8..0c4a5720f 100644 --- a/docs/ldap-authentication.markdown +++ b/docs/ldap-authentication.markdown @@ -46,10 +46,14 @@ define('LDAP_PORT', 389); // By default, require certificate to be verified for ldaps:// style URL. Set to false to skip the verification. define('LDAP_SSL_VERIFY', true); -// LDAP username to connect with. NULL for anonymous bind (by default). +// LDAP bind type: "anonymous", "user" (use the given user/password from the form) and "proxy" (a specific user to browse the LDAP directory) +define('LDAP_BIND_TYPE', 'anonymous'); + +// LDAP username to connect with. null for anonymous bind (by default). +// Or for user bind type, you can use a pattern like that %s@kanboard.local define('LDAP_USERNAME', null); -// LDAP password to connect with. NULL for anonymous bind (by default). +// LDAP password to connect with. null for anonymous bind (by default). define('LDAP_PASSWORD', null); // LDAP account base, i.e. root of all user account @@ -68,9 +72,58 @@ define('LDAP_ACCOUNT_FULLNAME', 'displayname'); define('LDAP_ACCOUNT_EMAIL', 'mail'); ``` +### LDAP bind type + +There is 3 possible ways to browse the LDAP directory: + +#### Anonymous browsing + +```php +define('LDAP_BIND_TYPE', 'anonymous'); +define('LDAP_USERNAME', null); +define('LDAP_PASSWORD', null); +``` + +This is the default value but some LDAP servers don't allow that. + +#### Proxy user + +A specific user is used to browse the LDAP directory. +By example, Novell eDirectory use that method. + +```php +define('LDAP_BIND_TYPE', 'proxy'); +define('LDAP_USERNAME', 'my proxy user'); +define('LDAP_PASSWORD', 'my proxy password'); +``` + +#### User credentials + +This method use the credentials provided by the end-user. +By example, Microsoft Active Directory doesn't allow anonymous browsing by default and if you don't want to use a proxy user you can use this method. + +```php +define('LDAP_BIND_TYPE', 'user'); +define('LDAP_USERNAME', '%s@mydomain.local'); +define('LDAP_PASSWORD', null); +``` + +Here, the `LDAP_USERNAME` is use to define a replacement pattern: + +```php +define('LDAP_USERNAME', '%s@mydomain.local'); + +// Another way to do the same: + +define('LDAP_USERNAME', 'MYDOMAIN\\%s'); +``` + ### Example for Microsoft Active Directory Let's say we have a domain `KANBOARD` (kanboard.local) and the primary controller is `myserver.kanboard.local`. +Microsoft Active Directory doesn't allow anonymous binding by default. + +First example with a proxy user: ```php