From 1ddbb3bdbb2c895b4c224d39e16120d5db94bebf Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Thu, 18 Oct 2018 08:18:51 +0200 Subject: [PATCH] Auth/LDAP, always add user DN to getLastAuthProperties() and optionally extend with properties available for the user, which might help ease debugging --- .../mvc/app/library/OPNsense/Auth/LDAP.php | 50 ++++++++++++++++--- src/www/system_authservers.php | 15 +++++- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/opnsense/mvc/app/library/OPNsense/Auth/LDAP.php b/src/opnsense/mvc/app/library/OPNsense/Auth/LDAP.php index 0bc8d403c..b89d1b9b5 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Auth/LDAP.php +++ b/src/opnsense/mvc/app/library/OPNsense/Auth/LDAP.php @@ -100,6 +100,17 @@ class LDAP extends Base implements IAuthConnector * @var bool if true, startTLS will be initialized */ private $useStartTLS = false; + + /** + * when set, $lastAuthProperties will contain the authenticated user properties + */ + private $ldapReadProperties = false; + + /** + * @var array internal list of authentication properties (returned by radius auth) + */ + private $lastAuthProperties = array(); + /** * close ldap handle if open */ @@ -204,7 +215,8 @@ class LDAP extends Base implements IAuthConnector "ldap_extended_query" => "ldapExtendedQuery", "ldap_authcn" => "ldapAuthcontainers", "ldap_scope" => "ldapScope", - "local_users" => "userDNmap" + "local_users" => "userDNmap", + "ldap_read_properties" => "ldapReadProperties" ); // map properties 1-on-1 @@ -356,7 +368,7 @@ class LDAP extends Base implements IAuthConnector */ public function getLastAuthProperties() { - return array(); + return $this->lastAuthProperties; } /** @@ -367,26 +379,48 @@ class LDAP extends Base implements IAuthConnector */ public function authenticate($username, $password) { - // todo: implement SSL parts (legacy : ldap_setup_caenv) + $ldap_is_connected = false; + $user_dn = null; // authenticate user if (empty($password)) { // prevent anonymous bind return false; } elseif (array_key_exists($username, $this->userDNmap)) { // we can map $username to distinguished name, just feed to connect + $user_dn = $this->userDNmap[$username]; $ldap_is_connected = $this->connect($this->ldapBindURL, $this->userDNmap[$username], $password); - return $ldap_is_connected; } else { // we don't know this users distinguished name, try to find it - $ldap_is_connected = $this->connect($this->ldapBindURL, $this->ldapBindDN, $this->ldapBindPassword); - if ($ldap_is_connected) { + if ($this->connect($this->ldapBindURL, $this->ldapBindDN, $this->ldapBindPassword)) { $result = $this->searchUsers($username, $this->ldapAttributeUser, $this->ldapExtendedQuery); if ($result !== false && count($result) > 0) { + $user_dn = $result[0]['dn']; $ldap_is_connected = $this->connect($this->ldapBindURL, $result[0]['dn'], $password); - return $ldap_is_connected; } } - return false; } + + if ($ldap_is_connected) { + $this->lastAuthProperties['dn'] = $user_dn; + if ($this->ldapReadProperties) { + $sr = @ldap_read($this->ldapHandle, $userdn, '(objectclass=*)'); + $info = @ldap_get_entries($this->ldapHandle, $sr); + if ($info['count'] != 0) { + // $this->lastAuthProperties['info'] = $info[0]; + foreach ($info[0] as $ldap_key => $ldap_value) { + if (!is_numeric($ldap_key) && $ldap_key !== 'count') { + if (isset($ldap_value['count'])) { + unset($ldap_value['count']); + $this->lastAuthProperties[$ldap_key] = implode("\n", $ldap_value); + } elseif ($ldap_value !== "") { + $this->lastAuthProperties[$ldap_key] = $ldap_value; + } + } + } + } + } + } + + return $ldap_is_connected; } } diff --git a/src/www/system_authservers.php b/src/www/system_authservers.php index 83bb2cb13..2fefec38d 100644 --- a/src/www/system_authservers.php +++ b/src/www/system_authservers.php @@ -88,6 +88,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { if (!empty($a_server[$id]['ldap_bindpw'])) { $pconfig['ldap_bindpw'] = $a_server[$id]['ldap_bindpw']; } + $pconfig['ldap_read_properties'] = !empty($a_server[$id]['ldap_read_properties']); } elseif ($pconfig['type'] == "radius") { $pconfig['radius_host'] = $a_server[$id]['host']; $pconfig['radius_auth_port'] = $a_server[$id]['radius_auth_port']; @@ -236,6 +237,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { unset($server['ldap_bindpw']); } } + $server['ldap_read_properties'] = !empty($pconfig['ldap_read_properties']); } elseif ($server['type'] == "radius") { $server['host'] = $pconfig['radius_host']; @@ -304,7 +306,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { // list of all possible fields for auth item (used for form init) $all_authfields = array( 'type','name','ldap_caref','ldap_host','ldap_port','ldap_urltype','ldap_protver','ldap_scope', - 'ldap_basedn','ldap_authcn','ldap_extended_query','ldap_binddn','ldap_bindpw','ldap_attr_user','radius_host', + 'ldap_basedn','ldap_authcn','ldap_extended_query','ldap_binddn','ldap_bindpw','ldap_attr_user', + 'ldap_read_properties', 'radius_host', 'radius_auth_port','radius_acct_port','radius_secret','radius_timeout','radius_srvcs' ); @@ -730,6 +733,16 @@ endif; ?> + + + + /> + + +