From c49f723f05739cf106c232a00fcedca7ca632793 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Fri, 6 Feb 2015 16:31:03 +0100 Subject: [PATCH 01/12] Let Icinga\Protocol\Ldap\Exception inherit from IcingaException --- library/Icinga/Protocol/Ldap/Connection.php | 72 ++++++++------------- library/Icinga/Protocol/Ldap/Exception.php | 4 +- 2 files changed, 31 insertions(+), 45 deletions(-) diff --git a/library/Icinga/Protocol/Ldap/Connection.php b/library/Icinga/Protocol/Ldap/Connection.php index db55858e9..2d425d12b 100644 --- a/library/Icinga/Protocol/Ldap/Connection.php +++ b/library/Icinga/Protocol/Ldap/Connection.php @@ -171,11 +171,9 @@ class Connection return false; } throw new LdapException( - sprintf( - 'LDAP list for "%s" failed: %s', - $dn, - ldap_error($this->ds) - ) + 'LDAP list for "%s" failed: %s', + $dn, + ldap_error($this->ds) ); } $children = ldap_get_entries($this->ds, $result); @@ -183,7 +181,7 @@ class Connection $result = $this->deleteRecursively($children[$i]['dn']); if (!$result) { //return result code, if delete fails - throw new LdapException(sprintf('Recursively deleting "%s" failed', $dn)); + throw new LdapException('Recursively deleting "%s" failed', $dn); } } return $this->deleteDN($dn); @@ -200,11 +198,9 @@ class Connection return false; } throw new LdapException( - sprintf( - 'LDAP delete for "%s" failed: %s', - $dn, - ldap_error($this->ds) - ) + 'LDAP delete for "%s" failed: %s', + $dn, + ldap_error($this->ds) ); } @@ -225,10 +221,8 @@ class Connection $rows = $this->fetchAll($query, $fields); if (count($rows) !== 1) { throw new LdapException( - sprintf( - 'Cannot fetch single DN for %s', - $query->create() - ) + 'Cannot fetch single DN for %s', + $query->create() ); } return key($rows); @@ -471,18 +465,14 @@ class Connection } else { Logger::debug('LDAP STARTTLS failed: %s', ldap_error($ds)); throw new LdapException( - sprintf( - 'LDAP STARTTLS failed: %s', - ldap_error($ds) - ) + 'LDAP STARTTLS failed: %s', + ldap_error($ds) ); } } elseif ($force_tls) { throw new LdapException( - sprintf( - 'TLS is required but not announced by %s', - $this->hostname - ) + 'TLS is required but not announced by %s', + $this->hostname ); } else { // TODO: Log noticy -> TLS enabled but not announced @@ -708,24 +698,20 @@ class Connection if (! $result) { throw new LdapException( - sprintf( - 'Capability query failed (%s:%d): %s. Check if hostname and port of the ldap resource are correct ' - . ' and if anonymous access is permitted.', - $this->hostname, - $this->port, - ldap_error($ds) - ) + 'Capability query failed (%s:%d): %s. Check if hostname and port of the' + . ' ldap resource are correct and if anonymous access is permitted.', + $this->hostname, + $this->port, + ldap_error($ds) ); } $entry = ldap_first_entry($ds, $result); if ($entry === false) { throw new LdapException( - sprintf( - 'Capabilities not available (%s:%d): %s. Discovery of root DSE probably not permitted.', - $this->hostname, - $this->port, - ldap_error($ds) - ) + 'Capabilities not available (%s:%d): %s. Discovery of root DSE probably not permitted.', + $this->hostname, + $this->port, + ldap_error($ds) ); } @@ -771,14 +757,12 @@ class Connection $r = @ldap_bind($this->ds, $this->bind_dn, $this->bind_pw); if (! $r) { throw new LdapException( - sprintf( - 'LDAP connection to %s:%s (%s / %s) failed: %s', - $this->hostname, - $this->port, - $this->bind_dn, - '***' /* $this->bind_pw */, - ldap_error($this->ds) - ) + 'LDAP connection to %s:%s (%s / %s) failed: %s', + $this->hostname, + $this->port, + $this->bind_dn, + '***' /* $this->bind_pw */, + ldap_error($this->ds) ); } $this->bound = true; diff --git a/library/Icinga/Protocol/Ldap/Exception.php b/library/Icinga/Protocol/Ldap/Exception.php index 784b84a9d..de7a10651 100644 --- a/library/Icinga/Protocol/Ldap/Exception.php +++ b/library/Icinga/Protocol/Ldap/Exception.php @@ -3,10 +3,12 @@ namespace Icinga\Protocol\Ldap; +use Icinga\Exception\IcingaException; + /** * Class Exception * @package Icinga\Protocol\Ldap */ -class Exception extends \Exception +class Exception extends IcingaException { } From 8b94e4c7019a0f7e01d204487bacd079b0815899 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Fri, 6 Feb 2015 16:32:26 +0100 Subject: [PATCH 02/12] Fix documentation and code style in the LdapUserBackend --- .../Backend/LdapUserBackend.php | 57 ++++++++++--------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/library/Icinga/Authentication/Backend/LdapUserBackend.php b/library/Icinga/Authentication/Backend/LdapUserBackend.php index fd7e39f54..7fde1f61b 100644 --- a/library/Icinga/Authentication/Backend/LdapUserBackend.php +++ b/library/Icinga/Authentication/Backend/LdapUserBackend.php @@ -5,6 +5,7 @@ namespace Icinga\Authentication\Backend; use Icinga\User; use Icinga\Authentication\UserBackend; +use Icinga\Protocol\Ldap\Query; use Icinga\Protocol\Ldap\Connection; use Icinga\Exception\AuthenticationException; use Icinga\Protocol\Ldap\Exception as LdapException; @@ -15,7 +16,7 @@ class LdapUserBackend extends UserBackend * Connection to the LDAP server * * @var Connection - **/ + */ protected $conn; protected $baseDn; @@ -36,7 +37,9 @@ class LdapUserBackend extends UserBackend } /** - * @return \Icinga\Protocol\Ldap\Query + * Create a query to select all usernames + * + * @return Query */ protected function selectUsers() { @@ -49,18 +52,18 @@ class LdapUserBackend extends UserBackend } /** - * Create query + * Create a query filtered by the given username * - * @param string $username + * @param string $username * - * @return \Icinga\Protocol\Ldap\Query - **/ + * @return Query + */ protected function selectUser($username) { - return $this->selectUsers()->where( - $this->userNameAttribute, - str_replace('*', '', $username) - ); + return $this->selectUsers()->setUsePagedResults(false)->where( + $this->userNameAttribute, + str_replace('*', '', $username) + ); } /** @@ -68,23 +71,22 @@ class LdapUserBackend extends UserBackend * * Try to bind to the backend and query all available users to check if: * * - * @throws AuthenticationException When authentication is not possible + * @throws AuthenticationException When authentication is not possible */ public function assertAuthenticationPossible() { try { - $q = $this->conn->select()->setBase($this->baseDn)->from($this->userClass); - $result = $q->fetchRow(); + $result = $this->selectUsers()->fetchRow(); } catch (LdapException $e) { throw new AuthenticationException('Connection not possible.', $e); } - if (! isset($result)) { + if ($result === null) { throw new AuthenticationException( 'No objects with objectClass="%s" in DN="%s" found.', $this->userClass, @@ -139,17 +141,16 @@ class LdapUserBackend extends UserBackend } /** - * Test whether the given user exists + * Return whether the given user exists * - * @param User $user + * @param User $user * * @return bool - * @throws AuthenticationException */ public function hasUser(User $user) { $username = $user->getUsername(); - $entry = $this->conn->fetchOne($this->selectUser($username)); + $entry = $this->selectUser($username)->fetchOne(); if (is_array($entry)) { return in_array(strtolower($username), array_map('strtolower', $entry)); @@ -159,16 +160,15 @@ class LdapUserBackend extends UserBackend } /** - * Authenticate the given user and return true on success, false on failure and null on error + * Return whether the given user credentials are valid * * @param User $user * @param string $password - * @param boolean $healthCheck Perform additional health checks to generate more useful exceptions in case - * of a configuration or backend error + * @param boolean $healthCheck Assert that authentication is possible at all * - * @return bool True when the authentication was successful, false when the username - * or password was invalid - * @throws AuthenticationException When an error occurred during authentication and authentication is not possible + * @return bool + * + * @throws AuthenticationException In case an error occured or the health check has failed */ public function authenticate(User $user, $password, $healthCheck = true) { @@ -176,7 +176,6 @@ class LdapUserBackend extends UserBackend try { $this->assertAuthenticationPossible(); } catch (AuthenticationException $e) { - // Authentication not possible throw new AuthenticationException( 'Authentication against backend "%s" not possible.', $this->getName(), @@ -184,24 +183,27 @@ class LdapUserBackend extends UserBackend ); } } + if (! $this->hasUser($user)) { return false; } + try { $userDn = $this->conn->fetchDN($this->selectUser($user->getUsername())); $authenticated = $this->conn->testCredentials( $userDn, $password ); + if ($authenticated) { $groups = $this->getGroups($userDn); if ($groups !== null) { $user->setGroups($groups); } } + return $authenticated; } catch (LdapException $e) { - // Error during authentication of this specific user throw new AuthenticationException( 'Failed to authenticate user "%s" against backend "%s". An exception was thrown:', $user->getUsername(), @@ -238,6 +240,7 @@ class LdapUserBackend extends UserBackend $users[] = $row->{$this->userNameAttribute}; } } + return $users; } } From 3852feb069f8e91b60dd0976d4d6187d8d3beb2d Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Fri, 6 Feb 2015 16:32:59 +0100 Subject: [PATCH 03/12] Add defaults for limit and offset in Icinga\Protocol\Ldap\Query --- library/Icinga/Protocol/Ldap/Query.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/Icinga/Protocol/Ldap/Query.php b/library/Icinga/Protocol/Ldap/Query.php index 8b71fc918..897f12f4e 100644 --- a/library/Icinga/Protocol/Ldap/Query.php +++ b/library/Icinga/Protocol/Ldap/Query.php @@ -27,8 +27,8 @@ class Query protected $connection; protected $filters = array(); protected $fields = array(); - protected $limit_count; - protected $limit_offset; + protected $limit_count = 0; + protected $limit_offset = 0; protected $sort_columns = array(); protected $count; protected $base; @@ -111,7 +111,7 @@ class Query */ public function hasLimit() { - return $this->limit_count !== null; + return $this->limit_count > 0; } /** From b828f8b13adfdbc7084da6ef3eb93bac7e024ce8 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Fri, 6 Feb 2015 16:37:35 +0100 Subject: [PATCH 04/12] Fix ldap authentication when authenticating against ActiveDirectory Unlike OpenLDAP, ActiveDirectory does not seem to react on the size limit passed to ldap_search() in global manner causing it to not to respond with LDAP_SIZELIMIT_EXCEEDED (4) in case a requested page contains more entries than the requested maximum. fixes #7993 --- library/Icinga/Protocol/Ldap/Connection.php | 218 ++++++++++++-------- 1 file changed, 127 insertions(+), 91 deletions(-) diff --git a/library/Icinga/Protocol/Ldap/Connection.php b/library/Icinga/Protocol/Ldap/Connection.php index 2d425d12b..6db88365a 100644 --- a/library/Icinga/Protocol/Ldap/Connection.php +++ b/library/Icinga/Protocol/Ldap/Connection.php @@ -32,6 +32,8 @@ class Connection { const LDAP_NO_SUCH_OBJECT = 32; const LDAP_SIZELIMIT_EXCEEDED = 4; + const LDAP_ADMINLIMIT_EXCEEDED = 11; + const PAGE_SIZE = 1000; protected $ds; protected $hostname; @@ -98,9 +100,6 @@ class Connection protected $namingContexts; protected $discoverySuccess = false; - protected $lastResult; - protected $pageCookie; - /** * Constructor * @@ -238,6 +237,7 @@ class Connection { $query = clone $query; $query->limit(1); + $query->setUsePagedResults(false); $results = $this->fetchAll($query, $fields); return array_shift($results); } @@ -267,35 +267,144 @@ class Connection $this->connect(); $this->bind(); - $offset = $limit = null; - if ($query->hasLimit()) { - $offset = $query->getOffset(); - $limit = $query->getLimit(); + if ($query->getUsePagedResults() && version_compare(PHP_VERSION, '5.4.0') >= 0) { + return $this->runPagedQuery($query, $fields); + } else { + return $this->runQuery($query, $fields); + } + } + + protected function runQuery(Query $query, $fields = array()) + { + $limit = $query->getLimit(); + $offset = $query->hasOffset() ? $query->getOffset() - 1 : 0; + + $results = @ldap_search( + $this->ds, + $query->hasBase() ? $query->getBase() : $this->root_dn, + $query->create(), + empty($fields) ? $query->listFields() : $fields, + 0, // Attributes and values + $limit ? $offset + $limit : 0 + ); + if ($results === false) { + if (ldap_errno($this->ds) === self::LDAP_NO_SUCH_OBJECT) { + return array(); + } + + throw new LdapException( + 'LDAP query "%s" (base %s) failed. Error: %s', + $query->create(), + $query->hasBase() ? $query->getBase() : $this->root_dn, + ldap_error($this->ds) + ); + } elseif (ldap_count_entries($this->ds, $results) === 0) { + return array(); + } + + foreach ($query->getSortColumns() as $col) { + ldap_sort($this->ds, $results, $col[0]); } $count = 0; $entries = array(); - $results = $this->runQuery($query, $fields); - while (! empty($results)) { + $entry = ldap_first_entry($this->ds, $results); + do { + $count += 1; + if ($offset === 0 || $offset < $count) { + $entries[ldap_get_dn($this->ds, $entry)] = $this->cleanupAttributes( + ldap_get_attributes($this->ds, $entry) + ); + } + } while (($limit === 0 || $limit !== count($entries)) && ($entry = ldap_next_entry($this->ds, $entry))); + + ldap_free_result($results); + return $entries; + } + + protected function runPagedQuery(Query $query, $fields = array()) + { + $limit = $query->getLimit(); + $offset = $query->hasOffset() ? $query->getOffset() - 1 : 0; + $queryString = $query->create(); + $base = $query->hasBase() ? $query->getBase() : $this->root_dn; + + if (empty($fields)) { + $fields = $query->listFields(); + } + + $count = 0; + $cookie = ''; + $entries = array(); + do { + ldap_control_paged_result($this->ds, static::PAGE_SIZE, true, $cookie); + $results = @ldap_search($this->ds, $base, $queryString, $fields, 0, $limit ? $offset + $limit : 0); + if ($results === false) { + if (ldap_errno($this->ds) === self::LDAP_NO_SUCH_OBJECT) { + break; + } + + throw new LdapException( + 'LDAP query "%s" (base %s) failed. Error: %s', + $queryString, + $base, + ldap_error($this->ds) + ); + } elseif (ldap_count_entries($this->ds, $results) === 0) { + if (in_array( + ldap_errno($this->ds), + array(static::LDAP_SIZELIMIT_EXCEEDED, static::LDAP_ADMINLIMIT_EXCEEDED) + )) { + Logger::warning( + 'Unable to request more than %u results. Does the server allow paged search requests? (%s)', + $count, + ldap_error($this->ds) + ); + } + + break; + } + $entry = ldap_first_entry($this->ds, $results); - while ($entry) { - $count++; - if ( - ($offset === null || $offset <= $count) - && ($limit === null || $limit > count($entries)) - ) { + do { + $count += 1; + if ($offset === 0 || $offset < $count) { $entries[ldap_get_dn($this->ds, $entry)] = $this->cleanupAttributes( ldap_get_attributes($this->ds, $entry) ); } + } while (($limit === 0 || $limit !== count($entries)) && ($entry = ldap_next_entry($this->ds, $entry))); - $entry = ldap_next_entry($this->ds, $entry); + try { + ldap_control_paged_result_response($this->ds, $results, $cookie); + } catch (Exception $e) { + // If the page size is greater than or equal to the sizeLimit value, the server should ignore the + // control as the request can be satisfied in a single page: https://www.ietf.org/rfc/rfc2696.txt + // This applies no matter whether paged search requests are permitted or not. You're done once you + // got everything you were out for. + if (count($entries) !== $limit) { + Logger::warning( + 'Unable to request paged LDAP results. Does the server allow paged search requests? (%s)', + $e->getMessage() + ); + } } - $results = $this->runQuery($query, $fields); + ldap_free_result($results); + } while ($cookie && ($limit === 0 || count($entries) < $limit)); + + if ($cookie) { + // A sequence of paged search requests is abandoned by the client sending a search request containing a + // pagedResultsControl with the size set to zero (0) and the cookie set to the last cookie returned by + // the server: https://www.ietf.org/rfc/rfc2696.txt + ldap_control_paged_result($this->ds, 0, false, $cookie); + ldap_search($this->ds, $base, $queryString, $fields); // Returns no entries, due to the page size + } else { + // Reset the paged search request so that subsequent requests succeed + ldap_control_paged_result($this->ds, 0); } - return $entries; + return $entries; // TODO(7693): Sort entries post-processed } protected function cleanupAttributes($attrs) @@ -314,79 +423,6 @@ class Connection return $clean; } - protected function runQuery(Query $query, $fields = array()) - { - if ($query->getUsePagedResults() && version_compare(PHP_VERSION, '5.4.0') >= 0) { - if ($this->pageCookie === null) { - $this->pageCookie = ''; - } else { - try { - ldap_control_paged_result_response($this->ds, $this->lastResult, $this->pageCookie); - } catch (Exception $e) { - $this->pageCookie = ''; - if (! $query->hasLimit() || ldap_errno($this->ds) !== static::LDAP_SIZELIMIT_EXCEEDED) { - Logger::error( - 'Unable to request paged LDAP results. Does the server allow paged search requests? (%s)', - $e->getMessage() - ); - } - } - - ldap_free_result($this->lastResult); - if (! $this->pageCookie) { - $this->pageCookie = $this->lastResult = null; - // Abandon the paged search request so that subsequent requests succeed - ldap_control_paged_result($this->ds, 0); - return false; - } - } - - // Does not matter whether we'll use a valid page size here, - // as the server applies its hard limit in case its too high - ldap_control_paged_result( - $this->ds, - $query->hasLimit() ? $query->getLimit() : 500, - true, - $this->pageCookie - ); - } elseif ($this->lastResult !== null) { - ldap_free_result($this->lastResult); - $this->lastResult = null; - return false; - } - - $base = $query->hasBase() ? $query->getBase() : $this->root_dn; - $results = @ldap_search( - $this->ds, - $base, - $query->create(), - empty($fields) ? $query->listFields() : $fields, - 0, // Attributes and values - $query->hasLimit() ? $query->getOffset() + $query->getLimit() : 0 // No limit - at least where possible - ); - - if ($results === false) { - if (ldap_errno($this->ds) === self::LDAP_NO_SUCH_OBJECT) { - return false; - } - throw new LdapException( - sprintf( - 'LDAP query "%s" (root %s) failed: %s', - $query->create(), - $this->root_dn, - ldap_error($this->ds) - ) - ); - } - - foreach ($query->getSortColumns() as $col) { - ldap_sort($this->ds, $results, $col[0]); - } - - $this->lastResult = $results; - return $results; - } - public function testCredentials($username, $password) { $this->connect(); From 58d48d9fa048c673b63903291afdc4b10d70825c Mon Sep 17 00:00:00 2001 From: Alexander Klimov Date: Fri, 6 Feb 2015 17:48:21 +0100 Subject: [PATCH 05/12] Accessibility: Text cue for required form control labels: Add prototype refs #7934 --- ...-cue-for-required-form-control-labels.html | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 doc/accessibility/text-cue-for-required-form-control-labels.html diff --git a/doc/accessibility/text-cue-for-required-form-control-labels.html b/doc/accessibility/text-cue-for-required-form-control-labels.html new file mode 100644 index 000000000..b9e624208 --- /dev/null +++ b/doc/accessibility/text-cue-for-required-form-control-labels.html @@ -0,0 +1,36 @@ + + + + + + Accessibility: Text cue for required form control labels + + + + + +
+ + + +
+ + \ No newline at end of file From 23ce15668197c5217d79cbc227a349f49608595d Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Sat, 7 Feb 2015 21:15:26 +0100 Subject: [PATCH 06/12] doc/installation: Add a note where to store the webserver's config --- doc/installation.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/installation.md b/doc/installation.md index d9483faef..aa85adb22 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -55,6 +55,14 @@ nginx: ./bin/icingacli setup config webserver nginx --document-root /usr/share/icingaweb2/public ```` +Save the output as new file in your webserver's configuration directory. + +Example for Apache on RHEL/CentOS: +```` +./bin/icingacli setup config webserver apache --document-root /usr/share/icingaweb2/public > /etc/httpd/conf.d/icingaweb2.conf +```` + + **Step 4: Preparing Web Setup** Because both web and CLI must have access to configuration and logs, permissions will be managed using a special From 4c9374cccafc58408c3d8b8b07f251aabbd0359a Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Sun, 8 Feb 2015 16:03:08 +0100 Subject: [PATCH 07/12] spec: Install doc and translation module fixes #8392 --- icingaweb2.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/icingaweb2.spec b/icingaweb2.spec index 1d97819d9..231b2642e 100644 --- a/icingaweb2.spec +++ b/icingaweb2.spec @@ -189,7 +189,7 @@ rm -rf %{buildroot} mkdir -p %{buildroot}/{%{basedir}/{modules,library,public},%{bindir},%{configdir}/modules/setup,%{logdir},%{phpdir},%{wwwconfigdir},%{_sysconfdir}/bash_completion.d,%{docsdir}} cp -prv application doc %{buildroot}/%{basedir} cp -pv etc/bash_completion.d/icingacli %{buildroot}/%{_sysconfdir}/bash_completion.d/icingacli -cp -prv modules/{monitoring,setup} %{buildroot}/%{basedir}/modules +cp -prv modules/{monitoring,setup,doc,translation} %{buildroot}/%{basedir}/modules cp -prv library/Icinga %{buildroot}/%{phpdir} cp -prv library/vendor %{buildroot}/%{basedir}/library cp -prv public/{css,img,js,error_norewrite.html} %{buildroot}/%{basedir}/public From d10beb7604875f39d96a9a7dd85af1e065b3237e Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Mon, 9 Feb 2015 15:26:55 +0100 Subject: [PATCH 08/12] js: no console.log. please! --- public/js/icinga/loader.js | 1 - public/js/icinga/utils.js | 2 -- 2 files changed, 3 deletions(-) diff --git a/public/js/icinga/loader.js b/public/js/icinga/loader.js index 6a82a6ee5..92aa1e9d8 100644 --- a/public/js/icinga/loader.js +++ b/public/js/icinga/loader.js @@ -737,7 +737,6 @@ } this.icinga.ui.assignUniqueContainerIds(); - console.log(origFocus); if (origFocus.length == origFocus[0] !== '') { setTimeout(function() { $(self.icinga.utils.getElementByDomPath(origFocus)).focus(); diff --git a/public/js/icinga/utils.js b/public/js/icinga/utils.js index bd64e586e..4b04b3d44 100644 --- a/public/js/icinga/utils.js +++ b/public/js/icinga/utils.js @@ -284,10 +284,8 @@ if (! $element) { $element = $(selector); } else { - console.log(selector); $element = $element.children(selector).first(); if (! $element[0]) { - console.log("element not existing stopping..."); return false; } } From 7b1b5b9b40f54404c1e2d6108e92382120ff4843 Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Mon, 9 Feb 2015 15:27:50 +0100 Subject: [PATCH 09/12] Authentication\Manager: do not override user groups Needs more care, but this way we are at least able to fetch groups unless we get out improved implementation. --- library/Icinga/Authentication/Manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/Icinga/Authentication/Manager.php b/library/Icinga/Authentication/Manager.php index 81221176e..993475636 100644 --- a/library/Icinga/Authentication/Manager.php +++ b/library/Icinga/Authentication/Manager.php @@ -84,7 +84,7 @@ class Manager $preferences = new Preferences(); } $user->setPreferences($preferences); - $groups = array(); + $groups = $user->getGroups(); foreach (Config::app('groups') as $name => $config) { try { $groupBackend = UserGroupBackend::create($name, $config); From 81f65a7cd4dadab8e31f4aa41092649551a8f20e Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Mon, 9 Feb 2015 15:29:52 +0100 Subject: [PATCH 10/12] LdapUserBackend: disable "health check" I see no point in checking this at every login. It could however be a nice addition for our config backends and the setup wizard. I'd also opt for completely removing this parameter - who wants to use this method should explicitely call it. --- library/Icinga/Authentication/Backend/LdapUserBackend.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/Icinga/Authentication/Backend/LdapUserBackend.php b/library/Icinga/Authentication/Backend/LdapUserBackend.php index 7fde1f61b..016512ab4 100644 --- a/library/Icinga/Authentication/Backend/LdapUserBackend.php +++ b/library/Icinga/Authentication/Backend/LdapUserBackend.php @@ -170,7 +170,7 @@ class LdapUserBackend extends UserBackend * * @throws AuthenticationException In case an error occured or the health check has failed */ - public function authenticate(User $user, $password, $healthCheck = true) + public function authenticate(User $user, $password, $healthCheck = false) { if ($healthCheck) { try { From 88315db1ebafc2e9d61711d2a114e44f2fbd7f17 Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Mon, 9 Feb 2015 15:31:47 +0100 Subject: [PATCH 11/12] UserBackend: reasonable defaults for AD groups I didn't do farther research, but those values seem to work fine. --- library/Icinga/Authentication/UserBackend.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/Icinga/Authentication/UserBackend.php b/library/Icinga/Authentication/UserBackend.php index b8bde164d..cb6eb458b 100644 --- a/library/Icinga/Authentication/UserBackend.php +++ b/library/Icinga/Authentication/UserBackend.php @@ -93,10 +93,10 @@ abstract class UserBackend implements Countable break; case 'msldap': $groupOptions = array( - 'group_base_dn' => $backendConfig->group_base_dn, - 'group_attribute' => $backendConfig->group_attribute, - 'group_member_attribute' => $backendConfig->group_member_attribute, - 'group_class' => $backendConfig->group_class + 'group_base_dn' => $backendConfig->get('group_base_dn', $resource->getDN()), + 'group_attribute' => $backendConfig->get('group_attribute', 'sAMAccountName'), + 'group_member_attribute' => $backendConfig->get('group_member_attribute', 'member'), + 'group_class' => $backendConfig->get('group_class', 'group') ); $backend = new LdapUserBackend( $resource, From 5bf89da6d7ed8956c180289bae4bb8b173cf9c58 Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Mon, 9 Feb 2015 15:38:43 +0100 Subject: [PATCH 12/12] PluginOutput: simplify code, add tab support refs #8366 --- .../views/helpers/PluginOutput.php | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/modules/monitoring/application/views/helpers/PluginOutput.php b/modules/monitoring/application/views/helpers/PluginOutput.php index e6c8b2d5a..d494a7810 100644 --- a/modules/monitoring/application/views/helpers/PluginOutput.php +++ b/modules/monitoring/application/views/helpers/PluginOutput.php @@ -5,34 +5,44 @@ class Zend_View_Helper_PluginOutput extends Zend_View_Helper_Abstract { protected static $purifier; + protected static $txtPatterns = array( + '~\\\n~', + '~\\\t~', + '~\\\n\\\n~', + '~(\[|\()OK(\]|\))~', + '~(\[|\()WARNING(\]|\))~', + '~(\[|\()CRITICAL(\]|\))~', + '~(\[|\()UNKNOWN(\]|\))~', + '~\@{6,}~' + ); + + protected static $txtReplacements = array( + "\n", + "\t", + "\n", + '$1OK$2', + '$1WARNING$2', + '$1CRITICAL$2', + '$1UNKNOWN$2', + '@@@@@@', + ); + public function pluginOutput($output) { if (empty($output)) { return ''; } $output = preg_replace('~]+>~', "\n", $output); - if (preg_match('~<\w+[^>]*>~', $output)) { + if (preg_match('~<\w+[^>^\\\]{,60}>~', $output)) { // HTML $output = preg_replace('~getPurifier()->purify($output) ); - } elseif (preg_match('~\\\n~', $output)) { - // Plaintext - $output = '
'
-               . preg_replace(
-              '~\\\n~', "\n", preg_replace(
-                '~\\\n\\\n~', "\n",
-                preg_replace('~\[OK\]~', '[OK]',
-                 preg_replace('~\[WARNING\]~', '[WARNING]',
-                  preg_replace('~\[CRITICAL\]~', '[CRITICAL]',
-                   preg_replace('~\@{6,}~', '@@@@@@',
-                     $this->view->escape($output)
-                ))))
-              )
-            ) . '
'; } else { - $output = '
'
-               . preg_replace('~\@{6,}~', '@@@@@@',
+            // Plaintext
+            $output = '
' . preg_replace(
+                self::$txtPatterns,
+                self::$txtReplacements,
                 $this->view->escape($output)
             ) . '
'; } @@ -55,7 +65,7 @@ class Zend_View_Helper_PluginOutput extends Zend_View_Helper_Abstract parse_str($m[1], $params); if (isset($params['host'])) { $tag->setAttribute('href', $this->view->baseUrl( - '/monitoring/detail/show?host=' . urlencode($params['host'] + '/monitoring/host/show?host=' . urlencode($params['host'] ))); } } else {