From be3193a0d78e4235fede837180042cfff290a713 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Fri, 12 Jul 2013 13:41:48 +0200 Subject: [PATCH] Update LDAP and Livestatus protocol --- library/Icinga/Protocol/Ldap/Connection.php | 446 ++++++++---------- library/Icinga/Protocol/Ldap/Query.php | 92 +--- .../Icinga/Protocol/Livestatus/Connection.php | 132 ++++-- library/Icinga/Protocol/Livestatus/Query.php | 35 +- 4 files changed, 328 insertions(+), 377 deletions(-) diff --git a/library/Icinga/Protocol/Ldap/Connection.php b/library/Icinga/Protocol/Ldap/Connection.php index fbf7883fc..2ce52b340 100644 --- a/library/Icinga/Protocol/Ldap/Connection.php +++ b/library/Icinga/Protocol/Ldap/Connection.php @@ -1,31 +1,10 @@ - * @author Icinga Development Team - */ -// {{{ICINGA_LICENSE_HEADER}}} +/** + * LDAP connection handler + */ namespace Icinga\Protocol\Ldap; -use Icinga\Exception\ConfigurationError as ConfigError; use Icinga\Application\Platform; use Icinga\Application\Config; use Icinga\Application\Logger as Log; @@ -46,89 +25,65 @@ use Icinga\Application\Logger as Log; * * @copyright Copyright (c) 2013 Icinga-Web Team * @author Icinga-Web Team - * @package Icinga\Protocol\Ldap * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License */ class Connection { - /** - * @var string - */ + const LDAP_NO_SUCH_OBJECT = 0x20; + protected $ds; - - /** - * @var string - */ protected $hostname; - - /** - * @var string - */ + protected $port = 389; protected $bind_dn; - - /** - * @var string - */ protected $bind_pw; - - /** - * @var string - */ protected $root_dn; - - /** - * @var string - */ protected $count; - - /** - * @var array - */ protected $ldap_extension = array( - '1.3.6.1.4.1.1466.20037' => 'STARTTLS', // notes? + '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.3' => '11.3', // Whoami // '1.3.6.1.1.8' => '8', // Cancel Extended Request ); - protected $use_tls = false; - protected $force_tls = false; - - - /** - * @var array - */ protected $ms_capability = array( // Prefix LDAP_CAP_ // Source: http://msdn.microsoft.com/en-us/library/cc223359.aspx // Running Active Directory as AD DS: - '1.2.840.113556.1.4.800' => 'ACTIVE_DIRECTORY_OID', + '1.2.840.113556.1.4.800' => 'ACTIVE_DIRECTORY_OID', + // Capable of signing and sealing on an NTLM authenticated connection // and of performing subsequent binds on a signed or sealed connection. '1.2.840.113556.1.4.1791' => 'ACTIVE_DIRECTORY_LDAP_INTEG_OID', + // If AD DS: running at least W2K3, if AD LDS running at least W2K8 '1.2.840.113556.1.4.1670' => 'ACTIVE_DIRECTORY_V51_OID', + // If AD LDS: accepts DIGEST-MD5 binds for AD LDSsecurity principals '1.2.840.113556.1.4.1880' => 'ACTIVE_DIRECTORY_ADAM_DIGEST', + // Running Active Directory as AD LDS '1.2.840.113556.1.4.1851' => 'ACTIVE_DIRECTORY_ADAM_OID', + // If AD DS: it's a Read Only DC (RODC) '1.2.840.113556.1.4.1920' => 'ACTIVE_DIRECTORY_PARTIAL_SECRETS_OID', + // Running at least W2K8 '1.2.840.113556.1.4.1935' => 'ACTIVE_DIRECTORY_V60_OID', + // Running at least W2K8r2 '1.2.840.113556.1.4.2080' => 'ACTIVE_DIRECTORY_V61_R2_OID', + // Running at least W2K12 '1.2.840.113556.1.4.2237' => 'ACTIVE_DIRECTORY_W8_OID', ); - /** - * @var string - */ protected $root; + protected $supports_v3 = false; + protected $supports_tls = false; + /** * Constructor * @@ -139,24 +94,17 @@ class Connection public function __construct($config) { $this->hostname = $config->hostname; - $this->bind_dn = $config->bind_dn; - $this->bind_pw = $config->bind_pw; - $this->root_dn = $config->root_dn; - $this->use_tls = isset($config->tls) ? $config->tls : false; - $this->force_tls = $this->use_tls; + $this->bind_dn = $config->bind_dn; + $this->bind_pw = $config->bind_pw; + $this->root_dn = $config->root_dn; + } - /** - * @return string - */ public function getDN() { return $this->root_dn; } - /** - * @return Root|string - */ public function root() { if ($this->root === null) { @@ -165,36 +113,22 @@ class Connection return $this->root; } - /** - * @return Query - */ public function select() { return new Query($this); } - /** - * @param $query - * @param array $fields - * @return mixed - */ public function fetchOne($query, $fields = array()) { - $row = (array)$this->fetchRow($query, $fields); + $row = (array) $this->fetchRow($query, $fields); return array_shift($row); } - /** - * @param $query - * @param array $fields - * @return mixed - * @throws Exception - */ public function fetchDN($query, $fields = array()) { $rows = $this->fetchAll($query, $fields); if (count($rows) !== 1) { - throw new Exception( + throw new \Exception( sprintf( 'Cannot fetch single DN for %s', $query @@ -204,11 +138,7 @@ class Connection return key($rows); } - /** - * @param $query - * @param array $fields - * @return mixed - */ + public function fetchRow($query, $fields = array()) { // TODO: This is ugly, make it better! @@ -216,31 +146,28 @@ class Connection return array_shift($results); } - /** - * @param Query $query - * @return int - */ public function count(Query $query) { $results = $this->runQuery($query, '+'); + if (! $results) { + return 0; + } return ldap_count_entries($this->ds, $results); } - /** - * @param $query - * @param array $fields - * @return array - */ public function fetchAll($query, $fields = array()) { $offset = null; $limit = null; if ($query->hasLimit()) { $offset = $query->getOffset(); - $limit = $query->getLimit(); + $limit = $query->getLimit(); } $entries = array(); $results = $this->runQuery($query, $fields); + if (! $results) { + return array(); + } $entry = ldap_first_entry($this->ds, $results); $count = 0; while ($entry) { @@ -248,7 +175,8 @@ class Connection && ($limit === null || ($offset + $limit) >= $count) ) { $attrs = ldap_get_attributes($this->ds, $entry); - $entries[ldap_get_dn($this->ds, $entry)] = $this->cleanupAttributes($attrs); + $entries[ldap_get_dn($this->ds, $entry)] + = $this->cleanupAttributes($attrs); } $count++; $entry = ldap_next_entry($this->ds, $entry); @@ -257,13 +185,9 @@ class Connection return $entries; } - /** - * @param $attrs - * @return object - */ public function cleanupAttributes(& $attrs) { - $clean = (object)array(); + $clean = (object) array(); for ($i = 0; $i < $attrs['count']; $i++) { $attr_name = $attrs[$i]; if ($attrs[$attr_name]['count'] === 1) { @@ -277,12 +201,6 @@ class Connection return $clean; } - /** - * @param $query - * @param $fields - * @return resource - * @throws Exception - */ protected function runQuery($query, $fields) { $this->connect(); @@ -293,17 +211,19 @@ class Connection // We do not support pagination right now, and there is no chance to // do so for PHP < 5.4. Warnings about "Sizelimit exceeded" will // therefore not be hidden right now. - Log::debug("Query: %s", $query->__toString()); - $results = ldap_search( + $results = @ldap_search( $this->ds, $this->root_dn, - (string)$query, + (string) $query, $fields, 0, // Attributes and values - 0 // No limit - at least where possible + 0 // No limit - at least where possible ); - if (!$results) { - throw new Exception( + if ($results === false) { + if (ldap_errno($this->ds) === self::LDAP_NO_SUCH_OBJECT) { + return false; + } + throw new \Exception( sprintf( 'LDAP query "%s" (root %s) failed: %s', $query, @@ -311,7 +231,6 @@ class Connection ldap_error($this->ds) ) ); - die('Query failed'); } $list = array(); @@ -323,186 +242,229 @@ class Connection return $results; } - /** - * @param $username - * @param $password - * @return bool - */ public function testCredentials($username, $password) { - Log::debug("Trying to connect to %s", $this->hostname); - $ds = ldap_connect($this->hostname); - Log::debug("ldap_bind (%s)", $username); + $ds = $this->prepareNewConnection(); + $r = @ldap_bind($ds, $username, $password); if ($r) { + log::debug( + 'Successfully tested LDAP credentials (%s / %s)', + $username, + '***' + ); return true; } else { - log::fatal( - 'LDAP connection (%s / %s) failed: %s', + log::debug( + 'Testing LDAP credentials (%s / %s) failed: %s', $username, '***', ldap_error($ds) ); return false; - /* TODO: Log failure - throw new Exception(sprintf( - 'LDAP connection (%s / %s) failed: %s', - $username, - '***', - ldap_error($ds) - )); - */ } } - /** - * @return string - */ - protected function getConfigDir() + protected function getConfigDir($sub = null) { - return Config::getInstance()->getConfigDir() . '/ldap'; + $dir = Config::getInstance()->getConfigDir() . '/ldap'; + if ($sub !== null) { + $dir .= '/' . $sub; + } + return $dir; } - /** - * @param $domain - */ protected function discoverServerlistForDomain($domain) { $ldaps_records = dns_get_record('_ldaps._tcp.' . $domain, DNS_SRV); - $ldap_records = dns_get_record('_ldap._tcp.' . $domain, DNS_SRV); + $ldap_records = dns_get_record('_ldap._tcp.' . $domain, DNS_SRV); } - /** - * - */ - protected function prepareTlsEnvironment() + protected function prepareNewConnection() { - $strict_tls = true; - $use_local_ca = true; - if (Platform::isWindows()) { - } else { - $cfg_dir = $this->getConfigDir(); - if ($strict_tls) { - putenv(sprintf('LDAPRC=%s/%s', $cfg_dir, 'ldap_ca.conf')); + $use_tls = false; + $force_tls = true; + $force_tls = false; + + if ($use_tls) { + $this->prepareTlsEnvironment(); + } + + $ds = ldap_connect($this->hostname, $this->port); + $cap = $this->discoverCapabilities($ds); + + if ($use_tls) { + if ($cap->starttls) { + if (@ldap_start_tls($ds)) { + Log::debug('LDAP STARTTLS succeeded'); + } else { + Log::debug('LDAP STARTTLS failed: %s', ldap_error($ds)); + throw new \Exception( + sprintf( + 'LDAP STARTTLS failed: %s', + ldap_error($ds) + ) + ); + } + } elseif ($force_tls) { + throw new \Exception( + sprintf( + 'TLS is required but not announced by %s', + $this->host_name + ) + ); } else { - putenv(sprintf('LDAPRC=%s/%s', $cfg_dir, 'ldap_nocert.conf')); + // TODO: Log noticy -> TLS enabled but not announced } } - // file_put_contents('/tmp/tom_LDAP.conf', "TLS_REQCERT never\n"); + // ldap_rename requires LDAPv3: + if ($cap->ldapv3) { + if (! ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)) { + throw new Exception('LDAPv3 is required'); + } + } else { + + // TODO: remove this -> FORCING v3 for now + ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); + + Log::warn('No LDAPv3 support detected'); + } + + // Not setting this results in "Operations error" on AD when using the + // whole domain as search base: + ldap_set_option($ds, LDAP_OPT_REFERRALS, 0); + // ldap_set_option($ds, LDAP_OPT_DEREF, LDAP_DEREF_NEVER); + return $ds; } - /** - * @return object - */ - protected function fetchRootDseDetails() + protected function prepareTlsEnvironment() { - $query = $this->select()->from('*', array('+')); - - /*, array( - 'defaultNamingContext', - 'namingContexts', - 'supportedSaslMechanisms', - 'dnsHostName', - 'schemaNamingContext', - 'supportedLDAPVersion', // => array(3, 2) - 'supportedCapabilities' - ))*/ + $strict_tls = true; + // TODO: allow variable known CA location (system VS Icinga) + if (Platform::isWindows()) { + // putenv('LDAP...') + } else { + if ($strict_tls) { + $ldap_conf = $this->getConfigDir('ldap_ca.conf'); + } else { + $ldap_conf = $this->getConfigDir('ldap_nocert.conf'); + } + putenv('LDAPRC=' . $ldap_conf); + if (getenv('LDAPRC') !== $ldap_conf) { + throw new Exception('putenv failed'); + } + } + } + protected function discoverCapabilities($ds) + { + $query = $this->select()->from( + '*', + array( + 'defaultNamingContext', + 'namingContexts', + 'vendorName', + 'vendorVersion', + 'supportedSaslMechanisms', + 'dnsHostName', + 'schemaNamingContext', + 'supportedLDAPVersion', // => array(3, 2) + 'supportedCapabilities', + 'supportedExtension', + '+' + ) + ); $fields = $query->listFields(); - $result = ldap_read( - $this->ds, + $result = @ldap_read( + $ds, '', - (string)$query, - $query->listFields(), - 0, - 0 + (string) $query, + $query->listFields() ); - $entry = ldap_first_entry($this->ds, $result); - $result = $this->cleanupAttributes(ldap_get_attributes($this->ds, $entry)); + if (! $result) { + throw new Exception( + sprintf( + 'Capability query failed: %s', + ldap_error($ds) + ) + ); + } + $entry = ldap_first_entry($ds, $result); + $cap = (object) array( + 'ldapv3' => false, + 'starttls' => false, + ); + + if ($entry === false) { + // TODO: Is it OK to have no capabilities? + return $cap; + } + + $result = $this->cleanupAttributes( + ldap_get_attributes($ds, $entry) + ); + /* + if (isset($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"; + // echo $this->ms_capability[$oid] . "\n"; } } } if (isset($result->supportedExtension)) { foreach ($result->supportedExtension as $oid) { if (array_key_exists($oid, $this->ldap_extension)) { - // STARTTLS -> läuft mit OpenLDAP + if ($this->ldap_extension[$oid] === 'STARTTLS') { + $cap->starttls = true; + } } } } - return $result; + return $cap; } - /** - * - */ - public function discoverCapabilities() - { - $this->fetchRootDseDetails(); - } - /** - * @throws Exception - */ public function connect() { if ($this->ds !== null) { return; } - - if ($this->use_tls) { - $this->prepareTlsEnvironment(); - } - Log::debug("Trying to connect to %s", $this->hostname); - $this->ds = ldap_connect($this->hostname, 389); - $this->discoverCapabilities(); - if ($this->use_tls) { - Log::debug("Trying ldap_start_tls()"); - if (@ldap_start_tls($this->ds)) { - Log::debug("Trying ldap_start_tls() succeeded"); - } else { - Log::warn( - "ldap_start_tls() failed: %s. Does your ldap_ca.conf point to the certificate? ", - ldap_error($this->ds) - ); - } - } - - - // ldap_rename requires LDAPv3: - if (!ldap_set_option($this->ds, LDAP_OPT_PROTOCOL_VERSION, 3)) { - throw new Exception('LDAPv3 is required'); - } - - // Not setting this results in "Operations error" on AD when using the - // whole domain as search base: - ldap_set_option($this->ds, LDAP_OPT_REFERRALS, 0); - - // ldap_set_option($this->ds, LDAP_OPT_DEREF, LDAP_DEREF_NEVER); - Log::debug("Trying ldap_bind(%s)", $this->bind_dn); + $this->ds = $this->prepareNewConnection(); $r = @ldap_bind($this->ds, $this->bind_dn, $this->bind_pw); - if (!$r) { - log::fatal( - 'LDAP connection (%s / %s) failed: %s', - $this->bind_dn, - '***', - ldap_error($this->ds) - ); - throw new ConfigError( + if (! $r) { + throw new \Exception( sprintf( - 'Could not connect to the authentication server, please '. - 'review your LDAP connection settings.' + 'LDAP connection to %s:%s (%s / %s) failed: %s', + $this->hostname, + $this->port, + $this->bind_dn, + '***' /* $this->bind_pw */, + ldap_error($this->ds) ) ); } } + + public function __destruct() + { + putenv('LDAPRC'); + } } diff --git a/library/Icinga/Protocol/Ldap/Query.php b/library/Icinga/Protocol/Ldap/Query.php index 083a680ca..92289fbbc 100644 --- a/library/Icinga/Protocol/Ldap/Query.php +++ b/library/Icinga/Protocol/Ldap/Query.php @@ -1,32 +1,12 @@ - * @author Icinga Development Team - */ -// {{{ICINGA_LICENSE_HEADER}}} namespace Icinga\Protocol\Ldap; -use Icinga\Web\Paginator\Adapter\QueryAdapter; - +/** + * Search class + * + * @package Icinga\Protocol\Ldap + */ /** * Search abstraction class * @@ -38,52 +18,24 @@ use Icinga\Web\Paginator\Adapter\QueryAdapter; * * @copyright Copyright (c) 2013 Icinga-Web Team * @author Icinga-Web Team - * @package Icinga\Protocol\Ldap + * @package Icinga\Protocol\Ldap * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License - * @package Icinga\Protocol\Ldap */ class Query { - /** - * @var Connection - */ protected $connection; - - /** - * @var array - */ protected $filters = array(); - - /** - * @var array - */ protected $fields = array(); - - /** - * @var - */ protected $limit_count; - - /** - * @var - */ protected $limit_offset; - - /** - * @var array - */ protected $sort_columns = array(); - - /** - * @var - */ protected $count; /** * Constructor * - * @param \Icinga\Protocol\Ldap\Connection $connection LDAP Connection object - * @return \Icinga\Protocol\Ldap\Query + * @param Connection LDAP Connection object + * @return void */ public function __construct(Connection $connection) { @@ -106,14 +58,11 @@ class Query /** * Count result set, ignoring limits * - * @param null $count - * @param null $offset - * @throws Exception * @return int */ public function limit($count = null, $offset = null) { - if (!preg_match('~^\d+~', $count . $offset)) { + if (! preg_match('~^\d+~', $count . $offset)) { throw new Exception( sprintf( 'Got invalid limit: %s, %s', @@ -122,8 +71,8 @@ class Query ) ); } - $this->limit_count = (int)$count; - $this->limit_offset = (int)$offset; + $this->limit_count = (int) $count; + $this->limit_offset = (int) $offset; return $this; } @@ -176,15 +125,12 @@ class Query { $result = $this->fetchAll(); $sorted = array(); + $quotedDn = preg_quote($this->connection->getDN(), '/'); foreach ($result as $key => & $item) { $new_key = LdapUtils::implodeDN( array_reverse( LdapUtils::explodeDN( - preg_replace( - '/,' . preg_quote($this->connection->getDN(), '/') . '$/', - '', - $key - ) + preg_replace('/,' . $quotedDn . '$/', '', $key) ) ) ); @@ -194,7 +140,11 @@ class Query ksort($sorted); $tree = Root::forConnection($this->connection); + $root_dn = $tree->getDN(); foreach ($sorted as $sort_key => & $key) { + if ($key === $root_dn) { + continue; + } $tree->createChildByDN($key, $result[$key]); } return $tree; @@ -246,8 +196,6 @@ class Query * * This creates an objectClass filter * - * @param $objectClass - * @param array $fields * @return Query */ public function from($objectClass, $fields = array()) @@ -308,8 +256,6 @@ class Query /** * Return a pagination adapter for the current query * - * @param null $limit - * @param null $page * @return \Zend_Paginator */ public function paginate($limit = null, $page = null) @@ -325,7 +271,7 @@ class Query } $paginator = new \Zend_Paginator( // TODO: Adapter doesn't fit yet: - new QueryAdapter($this) + new \Icinga\Web\Paginator\Adapter\QueryAdapter($this) ); $paginator->setItemCountPerPage($limit); $paginator->setCurrentPageNumber($page); @@ -364,7 +310,7 @@ class Query } /** - * Destructor + * Descructor */ public function __destruct() { diff --git a/library/Icinga/Protocol/Livestatus/Connection.php b/library/Icinga/Protocol/Livestatus/Connection.php index 1954ad983..eeec86c01 100755 --- a/library/Icinga/Protocol/Livestatus/Connection.php +++ b/library/Icinga/Protocol/Livestatus/Connection.php @@ -1,6 +1,28 @@ + * $lconf = new Connection((object) array( + * 'hostname' => 'localhost', + * 'root_dn' => 'dc=monitoring,dc=...', + * 'bind_dn' => 'cn=Mangager,dc=monitoring,dc=...', + * 'bind_pw' => '***' + * )); + * + * + * @copyright Copyright (c) 2013 Icinga-Web Team + * @author Icinga-Web Team + * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License + */ class Connection { const TYPE_UNIX = 1; @@ -49,19 +71,23 @@ class Connection $this->assertPhpExtensionLoaded('sockets'); if ($socket[0] === '/') { if (! is_writable($socket)) { - throw new \Exception(sprintf( - 'Cannot write to livestatus socket "%s"', - $socket - )); + throw new \Exception( + sprintf( + 'Cannot write to livestatus socket "%s"', + $socket + ) + ); } $this->socket_type = self::TYPE_UNIX; $this->socket_path = $socket; } else { if (! preg_match('~^tcp://([^:]+):(\d+)~', $socket, $m)) { - throw new \Exception(sprintf( - 'Invalid TCP socket syntax: "%s"', - $socket - )); + throw new \Exception( + sprintf( + 'Invalid TCP socket syntax: "%s"', + $socket + ) + ); } // TODO: Better syntax checks $this->socket_host = $m[1]; @@ -80,17 +106,17 @@ class Connection { $count = clone($query); $count->count(); - \Icinga\Benchmark::measure('Sending Livestatus Count Query'); - $data = $this->_fetch((string) $count); - \Icinga\Benchmark::measure('Got Livestatus count result'); + Benchmark::measure('Sending Livestatus Count Query'); + $data = $this->doFetch((string) $count); + Benchmark::measure('Got Livestatus count result'); return $data[0][0]; } public function fetchAll(Query $query) { - \Icinga\Benchmark::measure('Sending Livestatus Query'); - $data = $this->_fetch((string) $query); - \Icinga\Benchmark::measure('Got Livestatus Data'); + Benchmark::measure('Sending Livestatus Query'); + $data = $this->doFetch((string) $query); + Benchmark::measure('Got Livestatus Data'); if ($query->hasColumns()) { $headers = $query->getColumnAliases(); } else { @@ -114,12 +140,12 @@ class Connection $query->getLimit() ); } - \Icinga\Benchmark::measure('Data sorted, limits applied'); + Benchmark::measure('Data sorted, limits applied'); return $result; } - protected function _fetch($raw_query) + protected function doFetch($raw_query) { $conn = $this->getConnection(); $this->writeToSocket($raw_query); @@ -128,15 +154,17 @@ class Connection $length = (int) trim(substr($header, 4)); $body = $this->readFromSocket($length); if ($status !== 200) { - throw new \Exception(sprintf( - 'Problem while reading %d bytes from livestatus: %s', - $length, - $body - )); + throw new Exception( + sprintf( + 'Problem while reading %d bytes from livestatus: %s', + $length, + $body + ) + ); } $result = json_decode($body); if ($result === null) { - throw new \Exception('Got invalid response body from livestatus'); + throw new Exception('Got invalid response body from livestatus'); } return $result; @@ -147,13 +175,15 @@ class Connection $offset = 0; $buffer = ''; - while($offset < $length) { + while ($offset < $length) { $data = socket_read($this->connection, $length - $offset); if ($data === false) { - throw new \Exception(sprintf( - 'Failed to read from livestatus socket: %s', - socket_strerror(socket_last_error($this->connection)) - )); + throw new Exception( + sprintf( + 'Failed to read from livestatus socket: %s', + socket_strerror(socket_last_error($this->connection)) + ) + ); } $size = strlen($data); $offset += $size; @@ -164,10 +194,13 @@ class Connection } } if ($offset !== $length) { - throw new \Exception(sprintf( - 'Got only %d instead of %d bytes from livestatus socket', - $offset, $length - )); + throw new \Exception( + sprintf( + 'Got only %d instead of %d bytes from livestatus socket', + $offset, + $length + ) + ); } return $buffer; @@ -185,10 +218,12 @@ class Connection protected function assertPhpExtensionLoaded($name) { if (! extension_loaded($name)) { - throw new \Exception(sprintf( - 'The extension "%s" is not loaded', - $name - )); + throw new \Exception( + sprintf( + 'The extension "%s" is not loaded', + $name + ) + ); } } @@ -213,24 +248,28 @@ class Connection $this->connection = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if (! @socket_connect($this->connection, $this->socket_host, $this->socket_port)) { - throw new \Exception(sprintf( - 'Cannot connect to livestatus TCP socket "%s:%d": %s', - $this->socket_host, - $this->socket_port, - socket_strerror(socket_last_error($this->connection)) - )); + throw new \Exception( + sprintf( + 'Cannot connect to livestatus TCP socket "%s:%d": %s', + $this->socket_host, + $this->socket_port, + socket_strerror(socket_last_error($this->connection)) + ) + ); } socket_set_option($this->connection, SOL_TCP, TCP_NODELAY, 1); } protected function establishSocketConnection() { - $this->connection = socket_create(AF_UNIX, SOCK_STREAM, 0); + $this->connection = socket_create(AF_UNIX, SOCK_STREAM, 0); if (! socket_connect($this->connection, $this->socket_path)) { - throw new \Exception(sprintf( - 'Cannot connect to livestatus local socket "%s"', - $this->socket_path - )); + throw new \Exception( + sprintf( + 'Cannot connect to livestatus local socket "%s"', + $this->socket_path + ) + ); } } @@ -246,4 +285,3 @@ class Connection $this->disconnect(); } } - diff --git a/library/Icinga/Protocol/Livestatus/Query.php b/library/Icinga/Protocol/Livestatus/Query.php index e137d5429..50ba112d4 100755 --- a/library/Icinga/Protocol/Livestatus/Query.php +++ b/library/Icinga/Protocol/Livestatus/Query.php @@ -1,9 +1,10 @@ order_columns[] = array($col, $dir); return $this; @@ -82,11 +84,13 @@ class Query extends Protocol\AbstractQuery public function limit($count = null, $offset = null) { if (! preg_match('~^\d+~', $count . $offset)) { - throw new Exception(sprintf( - 'Got invalid limit: %s, %s', - $count, - $offset - )); + throw new Exception( + sprintf( + 'Got invalid limit: %s, %s', + $count, + $offset + ) + ); } $this->limit_count = (int) $count; $this->limit_offset = (int) $offset; @@ -116,10 +120,12 @@ class Query extends Protocol\AbstractQuery public function from($table, $columns = null) { if (! $this->connection->hasTable($table)) { - throw new Exception(sprintf( - 'This livestatus connection does not provide "%s"', - $table - )); + throw new Exception( + sprintf( + 'This livestatus connection does not provide "%s"', + $table + ) + ); } $this->table = $table; if (is_array($columns)) { @@ -207,4 +213,3 @@ class Query extends Protocol\AbstractQuery unset($this->connection); } } -