LDAP 专有名称验证器

and*_*Pat 5 ldap

是否有库、程序或简单的正则表达式来检查输入中指定的 DN 是否格式正确?

示例:输入:经理,ou=company,dc=net ---> 输出:格式不正确

输入:cn=manager, ou=company, dc=net ---> 输出:格式良好

mr.*_*tic 8

在 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"; }
}
Run Code Online (Sandbox Code Playgroud)

然后:

$ 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
Run Code Online (Sandbox Code Playgroud)

有许多函数可以验证 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>
Run Code Online (Sandbox Code Playgroud)

(如果您有从源代码构建的 OpenLDAP,它还附带了一个dntest作为其测试套件一部分构建的程序。它只解析 DN,没有模式检查。遗憾的是,它没有可用的错误代码,并且偶尔会显示格式错误的 DN有段错误...)

最后,正则表达式方法。正如@voretaq7 所建议的,您可以使用来自RFC 4514ABNF,但您还需要来自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>>
Run Code Online (Sandbox Code Playgroud)

以上是针对从特定命名规则 ( -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]))*)*$
Run Code Online (Sandbox Code Playgroud)

我已经填充并包裹了它以使其清晰易读,好吧,也许不那么难以辨认。简化分解是

^(attributename)=(attributevalue)(,(attributename)=(attributevalue))*$
Run Code Online (Sandbox Code Playgroud)

 attributevalue = not leading space or octothorpe |
                  any char except specials | 
                  escaped specials |
                  escaped hex-digit pair         
Run Code Online (Sandbox Code Playgroud)

至少需要以下自由:

  • 它在很大程度上忽略了 Unicode(尽管您可能会找到pcregrep --utf帮助)并且不会验证 UTF-8
  • 它不支持属性类型中的直接数字 OID
  • 它不支持多值 RDN(例如cn=Bob+sn=Smith
  • 它不处理未转义的尾随空格

根据规范,它不会处理开头、结尾或“,”周围的无偿格式化空白。


841*_*104 5

不要打扰。您所说的 LDAP 服务器也已经知道无效 DN 的样子。只需捕获错误(响应代码)并对其采取适当措施即可。