Alisson Machado
06 June 2016

Python e LDAP Search

Esse post foi criado para mostrar como é possível fazer a conexão à um servidor LDAP através da linguagem Python. Para começar, o primeiro passo é instalar o módulo ldap do python.
apt-get install python-ldap -y
O comando acima pode ser executado em distribuições baseadas em Debian, no meu caso estou usando o Debian 8 (Jessie). Uma vez com o módulo instalado é possível efetuar a conexão com o servidor:
#!/usr/bin/python

import ldap

# definindo variaveis de conexao

address = "ldap.exemplo.com.br"
user = "cn=admin,dc=exemplo,dc=com,dc=br"
password = "testepasswd"
base = "dc=exemplo,dc=com,dc=br"

# efetuando conexao

connection = ldap.initialize("ldap://%s"%address)
connection.protocol_version = ldap.VERSION3  #define versao 3 do protocolo ldap (recomendado)
connection.bind(user,password)

#efetuando uma busca
ldap_filter = '(mail=alisson.machado@exemplo.com.br)'

print connection.search_s(base,ldap.SCOPE_SUBTREE,ldap_filter)
No script acima logo no inicio foram definidas as variáveis de acesso ao servidor LDAP e logo mais abaixo do comentário efetuando conexao foram definidas as instruções que fazem conexão com o servidor.
connection = ldap.initialize("ldap://%s"%address)
A linha acima define qual é o servidor ldap em que vamos conectar.
connection.protocol_version = ldap.VERSION3
Logo na sequência é definido qual é o protocolo do LDAP que será usado, os mais comuns são ldapV2 e ldapV3, no meu caso estou utilizando o v3 mesmo.
connection.bind(user,password)
E na instrução acima é efetuada literalmente a conexão com o servidor passando as credenciais de acesso. A partir dessa linha podem ser efetuadas todas as buscas, alterações e inserções na sua base ldap, mas lembre que toda a conexão foi armazenada na variável connection.
#efetuando uma busca
ldap_filter = '(mail=alisson.machado@exemplo.com.br)'

print connection.search_s(base,ldap.SCOPE_SUBTREE,ldap_filter)
No bloco de código acima, na variável ldap_filter foi armazenada uma string com um tipo de filtro do LDAP, uma vez definido esse filtro e feita a busca logo abaixo, sendo o primeiro parâmetro a base em que é efetuada a busca, o segundo é o escopo da busca e por último o filtro, no entanto o método search_s pode receber mais uma parâmetro que são os atributos de um registro no ldap que você quer retornar, caso você queira todos como é o meu caso é só omitir o último parâmetro, caso você queira projetar o seu retorno, é possível fazer da seguinte maneira.
print connection.search_s(base,ldap.SCOPE_SUBTREE,ldap_filter,['cn','mail','description'])
E serão retornados somente esses atributos da entrada LDAP que você está buscando. No caso dos escopos, os possíveis são: - subtree ( ldap.SCOPE_SUBTREE ) - base ( ldap.SCOPE_BASE ) - onelevel ( ldap.SCOPE_ONELEVEL ) Explicando um pouco sobre o escopo. - Subtree, significa que você quer buscar em todas as subarvores da sua base ldap. - base, significa que você quer buscar a entrada somente na base, assim a busca irá retornar um único valor. - onelevel, significa que a busca só vai um level abaixo da sua base. A imagem abaixo mostra melhor. theThreeScopeOptions Mas voltando ao comando search_s, ele irá retornar uma lista com várias tuplas que representar os seus valores.
[
    (
        'cn=Alisson Machado de Menezes,cn=USERS,dc=exemplo,dc=com,dc=br', 
        {'userPassword': ['{SSHA}HASH_EM_ALGORITMO_SHA1'], 
        'uid': ['alisson.machado']}
    )
]
E agora você pode filtrar da maneira que achar melhor, por exemplo, vamos supor que eu tenha armazenado a consulta em uma variável chamada res e queria somente o dn (distinguished name) do usuário. A linha poderia ficar da seguinte forma:
res = connection.search_s(base,ldap.SCOPE_SUBTREE,ldap_filter,['cn','mail','description'])
print res[0][1]
Se analisarmos a lista no penúltimo bloco de instrução, temos uma lista que tem apenas 1 valor, então eu pego a posição zero dessa lista, e nessa posição zero temos uma tupla com vários valores, sendo eles na sequencia: - DN - Password - UID Que estão nas seguintes posições, 0 (DN), 1 (Password), 2 (UID). Bom, então é isso (=