diff --git a/lam/lib/import.inc b/lam/lib/import.inc index ed474d01..27674fbb 100644 --- a/lam/lib/import.inc +++ b/lam/lib/import.inc @@ -275,6 +275,9 @@ class Importer { } return new AddEntryTask($dn, $attributes); } + elseif ($type === 'modrdn') { + return $this->createModRdnTask($dn, $entry); + } $changes = array(); $subtasks = array(); $currentLines = array(); @@ -298,6 +301,31 @@ class Importer { } } + /** + * Returns a modrdn task. + * + * @param string $dn DN + * @param string[] $entry entry lines + * @return + * @throws LAMException syntax error + */ + private function createModRdnTask($dn, $entry) { + if (sizeof($entry) !== 2) { + throw new LAMException(_('Invalid data'), htmlspecialchars($dn)); + } + $newRdnData = $this->getLineKeyValue($entry[0]); + if ($newRdnData[Importer::KEY] !== 'newrdn') { + throw new LAMException(_('Invalid data'), htmlspecialchars($dn) . '
' . $newRdnData); + } + $newRdn = $newRdnData[Importer::VALUE]; + $delOldRdnData = $this->getLineKeyValue($entry[1]); + if (($delOldRdnData[Importer::KEY] !== 'deleteoldrdn') || !in_array($delOldRdnData[Importer::VALUE], array('0', '1'), true)) { + throw new LAMException(_('Invalid data'), htmlspecialchars($dn) . '
' . $delOldRdnData); + } + $delOldRdn = ($delOldRdnData[Importer::VALUE] === '0') ? false : true; + return new RenameEntryTask($dn, $newRdn, $delOldRdn); + } + /** * Returns a task for LDIF changeType entry. * @@ -410,6 +438,45 @@ class AddEntryTask implements ImporterTask { } +/** + * Renames an LDAP entry. + * + * @author Roland Gruber + */ +class RenameEntryTask implements ImporterTask { + + private $dn = ''; + private $newRdn = ''; + private $deleteOldRdn = true; + + /** + * Constructor + * + * @param string $dn DN + * @param string $newRdn new RDN value + * @param bool $deleteOldRdn delete old RDN value + */ + public function __construct($dn, $newRdn, $deleteOldRdn) { + $this->dn = $dn; + $this->newRdn = $newRdn; + $this->deleteOldRdn = $deleteOldRdn; + } + + /** + * {@inheritDoc} + * @see \LAM\TOOLS\IMPORT_EXPORT\ImporterTask::run() + */ + public function run() { + $ldap = $_SESSION['ldap']->server(); + $success = @ldap_rename($ldap, $this->dn, $this->newRdn, null, $this->deleteOldRdn); + if ($success) { + return Importer::formatMessage('INFO', _('Rename successful!'), htmlspecialchars($this->dn)); + } + throw new LAMException(_('Could not rename the entry.') . '
' . $this->dn, getExtendedLDAPErrorMessage($ldap)); + } + +} + /** * Combines multiple import tasks. * diff --git a/lam/tests/lib/importTest.php b/lam/tests/lib/importTest.php index 3c8caf62..a8cfdc74 100644 --- a/lam/tests/lib/importTest.php +++ b/lam/tests/lib/importTest.php @@ -3,6 +3,7 @@ use \LAM\TOOLS\IMPORT_EXPORT\Importer; use LAM\TOOLS\IMPORT_EXPORT\MultiTask; use LAM\TOOLS\IMPORT_EXPORT\AddAttributesTask; use LAM\TOOLS\IMPORT_EXPORT\AddEntryTask; +use LAM\TOOLS\IMPORT_EXPORT\RenameEntryTask; /* This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) @@ -162,4 +163,61 @@ class ImporterTest extends PHPUnit_Framework_TestCase { $this->assertEquals(AddEntryTask::class, get_class($task)); } + /** + * Change entry with modrdn changetype and invalid options. + */ + public function testChangeModRdnInvalidData() { + $lines = array( + "version: 1", + "", + "dn: uid=test,dc=example,dc=com", + "changeType: modrdn", + "uid: test", + ); + + $this->setExpectedException(LAMException::class, 'uid=test,dc=example,dc=com'); + + $importer = new Importer(); + $tasks = $importer->getTasks($lines); + } + + /** + * Change entry with modrdn changetype and invalid deleteoldrdn. + */ + public function testChangeModRdnInvalidDeleteoldrdn() { + $lines = array( + "version: 1", + "", + "dn: uid=test,dc=example,dc=com", + "changeType: modrdn", + "newrdn: uid1=test", + "deleteoldrdn: x", + ); + + $this->setExpectedException(LAMException::class, 'uid=test,dc=example,dc=com'); + + $importer = new Importer(); + $tasks = $importer->getTasks($lines); + } + + /** + * Change entry with modrdn changetype. + */ + public function testChangeModRdn() { + $lines = array( + "version: 1", + "", + "dn: uid=test,dc=example,dc=com", + "changeType: modrdn", + "newrdn: uid1=test", + "deleteoldrdn: 0", + ); + + $importer = new Importer(); + $tasks = $importer->getTasks($lines); + $this->assertEquals(1, sizeof($tasks)); + $task = $tasks[0]; + $this->assertEquals(RenameEntryTask::class, get_class($task)); + } + }