Em perl, com Net::LDAP
é quase trivial:
#!/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"; }
}
Então:
$ 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
Existem várias funções que validam DNs, ldap_explode_dn()
também pode ser útil se você deseja normalizar e processar DNs ainda mais.
É importante notar que "bem formado" e "válido" não são a mesma coisa, já que um DN sintaticamente bem formado pode não corresponder ao esquema de um determinado LDAP DIT e, portanto, ser rejeitado.
Se você tiver o OpenLDAP, qualquer versão recente deve vir com um programa slapdn
. Isso faz a verificação do esquema adequada, mas você deve ter um viável slapd.conf
e um esquema configurado no sistema que você executa naturalmente (o que pode exigir sua execução como root ou um usuário especial devido a permissões de arquivo arquivos de configuração operacional).
$ /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>
(Se você tiver o OpenLDAP construído a partir do código-fonte, ele também vem com um programa dntest
criado como parte de seu conjunto de testes. Ele só analisa DNs, nenhuma verificação de esquema. Infelizmente não possui um código de erro utilizável e parece ocasionalmente indicar DNs malformados com um segfault ...)
E finalmente, a abordagem regex. Como sugerido por @ voretaq7, você pode usar o ABNF de RFC 4514 , embora você também precise das sintaxes básicas de RFC 4512 (§1.4). Execute aqueles que qualquer conversor ABNF para ERE (por exemplo, abnf2regex , implementado em Java), e para fora ele aparece. Eu não vou colá-lo aqui, é aproximadamente 4k de ruído de linha. Você pode quebrar a porca inteira com abnf2regex
embora:
$ 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>>
O acima está testando uma string contra o regex gerado a partir da regra nomeada específica ( -t distinguishedName
). Se você tiver olhos aguçados, perceberá que eu trapacei um pouco, removi o espaço em branco do DN, já que ele não é tecnicamente parte do DN e quebrará o jogo.
E finalmente (realmente desta vez) um simplificado e imperfeito regex que você pode usar com < href="http://www.pcre.org/"> pcregrep -i
:
^([a-z][a-z0-9-]*)=(?![ #])(((?![\="+,;<>]).)|(\[ \#="+,;<>])|(\[a-f0-9][a-f0-9]))*
(,([a-z][a-z0-9-]*)=(?![ #])(((?![\="+,;<>]).)|(\[ \#="+,;<>])|(\[a-f0-9][a-f0-9]))*)*$
Eu tenho acolchoado e enrolado para torná-lo legível, bem, menos ilegível, talvez. Repartição simplificada é
^(attributename)=(attributevalue)(,(attributename)=(attributevalue))*$
com
attributevalue = not leading space or octothorpe |
any char except specials |
escaped specials |
escaped hex-digit pair
Isso leva pelo menos as seguintes liberdades:
- ele ignora em grande parte o Unicode (embora você possa achar que o
pcregrep --utf
ajuda) e não validará o UTF-8 - não suporta OIDs numéricos diretos em tipos de atributo
- não suporta RDNs com valores múltiplos (por exemplo,
cn=Bob+sn=Smith
) - ele não manipula espaços em branco sem escape
Como por-especificação, ele não lida com formatação de espaço em branco no começo, fim ou próximo ",".