Project sponsored by



Project hosted on

SourceForge Logo



The LDAP driver is built to be flexible and work with various schemas. Unfortunately, due to the nature of LDAP itself, this driver is not as flexible as the SQL based drivers. DLZ comes with an LDAP schema which was designed for DNS data. You may use it or design your own. The DLZ schema is used for the example configuration detailed below.

LDAP data is usually arranged in a tree structure. The DLZ schema easily supports two tree structures. Both hold the exact same data, but the first (tree structure 1) provides a bit more organization for human users. The diagrams below demonstrate the two tree structures. This configuration example will use tree structure 1.

LDAP objects also use inheritance. The diagram below demonstrates the inheritance of the objects in the DLZ schema.
Below is a small set of sample data in LDIF format. In this example, o=bind-dlz is the root of the LDAP server. DNS data is stored in ou=dns,o=bind-dlz.
# server suffix - o=bind-dlz

dn: o=bind-dlz
objectclass: organization
o: bind-dlz

dn: ou=dns,o=bind-dlz
objectclass: organizationalUnit
ou: dns

dn: dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzZone
dlzZoneName: example.com

dn: dlzHostName=@,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzHost
dlzHostName: @

dn: dlzHostName=www,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzHost
dlzHostName: www

dn: dlzHostName=mail,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzHost
dlzHostName: mail

dn: dlzHostName=backup,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzHost
dlzHostName: backup

dn: dlzHostName=ns1,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzHost
dlzHostName: ns1

dn: dlzHostName=ns2,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzHost
dlzHostName: ns2

dn: dlzHostName=~,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzHost
dlzHostName: ~

dn: dlzRecordID=1,dlzHostName=@,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzGenericRecord
dlzRecordID: 1
dlzHostName: @
dlzType: txt
dlzData: "this is a text record"
dlzTTL: 10

dn: dlzRecordID=2,dlzHostName=www,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzARecord
dlzRecordID: 2
dlzHostName: www
dlzType: a
dlzIPAddr: 192.168.0.1
dlzTTL: 10

dn: dlzRecordID=3,dlzHostName=mail,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzARecord
dlzRecordID: 3
dlzHostName: mail
dlzType: a
dlzIPAddr: 192.168.0.2
dlzTTL: 10

dn: dlzRecordID=4,dlzHostName=backup,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzARecord
dlzRecordID: 4
dlzHostName: backup
dlzType: a
dlzIPAddr: 192.168.0.3
dlzTTL: 10

dn: dlzRecordID=5,dlzHostName=@,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzMXRecord
dlzRecordID: 5
dlzHostName: @
dlzType: mx
dlzData: mail
dlzPreference: 20
dlzTTL: 10

dn: dlzRecordID=6,dlzHostName=@,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzMXRecord
dlzRecordID: 6
dlzHostName: @
dlzType: mx
dlzData: backup
dlzPreference: 40
dlzTTL: 10

dn: dlzRecordID=7,dlzHostName=www,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzMXRecord
dlzRecordID: 7
dlzHostName: www
dlzType: mx
dlzData: backup
dlzPreference: 40
dlzTTL: 10

dn: dlzRecordID=8,dlzHostName=www,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzMXRecord
dlzRecordID: 8
dlzHostName: www
dlzType: mx
dlzData: mail
dlzPreference: 20
dlzTTL: 10

dn: dlzRecordID=9,dlzHostName=ns1,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzARecord
dlzRecordID: 9
dlzHostName: ns1
dlzType: a
dlzIPAddr: 192.168.0.4
dlzTTL: 10

dn: dlzRecordID=10,dlzHostName=ns2,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzARecord
dlzRecordID: 10
dlzHostName: ns2
dlzType: a
dlzIPAddr: 192.168.0.5
dlzTTL: 10

dn: dlzRecordID=11,dlzHostName=@,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzSOARecord
dlzRecordID: 11
dlzHostName: @
dlzType: soa
dlzSerial: 2
dlzRefresh: 2800
dlzRetry: 7200
dlzExpire: 604800
dlzMinimum: 86400
dlzAdminEmail: root.example.com.
dlzPrimaryns: ns1.example.com.
dlzTTL: 10

dn: dlzRecordID=12,dlzHostName=@,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzNSRecord
dlzRecordID: 12
dlzHostName: @
dlzType: ns
dlzData: ns1.example.com.
dlzTTL: 10

dn: dlzRecordID=13,dlzHostName=@,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzNSRecord
dlzRecordID: 13
dlzHostName: @
dlzType: ns
dlzData: ns2
dlzTTL: 10

dn: dlzRecordID=14,dlzHostName=~,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzARecord
dlzRecordID: 14
dlzHostName: ~
dlzType: a
dlzIPAddr: 192.168.0.250
dlzTTL: 10

dn: dlzRecordID=15,dlzZoneName=example.com,ou=dns,o=bind-dlz
objectclass: dlzXFR
dlzRecordID: 15
dlzIPAddr: 127.0.0.1

These configuration samples have their long LDAP URL queries broken over multiple lines for readability on this page. When creating a real configuration, each LDAP URL should be on a single line with no spaces in any part of the URL.

This configuration will provide the best performance because it uses the fewest queries to obtain the information it needs. BIND is built single threaded on most UN*X based systems so one database connection (as configured here) is generally sufficient. If your system builds BIND multi-threaded by default, then you should configure your server to use more database connections. The MySQL documentation has a list of which systems are built single threaded by default.

When setting up your configuration, pay very close attention to spaces! If you include a space where you shouldn't, or don't include a space where you should, either your query will not work with the database, or BIND may not be able to properly parse the query results.

dlz "ldap zone" {
        database "ldap 1
           v3 simple {cn=Manager,o=bind-dlz} {secret} 192.168.2.12
           ldap:///dlzZoneName=%zone%,ou=dns,o=bind-dlz???objectclass=dlzZone
           ldap:///dlzHostName=%record%,dlzZoneName=%zone%,ou=dns,o=bind-dlz?
              dlzTTL,dlzType,dlzPreference,dlzData,dlzIPAddr,dlzPrimaryNS,
              dlzAdminEmail,dlzSerial,dlzRefresh,dlzRetry,dlzExpire,dlzMinimum?
              sub?objectclass=dlzAbstractRecord";
};

If you must support zone transfers with DLZ, use the configuration below with this example schema. Notice the section of the configuration in GREEN. It is a pair of brackets with NO SPACES between it. It is important that the brackets have no spaces. We are telling the driver not to use an LDAP query there. If there are any spaces between the brackets, the driver will think there is an LDAP query to execute and then fail when it does try to run it.

dlz "ldap zone" {
        database "ldap 1
           v3 simple {cn=Manager,o=bind-dlz} {secret} 192.168.2.12
           ldap:///dlzZoneName=%zone%,ou=dns,o=bind-dlz???objectclass=dlzZone
           ldap:///dlzHostName=%record%,dlzZoneName=%zone%,ou=dns,o=bind-dlz?
                 dlzTTL,dlzType,dlzPreference,dlzData,dlzIPAddr,dlzPrimaryNS,
                 dlzAdminEmail,dlzSerial,dlzRefresh,dlzRetry,dlzExpire,dlzMinimum?
                 sub?objectclass=dlzAbstractRecord
           {}
           ldap:///dlzZoneName=%zone%,ou=dns,o=bind-dlz?dlzTTL,dlzType,dlzHostName,
                 dlzPreference,dlzData,dlzIPAddr,dlzPrimaryNS,dlzAdminEmail,
                 dlzSerial,dlzRefresh,dlzRetry,dlzExpire,dlzMinimum?
                 sub?objectclass=dlzAbstractRecord
           ldap:///dlzZoneName=%zone%,ou=dns,o=bind-dlz??sub?
                 (&(objectclass=dlzXFR)(dlzIPAddr=%client%))";
};