The LdapJdbc driver allows reading LDAP directories via JDBC. Using SQL queries, data from an LDAP server can be extracted and processed just like from a database table.
LDAP ObjectClasses are addressed as tables for querying. Three components are used in the query:
inetOrgPerson, groupOfNames)cn, mail, telephoneNumber)The driver uses JNDI (Java Naming and Directory Interface) for LDAP communication and the SQL parser from basejdbc for query processing.
jdbc:ldap://server:port/baseDN (unencrypted)
jdbc:ldaps://server:port/baseDN (with SSL/TLS)
Unencrypted (LDAP on port 389):
jdbc:ldap://localhost:389/dc=example,dc=com
jdbc:ldap://ldap.myorg.de:389/o=myorg,c=de
Encrypted (LDAPS on port 636):
jdbc:ldaps://ldap.company.com:636/dc=company,dc=com
jdbc:ldaps://secure.example.com:636/ou=users,dc=example,dc=com
The URL consists of:
The connection can be established with authentication.
| Property | Description | Required |
|---|---|---|
bindDN |
The Distinguished Name (DN) for authentication | No (anonymous if not specified) |
password |
The password for authentication | No |
When no credentials are specified, an anonymous LDAP bind occurs:
Connection conn = DriverManager.getConnection(
"jdbc:ldap://localhost:389/dc=example,dc=com");
Properties props = new Properties();
props.setProperty("bindDN", "cn=admin,dc=example,dc=com");
props.setProperty("password", "secret");
Connection conn = DriverManager.getConnection(
"jdbc:ldap://localhost:389/dc=example,dc=com", props);
For encrypted connections use jdbc:ldaps:// and port 636:
Properties props = new Properties();
props.setProperty("bindDN", "cn=admin,dc=example,dc=com");
props.setProperty("password", "secret");
// Use ldaps:// and port 636 for encrypted connection
Connection conn = DriverManager.getConnection(
"jdbc:ldaps://ldap.company.com:636/dc=company,dc=com", props);
Note: For LDAPS you may need additional Java configuration for SSL certificates:
// Optional: Configure SSL certificates
System.setProperty("javax.net.ssl.trustStore", "/path/to/truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
SELECT dn, cn, mail, telephoneNumber
FROM inetOrgPerson
This searches the entire directory tree below the BaseDN for all entries with ObjectClass inetOrgPerson and returns the specified attributes.
The LdapJdbc driver uses the FILTER clause instead of WHERE for LDAP-specific filtering. The FILTER expression uses LDAP filter syntax:
SELECT dn, cn, mail
FROM inetOrgPerson
FILTER (mail=*@example.com)
-- Exact match
FILTER (uid=jdoe)
-- Wildcard search
FILTER (cn=John*)
-- Multiple conditions (AND)
FILTER (&(mail=*@example.com)(ou=IT))
-- Multiple conditions (OR)
FILTER (|(title=Manager)(title=Director))
-- Negation
FILTER (!(employeeType=contractor))
The driver supports all LDAP ObjectClasses. Commonly used ones are:
| ObjectClass | Description | Typical Attributes |
|---|---|---|
person |
Base person | dn, cn, sn |
organizationalPerson |
Organizational person | cn, sn, title, telephoneNumber, ou |
inetOrgPerson |
Internet organizational person | uid, cn, sn, mail, givenName, displayName |
groupOfNames |
Group | cn, member |
organizationalUnit |
Organizational unit | ou |
Note: Table names (ObjectClasses) are case-insensitive and are automatically converted to lowercase.
The available columns depend on the ObjectClass. The driver:
dn column is always available and serves as the Primary Keydn - Distinguished Name (always available, Primary Key)cn - Common Namesn - SurnamegivenName - First namemail - Email addresstelephoneNumber - Phone numberuid - User IDtitle - Title/positiondisplayName - Display nameou - Organizational UnitLDAP attributes can have multiple values (e.g. several email addresses). The driver concatenates these with "; ":
mail = "john@example.com; john.doe@company.com"
The LdapJdbc driver supports special system tables for metadata:
SELECT table_name, table_type, remarks
FROM system.table_list
WHERE table_name LIKE '%person%'
Returns all available ObjectClasses (tables).
SELECT column_name, type_name, remarks
FROM system.column_list
WHERE table_name = 'inetorgperson'
Returns all available attributes for an ObjectClass.
SELECT table_name, column_name
FROM system.primary_key_list
WHERE table_name = 'inetorgperson'
Returns the primary key columns (for LDAP always dn).
SELECT dn, cn, mail, telephoneNumber
FROM inetOrgPerson
SELECT dn, cn, mail, title
FROM inetOrgPerson
FILTER (mail=*@example.com)
SELECT dn, cn, member
FROM groupOfNames
The member attribute contains the DNs of the members, concatenated with "; " if multiple are present.
SELECT dn, ou
FROM organizationalUnit
SELECT dn, cn, mail, title
FROM inetOrgPerson
FILTER (title=*Manager*)
SELECT dn, cn, mail, telephoneNumber
FROM inetOrgPerson
FILTER (&(mail=*@example.com)(|(title=Developer)(title=Engineer)))
Searches for users with:
The conceptual mapping between LDAP and JDBC is as follows:
| LDAP Concept | JDBC Concept | Description |
|---|---|---|
| LDAP Server | Database | The LDAP server contains the data |
| ObjectClass | Table | An ObjectClass defines the type of entries |
| Entry | Row | An LDAP entry corresponds to a row |
| Attributes | Column | LDAP attributes are columns |
| Distinguished Name (DN) | Primary Key | The DN uniquely identifies an entry |
| LDAP Filter | WHERE/FILTER | Filtering of entries |
SELECT statementsFILTER clausesystem.table_list, system.column_list, system.primary_key_list)DatabaseMetaData functionsThe LdapJdbc driver uses:
"; "The FILTER clause uses the standard LDAP filter syntax (RFC 4515):
| Operator | Meaning | Example | ||
|---|---|---|---|---|
= |
Equality | (cn=John Doe) |
||
* |
Wildcard | (cn=John*) |
||
& |
AND | (&(cn=John*)(mail=*@example.com)) |
||
| ` | ` | OR | `( | (title=Manager)(title=Director))` |
! |
Negation | (!(ou=Sales)) |
||
>= |
Greater than or equal | (uidNumber>=1000) |
||
<= |
Less than or equal | (uidNumber<=9999) |
Simple filter:
FILTER (uid=jdoe)
Wildcard at end:
FILTER (cn=John*)
Wildcard at beginning:
FILTER (mail=*@example.com)
Wildcard in middle:
FILTER (cn=*Doe*)
AND combination:
FILTER (&(ou=IT)(title=*Developer*))
OR combination:
FILTER (|(ou=IT)(ou=Development))
Complex filter:
FILTER (&(objectClass=inetOrgPerson)(|(mail=*@example.com)(mail=*@company.com))(!(employeeType=inactive)))
Export all active users from an LDAP directory:
SELECT dn, uid, cn, mail, telephoneNumber, title
FROM inetOrgPerson
FILTER (!(employeeStatus=inactive))
SELECT cn AS group_name, member
FROM groupOfNames
With further processing you can create a membership matrix.
SELECT dn, ou
FROM organizationalUnit
SELECT dn, cn, mail, telephoneNumber
FROM inetOrgPerson
FILTER (&(cn=*${searchterm}*)(!(employeeType=inactive)))
Replace ${searchterm} with the user input.
Find users without email address:
SELECT dn, cn, uid
FROM inetOrgPerson
FILTER (!(mail=*))
The LdapJdbc driver can be seamlessly integrated into datasqill workflows:
Step 1: Query LDAP data
-- Source: LDAP
SELECT dn, uid, cn, mail, telephoneNumber
FROM inetOrgPerson
FILTER (ou=Marketing)
Step 2: Insert into target database
-- Target: PostgreSQL/MySQL/...
INSERT INTO users (ldap_dn, username, full_name, email, phone)
VALUES (?, ?, ?, ?, ?)
Use the driver in datasqill to regularly synchronize LDAP data with a database.
Cause: LDAP server not reachable or incorrect URL
Solution:
telnet ldap.example.com 389jdbc:ldap://server:port/baseDNCause: The ObjectClass does not contain the attribute in the schema
Solution:
SELECT * FROM system.column_list WHERE table_name = 'objectclass'Cause: Filter too restrictive or BaseDN incorrect
Solution:
Cause: Wrong schema used
Solution:
system instead of xyzFROM system.table_list instead of FROM xyz.table_list