Назад | Перейти на главную страницу

Средство проверки отличительного имени LDAP

Есть ли библиотека, программа или простое регулярное выражение для проверки правильности формирования 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         

Это требует по крайней мере следующие свободы:

  • он в значительной степени игнорирует Unicode (хотя вы можете найти pcregrep --utf помогает) и не проверяет UTF-8
  • он не поддерживает прямые числовые OID в типах атрибутов
  • он не поддерживает многозначные RDN (например, cn=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]+)*