Функционал динамической конфигурации OpenLDAP всё ещё развивается, поэтому иногда (не часто) приходится сталкиваться с ситуацией, когда поменять что-то "на лету" не получается. Например, мы отрабатывали примеры для данной книги на сборке OpenLDAP версии 2.4.45, корневая директория которой располагалась в /opt/openldap-2.4.45. В марте 2018 года вышла новая версия OpenLDAP 2.4.46 и мы решили перевести примеры на работу с ней. Конечно, ничего сложного в этом нет, за исключением пути к модулям slapd, который, как известно, настраивается в значении атрибута olcModulePath записи /etc/ldap/slapd.d/cn=config/cn=module{0}.ldif. Итак, мы собрали новую версию OpenLDAP в /opt/openldap-2.4.46 и предусмотрительно (чтобы в будущем не наступать на те же грабли) сделали на неё символическую ссылку openldap-lastest:
$ ls -l /opt итого 8 drwxr-xr-x 10 root root 4096 июн 7 2017 openldap-2.4.45 drwxr-xr-x 10 root root 4096 мар 25 2018 openldap-2.4.46 lrwxrwxrwx 1 root root 17 мар 25 2018 openldap-lastest -> ./openldap-2.4.46
Осталось только заменить путь к модулям в наших примерах:
dn: cn=module{0},cn=configchangetype: modifyreplace: olcModulePatholcModulePath: /opt/openldap-lastest/libexec/openldap/
Но не тут-то было:
$ ldapmodify -x -D cn=config -W -f ./modify_module_path.ldif
Enter LDAP Password:
modifying entry "cn=module{0},cn=config"
ldap_modify: Other (e.g., implementation specific) error (80)
additional info: cannot delete olcModulePath
А с учётом того, что olcModulePath — однозначный (SINGLE-VALUE) атрибут, мы заходим в тупик... Правильный путь в этом случае — начать всё заново, и постараться в дальнейшем быть более дальновидными. Но примеров так много, а переделывать всё так скучно, что мы всё-таки решаем остановить slapd, находим нужный файл в конфигурационной директории и, несмотря на строгое предупреждение в первой же строке, правим его вручную:
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 d4fcdb89
dn: cn=module{0}
objectClass: olcModuleList
cn: module{0}
olcModulePath: /opt/openldap-lastest/libexec/openldap
olcModuleLoad: {0}back_mdb.la
structuralObjectClass: olcModuleList
entryUUID: 0dbe4634-6770-1037-8520-090c21d99176
creatorsName: cn=config
createTimestamp: 20171127033735Z
entryCSN: 20171127033735.865760Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20171127033735Z
Ура, задача решена! Но теперь, как укор совести, при каждом запуске slapd или вызове его инструментов (например, slapcat) мы будем видеть такое:
ldif_read_file: checksum error on "/etc/ldap/slapd.d//cn=config/cn=module{0}.ldif"
К счастью, эта проблема решаема. Нужно просто пересчитать контрольную сумму CRC32 содержимого файла без первых двух строк комментария. В Linux это делается с помощью утилиты crc32, в Ubuntu она входит в пакет libarchive-zip-perl.
Разберём этот процесс поэтапно. Сначала получим содержимое файла без первых двух строк:
$ tail -n +3 /etc/ldap/slapd.d/cn\=config/cn\=module\{0\}.ldif
dn: cn=module{0}
objectClass: olcModuleList
cn: module{0}
olcModulePath: /opt/openldap-lastest/libexec/openldap
olcModuleLoad: {0}back_mdb.la
structuralObjectClass: olcModuleList
entryUUID: 0dbe4634-6770-1037-8520-090c21d99176
creatorsName: cn=config
createTimestamp: 20171127033735Z
entryCSN: 20171127033735.865760Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20171127033735Z
Теперь получим контрольную сумму этого содержимого:
$ crc32 <(tail -n +3 /etc/ldap/slapd.d/cn\=config/cn\=module\{0\}.ldif)
23f5b0da
Осталось подставить вновь сформированную контрольную сумму на её место в файле. Это можно сделать в любом текстовом редакторе, но можно и из командной строки. Мы, по привычке, используем для этой цели старый добрый perl. Сначала холостой прогон:
$ perl -wpe "s/^# CRC32 .+$/# CRC32 $(crc32 <(tail -n +3 /etc/ldap/slapd.d/cn\=config/cn\=module\{0\}.ldif))/" /etc/ldap/slapd.d/cn\=config/cn\=module\{0\}.ldif
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 23f5b0da
dn: cn=module{0}
objectClass: olcModuleList
cn: module{0}
olcModulePath: /opt/openldap-lastest/libexec/openldap
olcModuleLoad: {0}back_mdb.la
structuralObjectClass: olcModuleList
entryUUID: 0dbe4634-6770-1037-8520-090c21d99176
creatorsName: cn=config
createTimestamp: 20171127033735Z
entryCSN: 20171127033735.865760Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20171127033735Z
Всё в порядке, контрольная сумма заменена. Осталось применить это непосредственно к нашему файлу:
$ perl -i -wpe "s/^# CRC32 .+$/# CRC32 $(crc32 <(tail -n +3 /etc/ldap/slapd.d/cn\=config/cn\=module\{0\}.ldif))/" /etc/ldap/slapd.d/cn\=config/cn\=module\{0\}.ldif
$ cat /etc/ldap/slapd.d/cn\=config/cn\=module\{0\}.ldif
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 23f5b0da
dn: cn=module{0}
objectClass: olcModuleList
cn: module{0}
olcModulePath: /opt/openldap-lastest/libexec/openldap
olcModuleLoad: {0}back_mdb.la
structuralObjectClass: olcModuleList
entryUUID: 0dbe4634-6770-1037-8520-090c21d99176
creatorsName: cn=config
createTimestamp: 20171127033735Z
entryCSN: 20171127033735.865760Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20171127033735Z
Вот и всё. Контрольная сумма совпадает и назойливые сообщения больше не будут нас беспокоить.
Разумеется, таким способом восстанавливается контрольная сумма любого LDIF-файла в конфигурационной директории cn=config.