Как переместить запись eDirectory через php?

У меня есть эта запись ldap:

cn=blah,ou=apples,ou=people,dc=yay,dc=edu

Мне нужно переместить эту запись в:

cn=blah,ou=oranges,ou=people,dc=yay,dc=edu

Все мои скрипты PHP, поэтому я пытался использовать php.net/ldap_rename

ldap_rename($connection, "cn=blah,ou=apples,ou=people,dc=yay,dc=edu", "cn=blah", "ou=oranges,ou=people,dc=yay,dc=edu", true);

Не работает. Возвращает ложь.

В этом http://us2.php.net/manual/en/function.ldap-rename.php комментарии упоминается, что eDirectory хочет оставить родителя как NULL. Подобно:

ldap_rename($connection, "cn=blah,ou=apples,ou=people,dc=yay,dc=edu", "cn=blah", NULL, true);

Это возвращает TRUE, но фактически не перемещает запись. Не удивительно, поскольку это не меняет родителя... Я уверен, что это может изменить cn=blah на что-то другое...

Я думал об удалении записи и воссоздании ее. Но это болезненный способ сделать это. Написание и запуск файла LDIF также будет болезненным.

Итак, как мне переместить запись из одного подразделения в другое, в php, без боли двух других моих вариантов?

Что я бегу:

  • Ubuntu 12.04 LTS
  • PHP 5.3.10
  • eDirectory 8.8 находится на SLES 11

редактировать

Итак, я нашел это:

Тип изменения modrdn не может переместить запись в совершенно другое поддерево. Чтобы переместить запись в совершенно другую ветвь, вы должны создать новую запись в альтернативном поддереве, используя атрибуты старой записи, а затем удалить старую запись.

От http://www.centos.org/docs/5/html/CDS/ag/8.0/Creating_Directory_Entries-LDIF_Update_Statements.html

Я нашел пару других страниц с похожими утверждениями.

Похоже, мне нужно сделать новую запись, скопировать атрибуты, удалить старую. Как и второй болезненный вариант, который я упоминал выше.

3 ответа

Решение

Ну, в итоге я использовал метод "создать новую запись, удалить старую". Я все еще думаю, что у меня был другой способ работать некоторое время назад, но я не могу вспомнить, что. Итак, вот основная функция перемещения.

function move($connection, $ldapEntryReference, $new_dn){        
    //First, get the values of the current attributes.
    $attributes = array(); //start attributes array
    $firstattr = ldap_first_attribute($connection, $ldapEntryReference);
    $value = ldap_get_values($connection, $ldapEntryReference, $firstattr);
    $attributes[$firstattr] = $value;
    while($attr = ldap_next_attribute($connection, $ldapEntryReference)) {
        if (strcasecmp($attr, 'ACL') !== 0) { //We don't want ACL attributes since 
                                              //eDir/ldap should deal with them for us.
            if (strcasecmp($attr, 'jpegPhoto') === 0) {
                //binary values need to use the ldap_get_values_len function.
                $value = ldap_get_values_len($this->connection, $ldapEntryReference, $attr);
            } else {
                $value = ldap_get_values($this->connection, $ldapEntryReference, $attr);
            }
            $attributes[$attr] = $value;
        }
    }
    //Create a new entry array with the values.
    $entry = array(); //start entry array.
    foreach($attributes as $key => $value) {
        foreach($value as $key2 => $value2) {
            if (strcasecmp($key2, 'count') !== 0) {//get rid of 'count' indexes
                                                   //ldap_add chokes on them.
                $entry[$key][$key2] = $value2;
            }
        }
    }
    //Add the new entry.
    if (ldap_add($connection, $new_dn, $entry)) {
        //Delete the old entry.
        if (ldap_delete($connection, ldap_get_dn($connection, $ldapEntryReference)) {
            return true;
        } else {
            return false;
        }
    } else {
        return false; 
    }
}

Надеюсь, это когда-нибудь поможет.

Попробуй это:

ldap_rename($ldapconn, "cn=blah,ou=apples,ou=people,dc=yay,dc=edu", "cn=blah", "ou=oranges,ou=people,dc=yay,dc=edu", true);

На самом деле нет необходимости воссоздавать в eDir. Выполнение воссоздания вызывает проблемы в среде, в которой IDM запускается, поскольку у объекта будет новый GUID, и механизм IDM не увидит событие как истинное "движение".

Следующий код хорошо перемещает пользователей (протестировано eDir 8.8.x и eDir 9.x):

$olduserdn = "cn=userid,ou=container1,o=org";
$newdestdn = "ou=container2,o=org";
if (preg_match('/^(cn=[A-Za-z0-9]+)\,(.+)/i', $olduserdn, $rdnmatches))
{
    if (ldap_rename($ldapconn, $olduserdn, $rdnmatches[1], $newdestdn, TRUE))
    {
        print("Moved $olduserdn to $rdnmatches[1],$newdestdn");
    }
    else
    {
        print("Failed move because " . ldap_error($ldapconn));
    }
}

Не забудьте уделить немного времени репликации...

Также рассмотрите ограничения вокруг изменения / перемещения объектов, которые все еще копируются из предыдущего события перемещения.

Другие вопросы по тегам