diff options
Diffstat (limited to 'library/Icinga/Protocol/Ldap/Discovery.php')
-rw-r--r-- | library/Icinga/Protocol/Ldap/Discovery.php | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/library/Icinga/Protocol/Ldap/Discovery.php b/library/Icinga/Protocol/Ldap/Discovery.php new file mode 100644 index 0000000..9c7990a --- /dev/null +++ b/library/Icinga/Protocol/Ldap/Discovery.php @@ -0,0 +1,143 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Protocol\Ldap; + +use Icinga\Data\ConfigObject; +use Icinga\Protocol\Dns; + +class Discovery +{ + /** + * @var LdapConnection + */ + private $connection; + + /** + * @param LdapConnection $conn The ldap connection to use for the discovery + */ + public function __construct(LdapConnection $conn) + { + $this->connection = $conn; + } + + /** + * Suggests a resource configuration of hostname, port and root_dn + * based on the discovery + * + * @return array The suggested configuration as an array + */ + public function suggestResourceSettings() + { + return array( + 'hostname' => $this->connection->getHostname(), + 'port' => $this->connection->getPort(), + 'root_dn' => $this->connection->getCapabilities()->getDefaultNamingContext() + ); + } + + /** + * Suggests a backend configuration of base_dn, user_class and user_name_attribute + * based on the discovery + * + * @return array The suggested configuration as an array + */ + public function suggestBackendSettings() + { + if ($this->isAd()) { + return array( + 'backend' => 'msldap', + 'base_dn' => $this->connection->getCapabilities()->getDefaultNamingContext(), + 'user_class' => 'user', + 'user_name_attribute' => 'sAMAccountName' + ); + } else { + return array( + 'backend' => 'ldap', + 'base_dn' => $this->connection->getCapabilities()->getDefaultNamingContext(), + 'user_class' => 'inetOrgPerson', + 'user_name_attribute' => 'uid' + ); + } + } + + /** + * Whether the suggested ldap server is an ActiveDirectory + * + * @return boolean + */ + public function isAd() + { + return $this->connection->getCapabilities()->isActiveDirectory(); + } + + /** + * Whether the discovery was successful + * + * @return bool False when the suggestions are guessed + */ + public function isSuccess() + { + return $this->connection->discoverySuccessful(); + } + + /** + * Why the discovery failed + * + * @return \Exception|null + */ + public function getError() + { + return $this->connection->getDiscoveryError(); + } + + /** + * Discover LDAP servers on the given domain + * + * @param ?string $domain The object containing the form elements + * + * @return Discovery True when the discovery was successful, false when the configuration was guessed + */ + public static function discoverDomain($domain) + { + if (! isset($domain)) { + return false; + } + + // Attempt 1: Connect to the domain directly + $disc = Discovery::discover($domain, 389); + if ($disc->isSuccess()) { + return $disc; + } + + // Attempt 2: Discover all available ldap dns records and connect to the first one + $records = array_merge(Dns::getSrvRecords($domain, 'ldap'), Dns::getSrvRecords($domain, 'ldaps')); + if (isset($records[0])) { + $record = $records[0]; + return Discovery::discover( + isset($record['target']) ? $record['target'] : $domain, + isset($record['port']) ? $record['port'] : $domain + ); + } + + // Return the first failed discovery, which will suggest properties based on guesses + return $disc; + } + + /** + * Convenience method to instantiate a new Discovery + * + * @param $host The host on which to execute the discovery + * @param $port The port on which to execute the discovery + * + * @return Discovery The resulting Discovery + */ + public static function discover($host, $port) + { + $conn = new LdapConnection(new ConfigObject(array( + 'hostname' => $host, + 'port' => $port + ))); + return new Discovery($conn); + } +} |