LDAP专有名称validation器

有没有一个库,程序或简单的正则expression式来检查input中指定的DN是否格式正确?

例如:INPUT:manager,ou = company,dc = net —> OUTPUT:格式不正确

INPUT:cn = manager,ou = company,dc = net —> OUTPUT:格式正确

在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 

有许多validationDN的函数,如果你想规范和进一步处理DN, ldap_explode_dn()也可能有用。

值得注意的是,“格式良好”和“有效”并不是一回事,因为语法上格式良好的DN可能与特定LDAP DIT的模式不匹配,因此会被拒绝。

如果你有OpenLDAP,最近的版本应该有一个slapdn程序。 这样做会进行适当的模式检查,但是您当然必须在系统上设置一个可行的slapd.conf和模式(可能需要以root用户或特殊用户身份运行,因为操作configuration文件具有文件权限)。

 $ /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是从源代码构build的,它也带有一个作为testing套件的一部分构build的dntest程序,它只能parsingDN,没有模式检查,可悲的是它没有可用的错误代码,偶尔也会显示格式错误具有段错误的DN …)

最后,正则expression式的方法。 如@ voretaq7所示,您可以使用RFC 4514中的ABNF ,不过您还需要RFC 4512 (§1.4)中的基本语法。 运行这些通过任何ABNF到ERE转换器(例如,用Java实现的abnf2regex ),并将其popup。 我不打算粘贴在这里,大约有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 )生成的正则expression式testingstring。 如果你有锐利的眼睛,你会注意到我有点被欺骗了,我从DN中删除了空格,因为它在技术上并不是 DN的一部分,并且会打破这个匹配。


最后(真的这一次)一个简化和不完美的 正则expression式 ,你可以使用pcregrep -i

  ^([az][a-z0-9-]*)=(?![ #])(((?![\\="+,;<>]).)|(\\[ \\#="+,;<>])|(\\[a-f0-9][a-f0-9]))* (,([az][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 

至less需要以下的自由:

  • 它很大程度上忽略了Unicode(尽pipe你可能会发现pcregrep --utf帮助)并且不会validationUTF-8
  • 它不支持属性types中的直接数字OID
  • 它不支持多值RDN(例如cn=Bob+sn=Smith
  • 它不处理未转义的尾随空白

按照规范,它不会在开始,结束或在“左右”处理无格式的空格。

不要打扰。 您所说的LDAP服务器已经知道无效的DN是什么样子。 只要抓住错误(响应代码)并适当地采取行动。

openldap库提供了这个子例程,我不知道任何提供对这个api访问的ruby,perl等的ldap接口。 但是我没有看那么难。

 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; 

我改进我的问题,添加我简单(也许太简单)的替代答案:我创build了一个正则expression式来匹配所有可能的DNS

(\w+[=]{1}[a-zA-Z0-9\-\$&\(\)\[\]\{\}\.\s]+)([,{1}]\w+[=]{1}[a-zA-Z0-9\-\(\)\[\]\{\}\.\s]+)*