JDBC-LDAP Bridge Driver
Com a finalidade de facilitar a utilização do serviço de diretórios LDAP a Novell desenvolveu uma ponte JDBC-LDAP. Essa ponte permite a utilização de SQL para fazer consultas ou atualizações em uma árvore de diretórios através de aplicações Java.
O site do projeto é o http://www.openldap.org/jdbcldap/
Eu não encontrei nenhum release do projeto já compilado (se alguém encontrar me avise XD), mas os arquivos fontes podem ser baixados por qualquer cliente CVS. No meu caso utilizei o TortoiseCVS ( http://www.tortoisecvs.org/ ).
Antes de irmos ao código, vou mostrar como está disposta a hierarquia do meu serviço de diretórios:
Agora a classe que fiz para mostrar a facilidade de se usar a ponte JDBC-LDAP.
package org.paulovittor23.jdbcldap.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class ArtigoJdbcLdap {
public static void main(String[] args) throws Exception {
Connection con;
final String LDAP_CONNECTION_STRING = "jdbc:ldap://192.168.77.128:389/?SEARCH_SCOPE:=subTreeScope";
final String BASE_DN = "dc=paulovittor23,dc=org";
final String USERNAME = "cn=admin";
final String PASSWORD = "ldap123";
Class.forName("com.octetstring.jdbcLdap.sql.JdbcLdapDriver");
con = DriverManager.getConnection(
LDAP_CONNECTION_STRING,
USERNAME + "," + BASE_DN, PASSWORD
);
System.out.println(">>> CONEXÃO LDAP ESTABELECIDA !");
System.out.println(">>> LDAP_CONNECTION_STRING: " + LDAP_CONNECTION_STRING);
System.out.println(">>> LDAP_ADMIN: " + USERNAME + "," + BASE_DN);
System.out.println(">>> LDAP_PASSWORD: " + PASSWORD + "n");
try {
PreparedStatement stmt = null;
//insere 20 pessoas na "ou=funcionarios"
for( int i = 1; i <= 20; i++ ){
String insertSQL =
"INSERT INTO uid=func_" + i + ",ou=funcionarios,o=empresa," + BASE_DN +
"(objectClass,objectClass,objectClass,objectClass,cn,sn,uid)" +
" VALUES (top,person,inetOrgPerson,organizationalPerson, " +
"Nome " + i + ", Sobrenome " + i + ", func_" + i + ")" ;
stmt = con.prepareStatement( insertSQL );
stmt.executeUpdate();
}
//consulta o sobrenome das pessoas da "ou=funcionarios"
String querySQL = "SELECT sn FROM ou=funcionarios,o=empresa," + BASE_DN;
stmt = con.prepareStatement( querySQL );
ResultSet rs = stmt.executeQuery();
while( rs.next() ){
System.out.println( rs.getString( "sn" ) );
}
//atualiza o sobrenome do funcionário 1
String updateSQL =
"UPDATE uid=func_1,ou=funcionarios,o=empresa," + BASE_DN +
" SET sn=Novo Sobrenome Funcionário 1" ;
stmt = con.prepareStatement( updateSQL );
stmt.executeUpdate();
//exclui todas as pessoas da "ou=funcionarios"
String deleteSQL =
"DELETE FROM ou=funcionarios,o=empresa," + BASE_DN +
" WHERE objectClass=person";
//este where serve para não excluir também a "ou=funcionarios"
stmt = con.prepareStatement( deleteSQL );
stmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
O código acima é apenas uma amostra de como fica mais intuitivo trabalhar com LDAP utilizando SQL. Procurei manter todo o código dentro do método “main” porque fica mais fácil para postar. Mas caso você esteja pensando em utilizá-lo seria interessante refatorá-lo.



Olá Paulo!
Estou tentando desenvolver um navegador LDAP, que tenha como principal funcionalidade a execução de comandos SQL para a base, mas, estou fazendo um select e ele parece estar nulo, sem trazer resultado algum.
A conexao é estabelecida normalmente e a consistencia do select é valida, porem, quando realizo a depuração o LdapResultSet parece nao ter armazenado nenhum valor resultante do select.
Voce poderia dar uma dica?
Obrigado.
Olá Guilherme,
você poderia me passar o código da consulta e a estrutura do seu serviço de diretório?
ps: com relação a sua idéia de desenvolver um browser que execute consultas SQL, dê uma olhada nesse link: http://myvd.sourceforge.net/browser.html
Abs!
Opa,
Eu ja havia localizado esse navegador nas minhas buscas mas pelo que vi nao é feito para windows, voce sabe se existe um para tal?
Aqui vai o codigo (infelizmente não poderei passar a estrutura de diretorios, apenas o select que esta sendo executado e que esta no comentario que antecede o metodo de execução da Query – query(String query)):
public String conectar(String servidor, String porta, String banco_nome, String usuario, char[] senha) throws ClassNotFoundException{
String s = new String(senha);
String log_conexao;
if(conexao_ativa != true){
try {
Class.forName(“com.octetstring.jdbcLdap.sql.JdbcLdapDriver”);
//DriverManager.registerDriver(new com.octetstring.jdbcLdap.sql.JdbcLdapDriver());
conexao = DriverManager.getConnection(“jdbc:ldap://”+servidor+”:”+porta+”/dc=etadb?SEARCH_SCOPE:=subTreeScope”, usuario, s);
if(conexao != null){
log_conexao = “Conectado.\n”;
conexao_ativa = true;
return log_conexao;
}
else{
log_conexao = “Não foi possível conectar.\n”;
return log_conexao;
}
} catch (SQLException e) {
log_conexao = “Não foi possível conectar:\n”+e.getMessage()+”\n”;
return log_conexao;
}
}
else{
log_conexao = “Já existe uma conexão ativa.\n”;
return log_conexao;
}
}
/* Método que executa a Query :
* SELECT eTID from eTRoleContainerName=Roles,eTNamespaceName=CommonObjects,dc=BR_ITSECURITY,dc=etadb WHERE eTRoeleName = ‘BR-BLU-ACCESS XP’
*/
public ResultSet query(String query) throws SQLException{
this.query = query;
//Execução da Query
if(conexao_ativa == true){
try {
stmt = conexao.prepareStatement(query);
} catch (SQLException e) {
log_query = “Não foi possivel criar a Query:\n”+e.getMessage();
}
try {
rquery = stmt.executeQuery();
log_query = “Executado com sucesso:\n”+”>”+query;
} catch (SQLException e) {
log_query = “Nao foi possivel executar a Query:\n”+e.getMessage();
}
return rquery;
}
else{
log_query = “Desconectado do Servidor.”;
rquery = null;
return rquery;
}
}