LdapCapabilities: discover NetBIOS name of an AD

refs #2153
This commit is contained in:
Alexander A. Klimov 2017-05-31 18:11:38 +02:00
parent 2b9e9bf2b3
commit 8359771271
2 changed files with 77 additions and 31 deletions

View File

@ -303,7 +303,7 @@ class LdapBackendForm extends Form
$cap = LdapCapabilities::discoverCapabilities($connection);
if ($cap->isActiveDirectory()) {
$netBiosName = $this->discoverADConfigOption($connection, 'nETBIOSName', $cap);
$netBiosName = $cap->getNetBiosName();
if ($netBiosName !== null) {
$domains[] = $netBiosName;
}
@ -336,33 +336,4 @@ class LdapBackendForm extends Form
}
}
}
/**
* Discover an AD-specific configuration option (e.g. nETBIOSName)
*
* @param LdapConnection $connection A connection to the AD
* @param string $option The option to discover
* @param LdapCapabilities|null $cap The AD's capabilities if already discovered
*
* @return string|null The value of the option
*/
protected function discoverADConfigOption(LdapConnection $connection, $option, LdapCapabilities $cap = null)
{
if ($cap === null) {
$cap = LdapCapabilities::discoverCapabilities($connection);
}
$configurationNamingContext = $cap->getConfigurationNamingContext();
$defaultNamingContext = $cap->getDefaultNamingContext();
if (!($configurationNamingContext === null || $defaultNamingContext === null)) {
$value = $connection->select()
->setBase('CN=Partitions,' . $configurationNamingContext)
->from('*', array($option))
->where('nCName', $defaultNamingContext)
->fetchOne();
if ($value !== false) {
return $value;
}
}
}
}

View File

@ -90,7 +90,7 @@ class LdapCapabilities
*
* @var array
*/
private $oids = array();
private $oids;
/**
* Construct a new capability
@ -98,8 +98,19 @@ class LdapCapabilities
* @param $attributes StdClass The attributes returned, may be null for guessing default capabilities
*/
public function __construct($attributes = null)
{
$this->setAttributes($attributes);
}
/**
* Set the attributes and (re)build the OIDs
*
* @param $attributes StdClass The attributes returned, may be null for guessing default capabilities
*/
protected function setAttributes($attributes)
{
$this->attributes = $attributes;
$this->oids = array();
$keys = array('supportedControl', 'supportedExtension', 'supportedFeatures', 'supportedCapabilities');
foreach ($keys as $key) {
@ -215,6 +226,18 @@ class LdapCapabilities
}
}
/**
* Get the NetBIOS name
*
* @return string|null
*/
public function getNetBiosName()
{
if (isset($this->attributes->nETBIOSName)) {
return $this->attributes->nETBIOSName;
}
}
/**
* Fetch the namingContexts
*
@ -323,9 +346,61 @@ class LdapCapabilities
}
$cap = new LdapCapabilities($connection->cleanupAttributes(ldap_get_attributes($ds, $entry), $fields));
$cap->discoverAdConfigOptions($connection);
return $cap;
}
/**
* Discover the AD-specific configuration options of the given LDAP server
*
* @param LdapConnection $connection The ldap connection to use
*
* @throws LdapException In case the configuration options query has failed
*/
protected function discoverAdConfigOptions(LdapConnection $connection)
{
if ($this->isActiveDirectory()) {
$configurationNamingContext = $this->getConfigurationNamingContext();
$defaultNamingContext = $this->getDefaultNamingContext();
if (!($configurationNamingContext === null || $defaultNamingContext === null)) {
$ds = $connection->bind()->getConnection();
$adFields = array('nETBIOSName');
$partitions = 'CN=Partitions,' . $configurationNamingContext;
$result = @ldap_list(
$ds,
$partitions,
(string) $connection->select()->from('*', $adFields)->where('nCName', $defaultNamingContext),
$adFields
);
if (! $result) {
throw new LdapException(
'Configuration options query failed (%s:%d): %s. Check if hostname and port of the'
. ' ldap resource are correct and if anonymous access is permitted.',
$connection->getHostname(),
$connection->getPort(),
ldap_error($ds)
);
}
$entry = ldap_first_entry($ds, $result);
if ($entry === false) {
throw new LdapException(
'Configuration options not available (%s:%d). Discovery of "'
. $partitions . '" probably not permitted.',
$connection->getHostname(),
$connection->getPort()
);
}
$this->setAttributes((object) array_merge(
(array) $this->attributes,
(array) $connection->cleanupAttributes(ldap_get_attributes($ds, $entry), $adFields)
));
}
}
}
/**
* Determine the active directory version using the available capabillities
*