From c7e99a2523242120a053cb6ffbc9ca8c0eabcbe5 Mon Sep 17 00:00:00 2001 From: Artem Stepin Date: Tue, 15 Dec 2020 18:16:31 +0100 Subject: [PATCH] [Ldap] Incorrect determination of RelativeDistinguishedName for the "move" operation --- .../Ldap/Adapter/ExtLdap/EntryManager.php | 6 ++-- .../Adapter/ExtLdap/EntryManagerTest.php | 30 +++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php index 8ed1b7d668be9..0e2087f63cee1 100644 --- a/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php @@ -79,7 +79,7 @@ public function addAttributeValues(Entry $entry, string $attribute, array $value $con = $this->getConnectionResource(); if (!@ldap_mod_add($con, $entry->getDn(), [$attribute => $values])) { - throw new LdapException(sprintf('Could not add values to entry "%s", attribute %s: ', $entry->getDn(), $attribute).ldap_error($con)); + throw new LdapException(sprintf('Could not add values to entry "%s", attribute "%s": ', $entry->getDn(), $attribute).ldap_error($con)); } } @@ -94,7 +94,7 @@ public function removeAttributeValues(Entry $entry, string $attribute, array $va $con = $this->getConnectionResource(); if (!@ldap_mod_del($con, $entry->getDn(), [$attribute => $values])) { - throw new LdapException(sprintf('Could not remove values from entry "%s", attribute %s: ', $entry->getDn(), $attribute).ldap_error($con)); + throw new LdapException(sprintf('Could not remove values from entry "%s", attribute "%s": ', $entry->getDn(), $attribute).ldap_error($con)); } } @@ -159,7 +159,7 @@ public function applyOperations(string $dn, iterable $operations): void private function parseRdnFromEntry(Entry $entry): string { - if (!preg_match('/^([^,]+),/', $entry->getDn(), $matches)) { + if (!preg_match('/(^[^,\\\\]*(?:\\\\.[^,\\\\]*)*),/', $entry->getDn(), $matches)) { throw new LdapException(sprintf('Entry "%s" malformed, could not parse RDN.', $entry->getDn())); } diff --git a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/EntryManagerTest.php b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/EntryManagerTest.php index a4aed634f5ea0..d571c10ce0b1e 100644 --- a/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/EntryManagerTest.php +++ b/src/Symfony/Component/Ldap/Tests/Adapter/ExtLdap/EntryManagerTest.php @@ -44,4 +44,34 @@ public function testGetResources() $entryManager = new EntryManager($connection); $entryManager->update($entry); } + + /** + * @see https://tools.ietf.org/html/rfc4514#section-3 + * + * @dataProvider moveWithRFC4514DistinguishedNameProvider + */ + public function testMoveWithRFC4514DistinguishedName(string $dn, string $expectedRdn) + { + $connection = $this->createMock(Connection::class); + + $entry = new Entry($dn); + $entryManager = new EntryManager($connection); + + $method = (new \ReflectionClass(EntryManager::class))->getMethod('parseRdnFromEntry'); + $method->setAccessible(true); + + $cn = $method->invokeArgs($entryManager, [$entry, 'a']); + + $this->assertSame($expectedRdn, $cn); + } + + public function moveWithRFC4514DistinguishedNameProvider(): array + { + return [ + ['CN=Simple,DC=example,DC=net', 'CN=Simple'], + ['CN=James \"Jim\" Smith\, III,DC=example,DC=net', 'CN=James \"Jim\" Smith\, III'], + ['UID=jsmith,DC=example,DC=net', 'UID=jsmith'], + ["CN=Before\0dAfter,DC=example,DC=net", "CN=Before\0dAfter"], + ]; + } }