Merge branch 'feature/ldap-get-naming-contexts-6097'

This commit is contained in:
Matthias Jentsch 2014-06-06 18:20:02 +02:00
commit 506cfe214b
1 changed files with 136 additions and 43 deletions

View File

@ -63,6 +63,7 @@ class Connection
protected $bind_pw; protected $bind_pw;
protected $root_dn; protected $root_dn;
protected $count; protected $count;
protected $ldap_extension = array( protected $ldap_extension = array(
'1.3.6.1.4.1.1466.20037' => 'STARTTLS', '1.3.6.1.4.1.1466.20037' => 'STARTTLS',
// '1.3.6.1.4.1.4203.1.11.1' => '11.1', // PASSWORD_MODIFY // '1.3.6.1.4.1.4203.1.11.1' => '11.1', // PASSWORD_MODIFY
@ -109,6 +110,8 @@ class Connection
protected $supports_v3 = false; protected $supports_v3 = false;
protected $supports_tls = false; protected $supports_tls = false;
protected $capabilities;
/** /**
* Constructor * Constructor
* *
@ -365,6 +368,7 @@ class Connection
$ds = ldap_connect($this->hostname, $this->port); $ds = ldap_connect($this->hostname, $this->port);
$cap = $this->discoverCapabilities($ds); $cap = $this->discoverCapabilities($ds);
$this->capabilities = $cap;
if ($use_tls) { if ($use_tls) {
if ($cap->starttls) { if ($cap->starttls) {
@ -399,7 +403,6 @@ class Connection
// TODO: remove this -> FORCING v3 for now // TODO: remove this -> FORCING v3 for now
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
Logger::warning('No LDAPv3 support detected'); Logger::warning('No LDAPv3 support detected');
} }
@ -429,6 +432,116 @@ class Connection
} }
} }
protected function hasCapabilityStarTSL($cap)
{
$cap = $this->getExtensionCapabilities($cap);
return isset($cap['1.3.6.1.4.1.1466.20037']);
}
protected function hasCapabilityLdapV3($cap)
{
if ((is_string($cap->supportedLDAPVersion)
&& (int) $cap->supportedLDAPVersion === 3)
|| (is_array($cap->supportedLDAPVersion)
&& in_array(3, $cap->supportedLDAPVersion)
)) {
return true;
}
return false;
}
protected function getExtensionCapabilities($cap)
{
$extensions = array();
if (isset($cap->supportedExtension)) {
foreach ($cap->supportedExtension as $oid) {
if (array_key_exists($oid, $this->ldap_extension)) {
if ($this->ldap_extension[$oid] === 'STARTTLS') {
$extensions['1.3.6.1.4.1.1466.20037'] = $this->ldap_extension['1.3.6.1.4.1.1466.20037'];
}
}
}
}
return $extensions;
}
protected function getMsCapabilities($cap)
{
$ms = array();
foreach ($this->ms_capability as $name) {
$ms[$this->convName($name)] = false;
}
if (isset($cap->supportedCapabilities)) {
foreach ($cap->supportedCapabilities as $oid) {
if (array_key_exists($oid, $this->ms_capability)) {
$ms[$this->convName($this->ms_capability[$oid])] = true;
}
}
}
return (object)$ms;
}
private function convName($name)
{
$parts = explode('_', $name);
foreach ($parts as $i => $part) {
$parts[$i] = ucfirst(strtolower($part));
}
return implode('', $parts);
}
/**
* Get the capabilities of this ldap server
*
* @return stdClass An object, providing the flags 'ldapv3' and 'starttls' to indicate LdapV3 and StartTLS
* support and an additional property 'msCapabilities', containing all supported active directory capabilities.
*/
public function getCapabilities()
{
return $this->capabilities;
}
/**
* Get the default naming context of this ldap connection
*
* @return String|null the default naming context, or null when no contexts are available
*/
public function getDefaultNamingContext()
{
$cap = $this->capabilities;
if (isset($cap->defaultNamingContext)) {
return $cap->defaultNamingContext;
}
$namingContexts = $this->namingContexts($cap);
return empty($namingContexts) ? null : $namingContexts[0];
}
/**
* Fetch the namingContexts for this Ldap-Connection
*
* @return array the available naming contexts
*/
public function namingContexts()
{
$cap = $this->capabilities;
if (!isset($cap->namingContexts)) {
return array();
}
if (!is_array($cap->namingContexts)) {
return array($cap->namingContexts);
}
return $cap->namingContexts;
}
/**
* Discover the capabilities of the given ldap-server
*
* @param $ds The link identifier of the current ldap connection
*
* @return bool|object The capabilities or false if the server has none
* @throws Exception When the capability query fails
*/
protected function discoverCapabilities($ds) protected function discoverCapabilities($ds)
{ {
$query = $this->select()->from( $query = $this->select()->from(
@ -471,58 +584,37 @@ class Connection
$cap = (object) array( $cap = (object) array(
'ldapv3' => false, 'ldapv3' => false,
'starttls' => false, 'starttls' => false,
'msCapabilities' => array()
); );
if ($entry === false) { if ($entry === false) {
// TODO: Is it OK to have no capabilities? // TODO: Is it OK to have no capabilities?
return $cap; return false;
} }
$ldapAttributes = ldap_get_attributes($ds, $entry); $ldapAttributes = ldap_get_attributes($ds, $entry);
$result = $this->cleanupAttributes( $result = $this->cleanupAttributes($ldapAttributes);
$ldapAttributes $cap->ldapv3 = $this->hasCapabilityLdapV3($result);
); $cap->starttls = $this->hasCapabilityStarTSL($result);
$cap->msCapabilities = $this->getMsCapabilities($result);
$cap->namingContexts = $result->namingContexts;
/* /*
if (isset($result->dnsHostName)) { if (isset($result->dnsHostName)) {
ldap_set_option($ds, LDAP_OPT_HOST_NAME, $result->dnsHostName); ldap_set_option($ds, LDAP_OPT_HOST_NAME, $result->dnsHostName);
} }
*/ */
if ((is_string($result->supportedLDAPVersion)
&& (int) $result->supportedLDAPVersion === 3)
|| (is_array($result->supportedLDAPVersion)
&& in_array(3, $result->supportedLDAPVersion)
)) {
$cap->ldapv3 = true;
}
if (isset($result->supportedCapabilities)) {
foreach ($result->supportedCapabilities as $oid) {
if (array_key_exists($oid, $this->ms_capability)) {
// echo $this->ms_capability[$oid] . "\n";
}
}
}
if (isset($result->supportedExtension)) {
foreach ($result->supportedExtension as $oid) {
if (array_key_exists($oid, $this->ldap_extension)) {
if ($this->ldap_extension[$oid] === 'STARTTLS') {
$cap->starttls = true;
}
}
}
}
return $cap; return $cap;
} }
public function connect() public function connect($anonymous = false)
{ {
if ($this->ds !== null) { if ($this->ds !== null) {
return; return;
} }
$this->ds = $this->prepareNewConnection(); $this->ds = $this->prepareNewConnection();
if (!$anonymous) {
$r = @ldap_bind($this->ds, $this->bind_dn, $this->bind_pw); $r = @ldap_bind($this->ds, $this->bind_dn, $this->bind_pw);
if (! $r) { if (! $r) {
throw new \Exception( throw new \Exception(
sprintf( sprintf(
@ -536,6 +628,7 @@ class Connection
); );
} }
} }
}
/** /**
* Create an ldap entry * Create an ldap entry