diff --git a/test/php/library/Icinga/Protocol/Ldap/ConnectionTest.php b/test/php/library/Icinga/Protocol/Ldap/ConnectionTest.php new file mode 100644 index 000000000..182004703 --- /dev/null +++ b/test/php/library/Icinga/Protocol/Ldap/ConnectionTest.php @@ -0,0 +1,258 @@ +getAttributesMock; + } + + function ldap_start_tls() + { + global $self; + $self->startTlsCalled = true; + } + + function ldap_set_option($ds, $option, $value) + { + global $self; + $self->activatedOptions[$option] = $value; + return true; + } + + function ldap_set($ds, $option) + { + global $self; + $self->activatedOptions[] = $option; + } + + function ldap_control_paged_result() + { + global $self; + $self->pagedResultsCalled = true; + return true; + } + + function ldap_control_paged_result_response() + { + return true; + } + + function ldap_get_dn() + { + return NULL; + } + + function ldap_free_result() + { + return NULL; + } + } + + private function node(&$element, $name) + { + $element['count']++; + $element[$name] = array('count' => 0); + $element[] = $name; + } + + private function addEntry(&$element, $name, $entry) + { + $element[$name]['count']++; + $element[$name][] = $entry; + } + + private function mockQuery() + { + return Mockery::mock('overload:Icinga\Protocol\Ldap\Query') + ->shouldReceive(array( + 'from' => Mockery::self(), + 'create' => array('count' => 1), + 'listFields' => array('count' => 1), + 'getLimit' => 1, + 'hasOffset' => false, + 'hasBase' => false, + 'getSortColumns' => array(), + 'getUsePagedResults' => true + )); + } + + private function connectionFetchAll() + { + $this->mockQuery(); + $this->connection->connect(); + $this->connection->fetchAll(Mockery::self()); + } + + public function setUp() + { + $this->pagedResultsCalled = false; + $this->startTlsCalled = false; + $this->activatedOptions = array(); + + $this->mockLdapFunctions(); + + $config = new ConfigObject( + array( + 'hostname' => 'localhost', + 'root_dn' => 'dc=example,dc=com', + 'bind_dn' => 'cn=user,ou=users,dc=example,dc=com', + 'bind_pw' => '***' + ) + ); + $this->connection = new Connection($config); + + $caps = array('count' => 0); + $this->node($caps, 'defaultNamingContext'); + $this->node($caps, 'namingContexts'); + $this->node($caps, 'supportedCapabilities'); + $this->node($caps, 'supportedControl'); + $this->node($caps, 'supportedLDAPVersion'); + $this->node($caps, 'supportedExtension'); + $this->getAttributesMock = $caps; + } + + public function testUsePageControlWhenAnnounced() + { + if (version_compare(PHP_VERSION, '5.4.0') < 0) { + $this->markTestSkipped('Page control needs at least PHP_VERSION 5.4.0'); + } + + $this->addEntry($this->getAttributesMock, 'supportedControl', Capability::LDAP_PAGED_RESULT_OID_STRING); + $this->connectionFetchAll(); + + // see ticket #7993 + $this->assertEquals(true, $this->pagedResultsCalled, "Use paged result when capability is present."); + } + + public function testDontUsePagecontrolWhenNotAnnounced() + { + if (version_compare(PHP_VERSION, '5.4.0') < 0) { + $this->markTestSkipped('Page control needs at least PHP_VERSION 5.4.0'); + } + $this->connectionFetchAll(); + + // see ticket #8490 + $this->assertEquals(false, $this->pagedResultsCalled, "Don't use paged result when capability is not announced."); + } + + public function testUseLdapV2WhenAnnounced() + { + // TODO: Test turned off, see other TODO in Ldap/Connection. + $this->markTestSkipped('LdapV2 currently turned off.'); + + $this->addEntry($this->getAttributesMock, 'supportedLDAPVersion', 2); + $this->connectionFetchAll(); + + $this->assertArrayHasKey(LDAP_OPT_PROTOCOL_VERSION, $this->activatedOptions, "LDAP version must be set"); + $this->assertEquals($this->activatedOptions[LDAP_OPT_PROTOCOL_VERSION], 2); + } + + public function testUseLdapV3WhenAnnounced() + { + $this->addEntry($this->getAttributesMock, 'supportedLDAPVersion', 3); + $this->connectionFetchAll(); + + $this->assertArrayHasKey(LDAP_OPT_PROTOCOL_VERSION, $this->activatedOptions, "LDAP version must be set"); + $this->assertEquals($this->activatedOptions[LDAP_OPT_PROTOCOL_VERSION], 3, "LDAPv3 must be active"); + } + + public function testDefaultSettings() + { + $this->connectionFetchAll(); + + $this->assertArrayHasKey(LDAP_OPT_PROTOCOL_VERSION, $this->activatedOptions, "LDAP version must be set"); + $this->assertEquals($this->activatedOptions[LDAP_OPT_PROTOCOL_VERSION], 3, "LDAPv3 must be active"); + + $this->assertArrayHasKey(LDAP_OPT_REFERRALS, $this->activatedOptions, "Following referrals must be turned off"); + $this->assertEquals($this->activatedOptions[LDAP_OPT_REFERRALS], 0, "Following referrals must be turned off"); + } + + + public function testActiveDirectoryDiscovery() + { + $this->addEntry($this->getAttributesMock, 'supportedCapabilities', Capability::LDAP_CAP_ACTIVE_DIRECTORY_OID); + $this->connectionFetchAll(); + + $this->assertEquals(true, $this->connection->getCapabilities()->hasAdOid(), + "Server with LDAP_CAP_ACTIVE_DIRECTORY_OID must be recognized as Active Directory."); + } + + public function testDefaultNamingContext() + { + $this->addEntry($this->getAttributesMock, 'defaultNamingContext', 'dn=default,dn=contex'); + $this->connectionFetchAll(); + + $this->assertEquals('dn=default,dn=contex', $this->connection->getCapabilities()->getDefaultNamingContext(), + 'Default naming context must be correctly recognized.'); + } + + public function testDefaultNamingContextFallback() + { + $this->addEntry($this->getAttributesMock, 'namingContexts', 'dn=some,dn=other,dn=context'); + $this->addEntry($this->getAttributesMock, 'namingContexts', 'dn=default,dn=context'); + $this->connectionFetchAll(); + + $this->assertEquals('dn=some,dn=other,dn=context', $this->connection->getCapabilities()->getDefaultNamingContext(), + 'If defaultNamingContext is missing, the connection must fallback to first namingContext.'); + } +}