mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-25 08:34:29 +00:00
- Renamed libraries/LDAPLib.php to libraries/AuthLDAPLib.php
- Removed constants LDAP_NO_USER_DN and LDAP_TOO_MANY_USER_DN from config/constants.php - Added config entry timeout to config/ldap.php - Changed private method libraries/AuthLib->_checkLDAPAuthentication to use libraries/AuthLDAPLib->checkUsernamePassword - Changed AuthLDAPLib to have only one public method called checkUsernamePassword that makes use of the other private methods to check if a username and password are valid on many LDAP servers
This commit is contained in:
@@ -57,14 +57,6 @@ define('AUTH_SUCCESS', 0);
|
|||||||
define('AUTH_NOT_AUTHENTICATED', 1);
|
define('AUTH_NOT_AUTHENTICATED', 1);
|
||||||
define('AUTH_INVALID_CREDENTIALS', 2);
|
define('AUTH_INVALID_CREDENTIALS', 2);
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| LDAP constants
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
define('LDAP_NO_USER_DN', 10);
|
|
||||||
define('LDAP_TOO_MANY_USER_DN', 11);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Language constants
|
| Language constants
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ if (defined('LDAP_SERVER')) // 1st LDAP server
|
|||||||
'basedn' => LDAP_BASE_DN,
|
'basedn' => LDAP_BASE_DN,
|
||||||
'username' => LDAP_BIND_USER,
|
'username' => LDAP_BIND_USER,
|
||||||
'password' => LDAP_BIND_PASSWORD,
|
'password' => LDAP_BIND_PASSWORD,
|
||||||
'usf' => LDAP_USER_SEARCH_FILTER
|
'usf' => LDAP_USER_SEARCH_FILTER,
|
||||||
|
'timeout' => 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +31,8 @@ if (defined('LDAP2_SERVER')) // 2nd LDAP server
|
|||||||
'basedn' => LDAP2_BASE_DN,
|
'basedn' => LDAP2_BASE_DN,
|
||||||
'username' => LDAP2_BIND_USER,
|
'username' => LDAP2_BIND_USER,
|
||||||
'password' => LDAP2_BIND_PASSWORD,
|
'password' => LDAP2_BIND_PASSWORD,
|
||||||
'usf' => LDAP2_USER_SEARCH_FILTER
|
'usf' => LDAP2_USER_SEARCH_FILTER,
|
||||||
|
'timeout' => 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +47,8 @@ if (defined('LDAP_SERVER')) // 1st LDAP server
|
|||||||
'basedn' => LDAP_BASE_DN,
|
'basedn' => LDAP_BASE_DN,
|
||||||
'username' => LDAP_BIND_USER,
|
'username' => LDAP_BIND_USER,
|
||||||
'password' => LDAP_BIND_PASSWORD,
|
'password' => LDAP_BIND_PASSWORD,
|
||||||
'usf' => LDAP_USER_SEARCH_FILTER
|
'usf' => LDAP_USER_SEARCH_FILTER,
|
||||||
|
'timeout' => 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,6 +61,8 @@ if (defined('LDAP2_SERVER')) // 2nd LDAP server
|
|||||||
'basedn' => LDAP2_BASE_DN,
|
'basedn' => LDAP2_BASE_DN,
|
||||||
'username' => LDAP2_BIND_USER,
|
'username' => LDAP2_BIND_USER,
|
||||||
'password' => LDAP2_BIND_PASSWORD,
|
'password' => LDAP2_BIND_PASSWORD,
|
||||||
'usf' => LDAP2_USER_SEARCH_FILTER
|
'usf' => LDAP2_USER_SEARCH_FILTER,
|
||||||
|
'timeout' => 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,309 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class AuthLDAPLib
|
||||||
|
{
|
||||||
|
const LDAP_CONF_FILE = 'ldap'; // LDAP config file name
|
||||||
|
|
||||||
|
// LDAP codes
|
||||||
|
const LDAP_NO_USER_DN = 10; // No users found
|
||||||
|
const LDAP_TOO_MANY_USER_DN = 11; // More then one user found
|
||||||
|
|
||||||
|
// LDAP configuration array elements
|
||||||
|
const SERVER = 'server';
|
||||||
|
const PORT = 'port';
|
||||||
|
const STARTTLS = 'starttls';
|
||||||
|
const BASEDN = 'basedn';
|
||||||
|
const USERNAME = 'username';
|
||||||
|
const PASSWORD = 'password';
|
||||||
|
const USF = 'usf';
|
||||||
|
const TIMEOUT = 'timeout';
|
||||||
|
|
||||||
|
const DN = 'dn'; // LDAP dn name
|
||||||
|
|
||||||
|
const LDAP_PROTOCOL_VERSION = 3; // Specifies the LDAP protocol to be used (V2 or V3) V2 is deprecated
|
||||||
|
const LDAP_REFERRALS = 0; // Specifies whether to automatically follow referrals returned by the LDAP server (0 = disabled)
|
||||||
|
const LDAP_INVALID_CREDENTIALS = 49; // LDAP invalid credentials code
|
||||||
|
const LDAP_DEFAULT_TIMEOUT = 1; // Default LDAP timeout in seconds
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the properties and loads the LDAP configuration
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
// Gets CI instance
|
||||||
|
$this->_ci =& get_instance();
|
||||||
|
|
||||||
|
// Loads the LogLib
|
||||||
|
$this->_ci->load->library('LogLib');
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------------------------
|
||||||
|
// Public methods
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given credentials are valid on one of the configured LDAP servers
|
||||||
|
*/
|
||||||
|
public function checkUsernamePassword($username, $password)
|
||||||
|
{
|
||||||
|
$authenticated = false;
|
||||||
|
|
||||||
|
if (isEmptyString($username) || isEmptyString($password)) return error('Wrong username and password');
|
||||||
|
|
||||||
|
$ldapConfigArrays = $this->_loadConfig(); // NOTE: always the last to be called!
|
||||||
|
|
||||||
|
// For each configured LDAP server
|
||||||
|
foreach ($ldapConfigArrays as $ldapConfigs)
|
||||||
|
{
|
||||||
|
// Check if the LDAP server is up and running
|
||||||
|
if (!$this->_servicePing($ldapConfigs))
|
||||||
|
{
|
||||||
|
// If not available log debug and skip to the next configured server
|
||||||
|
$this->_ci->loglib->logError('This LDAP server is not available: '.$ldapConfigs[self::SERVER]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connection without username and passoword _or_ with the configured username and password
|
||||||
|
$noCredentialsConnectResult = $this->_connect($ldapConfigs);
|
||||||
|
if (isError($noCredentialsConnectResult)) // If an error occurred
|
||||||
|
{
|
||||||
|
// If the error is due to invalid credentials or
|
||||||
|
// the LDAP server does not support anonymous authentication
|
||||||
|
if (getCode($noCredentialsConnectResult) == AUTH_INVALID_CREDENTIALS)
|
||||||
|
{
|
||||||
|
$this->_ci->loglib->logDebug(getError($noCredentialsConnectResult).' on server '.$ldapConfigs[self::SERVER]);
|
||||||
|
}
|
||||||
|
else // otherwise if it was due to a fatal error
|
||||||
|
{
|
||||||
|
$this->_ci->loglib->logError(getError($noCredentialsConnectResult).' on server '.$ldapConfigs[self::SERVER]);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue; // anyway skip to the next configured server
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it is a success
|
||||||
|
$noCredentialsConnection = getData($noCredentialsConnectResult);
|
||||||
|
|
||||||
|
// Check if the user exists on this LDAP server
|
||||||
|
$userDNResult = $this->_getUserDN(
|
||||||
|
$noCredentialsConnection,
|
||||||
|
$ldapConfigs[self::BASEDN],
|
||||||
|
$ldapConfigs[self::USF],
|
||||||
|
$username
|
||||||
|
);
|
||||||
|
// If an error occurred or the user was not found or many users were found
|
||||||
|
if (isError($userDNResult))
|
||||||
|
{
|
||||||
|
// Log debug and skip to the next configured server
|
||||||
|
// If the error is due to invalid credentials or
|
||||||
|
// the LDAP server does not support anonymous authentication
|
||||||
|
if (getCode($userDNResult) == self::LDAP_NO_USER_DN)
|
||||||
|
{
|
||||||
|
$this->_ci->loglib->logDebug(getError($userDNResult).' on server '.$ldapConfigs[self::SERVER]);
|
||||||
|
}
|
||||||
|
elseif (getCode($userDNResult) == self::LDAP_TOO_MANY_USER_DN)
|
||||||
|
{
|
||||||
|
$this->_ci->loglib->logDebug(getError($userDNResult).' on server '.$ldapConfigs[self::SERVER]);
|
||||||
|
}
|
||||||
|
else // otherwise if it was due to a fatal error
|
||||||
|
{
|
||||||
|
$this->_ci->loglib->logError(getError($userDNResult).' on server '.$ldapConfigs[self::SERVER]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_close($noCredentialsConnection); // Close the current LDAP connection
|
||||||
|
continue; // anyway skip to the next configured server
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_close($noCredentialsConnection); // Close the current LDAP connection
|
||||||
|
|
||||||
|
// Connect to LDAP with the userDN and password
|
||||||
|
$credentialsConnectResult = $this->_connect($ldapConfigs, getData($userDNResult), $password);
|
||||||
|
if (isError($credentialsConnectResult)) // If an error occurred
|
||||||
|
{
|
||||||
|
// Log debug and skip to the next configured server
|
||||||
|
$this->_ci->loglib->logError(getError($credentialsConnectResult).' on server '.$ldapConfigs[self::SERVER]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else // otherwise the user is authenticated
|
||||||
|
{
|
||||||
|
$this->_close(getData($credentialsConnectResult));
|
||||||
|
$authenticated = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $authenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------------------------
|
||||||
|
// Private methods
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the LDAP configuration file and returns the LDAP configuration array
|
||||||
|
*/
|
||||||
|
private function _loadConfig()
|
||||||
|
{
|
||||||
|
// Tries to require the LDAP configuration file...
|
||||||
|
// ...first in the ENVIRONMENT subdirectory...
|
||||||
|
if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/'.self::LDAP_CONF_FILE.'.php'))
|
||||||
|
{
|
||||||
|
require_once(APPPATH.'config/'.ENVIRONMENT.'/'.self::LDAP_CONF_FILE.'.php');
|
||||||
|
}
|
||||||
|
else // ...then in the default config directory
|
||||||
|
{
|
||||||
|
require_once(APPPATH.'config/'.self::LDAP_CONF_FILE.'.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ldap[$ldap_active_group];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Establish a connection to LDAP with the given LDAP configuration array and eventually with
|
||||||
|
* with a given username and password
|
||||||
|
*/
|
||||||
|
private function _connect($ldapConfigs, $username = null, $password = null)
|
||||||
|
{
|
||||||
|
// Checks if the LDAP configuraion is empty
|
||||||
|
if (isEmptyArray($ldapConfigs)) return error('Wrong parameters given');
|
||||||
|
|
||||||
|
// LDAP connection
|
||||||
|
$ldapConnection = @ldap_connect($ldapConfigs[self::SERVER].':'.$ldapConfigs[self::PORT]);
|
||||||
|
if ($ldapConnection) // if success
|
||||||
|
{
|
||||||
|
// Sets the LDAP protocol version
|
||||||
|
if (!@ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, self::LDAP_PROTOCOL_VERSION))
|
||||||
|
{
|
||||||
|
return error('Was not possible to set the protocol version using LDAP sever '.$ldapConfigs[self::SERVER]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable/disable the LDAP referrals
|
||||||
|
if (!@ldap_set_option($ldapConnection, LDAP_OPT_REFERRALS, self::LDAP_REFERRALS))
|
||||||
|
{
|
||||||
|
return error('Was not possible to enable referrals using LDAP sever '.$ldapConfigs[self::SERVER]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Starts TLS if required
|
||||||
|
if ($ldapConfigs[self::STARTTLS] === true && !@ldap_start_tls($ldapConnection))
|
||||||
|
{
|
||||||
|
return error('Was not possible to enable TLS using LDAP sever '.$ldapConfigs[self::SERVER]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If username or password are not provided...
|
||||||
|
if (isEmptyString($username) || isEmptyString($password))
|
||||||
|
{
|
||||||
|
// ...use those provided by the configuration
|
||||||
|
$username = $ldapConfigs[self::USERNAME];
|
||||||
|
$password = $ldapConfigs[self::PASSWORD];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Binds to LDAP directory
|
||||||
|
if (!@ldap_bind($ldapConnection, $username, $password))
|
||||||
|
{
|
||||||
|
// Wrong username and/or password
|
||||||
|
if (ldap_errno($ldapConnection) == self::LDAP_INVALID_CREDENTIALS)
|
||||||
|
{
|
||||||
|
return error('Invalid credentials', AUTH_INVALID_CREDENTIALS);
|
||||||
|
}
|
||||||
|
else // Error
|
||||||
|
{
|
||||||
|
return error('Was not possible to bind to the LDAP sever '.$ldapConfigs[self::SERVER]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success($ldapConnection); // connected!!!
|
||||||
|
}
|
||||||
|
else // Connection error
|
||||||
|
{
|
||||||
|
return error('An error occurred while connecting to the LDAP server '.$ldapConfigs[self::SERVER]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the network service is up and running
|
||||||
|
*/
|
||||||
|
private function _servicePing($ldapConfigs)
|
||||||
|
{
|
||||||
|
// Set the default timeout
|
||||||
|
$timeout = self::LDAP_DEFAULT_TIMEOUT;
|
||||||
|
|
||||||
|
// If a timeout was configured for this server then use it
|
||||||
|
if (isset($ldapConfigs[self::TIMEOUT])) $timeout = $ldapConfigs[self::TIMEOUT];
|
||||||
|
|
||||||
|
// The LDAP server name or URL
|
||||||
|
$host = $ldapConfigs[self::SERVER];
|
||||||
|
|
||||||
|
// If it is a URL
|
||||||
|
if (strpos($ldapConfigs[self::SERVER], 'ldap://') !== false
|
||||||
|
|| strpos($ldapConfigs[self::SERVER], 'ldaps://') !== false)
|
||||||
|
{
|
||||||
|
// Get the host from the URL
|
||||||
|
$host = parse_url($ldapConfigs[self::SERVER], PHP_URL_HOST);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the given host answers on the given port using the given timeout
|
||||||
|
if ($op = @fsockopen($host, $ldapConfigs[self::PORT], $errno, $errstr, $timeout))
|
||||||
|
{
|
||||||
|
// If it works then close the socket connection
|
||||||
|
fclose($op);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // otherwise this server is not up or LDAP service is not running on the given port
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the current connection to LDAP if present
|
||||||
|
*/
|
||||||
|
private function _close($connection)
|
||||||
|
{
|
||||||
|
@ldap_unbind($connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user DN from LDAP using the given username
|
||||||
|
*/
|
||||||
|
private function _getUserDN($connection, $baseDN, $usf, $username)
|
||||||
|
{
|
||||||
|
$userDN = error('AuthLDAPLib->_getUserDN() failed');
|
||||||
|
|
||||||
|
// Tries to search for a user DN using the given username
|
||||||
|
$searchResultIdentifier = @ldap_search(
|
||||||
|
$connection,
|
||||||
|
$baseDN,
|
||||||
|
$usf.'='.$username
|
||||||
|
);
|
||||||
|
if (!$searchResultIdentifier) // Error
|
||||||
|
{
|
||||||
|
$userDN = error(ldap_error($connection));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Counts the number of found entries
|
||||||
|
$countEntries = @ldap_count_entries($connection, $searchResultIdentifier);
|
||||||
|
if ($countEntries === false) // Error
|
||||||
|
{
|
||||||
|
$userDN = error(ldap_error($connection));
|
||||||
|
}
|
||||||
|
elseif ($countEntries == 0)
|
||||||
|
{
|
||||||
|
$userDN = error('No user DN were found with username: '.$username, self::LDAP_NO_USER_DN);
|
||||||
|
}
|
||||||
|
elseif ($countEntries > 1)
|
||||||
|
{
|
||||||
|
$userDN = error('Too many users DN were found with username: '.$username, self::LDAP_TOO_MANY_USER_DN);
|
||||||
|
}
|
||||||
|
else // One entry was found
|
||||||
|
{
|
||||||
|
$entries = @ldap_get_entries($connection, $searchResultIdentifier);
|
||||||
|
if (!$entries) // Error
|
||||||
|
{
|
||||||
|
$userDN = error(ldap_error($connection));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$userDN = success($entries[0][self::DN]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $userDN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -385,7 +385,7 @@ class AuthLib
|
|||||||
// Invalid credentials
|
// Invalid credentials
|
||||||
// NOTE: this is a corner case because of the HTTP basic authentication
|
// NOTE: this is a corner case because of the HTTP basic authentication
|
||||||
if (getCode($hta) == AUTH_NOT_AUTHENTICATED || getCode($hta) == AUTH_INVALID_CREDENTIALS
|
if (getCode($hta) == AUTH_NOT_AUTHENTICATED || getCode($hta) == AUTH_INVALID_CREDENTIALS
|
||||||
|| getCode($hta) == LDAP_NO_USER_DN || getCode($hta) == LDAP_TOO_MANY_USER_DN)
|
|| getCode($hta) == AuthLDAPLib::LDAP_NO_USER_DN || getCode($hta) == AuthLDAPLib::LDAP_TOO_MANY_USER_DN)
|
||||||
{
|
{
|
||||||
$this->_showInvalidAuthentication(); // this also stop the execution
|
$this->_showInvalidAuthentication(); // this also stop the execution
|
||||||
}
|
}
|
||||||
@@ -404,37 +404,12 @@ class AuthLib
|
|||||||
{
|
{
|
||||||
$ldap = error('Not authenticated', AUTH_NOT_AUTHENTICATED); // by default is NOT authenticated
|
$ldap = error('Not authenticated', AUTH_NOT_AUTHENTICATED); // by default is NOT authenticated
|
||||||
|
|
||||||
$this->_ci->load->library('LDAPLib'); // Loads the LDAP library
|
$this->_ci->load->library('AuthLDAPLib'); // Loads the LDAP library
|
||||||
|
|
||||||
$ldapConnection = $this->_ci->ldaplib->anonymousConnect(); // connect anonymously!
|
// If it is possible to authenticate on LDAP with the given username and password
|
||||||
if (isSuccess($ldapConnection)) // connected!!
|
if ($this->_ci->authldaplib->checkUsernamePassword($username, $password) === true)
|
||||||
{
|
{
|
||||||
// Get the user DN from LDAP
|
$ldap = success('Authenticated', AUTH_SUCCESS); // authenticated!
|
||||||
$userDN = $this->_ci->ldaplib->getUserDN($username);
|
|
||||||
if (isSuccess($userDN)) // got it!
|
|
||||||
{
|
|
||||||
$this->_ci->ldaplib->close(); // close the previous LDAP anonymous connection
|
|
||||||
|
|
||||||
// Connects to LDAP using the last working configuration + the retrieved user DN + the provided password
|
|
||||||
$ldapConnection = $this->_ci->ldaplib->connectUsernamePassword(getData($userDN), $password);
|
|
||||||
if (isSuccess($ldapConnection)) // connected!
|
|
||||||
{
|
|
||||||
$this->_ci->ldaplib->close(); // close the previous connection
|
|
||||||
$ldap = success('Authenticated', AUTH_SUCCESS); // authenticated!
|
|
||||||
}
|
|
||||||
else // blocking error
|
|
||||||
{
|
|
||||||
$ldap = $ldapConnection;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // blocking error
|
|
||||||
{
|
|
||||||
$ldap = $userDN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // blocking error
|
|
||||||
{
|
|
||||||
$ldap = $ldapConnection;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ldap;
|
return $ldap;
|
||||||
|
|||||||
@@ -1,228 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class LDAPLib
|
|
||||||
{
|
|
||||||
const LDAP_CONF_FILE = 'ldap'; // LDAP config file name
|
|
||||||
|
|
||||||
// LDAP configuration array elements
|
|
||||||
const SERVER = 'server';
|
|
||||||
const PORT = 'port';
|
|
||||||
const STARTTLS = 'starttls';
|
|
||||||
const BASEDN = 'basedn';
|
|
||||||
const USERNAME = 'username';
|
|
||||||
const PASSWORD = 'password';
|
|
||||||
const USF = 'usf';
|
|
||||||
|
|
||||||
const DN = 'dn'; // LDAP dn name
|
|
||||||
|
|
||||||
const LDAP_PROTOCOL_VERSION = 3; // Specifies the LDAP protocol to be used (V2 or V3) V2 is deprecated
|
|
||||||
const LDAP_REFERRALS = 0; // Specifies whether to automatically follow referrals returned by the LDAP server (0 = disabled)
|
|
||||||
const LDAP_INVALID_CREDENTIALS = 49; // LDAP invalid credentials code
|
|
||||||
|
|
||||||
// Private properties
|
|
||||||
private $_connection;
|
|
||||||
private $_workingConfigArray;
|
|
||||||
private $_ldapConfigArray;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the properties and loads the LDAP configuration
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->_connection = null;
|
|
||||||
$this->_workingConfigArray = null;
|
|
||||||
$this->_ldapConfigArray = null;
|
|
||||||
|
|
||||||
$this->_loadConfig(); // NOTE: always the last to be called!
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------------------------
|
|
||||||
// Public methods
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries to connect to LDAP using configurations in property _ldapConfigArray
|
|
||||||
* The first that works is used and stored in property _workingConfigArray
|
|
||||||
* The LDAP connection link is stored in _connection
|
|
||||||
*/
|
|
||||||
public function anonymousConnect()
|
|
||||||
{
|
|
||||||
$connect = error('Did not found a working LDAP configuration');
|
|
||||||
|
|
||||||
// Loops through LDAP configurations
|
|
||||||
foreach ($this->_ldapConfigArray as $ldapConfigs)
|
|
||||||
{
|
|
||||||
// Tries to establish a connection
|
|
||||||
$connect = $this->_connect($ldapConfigs);
|
|
||||||
if (isSuccess($connect))
|
|
||||||
{
|
|
||||||
break; // found a working LDAP configuration and successfully connected!
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->close(); // close the eventually established connection
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $connect;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries to connect using the given username and password and the last working configuration with anonymous connection
|
|
||||||
*/
|
|
||||||
public function connectUsernamePassword($username, $password)
|
|
||||||
{
|
|
||||||
if (isEmptyString($username) || isEmptyString($password)) return error('Wrong username and password');
|
|
||||||
|
|
||||||
return $this->_connect($this->_workingConfigArray, $username, $password);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the current connection to LDAP if present
|
|
||||||
*/
|
|
||||||
public function close()
|
|
||||||
{
|
|
||||||
if ($this->_connection != null) @ldap_unbind($this->_connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the user DN from LDAP using the given username
|
|
||||||
*/
|
|
||||||
public function getUserDN($username)
|
|
||||||
{
|
|
||||||
$userDN = error('No user DN were found', LDAP_NO_USER_DN);
|
|
||||||
|
|
||||||
// Tries to search for a user DN using the given username
|
|
||||||
$searchResultIdentifier = @ldap_search(
|
|
||||||
$this->_connection,
|
|
||||||
$this->_workingConfigArray[self::BASEDN],
|
|
||||||
$this->_workingConfigArray[self::USF].'='.$username
|
|
||||||
);
|
|
||||||
if (!$searchResultIdentifier) // Error
|
|
||||||
{
|
|
||||||
$userDN = error(ldap_error($this->_connection));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Counts the number of found entries
|
|
||||||
$countEntries = @ldap_count_entries($this->_connection, $searchResultIdentifier);
|
|
||||||
if ($countEntries === false) // Error
|
|
||||||
{
|
|
||||||
$userDN = error(ldap_error($this->_connection));
|
|
||||||
}
|
|
||||||
elseif ($countEntries == 0)
|
|
||||||
{
|
|
||||||
$userDN = error('No user DN were found', LDAP_NO_USER_DN);
|
|
||||||
}
|
|
||||||
elseif ($countEntries > 1)
|
|
||||||
{
|
|
||||||
$userDN = error('Too many users DN were found', LDAP_TOO_MANY_USER_DN);
|
|
||||||
}
|
|
||||||
else // One entry was found
|
|
||||||
{
|
|
||||||
$entries = @ldap_get_entries($this->_connection, $searchResultIdentifier);
|
|
||||||
if (!$entries) // Error
|
|
||||||
{
|
|
||||||
$userDN = error(ldap_error($this->_connection));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$userDN = success($entries[0][self::DN]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $userDN;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------------------------
|
|
||||||
// Private methods
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the LDAP configuration file and store the LDAP configuration array into _ldapConfigArray property
|
|
||||||
*/
|
|
||||||
private function _loadConfig()
|
|
||||||
{
|
|
||||||
// Tries to require the LDAP configuration file...
|
|
||||||
// ...first in the ENVIRONMENT subdirectory...
|
|
||||||
if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/'.self::LDAP_CONF_FILE.'.php'))
|
|
||||||
{
|
|
||||||
require_once(APPPATH.'config/'.ENVIRONMENT.'/'.self::LDAP_CONF_FILE.'.php');
|
|
||||||
}
|
|
||||||
else // ...then in the default config directory
|
|
||||||
{
|
|
||||||
require_once(APPPATH.'config/'.self::LDAP_CONF_FILE.'.php');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->_ldapConfigArray = $ldap[$ldap_active_group]; // store the active LDAP configuration array
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Establish a connection to LDAP with the given LDAP configuration array and eventually with
|
|
||||||
* with a given username and password
|
|
||||||
*/
|
|
||||||
private function _connect($ldapConfigs, $username = null, $password = null)
|
|
||||||
{
|
|
||||||
// Checks if the LDAP configuraion is empty
|
|
||||||
if (isEmptyArray($ldapConfigs))
|
|
||||||
{
|
|
||||||
return error('Wrong parameters given');
|
|
||||||
}
|
|
||||||
|
|
||||||
// LDAP connection
|
|
||||||
$ldapConnection = @ldap_connect($ldapConfigs[self::SERVER].':'.$ldapConfigs[self::PORT]);
|
|
||||||
if ($ldapConnection) // if success
|
|
||||||
{
|
|
||||||
// Sets the LDAP protocol version
|
|
||||||
if (!@ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, self::LDAP_PROTOCOL_VERSION))
|
|
||||||
{
|
|
||||||
return error(ldap_error($ldapConnection));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable/disable the LDAP referrals
|
|
||||||
if (!@ldap_set_option($ldapConnection, LDAP_OPT_REFERRALS, self::LDAP_REFERRALS))
|
|
||||||
{
|
|
||||||
return error(ldap_error($ldapConnection));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Starts TLS if required
|
|
||||||
if ($ldapConfigs[self::STARTTLS] === true)
|
|
||||||
{
|
|
||||||
if (!@ldap_start_tls($ldapConnection))
|
|
||||||
{
|
|
||||||
return error(ldap_error($ldapConnection));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If username and password are not provided...
|
|
||||||
if ($username == null || $password == null)
|
|
||||||
{
|
|
||||||
// ...uses those provided by the configuration
|
|
||||||
$username = $ldapConfigs[self::USERNAME];
|
|
||||||
$password = $ldapConfigs[self::PASSWORD];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Binds to LDAP directory
|
|
||||||
if (!@ldap_bind($ldapConnection, $username, $password))
|
|
||||||
{
|
|
||||||
// Wrong username and/or password
|
|
||||||
if (ldap_errno($ldapConnection) == self::LDAP_INVALID_CREDENTIALS)
|
|
||||||
{
|
|
||||||
return error('Invalid credentials', AUTH_INVALID_CREDENTIALS);
|
|
||||||
}
|
|
||||||
else // Error
|
|
||||||
{
|
|
||||||
return error(ldap_error($ldapConnection));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->_connection = $ldapConnection; // save the connection into _connection property
|
|
||||||
$this->_workingConfigArray = $ldapConfigs; // save the working LDAP configuration into _workingConfigArray property
|
|
||||||
|
|
||||||
return success('Connected'); // connected!!!
|
|
||||||
}
|
|
||||||
else // Connection error
|
|
||||||
{
|
|
||||||
return error(
|
|
||||||
'An error occurred while connecting to the LDAP server: '.$ldapConfigs[self::SERVER].':'.$ldapConfigs[self::PORT]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user