Есть ли библиотека, программа или простое регулярное выражение для проверки правильности формирования DN, указанного во входных данных?
Пример: INPUT: manager, ou = company, dc = net ---> OUTPUT: неправильно сформирован
ВХОД: cn = менеджер, ou = компания, dc = net ---> ВЫХОД: правильно сформирован
В perl с Net::LDAP
это почти тривиально:
#!/usr/bin/perl
use strict;
use warnings;
use Net::LDAP::Util qw/canonical_dn/;
foreach my $dn (@ARGV) {
if (!defined(canonical_dn($dn))) { print "not well formed: $dn\n"; }
else { print "well formed: $dn\n"; }
}
Затем:
$ perl ldapdn.pl "manager, ou=company, dc=net" "cn=manager, ou=company, dc=net"
not well formed: manager, ou=company, dc=net
well formed: cn=manager, ou=company, dc=net
Есть несколько функций, которые проверяют DN, ldap_explode_dn()
также может быть полезно, если вы хотите нормализовать и обрабатывать DN.
Стоит отметить, что «правильно сформированный» и «действительный» - не одно и то же, поскольку синтаксически правильно сформированный DN может не соответствовать схеме конкретного LDAP DIT и, следовательно, быть отклонен.
Если у вас установлен OpenLDAP, любая последняя версия должна иметь slapdn
программа. это делает правильная проверка схемы, но у вас должен быть жизнеспособный slapd.conf
и схема, установленная в системе, в которой вы его запускаете, конечно (что может потребовать запуска от имени пользователя root или специального пользователя из-за прав доступа к файлам операционной конфигурации).
$ /usr/local/sbin/slapdn -v "cn=manager, ou=company, dc=net"
DN: <cn=manager, ou=company, dc=net> check succeeded
normalized: <cn=manager,ou=company,dc=net>
pretty: <cn=manager,ou=company,dc=net>
(Если у вас OpenLDAP, созданный из исходного кода, он также поставляется с dntest
программа, созданная как часть своего набора тестов. Он только анализирует DN, без проверки схемы. К сожалению, у него нет подходящего кода ошибки, и, кажется, иногда он указывает на неправильные DN с помощью segfault ...)
И, наконец, подход с использованием регулярных выражений. Как было предложено @ voretaq7, вы можете использовать ABNF из RFC 4514, хотя вам также понадобятся базовые синтаксисы из RFC 4512 (§1.4). Запустите их через любой конвертер ABNF в ERE (например, abnf2regex, реализованный на Java), и он выскакивает. Я не собираюсь вставлять его сюда, это примерно 4k линейного шума. Можно расколоть весь орех abnf2regex
хотя:
$ java -jar abnf2regex.jar -t distinguishedName \
"cn=manager,ou=company,dc=net" rfc4512.abnf rfc4514dn.abnf
Rule "distinguishedName" matches: cn=manager,ou=company,dc=net
Rule: [relativeDistinguishedName *(COMMA relativeDistinguishedName)]
Expanded: [(((%x41-5a / %x61-7a) *(%x41-5a / %x61-7a / %x30 / %x31-39 / %x2d))
... <<expanded ABNF snipped>>
Regex: (?:(?:[A-Za-z][\-01-9A-Za-z]*|(?:[01-9]|[1-9][01-9]+)(?:\.(?:[01-9]
... <<expanded regex snipped>>
Вышеупомянутое тестирует строку на соответствие регулярному выражению, сгенерированному из определенного именованного правила (-t distinguishedName
). Если у вас острый взгляд, вы заметите, что я немного обманул, я удалил пробелы из DN, так как это технически не является частью DN и сломает матч.
И наконец (действительно на этот раз) упрощенный и несовершенный регулярное выражение что вы можете использовать с pcregrep -i
:
^([a-z][a-z0-9-]*)=(?![ #])(((?![\\="+,;<>]).)|(\\[ \\#="+,;<>])|(\\[a-f0-9][a-f0-9]))*
(,([a-z][a-z0-9-]*)=(?![ #])(((?![\\="+,;<>]).)|(\\[ \\#="+,;<>])|(\\[a-f0-9][a-f0-9]))*)*$
Я набил и обернул его, чтобы он был разборчивым, ну, возможно, менее неразборчивым. Упрощенная разбивка
^(attributename)=(attributevalue)(,(attributename)=(attributevalue))*$
с участием
attributevalue = not leading space or octothorpe |
any char except specials |
escaped specials |
escaped hex-digit pair
Это требует по крайней мере следующие свободы:
pcregrep --utf
помогает) и не проверяет UTF-8cn=Bob+sn=Smith
)Согласно спецификации, он не имеет дело с ненужным форматированием пробелов в начале, конце или вокруг ",".
Не беспокойся. Сервер LDAP, о котором вы говорите, уже знает, как выглядит недопустимый DN. Просто поймите ошибку (код ответа) и действуйте соответствующим образом.
Библиотека openldap предоставляет эту подпрограмму, я не знаю никаких интерфейсов ldap для ruby, perl и т. Д., Которые обеспечивают доступ к этому api. Но я не смотрел так сильно.
ldap_str2dn() parses a string representation of a distinguished name
contained in str into its components, which are stored in dn as
ldap_ava structures, arranged in LDAPAVA, LDAPRDN, and LDAPDN terms,
defined as:
typedef struct ldap_ava {
char *la_attr;
struct berval *la_value;
unsigned la_flags;
} LDAPAVA;
Я улучшаю свой вопрос, добавляя простой (возможно, слишком простой) альтернативный ответ: я создал регулярное выражение для соответствия всем возможным DNS
(\w+[=]{1}[a-zA-Z0-9\-\$&\(\)\[\]\{\}\.\s]+)([,{1}]\w+[=]{1}[a-zA-Z0-9\-\(\)\[\]\{\}\.\s]+)*