Исторически OpenLDAP настраивался статически, то есть, чтобы произвести изменение, нужно было править конфигурационный файл slapd.conf, а затем останавливать и запускать slapd. При увеличении количества записей в каталоге перезапуск будет занимать всё более продолжительное время, и, в случае высоконагруженных каталогов, такой метод переконфигурации становится всё более неприемлемым. В OpenLDAP версии 2.3 была представлена опциональная новая возможность, посредством которой конфигурация может быть произведена во время исполнения с помощью модификации записей специального DIT, называемого cn=config. У данной возможности несколько разных имён (что создаёт некоторую путаницу), в том числе: конфигурация времени исполнения (on-line configuration, OLC) (наше любимое), конфигурация с нулевым временем простоя (zero down-time configuration), cn=config и slapd.d. Для начала, несколько тезисов:
В настоящий момент (OpenLDAP версии 2.4) данная возможность всё ещё остаётся опциональной. Это означает, что конфигурация с помощью slapd.conf, хотя формально и считается устаревшей, продолжает работать несмотря на то, что многие дистрибутивы *nix сделали OLC конфигурацией по умолчанию при инсталляции.
Исторически сложилось так, что OpenLDAP может резко и неожиданно прекращать поддержку своих старых функций. Это значит, что переход на конфигурацию времени исполнения (OLC) нужно произвести, по возможности, в кратчайшие сроки. Лучше произвести это в спокойных условиях, когда Вам не требуется переходить на новый релиз, чем, экстренно перейдя на новый релиз из-за критической ошибки, Вы будете вынуждены переходить на новый метод конфигурации в авральном режиме.
Для управления настройками рабочей среды в конфигурации времени исполнения (OLC) используется конфигурационное DIT с жёстко установленным суффиксом cn=config. Концептуально, модификация записей в этом DIT (с помощью LDAP-браузера или файлов LDIF) приводит к немедленному изменению поведения рабочей среды slapd без необходимости перезапуска slapd (как это приходилось делать после изменения slapd.conf).
Для создания DIT cn=config (OLC) можно ЛИБО создать серию файлов LDIF, описывающих конфигурацию, и применить их с помощью slapadd, ЛИБО переконвертировать Ваш существующий файл slapd.conf. Если Вы мазохист — мы рекомендуем использовать первый подход. Если же Вы нормальный человек — переконвертируйте slapd.conf так, как описано ниже. Переконвертация — это процесс, который выполняется один раз (кроме того, существует возможность отката назад). После того, как Вы переконвертировали файл slapd.conf, он больше не требуется. Во время загрузки slapd ищет конфигурационную директорию (по умолчанию slapd.d), считывает оттуда LDIF-файлы и инициализирует DIT cn=config (OLC). Если директория slapd.d не найдена, slapd ищет файл slapd.conf.
Чтобы перейти от slapd.conf к конфигурации времени исполнения (cn=config), выполните следующие действия:
Убедитесь в том, что конфигурационный файл slapd.conf является рабочим и отражает необходимую функциональность. Это делается в качестве меры предосторожности. Подразумевается, что Вы разбираетесь в текущей версии конфигурации, основанной на slapd.conf. Последнее, что неплохо бы сделать до перехода, — это внедрить те новые функции, которые Вам могут понадобиться, и сразу же их испробовать. Пускай это несколько замедлит процесс перехода, зато Вы приобретёте необходимые новые знания и опыт в спокойной обстановке.
Остановите LDAP-сервер.
Отредактируйте файл slapd.conf, добавив в него следующие строки:
# Перед первым определением database database config # ПРИМЕЧАНИЕ: суффикс жёстко определён как cn=config # и директивы suffix НЕ ДОЛЖНО быть # применяются стандартные правила - rootdn может быть любым DN # но ДОЛЖЕН быть определён в разделе cn=config rootdn "cn=admin,cn=config" # Используйте любой поддерживаемый формат пароля, такой как {SSHA} и т.п. # или оставьте пароль в открытом виде, как показано rootpw config
Существует много материалов, описывающих тонкости подготовки конвертации в slapd.d (cn=config); по большому счёту, всё что в них написано — правда. Однако, для того, чтобы просто использовать функцию cn=config (читать, добавлять и изменять атрибуты) с помощью, скажем, LDAP-браузера, необходимо и достаточно лишь добавить те строки, которые приведены выше.
Переконвертируйте текущий файл slapd.conf в конфигурацию времени исполнения (OLC, cn=config), выполнив следующие команды:
# Будем использовать slaptest (наиболее разумный способ), # однако конвертацию может выполнить любая утилита, # поддерживающая аргументы -f file и -F dir, # например, slapcat, slapadd и другие. # Останавливаем slapd [fc]/etc/rc.d/init.d/slapd stop # ИЛИ вручную killall slapd # ИЛИ [bsd]/usr/local/etc/rc.d/slapd.sh stop [fc]cd /etc/openldap [bsd]cd /usr/local/etc/openldap # ОБЯЗАТЕЛЬНО - создаём стандартную директорию по умолчанию mkdir slapd.d # Конвертируем slapd.conf slaptest -f slapd.conf -F slapd.d # В зависимости от того, под каким пользователем Вы выполняли slaptest # может потребоваться изменить владельца slapd.d и всех файлов внутри chown -R ldap:ldap slapd.d # Как ни странно, минимальный уровень прав должен быть, судя по всему, # не меньше 0750 chmod -R 0750 slapd.d # Переименовываем slapd.conf # Данный шаг не строго обязателен, но полезен # чтобы убедиться, что используется именно slapd.d mv slapd.conf slapd.conf.bak # Запускаем slapd [fc]/etc/rc.d/init.d/slapd start # ИЛИ вручную slapd -u ldap -g ldap # Пользователям [bsd] нужно добавить # slapd_cn_config="YES" в /etc/rc.conf # Если slapd не загрузился, используем slapd -d -1 -u ldap -g ldap # и смотрим отладочные сообщения
Примечания:
Нет строгой необходимости переименовывать файл slapd.conf после переконвертации с помощью slaptest, но это даёт уверенность в том, что мы будем использовать именно cn=config, а не переходить по умолчанию на использование slapd.conf в случае возникновения ошибок при загрузке. Недостатком такого переименования можно считать то, что некоторые стандартные скрипты запуска могут подразумевать присутствие именно файла slapd.conf. Так было со скриптом запуска на нашей FreeBSD (/usr/local/etc/rc.d/slapd.sh) — он аварийно завершал работу, поскольку считал, что файл slapd.conf должен присутствовать. Мы закомментировали строку required_files и строку изменения владельца (chown) slapd.conf в скрипте, и снова воцарился мир и покой.
Будьте осторожны: Вы можете сконфигурировать OLC (cn=config) так, что он придёт в нерабочее состояние. Мы поменяли rootdn базы данных cn=config с помощью LDAP-браузера с cn=config на cn=admin — неверное изменение, поскольку все элементы конфигурационной базы данных должны заканчиваться (иметь своим корнем) cn=config. Однако, данное изменение было принято. Соединение было немедленно разорвано (как и должно было быть), но мы не смогли вновь подсоединиться ни под каким значением — ни старым, ни новым. Мы остановили и попытались запустить slapd, что тоже закончилось неудачей, поскольку slapd отказался загружаться с нашим новым модифицированным rootdn (cn=admin). Единственным решением стало редактирование slapd.d/cn=config/olcDatabase={0}config.ldif и восстановление атрибута olcRootDn в cn=config. Затем мы загрузили slapd, с помощью LDAP-браузера изменили атрибут olcRootDn на cn=admin,cn=config и всё работало прекрасно.
rootDn базы данных cn=config может быть любая запись, но она ДОЛЖНА иметь своим корнем cn=config. Например, cn=manager,cn=config будет работать, а cn=manager,cn=admin будет принята, но не даст получить доступ к cn=config и, вследствие этого, slapd не будет загружаться.
Почти переход: Если Вам хочется посмотреть, что из себя представляет будущее, но морально Вы еще не готовы к переходу, либо Вам просто хочется поэкспериментировать, можете отредактировать slapd.conf как показано выше в шаге 3 (добавить то, что касается database config), а затем, не выполняя переконвертации, показанной в шаге 4, просто загрузите slapd. Вы сможете подключиться к cn=config и изменять атрибуты во время исполнения, однако, когда Вы остановите и вновь запустите slapd, все ваши изменения потеряются. Мы ведь говорили, что это почти переход.
Если Вы любознательны, стоит просмотреть файлы и директории, созданные в директории slapd.d после конвертации. Возможно, однажды Вам придётся их восстанавливать или ремонтировать.
Для доступа к возможностям OLC (cn=config) из LDAP-браузера настройте его соответствующим образом (подразумевается, что Вы использовали приведённые выше настройки, в противном случае — измените на свои):
# Используются нормальные установки порта и имени хоста # Значения для LDAPBrowser/Editor BaseDN cn=config BindDN cn=admin,cn=config password config # либо можно использовать ldapsearch ldapsearch -w config -x -D cn=admin,cn=config -b cn=config
Если всё пошло не так, либо Вы хотите вернуться к старомодной(!) конфигурации slapd.conf (Вы увидели будущее, но оно Вас пока не устроило), есть возможность всё вернуть:
# Останавливаем slapd killall slapd # ИЛИ [fc]/etc/rc.d/init.d/slapd stop [fc]cd /etc/openldap [bsd]cd /usr/local/etc/openldap # Удаляем директорию slapd.d rm -r slapd.d # Если Вы переименовывали slapd.conf, как было # показано в процедуре переконвертации выше, # необходимо вновь назвать его slapd.conf # Закомментируйте наши строки database config # в slapd.conf # Теперь перезапустим slapd [fc]/etc/rc.d/init.d/slapd start # ИЛИ вручную slapd -u ldap -g ldap
Когда Вы почувствуете себя готовыми и захотите попробовать снова, просто повторите процесс конвертации. Его можно повторять сколько угодно раз. Примечание: Если Вы изменяли конфигурацию в режиме OLC (cn=config), удаление директории slapd.d (как показано выше) приведёт к потере всех изменений. В зависимости от того, какие изменения Вы проводили, например, изменения индексов в режиме cn=config, возможно, при возврате к slapd.conf придётся выполнять некоторые действия по восстановлению каталога. В целом, пока Вы не решились на окончательный переход, лучше ограничить свои эксперименты с возможностями OLC (cn=config).
Расположение элементов OLC (cn=config) DIT:
Примечания:
Корневая запись cn=config (1) основывается на объектном классе olcGlobal и содержит глобальные атрибуты, влияющие на работу slapd. После первоначального переконвертирования она содержит все глобальные директивы из файла slapd.conf (а также экзотический набор значений по умолчанию для тех директив, которых не было в файле), за исключением подключённых наборов схемы данных (смотрите ниже cn=schema) и динамически загружаемых модулей (смотрите cn=module{0}). Полный список атрибутов olcGlobal смотрите здесь.
Запись cn=module{Z},cn=config (2) основывается на объектном классе olcModuleList и содержит список всех динамически загружаемых объектов и путей к ним. После первоначального переконвертирования она содержит элементы, определенные в директивах moduleload и modulepath файла slapd.conf. Полный список атрибутов olcModuleList смотрите здесь. Если OpenLDAP собран со статическими наложениями, эта запись не нужна. Добавление/удаление модулей в OLC (cn=config) описано здесь.
Запись cn=schema,cn=config (3) использует объектный класс olcSchemaConfig и содержит все объекты, используемые системой cn=config. Полный список атрибутов olcSchemaConfig смотрите здесь. Примечание: Атрибуты и объектные классы определяются с помощью атрибутов olcAttributeTypes и olcObjectClasses соответственно. Каждая дочерняя запись определяет подключаемый набор схемы данных.
Дочерние записи cn={Z}xxx,cn=schema,cn=config (4) используют объектный класс olcSchemaConfig и содержат все объекты (атрибуты и объектные классы), определённые в данном наборе схемы. Здесь {Z} — числовой счётчик, нумерация которого начинается с 0, а xxxx — имя набора схемы данных. То есть, если первым подключается набор схемы core.schema, то данное значение будет {0}core. Полный список атрибутов olcSchemaConfig смотрите здесь. Примечание: При загрузке в cn=config определённые в наборе схемы данных атрибуты трансформируются из attributetype (как они определены в файле набора схемы) в атрибуты olcAttributeTypes, а объектные классы — из objectclass (как они определены в файле набора схемы) в атрибуты olcObjectClasses. Процедуры добавления/удаление наборов схемы данных в OLC (cn=config) описаны здесь.
Запись olcDatabase={Z}xxx,cn=config (5) использует объектный класс olcDatabaseConfig (содержащий общие атрибуты, определяемые для всех типов баз данных), а также объектный класс, специфичный для конкретного типа базы данных. Здесь {Z} — числовой счётчик, нумерация которого начинается с 0, а xxxx — имя типа базы данных. То есть, если первой определяется база данных типа bdb, то данное значение будет {0}bdb, и эта запись будет строиться на объектном классе olcBdbConfig, содержащем атрибуты, специфичные для этого типа баз данных. Полный список атрибутов olcDatabaseConfig смотрите здесь. Полный список атрибутов olcBdbConfig смотрите здесь. Могут присутствовать дочерние записи для каждого наложения, используемого этой базой данных (описание смотрите ниже). Процедуры добавления/удаление баз данных в OLC (cn=config) описаны здесь.
Примечание по поводу записи olcDatabase={-1}frontend,cn=config: Данная запись присутствует всегда, выглядит ужасно и содержит специфические атрибуты из объектного класса olcFrontendConfig, определяющие глобальные установки или свойства.
Запись olcOverlay={Z}xxx,olcDatabase={Z}xxx,cn=config (6) использует объектный класс olcOverlayConfig, содержащий общие атрибуты, определяемые для всех наложений, а также объектный класс, специфичный для конкретного наложения. Здесь {Z} — числовой счётчик, нумерация которого начинается с 0, а xxx — имя наложения. То есть, если первым из наложений определяется наложение syncprov, то данное значение будет {0}syncprov, и эта запись будет строиться на объектном классе olcSyncProvConfig, содержащем атрибуты, специфичные для этого наложения. Точно также, другие наложения будут использовать специфичные для них объектные классы, содержащие их уникальные атрибуты. Полный список атрибутов olcOverlayConfig смотрите здесь. Полный список атрибутов olcSyncProvConfig смотрите здесь. Процедуры добавления/удаление наложений в OLC (cn=config) описаны здесь.
DIT cn=config можно прочитать с помощью стандартных инструментов командной строки LDAP, таких как ldapsearch, и изменять с помощью ldapadd или ldapmodify, что, по нашему скромному мнению, в наибольшей степени соответствует концепции конфигурации времени исполнения (OLC). Альтернативный метод — использовать LDAP-браузер для интерактивного чтения и записи атрибутов и записей данного DIT. О том, как получить доступ к cn=config из LDAPBrowser/Editor, читайте здесь.
Следующие замечания могут оказаться полезными (или нет) при использовании OLC (cn=config):
В конфигурации OLC (cn-config) в значениях атрибутов широко используется синтаксис {X}value (в описании этих атрибутов есть элемент X-ORDERED). С помощью данного синтаксиса создаётся представление упорядоченного множества атрибутов. Примеры: при наличии нескольких наборов схемы данных в cn=schema,cn=config они будут иметь значения cn={Z}xxxx,cn=schema,cn=config, где Z — порядковый номер, начинающийся с 0, а xxxx — уникальное имя набора схемы. При наличии нескольких ACP/ACL в разделе глобальных настроек (cn=config) или в разделе database (olcDatabase={Z}yyyy,cn=config — в данном случае Z будет иметь то же значение, что и выше, а yyyy будет типом базы данных) каждый ACP/ACL будет определяться атрибутом olcAccess и иметь формат {Z}to ...... В большинстве случаев (но не во всех) действует следующий принцип редактирования: если при добавлении атрибута указывается значение в фигурных скобках, то атрибут будет добавлен в позицию, определённую этим значением, а все последующие (смещаемые) атрибуты будут по мере необходимости перенумерованы для поддержания упорядоченного множества. Если число в фигурных скобках не используется, то атрибут будет добавлен в конец упорядоченного множества атрибутов и в начало значения этого атрибута будет добавлен следующий порядковый номер в фигурных скобках. Это очень полезное правило, здорово упрощающее вставку и удаление атрибутов/записей.
Напомним, что OLC (cn=config) по своей природе оперирует с живыми данными. Изменения системы производятся во время того, как пользователи осуществляют к ней доступ. Предположим, выполняется изменение из двух этапов, скажем (исключительно для иллюстрации), удаления одного атрибута и модификация другого, в результате чего будет введён новый режим с высокой степенью безопасности. В какой-то очень или не очень небольшой (в зависимости от природы изменения) период будет применено только первое изменение. Пользователи же, однако, будут продолжать пользоваться системой. Очень важно учитывать состояние системы после каждого изменения, так как, в течение этого переходного периода, они могут привести к непреднамеренному воздействию на данные или к другим не менее ужасным последствиям. Вспомните закон Мерфи, закон непредвиденных последствий и все остальные законы техногенных катастроф: стоит только зазеваться, и ... Вполне возможно, что для преодоления такой проблемы "временного статуса" подобные двухэтапные изменения потребуется произвести в три, четыре, а то и более этапов.
По состоянию на OpenLDAP версии 2.4.31, невозможно удалить какую-либо запись (удаления атрибутов в основном допускаются) в OLC (cn=config) с помощью нормальных процедур LDAP, таких как ldapdelete или используя LDAP-браузер. В некоторых случаях, таких как записи наборов схемы данных, это ограничение, похоже, будет присутствовать постоянно, в других — (по слухам) такое положение может измениться. Во всех случаях такие записи могут быть удалены либо путём возврата к файлу slapd.conf, внесения соответствующих изменений и повторного переконвертирования данного файла, либо путём прямого редактирования определений slapd.d (как правило, лучше не пробовать так делать, если Вы не эксперт, однако для искателей приключений процесс описан ниже). В целом, в связи с существующими ныне формальными ограничениями на удаление, имеет смысл: (a) перед переконвертацией файла slapd.conf убедиться, что он находится в хорошей форме, (b) перед окончательным переходом к OLC (cn=config) поэкспериментировать с описанным выше процессом почти перехода, (c) молиться своим богам, и почаще.
Примечание: При первоначальном переходе к использованию OLC (cn=config), когда производится описанный выше процесс переконвертации, все подключенные наборы схемы данных преобразуются автоматически. Приводимый ниже процесс требуется только при добавлении нового файла набора схемы к существующей конфигурации OLC (cn=config).
При использовании с OLC (cn=config) стандартные наборы схемы данных LDAP должны быть преобразованы в формат LDIF. Получившийся в результате файл LDIF затем импортируется с помощью ldapadd или подходящего LDAP-браузера. Преобразование из формата schema может быть выполнено вручную (если файл невелик), либо с помощью утилиты slaptest с парой ручных правок, что является самым быстрым способом для больших файлов. Оба метода будут продемонстрированы ниже на примере тривиального файла набора схемы с одним атрибутом и одним объектным классом, выбранного исключительно в целях иллюстрации процесса (этот файл представляет собой отредактированную версию стандартного файла java.schema, так что если Вы уже используете данный набор схемы и попробуете добавить получившийся в примере LDIF, это приведёт к ошибке, поскольку такие объекты уже будут существовать — в этом случае попробуйте поэкспериментировать с другим файлом). Даже если у Вас большой файл, будет полезно почитать раздел о ручном преобразовании, если Вы хотите глубже понимать данный процесс.
Исторически все файлы наборов схемы данных для OpenLDAP выпускались в классическом текстовом формате с расширением файла .schema, например, core.schema. В современных дистрибутивах файлы для каждого набора схемы данных предоставляются как в классическом формате, так и в формате LDIF. Последние могут быть напрямую добавлены в конфигурацию cn=config с помощью такой команды:
ldapadd -H ldap-url -x -W -D cn=config-bind-dn -f /path-to-schema-ldif
Внимание: После того, как Вы добавили набор схемы, Вы не можете удалить его иначе как используя специальный и потенциально опасный процесс ручного удаления. Начиная с версии 2.4 Вы можете модифицировать существующие определения атрибутов и объектных классов в установленных или добавленных наборах схемы данных.
Целевой файл набора схемы, который будет добавляться в данном примере (test.schema):
# модифицированный файл java.schema - Java Object Schema - используется только для примера # Copyright Notice # # Copyright (C) The Internet Society (1999). All Rights Reserved. # # Определение атрибута attributetype ( 1.3.6.1.4.1.42.2.27.4.1.6 NAME 'javaClassName' DESC 'Fully qualified name of distinguished Java class or interface' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) # Определение объектного класса objectclass ( 1.3.6.1.4.1.42.2.27.4.2.1 NAME 'javaContainer' DESC 'Container for a Java object' SUP top STRUCTURAL MUST cn )
Этот файл будет отредактирован вручную, в результате чего будет создан файл LDIF для добавления записи, содержащей оба определения атрибута и объектного класса из набора схемы. Подобные записи наборов схемы размещаются в ветке cn=schema,cn=config. Мы решили использовать cn=test в качестве уникального имени данного набора схемы (для реального набора схемы, очевидно, нужно подобрать более описательное имя). Исходя из этого предположения, мы будем загружать новый набор схемы как dn: cn=test,cn=schema,cn=config. Для добавления набора схемы применяется объектный класс olcSchemaConfig (не имеющий, как ни странно, обязательных (MUST) атрибутов, хотя необходимость определения атрибута cn, по существу, делает его обязательным), использующий атрибуты olcAttributeTypes (заменяющий attributetype) и olcObjectClasses (заменяющий objectclass) для добавления соответствующих определений объектов. Получившийся в результате файл сохраним как test.ldif или под каким-нибудь более подходящим именем.
После ручного редактирования файл выглядит так:
# отредактированный вручную файл # красные строки были добавлены, зелёные - изменены # в начале и в конце каждой строки определений olcAttributeTypes и # olcObjectClasses должно быть по одному пробельному символу dn: cn=test,cn=schema,cn=config objectClass: olcSchemaConfig cn: test olcAttributeTypes: ( 1.3.6.1.4.1.42.2.27.4.1.6 NAME 'javaClassName' DESC 'Fully qualified name of distinguished Java class or interface' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) olcObjectClasses: ( 1.3.6.1.4.1.42.2.27.4.2.1 NAME 'javaContainer' DESC 'Container for a Java object' SUP top STRUCTURAL MUST cn )
Для добавления файла test.ldif (или как Вы его назвали) в OLC (cn=config) используйте LDAP-браузер или ldapadd.
Исходный файл набора схемы данных в точности тот же, что мы использовали для примера с ручным преобразованием:
# модифицированный файл java.schema - Java Object Schema - используется только для примера # Copyright Notice # # Copyright (C) The Internet Society (1999). All Rights Reserved. # # Определение атрибута attributetype ( 1.3.6.1.4.1.42.2.27.4.1.6 NAME 'javaClassName' DESC 'Fully qualified name of distinguished Java class or interface' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) # Определение объектного класса objectclass ( 1.3.6.1.4.1.42.2.27.4.2.1 NAME 'javaContainer' DESC 'Container for a Java object' SUP top STRUCTURAL MUST cn )
Теперь нам нужно выбрать подходящее место и создать пустой файл slapd.conf с подключением нашего набора схемы test.schema. Пустой файл (назовём его test.conf или что-то в этом роде) выглядит так:
include /path/to/test.schema
В этот файл можно добавить сразу несколько подключений файлов наборов схемы — каждое из них создаст отдельный файл ldif. Теперь создадим директорию (testdir) и запустим slaptest для преобразования нашего test.conf в эту директорию:
# создаём директорию mkdir testdir # запускаем slaptest slaptest -f test.conf -F testdir
В результате получится файл testdir/cn=config/cn=schema/cn={0}test.ldif, содержащий следующее:
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify. # CRC32 ed5d248b dn: cn={0}test objectClass: olcSchemaConfig cn: {0}test olcAttributeTypes: {0}( 1.3.6.1.4.1.42.2.27.4.1.6 NAME 'javaClassName' DESC 'F ully qualified name of distinguished Java class or interface' EQUALITY caseEx actMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) olcObjectClasses: {0}( 1.3.6.1.4.1.42.2.27.4.2.1 NAME 'javaContainer' DESC 'Co ntainer for a Java object' SUP top STRUCTURAL MUST cn ) structuralObjectClass: olcSchemaConfig entryUUID: 1cf25098-2f16-1031-9bb3-07590c97897d creatorsName: cn=config createTimestamp: 20120510180255Z entryCSN: 20120510180255.489367Z#000000#000#000000 modifiersName: cn=config modifyTimestamp: 20120510180255Z
Отредактируем данный файл как показано ниже и сохраним его, скажем, как test.ldif или как Вам больше нравится:
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify. # CRC32 ed5d248b # зелёные строки были изменены, а красные требуется удалить dn: cn=test,cn=schema,cn=config objectClass: olcSchemaConfig cn: test olcAttributeTypes: {0}( 1.3.6.1.4.1.42.2.27.4.1.6 NAME 'javaClassName' DESC 'F ully qualified name of distinguished Java class or interface' EQUALITY caseEx actMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) olcObjectClasses: {0}( 1.3.6.1.4.1.42.2.27.4.2.1 NAME 'javaContainer' DESC 'Co ntainer for a Java object' SUP top STRUCTURAL MUST cn ) structuralObjectClass: olcSchemaConfig entryUUID: 1cf25098-2f16-1031-9bb3-07590c97897d creatorsName: cn=config createTimestamp: 20120510180255Z entryCSN: 20120510180255.489367Z#000000#000#000000 modifiersName: cn=config modifyTimestamp: 20120510180255Z
Остаётся только добавить test.ldif (или как Вы его там назвали) в OLC (cn=config) с помощью LDAP-браузера или ldapadd.
Примечания:
Личности, обладающие ненасытным любопытством (или склонные к цинизму), наверняка захотят разобраться, для чего же нужно редактировать этот глупый LDIF-файл. Вспомните, что мы хотели добавить этот новый набор схемы к существующей рабочей конфигурации. Вспомните также, что файлы наборов схемы уже присутствуют в рабочей конфигурации в виде упорядоченной последовательности. Когда slaptest вершит свои тёмные делишки над подключенным набором схемы в нашем фиктивном файле slapd.conf и конвертирует его в LDIF-файл, он создаёт новое отдельное упорядоченное множество из подключенных наборов схемы, в приведённом выше примере подразумевается, что это будет {0}test. В рабочей конфигурации у нас уже есть запись с порядковым номером {0}, поэтому мы получим конфликт, который либо приведёт к отклонению попытки загрузки и перезаписи существующей записи с номером {0}, либо нанесёт непоправимый урон всей системе электропитания западного полушария (в зависимости от того, какую версию OpenLDAP Вы используете). Удаляя порядковый номер {0}, мы тем самым вынуждаем OpenLDAP добавить данный набор схемы в конец текущего множества записей наборов схемы в рабочей конфигурации и присвоить ему следующий доступный порядковый номер. Строки, выделенные красным, — просто операционные атрибуты, которые при добавлении записи в рабочую конфигурацию будут немедленно сгенерированы заново и в них будут помещены текущие значения. Вот и всё.
Ложка дёгтя. Метод преобразования с использованием slaptest прекрасно работает лишь тогда, когда определения объектных классов ссылаются только на атрибуты, определённые в том же наборе схемы данных. Если атрибут содержится в другом наборе схемы, slaptest выполнит проверку и радостно выдаст: AttributeType not found "xxxx". Придётся преобразовывать вручную.
С помощью стандартных функций OLC (cn=config) невозможно удалить набор схемы данных целиком, но теперь — начиная с версии 2.4 — есть возможность отредактировать специальные атрибуты (содержащие определения атрибутов или объектных классов, как показано выше в примере с ручным преобразованием набора схемы) любого загруженного набора схемы. Невозможность удаления целого набора схемы — преднамеренное конструктивное решение OpenLDAP, и, видимо, положение дел в ближайшее время не изменится (если вообще когда-нибудь изменится). Причина такого решения в том, что после удаления набора схемы будет практически невозможно осуществлять поиск в базах данных по атрибутам и объектным классам, содержащимся в удалённом наборе схемы, и принимать решения об обслуживании или отклонении таких запросов. Есть возможность, при соблюдении крайней аккуратности и точности, удалить любой набор схемы данных вручную, как описано ниже.
<Предупреждение> Если какой-либо атрибут или объектный класс, определённый в удаляемом с помощью описанного ниже процесса (или любого другого процесса) наборе схемы данных используется в какой-нибудь базе данных, то эта база данных придёт в нерабочее состояние. Повторяем — не будет работать. Совсем не будет. Нужно быть абсолютно уверенным (и держать на готове резервные копии), что ни в одной из баз данных не используются какие-либо атрибуты и объектные классы из того набора схемы, который Вы собираетесь удалять, перед тем как пытаться удалить этот набор схемы с помощью описанного ниже (или любого другого) метода.</Предупреждение>
Примечание: Подобного рода процесс ручного исправления злые языки, не способные понять всей находчивости и изобретательности тех, кто на него решается, иногда пренебрежительно называют ковбойской правкой. Что ж, можете считать это комплиментом.
Для удаления набора схемы из рабочей системы OLC (cn=config) выполните следующее:
Определите DN того набора схемы, который Вы хотите удалить, путём просмотра поддерева cn=schema,cn=config с помощью LDAP-браузера или ldapsearch. У всех наборов схемы DN имеет форму cn={Z}xxxx,cn=schema,cn=config. В качестве примера, если Вы добавляли приведённый выше набор схемы, он будет иметь DN что-то вроде cn={6}test,cn=schema,cn=config (значение 6 в фигурных скобках может быть больше или меньше, в зависимости от того, сколько наборов схемы было загружено). Запомните это значение.
Остановите slapd. Перейдите в директорию slapd.d (обычно [fc]/etc/openldap/slapd.d или [bsd] /usr/local/etc/openldap/slapd.d) и скопируйте всю директорию целиком вместе с поддиректориями и файлами в подходящее место (данная копия может быть использована для восстановления всего в случае возникновения проблем).
Перейдите из директории slapd.d в поддиректорию cn=config, а затем в cn=schema. В этой директории Вы найдёте все наборы схемы в виде LDIF-файлов, в том числе файл (исходя из сделанного выше предположения) cn={6}test.ldif (напомним, что значение 6 может отличаться в зависимости от того, сколько наборов схемы было загружено). Удалите данный файл (Вы ведь сделали полную копию директории slapd.d на шаге 2, правда?).
Если у удалённого Вами ldif-файла в фигурных скобках было наибольшее значение из всех в этой директории, то данный шаг можно пропустить. Если нет, переименуйте все файлы, у которых значения в фигурных скобках в пределах данной директории были выше, для поддержания непрерывной последовательности нумерации, начиная с 0. Так, если Вы удалили cn={6}test.ldif, но в директории есть файл, скажем, cn={7}splodge.ldif, то для поддержания непрерывной последовательности нумерации его нужно переименовать в cn={6}splodge.ldif.
Сделайте глубокий вдох и запустите slapd. Убедитесь в том, что удалённый набор схемы действительно был удалён.
Если что-то пошло не так, немедленно остановите slapd и проверяйте сообщения об ошибках в log-файлах. Восстановите директорию slapd.d целиком со всеми поддиректориями и файлами из резервной копии, сделанной на шаге 2, и снова запустите slapd. Затем попытайтесь выяснить, что же там произошло. Мы предупреждали, что резать по живому — не самое удачное решение.
ACP/ACL могут присутствовать, как и положено, в разделе глобальных настроек (в записи cn=config) или в разделе database (olcDatabase={Z}type,cn=config). В обоих случаях каждый ACP/ACL содержится в атрибуте olcAccess, которые вместе составляют упорядоченное множество: в начале каждого атрибута указывается порядковый номер (начиная с 0) в фигурных скобках, как показано в примере ниже (разделение строк выполнено только для удобства чтения):
olcAccess: {0}to attrs=userpassword by self write by anonymous auth by gro up/groupOfNames/member.exact="cn=itpeople,ou=groups,dc=example,dc=com" write by * none olcAccess: {1}to attrs=carlicense,homepostaladdress,homephone by self write by group/groupOfNames/member.exact="cn=hrpeople,ou=groups,dc=example,dc=com " write by * none olcAccess: {2}to * by self write by group/groupOfNames/member.exact="cn=hrp eople,ou=groups,dc=example,dc=com" write by users read by * none
Если теперь добавить (с помощью ldapmodify или LDAP-браузера) новый ACL/ACP, используя атрибут olcAccess начинающийся с {1}to..., то он будет помещён непосредственно за атрибутом, начинающимся с {0}, а последующие атрибуты будут перенумерованы:
olcAccess: {0}to attrs=userpassword by self write by anonymous auth by gro up/groupOfNames/member.exact="cn=itpeople,ou=groups,dc=example,dc=com" write by * none olcAccess: {1}to ... ... olcAccess: {2}to attrs=carlicense,homepostaladdress,homephone by self write by group/groupOfNames/member.exact="cn=hrpeople,ou=groups,dc=example,dc=com " write by * none olcAccess: {3}to * by self write by group/groupOfNames/member.exact="cn=hrp eople,ou=groups,dc=example,dc=com" write by users read by * none
Если новый атрибут добавляется без использования синтаксиса {}, то он будет помещён в конец множества атрибутов и ему будет присвоен следующий порядковый номер:
olcAccess: {0}to attrs=userpassword by self write by anonymous auth by gro up/groupOfNames/member.exact="cn=itpeople,ou=groups,dc=example,dc=com" write by * none olcAccess: {1}to attrs=carlicense,homepostaladdress,homephone by self write by group/groupOfNames/member.exact="cn=hrpeople,ou=groups,dc=example,dc=com " write by * none olcAccess: {2}to * by self write by group/groupOfNames/member.exact="cn=hrp eople,ou=groups,dc=example,dc=com" write by users read by * none olcAccess: {4}to ... ...
При изменении или удалении любого атрибута olcAccess Вы должны использовать синтаксис {} для идентификации конкретного атрибута.
Динамически подгружаемые модули определяются в записи cn=Module{0},cn=config, использующей объектный класс olcModuleList. Конкретный модуль определяется с помощью атрибута olcModuleLoad. Для загрузки нового модуля требуется просто определить атрибут с необходимым модулем (без использования синтаксиса {}). При этом подразумевается, что должны быть удовлетворены две зависимости. Во-первых, этот модуль должен существовать (быть создан при установке программы), и, во-вторых, он должен быть доступен по одному из путей по умолчанию, либо по тому пути, который определён в атрибуте olcModulePath (этот атрибут SINGLE-VALUE, то есть может иметь только одно значение, однако в этом значении может быть список путей, разделённых двоеточиями — смотрите спецификацию формата). Атрибуты olcModuleLoad добавляются без использования синтаксиса {} (нет никакой разницы в том, в каком порядке загружаются динамически подгружаемые модули), поэтому новый модуль помещается в конец множества атрибутов и ему присваивается следующий порядковый номер. Если имя модуля неверное (то есть не входит в состав модулей OpenLDAP), то запрос на добавление данного атрибута будет отклонён, а если модуль вкомпилирован в саму программу (и нет соответствующего динамически подгружаемого модуля), атрибут будет добавлен (что, по существу, избыточно).
Вы не можете удалить какой-либо атрибут olcModuleLoad, что логично для существующей политики OpenLDAP (по крайней мере на текущий момент). Несколько странно, что при попытке удалить данный атрибут выдаётся ошибка 80 (неизвестная ошибка (unknown error), снабжённая хорошим текстовым описанием), а не ошибка 53 (сервер не желает выполнять (server unwilling to perform)).
Базы данных определяются с использованием объектного класса olcDatabaseConfig с обязательным (MUST) атрибутом olcDatabase, а также объектного класса для конкретного типа базы данных, позволяющего задавать специфичные атрибуты, используемые в определении базы данных. Например, при определении базы данных типа bdb используется объектный класс olcBdbConfig (с обязательным атрибутом olcDbDirectory). Все записи баз данных создают упорядоченное (с помощью синтаксиса {}) множество типов баз данных в форме olcDatabase={Z}xxx,cn=config. Здесь {Z} — порядковый номер, а xxxx — имя типа базы данных. Если при добавлении новой базы данных используется синтаксис {}, то она (начиная с версии 2.4) будет добавлена в указанное место множества, а все последующие базы данных будут перенумерованы. Если синтаксис {} не указывался, база данных будет добавлена в конец текущего списка и ей будет присвоен следующий порядковый номер.
Возможно, не стоило тратить драгоценное время на такую ерунду, но: на практике, хотя он и не является обязательным, атрибут olcSuffix должен присутствовать, иначе создать запись базы данных не удастся (ошибка error 80 fail setup). Вот.
В качестве примера, предполагая, что в текущей конфигурации присутствуют записи баз данных olcDatabase={0}config,cn=config и olcDatabase={1}bdb,cn=config, с помощью приведённой ниже минимальной конфигурации создадим запись с DN olcDatabase={2}bdb,cn=config.
# Порядковый номер {} не указан, поэтому запись будет # добавлена в конец текущего списка баз данных. # Примечание: olcBdbConfig наследуется от класса olcDatabaseConfig. # Мы не стали указывать родительский класс, но если Вам нравится # печатать, добавьте # objectclass: olcDatabaseConfig dn: olcDatabase=bdb,cn=config objectClass: olcBdbConfig olcDatabase: bdb olcDbDirectory: /var/db/new-db olcSuffix: dc=example,dc=net # Если Вы хотите иметь суперпользователя для этого DIT, добавьте olcRootDN: cn=something,dc=example,dc=net olcRootPW: somesecret
Поскольку запись создаётся без использования синтаксиса упорядочения (нет значения {Z}), она будет добавлена в конец текущего упорядоченного множества и ей будет присвоен следующий порядковый номер, в данном примере {2}. Не возбраняется и явно указывать значение olcDatabase: {2}bdb (внеся соответствующие изменения и в строку dn:), результат будет тот же. Если же Вы укажете значение olcDatabase: {1}bdb (опять таки, внеся соответствующие изменения в строку dn:), то при добавлении в подразумеваемую нами конфигурацию, текущая база данный с номером {1} будет перенумерована в {2}, а новая база данных будет добавлена на её место в упорядоченном множестве. При создании записи olcDatabase обязательными для определения являются лишь атрибуты olcDatabase и olcDbDirectory (хотя добавить запись не получится без атрибута olcSuffix). Дополнительные атрибуты (в том числе такие очевидные, как olcRootDN и olcRootPW) можно добавить как на этапе создания записи, так и позже. Напоминаем, что директория, в которой размещаются файлы базы данных (определяемая атрибутом olcDbDirectory), должна существовать (и иметь приемлемые права доступа) до того, как её необходимо будет использовать, то есть перед созданием записи базы данных.
По состоянию на OpenLDAP версии 2.4.31 невозможно удалить запись Database. Любые попытки это сделать отклоняются и выдаётся ошибка 53 (Server unwilling to perform (сервер не желает исполнять)), как видите, описание вполне информативно. Ходят слухи, что есть какой-то экспериментальный код, реализующий удаление, который якобы можно получить, но пока дела обстоят так.
Существует несколько способов решения этой проблемы:
Удалить атрибуты olcRootDN и olcRootPassword в cn=config, а также все файлы базы данных (slapd должен быть остановлен) в директории, определённой в атрибуте olcDbDirectory. База данных продолжит существовать, но только в виде имени. Примечание: Директорию, в которой должны находиться файлы базы данных, удалять не следует, только файлы. При перезапуске slapd произведёт инициализацию файлов новой (пустой) базы данных. По своей сути эти файлы безвредны, если не считать того, что они занимают место на диске.
Создать новую систему OpenLDAP только с необходимыми DIT и либо настроить syncrepl для копирования содержимого этих DIT, либо произвести экспорт и импорт содержимого в формате LDIF.
Можно удалить базу данных путём ручной правки директории slapd.d и связанных с этой базой файлов .ldif. Этот способ описан ниже.
<Предупреждение> Будьте осторожны, поскольку при операциях с отсылками на удалённую базу данных могут быть негативные последствия. То есть, если в какой-либо базе данных содержатся отсылки на удалённую (несуществующую) базу данных LDAP, переход по этим отсылкам будет вызывать ошибки (положение усугубляется ещё и тем, что большинство LDAP-браузеров по умолчанию пытаются разрешать отсылки автоматически). Такие отсылки необходимо исправить вручную с помощью LDAP-браузера или LDIF.</Предупреждение>
Примечание: Подобного рода процесс ручного исправления злые языки, не способные понять всей находчивости и изобретательности тех, кто на него решается, иногда пренебрежительно называют ковбойской правкой. Что ж, можете считать это комплиментом.
Для примера предположим, что в текущей конфигурации есть записи баз данных olcDatabase={0}config, olcDatabase={1}monitor, olcDatabse={2}bdb и olcDatabse={3}bdb. И Вы хотите удалить olcDatabase={2}bdb. Ваши действия:
Примечание: Процедура нетривиальна. Будьте внимательны и осторожны. Перед началом убедитесь, что Вы сделали резервную копию директории slapd.d. Тогда при возникновении ошибок Вы в любой момент сможете всё вернуть.
Убедитесь в правильности DN той базы данных, которую Вы собираетесь удалить, исследовав дерево cn=config с помощью LDAP-браузера или ldapsearch. У всех баз данных DN в форме olcDatabase={Z}xxx. Если, к примеру, у Вас есть база данных, добавленная позже той, которую Вы собираетесь удалить, её DN будет иметь вид olcDatabase={3}bdb (значение 3 внутри фигурных скобок может быть больше или меньше, в зависимости от того, сколько баз данных определено). Запомните значение, соответствующее удаляемой базе данных. Убедитесь, что это нужная Вам база данных, изучив атрибут olsSuffix. Вы ведь не хотите, выполнив столь нервную операцию, обнаружить, что удалили не ту базу данных. В последующих инструкциях подставляйте вместо {Z} значение порядкового номера той базы данных, которую Вы хотите удалить.
Остановите slapd. Перейдите к директории slapd.d (обычно [fc]/etc/openldap/slapd.d или [bsd] /usr/local/etc/openldap/slapd.d) и скопируйте её целиком вместе с поддиректориями и файлами в подходящее место (в случае возникновения проблем эту копию можно будет использовать для восстановления всего в исходное состояние).
Из директории slapd.d перейдите в поддиректорию cn=config. В этой директории Вы обнаружите LDIF-файлы всех баз данных, в том числе файл olcDatabase={2}bdb.ldif, который мы хотим удалить (вместо {Z} подставляйте актуальное для Вас значение). Кроме того, Вы также обнаружите директории этих баз данных с названиями в форме olcDatabase={Z}xxx (без .ldif). Подразумевая, что мы избавляемся от базы данных olcDatabase={2}bdb, удалим файл olcDatabase={2}bdb.ldif и директорию olcDatabase={2}bdb (Вы ведь не забыли сделать полную копию директории slapd.d на шаге 2?).
Если у удалённого Вами файла ldif было наибольшее в этой директории значение в фигурных скобках (индекс {Z}), можете пропустить следующий шаг. В противном случае переименуйте все файлы с большим значением в фигурных скобках в этой директории для создания непрерывной последовательности нумерации индексов, начинающейся с нуля. Так, если Вы удалили файл olcDatabase={2}bdb.ldif, но у Вас остался файл с именем olcDatabase={3}bdb.ldif, переименуйте его в olcDatabase={2}bdb.ldif. Переименуйте и соответствующие директории. Так, если Вы удалили директорию olcDatabase={2}bdb, но у Вас осталась директория с именем olcDatabase={3}bdb, переименуйте её в olcDatabase={2}bdb. Повторите эту процедуру для всех файлов olcDatabase={Z}.xxx.ldif и директорий olcDatabase={Z}.xxx, пока не получите непрерывной последовательности нумерации индексов баз данных.
Финальный шаг — это редактирование различных файлов olcDatabase={Z}xxx.ldif с целью изменения их внутренних DN. Опять же подразумевая, что мы удалили оригинальный файл olcDatabase={2}bdb.ldif (и соответствующую ему директорию), мы получаем, что текущий файл olcDatabase={2}bdb.ldif (и соответствующая ему директория) представляют собой ни что иное, как копию нашего предыдущего файла olcDatabase={3}bdb.ldif (и его директории) и содержат информацию, относящуюся к старому индексу {Z}, в нашем случае это будет {3}. Поправьте файл olcDatabase={2}bdb.ldif в Вашем любимом текстовом редакторе следующим образом:
vi olcDatabase={2}bdb.ldif # Отобразятся примерно такие строки dn: olcDatabase={3}bdb ... olcDatabase: {3}bdb ... # Отредактируйте эти два значения # (или значения индекса Z из Вашего файла) dn: olcDatabase={2}bdb olcDatabase: {2}bdb
Повторим этот процесс для всех файлов olcDatabase={Z}xxx.ldif, в которых индекс {Z} превышал индекс удалённого файла, чтобы, опять же, создать непрерывную последовательность нумерации индексов.
Вот и всё. Сделайте глубокий вдох и перезапустите slapd. Убедитесь в том, что удаляемая Вами база данных и в самом деле удалилась. Возможно, Вы решите также удалить и все файлы этой базы данных, находящиеся в директории, на которую указывало значение атрибута olcDirectory.
Если что-то пошло не так, немедленно остановите slapd и проверяйте сообщения об ошибках в log-файлах. Восстановите директорию slapd.d целиком со всеми поддиректориями и файлами из резервной копии, сделанной на шаге 2, и снова запустите slapd. Затем попытайтесь выяснить, что же там произошло. Мы предупреждали, что резать по живому — процесс рискованный.
Наложения описываются в записях, дочерних по отношению к соответствующей записи olcDatabse={Z}xxx,cn=config, к которой они применяются. Записи наложений используют общий объектный класс olcOverlayConfig (обязательный атрибут olcOverlay) и специфичный для наложения объектный класс (всегда являющийся потомком olcOverlayConfig), представляющий собой контейнер для специфичных атрибутов данного наложения. Например, наложение syncprov (поставщик репликации) использует объектный класс olcSyncProvConfig (нет обязательных атрибутов). Если наложение использует динамически подгружаемый модуль, то он должен быть добавлен до определения наложения. С помощью приведённой ниже минимальной конфигурации можно создать запись syncprov, как дочернюю к записи базы данных olcDatabase={1}bdb,cn=config:
dn: olcOverlay=syncprov,olcDatabase={1}bdb,cn=config objectсlass: olcSyncProvConfig olcOverlay: syncprov
Поскольку запись создаётся без использования синтаксиса упорядочения (нет значения {Z}), она будет добавлена в конец текущего упорядоченного множества и ей будет присвоен следующий порядковый номер, в данном случае {0}. Не возбраняется, подразумевая, что это первая запись, и явно указывать значение olcOverlay: {0}syncprov (внеся соответствующие изменения и в строку dn:), результат будет тот же. Напомним, что порядок определения наложений определяет порядок их обработки, что во многих случаях может иметь важное значение. Для добавления наложений в корректном порядке как раз подойдёт синтаксис упорядоченного множества {Z} (все последующие записи будут перенумерованы для поддержания правильного упорядоченного множества). Дополнительные атрибуты можно добавить как на этапе создания записи, так и позже.
Возможно, для Вас это будет сюрпризом, но... по состоянию на OpenLDAP версии 2.4.31 невозможно удалить запись Overlay. Любые попытки это сделать отклоняются и выдаётся ошибка 53 (Server unwilling to perform (сервер не желает исполнять)), как видите, описание вполне информативно. Ходят слухи, что есть какой-то экспериментальный код, реализующий удаление, который якобы можно получить, но пока дела обстоят так. Есть вариант использовать для удаления какого-либо неверно добавленного наложения технику, сходную с той, что мы рассматривали для удаления лишних наборов схемы данных. Как всегда, будьте осторожны.
Проблемы, комментарии, предположения, исправления (включая битые ссылки) или есть что добавить? Пожалуйста, выкроите время в потоке занятой жизни, чтобы написать нам, вебмастеру или в службу поддержки. Оставшийся день Вы проведёте с чувством удовлетворения.
Нашли ошибку в переводе? Сообщите переводчикам!
Copyright © 1994-2017 ZyTrax, Inc. Все права защищены. Последнее изменение страницы: 24 мая 2019 г.
Переведено участниками проекта Pro-LDAP.ru в 2012-2019 г.