Project sponsored by
Project hosted on
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%))";
    };