From 6b866fa917a13cc0fc6c9d9733e9fc75b26c6fe7 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 3 Nov 2015 17:17:00 +0100 Subject: [PATCH 1/2] LDAP: attempt to connect to backup server again, if main server is not available. Fixes #18701 --- apps/user_ldap/lib/connection.php | 51 +++++++++++++++++++------------ 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index f6b123babd..3f3953bb28 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -526,30 +526,41 @@ class Connection extends LDAPUtility { \OCP\Util::WARN); } } - if(!$this->configuration->ldapOverrideMainServer - && !$this->getFromCache('overrideMainServer')) { - $this->doConnect($this->configuration->ldapHost, - $this->configuration->ldapPort); - $bindStatus = $this->bind(); - $error = $this->ldap->isResource($this->ldapConnectionRes) ? - $this->ldap->errno($this->ldapConnectionRes) : -1; - } else { - $bindStatus = false; - $error = null; + + $bindStatus = false; + $error = null; + try { + if (!$this->configuration->ldapOverrideMainServer + && !$this->getFromCache('overrideMainServer') + ) { + $this->doConnect($this->configuration->ldapHost, + $this->configuration->ldapPort); + $bindStatus = $this->bind(); + $error = $this->ldap->isResource($this->ldapConnectionRes) ? + $this->ldap->errno($this->ldapConnectionRes) : -1; + } + if($bindStatus === true) { + return $bindStatus; + } + } catch (\OC\ServerNotAvailableException $e) { + if(trim($this->configuration->ldapBackupHost) === "") { + throw $e; + } } //if LDAP server is not reachable, try the Backup (Replica!) Server - if((!$bindStatus && ($error !== 0)) + if( $error !== 0 || $this->configuration->ldapOverrideMainServer - || $this->getFromCache('overrideMainServer')) { - $this->doConnect($this->configuration->ldapBackupHost, - $this->configuration->ldapBackupPort); - $bindStatus = $this->bind(); - if(!$bindStatus && $error === -1) { - //when bind to backup server succeeded and failed to main server, - //skip contacting him until next cache refresh - $this->writeToCache('overrideMainServer', true); - } + || $this->getFromCache('overrideMainServer')) + { + $this->doConnect($this->configuration->ldapBackupHost, + $this->configuration->ldapBackupPort); + $bindStatus = $this->bind(); + if($bindStatus && $error === -1) { + //when bind to backup server succeeded and failed to main server, + //skip contacting him until next cache refresh + $this->writeToCache('overrideMainServer', true); + } } return $bindStatus; } From 253e4bcf6320a1994f2db2912f450a2d9a16a895 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 4 Nov 2015 00:18:35 +0100 Subject: [PATCH 2/2] integration tests --- .../lib/integrationtestbackupserver.php | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 apps/user_ldap/tests/integration/lib/integrationtestbackupserver.php diff --git a/apps/user_ldap/tests/integration/lib/integrationtestbackupserver.php b/apps/user_ldap/tests/integration/lib/integrationtestbackupserver.php new file mode 100644 index 0000000000..95cb4b8f27 --- /dev/null +++ b/apps/user_ldap/tests/integration/lib/integrationtestbackupserver.php @@ -0,0 +1,118 @@ + + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\user_ldap\tests\integration\lib; + +use OCA\user_ldap\lib\user\Manager as LDAPUserManager; +use OCA\user_ldap\tests\integration\AbstractIntegrationTest; +use OCA\User_LDAP\Mapping\UserMapping; +use OCA\user_ldap\USER_LDAP; + +require_once __DIR__ . '/../../../../../lib/base.php'; + +class IntegrationBackupServer extends AbstractIntegrationTest { + /** @var UserMapping */ + protected $mapping; + + /** @var USER_LDAP */ + protected $backend; + + /** + * sets up the LDAP configuration to be used for the test + */ + protected function initConnection() { + parent::initConnection(); + $originalHost = $this->connection->ldapHost; + $originalPort = $this->connection->ldapPort; + $this->connection->setConfiguration([ + 'ldapHost' => 'qwertz.uiop', + 'ldapPort' => '32123', + 'ldap_backup_host' => $originalHost, + 'ldap_backup_port' => $originalPort, + ]); + } + + /** + * tests that a backup connection is being used when the main LDAP server + * is offline + * + * Beware: after starting docker, the LDAP host might not be ready yet, thus + * causing a false positive. Retry in that caseā€¦ or increase the sleep time + * in run-test.sh + * + * @return bool + */ + protected function case1() { + try { + $this->connection->getConnectionResource(); + } catch (\OC\ServerNotAvailableException $e) { + return false; + } + return true; + } + + /** + * ensures that an exception is thrown if LDAP main server and LDAP backup + * server are not available + * + * @return bool + */ + protected function case2() { + // reset possible LDAP connection + $this->initConnection(); + try { + $this->connection->setConfiguration([ + 'ldap_backup_host' => 'qwertz.uiop', + 'ldap_backup_port' => '32123', + ]); + $this->connection->getConnectionResource(); + } catch (\OC\ServerNotAvailableException $e) { + return true; + } + return false; + } + + /** + * ensures that an exception is thrown if main LDAP server is down and a + * backup server is not given + * + * @return bool + */ + protected function case3() { + // reset possible LDAP connection + $this->initConnection(); + try { + $this->connection->setConfiguration([ + 'ldap_backup_host' => '', + 'ldap_backup_port' => '', + ]); + $this->connection->getConnectionResource(); + } catch (\OC\ServerNotAvailableException $e) { + return true; + } + return false; + } +} + +require_once(__DIR__ . '/../setup-scripts/config.php'); +$test = new IntegrationBackupServer($host, $port, $adn, $apwd, $bdn); +$test->init(); +$test->run();