summaryrefslogtreecommitdiffstats
path: root/library/Icinga/Protocol/Ldap/Discovery.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Icinga/Protocol/Ldap/Discovery.php')
-rw-r--r--library/Icinga/Protocol/Ldap/Discovery.php143
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);
+ }
+}