bug #39518 [Ldap] Incorrect determination of RelativeDistinguishedName for the "move" operation (astepin)

This PR was squashed before being merged into the 4.4 branch.

Discussion
----------

[Ldap] Incorrect determination of RelativeDistinguishedName for the "move" operation

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | -
| License       | MIT
| Doc PR        | -

If the specified "DistinguishedName" contains a comma in the first value, the first "RelativeDistinguishedName" was determined incorrectly.
The regular expression now matches up to the first comma which was not escaped with backslash.

Testing private methods is a bit messy here. However, I thought it was better than testing this against an LDAP server.

Source: https://tools.ietf.org/html/rfc4514#section-3

Commits
-------

c7e99a2523 [Ldap] Incorrect determination of RelativeDistinguishedName for the "move" operation
This commit is contained in:
Jérémy Derussé 2020-12-17 12:39:59 +01:00
commit a316a3103d
No known key found for this signature in database
GPG Key ID: 2083FA5758C473D2
2 changed files with 33 additions and 3 deletions

View File

@ -79,7 +79,7 @@ class EntryManager implements EntryManagerInterface
$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 @@ class EntryManager implements EntryManagerInterface
$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 @@ class EntryManager implements EntryManagerInterface
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()));
}

View File

@ -44,4 +44,34 @@ class EntryManagerTest extends TestCase
$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"],
];
}
}