3216 lines
104 KiB
Diff
3216 lines
104 KiB
Diff
diff --git a/Makefile.am b/Makefile.am
|
|
index f5ff369..31ba5d6 100644
|
|
--- a/Makefile.am
|
|
+++ b/Makefile.am
|
|
@@ -2,4 +2,4 @@ ACLOCAL_AMFLAGS = -I m4
|
|
|
|
SUBDIRS = doc src
|
|
|
|
-doc_DATA = README NEWS
|
|
+dist_doc_DATA = README.md NEWS COPYING
|
|
diff --git a/NEWS b/NEWS
|
|
index 12aa18a..8fac0dd 100644
|
|
--- a/NEWS
|
|
+++ b/NEWS
|
|
@@ -1,3 +1,14 @@
|
|
+11.0
|
|
+====
|
|
+[1] The plugin was ported to BIND 9.11. Minimal BIND version is now 9.11.0rc1.
|
|
+ https://fedorahosted.org/bind-dyndb-ldap/ticket/161
|
|
+
|
|
+[2] Configuration format in named.conf is different
|
|
+ and incompatible with all previous versions. Please see README.md.
|
|
+
|
|
+[3] Obsolete plugin options were removed:
|
|
+ cache_ttl, psearch, serial_autoincrement, zone_refresh.
|
|
+
|
|
10.1
|
|
====
|
|
[1] Prevent crash while reloading previously invalid but now valid DNS zone.
|
|
diff --git a/README b/README
|
|
deleted file mode 100644
|
|
index 2fd09b5..0000000
|
|
--- a/README
|
|
+++ /dev/null
|
|
@@ -1,539 +0,0 @@
|
|
-1. Introduction
|
|
-===============
|
|
-
|
|
-The dynamic LDAP back-end is a plug-in for BIND that provides an LDAP
|
|
-database back-end capabilities. For now, it requires that BIND is patched
|
|
-to support dynamic loading of database back-ends. You can get a patch
|
|
-for your version here:
|
|
-
|
|
- https://github.com/pspacek/bind-dynamic_db
|
|
-
|
|
-Hopefully, the patch will once be included in the official BIND release.
|
|
-
|
|
-BIND >= 9.9.0 is required.
|
|
-
|
|
-2. Features
|
|
-===========
|
|
-
|
|
-* support for dynamic updates
|
|
-* SASL authentication
|
|
-* SyncRepl (RFC 4533) for run-time synchronization with LDAP server
|
|
-* read-query performance nearly same as with plain BIND
|
|
-* AXFR and IXFR zone transfers are supported
|
|
-* DNSSEC in-line signing is supported, including dynamic updates
|
|
-
|
|
-
|
|
-3. Installation
|
|
-===============
|
|
-
|
|
-To install the LDAP back-end, extract the tarball and go to the unpacked
|
|
-directory. Then follow these steps:
|
|
-
|
|
-$ ./configure --libdir=<libdir>
|
|
-$ make
|
|
-
|
|
-Where <libdir> is a directory where your libdns is installed. This is
|
|
-typically going to be /usr/lib or /usr/lib64 on 64 bit systems.
|
|
-
|
|
-If configure script complains that it "Can't obtain libdns version",
|
|
-please verify you have installed bind development files (package bind9-dev
|
|
-or bind-devel) and you exported correct CPPFLAGS via
|
|
-"export CPPFLAGS=`isc-config.sh --cflags`" command.
|
|
-
|
|
-Then, to install, run this as root:
|
|
-# make install
|
|
-
|
|
-This will install the file ldap.so into the <libdir>/bind/ directory.
|
|
-
|
|
-Alternatively, the latest version can be obtained from Git repository.
|
|
-You can use following commands to prepare latest source tree for compilation:
|
|
-
|
|
-$ git clone https://git.fedorahosted.org/git/bind-dyndb-ldap.git
|
|
-$ cd bind-dyndb-ldap
|
|
-$ autoreconf -fvi
|
|
-
|
|
-4. LDAP schema
|
|
-==============
|
|
-
|
|
-You can find the complete LDAP schema in the documentation directory. An
|
|
-example zone ldif is available in the doc directory.
|
|
-
|
|
-4.1 Master zone (idnsZone)
|
|
---------------------------
|
|
-Object class idnsZone is equivalent to type "master" statement in named.conf.
|
|
-
|
|
-Attributes:
|
|
-* idnsAllowDynUpdate
|
|
- Allow dynamic update of records in this zone. If attribute doesn't exist,
|
|
- value "dyn_update" from plugin configuration will be used.
|
|
-
|
|
-* idnsAllowQuery
|
|
- Specifies BIND9 zone ACL element as one string.
|
|
-
|
|
- Example 1: idnsAllowQuery: 192.0.2.1;
|
|
- In the first example above, only the client with 192.0.2.1 IP address
|
|
- is allowed to query records from the zone.
|
|
-
|
|
- Example 2: idnsAllowQuery: !192.0.2.33; 192.0.2.0/24;
|
|
- In the second example, queries from client 192.0.2.33 are refused
|
|
- but queries from all other clients in the 192.0.2.0/24 network
|
|
- are allowed.
|
|
-
|
|
- You can specify IPv4/IPv6 address, IPv4/IPv6 network address in CIDR
|
|
- format, and "any" or "none" keywords. The "!" prefix (for example
|
|
- !192.0.2.33) means negation of the ACL element.
|
|
-
|
|
- If not set, then zone inherits global allow-query from named.conf.
|
|
-
|
|
-* idnsAllowTransfer
|
|
- Uses same format as idnsAllowQuery. Allows zone transfers for matching
|
|
- clients.
|
|
-
|
|
- If not set then zone inherits global allow-transfer from named.conf.
|
|
-
|
|
-* idnsAllowSyncPTR
|
|
- Allow synchronization of A/AAAA records in zone with PTR records in reverse
|
|
- zone. Reverse zone must have Dynamic update allowed.
|
|
- (See idnsAllowDynUpdate attribute and dyn_update configuration parameter.)
|
|
-
|
|
-* idnsForwardPolicy (default "first")
|
|
- Specifies BIND9 zone forward policy. Proprietary value "none"
|
|
- is equivalent to "forwarders {};" in BIND configuration,
|
|
- i.e. effectively disables forwarding and ignores idnsForwarders
|
|
- attribute.
|
|
-
|
|
- Values "first" and "only" are relevant in conjunction with a valid
|
|
- idnsForwarders attribute. Their meaning is same as in BIND9.
|
|
-
|
|
-* idnsForwarders
|
|
- Defines multiple IP addresses to which recursive queries will be
|
|
- forwarded. This is equivalent to "forwarders" statement in "master"
|
|
- zone configuration.
|
|
-
|
|
- I.e. local BIND replies authoritatively to queries when possible
|
|
- (including authoritative NXDOMAIN answers) so forwarding affects only
|
|
- queries made by BIND to answer recursive queries which cannot be
|
|
- answered locally. Please see
|
|
- https://lists.isc.org/pipermail/bind-users/2006-January/060810.html
|
|
- https://lists.isc.org/pipermail/bind-users/2011-March/083244.html
|
|
-
|
|
- It is multi-value attribute: Each IP address (and optional port) has to
|
|
- be in own value. BIND9 syntax for "forwarders" is required.
|
|
- Optional port can be specified by adding " port <number>" after IP
|
|
- address. IPv4 and IPv6 addresses are supported.
|
|
- Examples: "1.2.3.4" or "1.2.3.4 port 553" or "A::B" or "A::B port 553"
|
|
-
|
|
-* idnsName
|
|
- Absolute name of DNS zone. It is recommended to use names with trailing
|
|
- period, e.g. "example.com."
|
|
-
|
|
-* idnsSecInlineSigning (default FALSE)
|
|
- DNSSEC in-line signing configuration. Value TRUE is equivalent to
|
|
- following zone configuration in named.conf (default BIND values):
|
|
-
|
|
- auto-dnssec maintain;
|
|
- sig-validity-interval 2592000; # 30 days
|
|
- # re-sign interval will be 648000 seconds = 7.5 days
|
|
- sig-signing-signatures 10;
|
|
- sig-signing-nodes 10;
|
|
- sig-signing-type 65534;
|
|
- update-check-ksk yes;
|
|
- dnssec-loadkeys-interval 60; # minutes
|
|
- key-directory "<plugin-instance-dir>/<zone-name>/keys";
|
|
-
|
|
- There is no way to change those values at this moment.
|
|
-
|
|
-* idnsSOAserial
|
|
- SOA serial number. It is automatically incremented after each change
|
|
- in LDAP. External changes done by other LDAP clients are detected via
|
|
- RFC 4533 (so-called syncrepl).
|
|
-
|
|
- If serial number is lower than current UNIX timestamp, then
|
|
- it is set to the timestamp value. If SOA serial is greater or equal
|
|
- to current timestamp, then the serial is incremented by one.
|
|
- (This is equivalent to BIND option 'serial-update-method unix'.)
|
|
-
|
|
- In multi-master LDAP environments it is recommended to make
|
|
- idnsSOAserial attribute non-replicated (locally significant).
|
|
- It is recommended not to use multiple masters for single slave zone
|
|
- if SOA serial is locally significant because serial numbers between
|
|
- masters aren't synchronized. It will cause problems with zone
|
|
- transfers from multiple masters to single slave.
|
|
-
|
|
-* idnsZoneActive
|
|
- Boolean which speicifies if particular DNS zone should be visible
|
|
- to clients or not. This attribute can be changed at run-time.
|
|
-
|
|
- Inactive zones are loaded into memory in the same way as active zones.
|
|
- The only difference is that inactive zones are not added to DNS view
|
|
- used by bind-dyndb-ldap.
|
|
-
|
|
- Zone will be re-added to DNS view if idnsActiveZone attribute is
|
|
- changed to TRUE so the change should be almost immediate.
|
|
-
|
|
- Usual zone maintenance (serial number maintenance, DNSSEC in-line
|
|
- signing etc.) is done for all zones, no matter if the zone
|
|
- is active or not. This allows us to maintain zone journal so IXFR
|
|
- works correctly even after zone re-activation.
|
|
-
|
|
-* nSEC3PARAMRecord
|
|
- NSEC3PARAM resource record definition according to RFC5155.
|
|
- Zone without NSEC3PARAM RR will use NSEC by default.
|
|
-
|
|
-
|
|
-4.2 Forward zone (idnsForwardZone)
|
|
-----------------------------------
|
|
-Object class idnsForwardZone is equivalent to type "forward" statement
|
|
-in named.conf.
|
|
-
|
|
-Attributes:
|
|
-* idnsForwarders
|
|
- Defines multiple IP addresses to which all queries for sub-tree of DNS
|
|
- will be forwarded. This is equivalent to "forwarders" statement in
|
|
- "forward" zone configuration.
|
|
-
|
|
- It is multi-value attribute: Each IP address (and optional port) has to
|
|
- be in own value. BIND9 syntax for "forwarders" is required.
|
|
- Optional port can be specified by adding " port <number>" after IP
|
|
- address. IPv4 and IPv6 addresses are supported.
|
|
- Examples: "1.2.3.4" or "1.2.3.4 port 553" or "A::B" or "A::B port 553"
|
|
-
|
|
-* idnsForwardPolicy (default "first")
|
|
- Specifies BIND9 zone forward policy. Proprietary value "none"
|
|
- is equivalent to "forwarders {};" in BIND configuration,
|
|
- i.e. effectively disables forwarding and ignores idnsForwarders
|
|
- attribute.
|
|
-
|
|
- Values "first" and "only" are relevant in conjunction with a valid
|
|
- idnsForwarders attribute. Their meaning is same as in BIND9.
|
|
-
|
|
-* idnsName
|
|
- Absolute name of DNS zone. It is recommended to use names with trailing
|
|
- period, e.g. "example.com."
|
|
-
|
|
-Forward zones may conflict with automatic empty zones (defined in RFC 6303)
|
|
-because empty zones are authoritative and thus have higher priority
|
|
-than forwarding.
|
|
-Bind-dyndb-ldap will automatically unload empty zones which are super/sub
|
|
-domains of a forward zones if the forwarding policy is "only".
|
|
-A warning will be issued (and zone not unloaded) if the policy is "first"
|
|
-because this policy does not guarantee that queries will not leak to
|
|
-the public Internet.
|
|
-
|
|
-Unloaded empty zones will not be loaded back even if the forward zone is later
|
|
-deleted. The empty zones will be loaded on each BIND reload.
|
|
-
|
|
-
|
|
-4.3 Global configuration object (idnsConfigObject)
|
|
---------------------------------------------------
|
|
-Object class idnsConfigObject provides global configuration common
|
|
-for all zones.
|
|
-
|
|
-Attributes:
|
|
-* idnsAllowSyncPTR
|
|
- Semantics is equivalent to "sync_ptr" option described in plugin's
|
|
- config and to idnsAllowSyncPTR attribute in idnsZone.
|
|
-
|
|
-* idnsForwarders
|
|
-* idnsForwardPolicy
|
|
- Semantics is equivalent to "forward" statement in named.conf.
|
|
- Syntax is the same as in forward zone, please see previous section.
|
|
-
|
|
-
|
|
-4.4 Per-server configuration object (idnsServerConfigObject)
|
|
-------------------------------------------------------------
|
|
-Object class idnsConfigObject provides global configuration common
|
|
-for all zones. A plugin instance will read configuration
|
|
-only from entries with matching idnsServerId.
|
|
-
|
|
-Attributes:
|
|
-* idnsServerId
|
|
- Configuration identifier (arbitrary string).
|
|
- A plugin instance will use only objects whose idnsServerId value
|
|
- matches server_id value in plugin's config.
|
|
-
|
|
-* idnsForwarders
|
|
-* idnsForwardPolicy
|
|
- Same meaning as in global configuration object (idnsConfigObject).
|
|
-
|
|
-* idnsSOAmName
|
|
- Equivalent to fake_mname option in plugin's config.
|
|
-
|
|
-* idnsSubstitutionVariable
|
|
- This attribute associates string value with user-defined name.
|
|
- These named variables can be used later in record template processing.
|
|
- Variable name is specified as LDAP sub-type. (The attribute cannot be
|
|
- used without sub-type. Exactly one instance of each sub-type
|
|
- is required.)
|
|
- For further information please see
|
|
- https://fedorahosted.org/bind-dyndb-ldap/wiki/Design/RecordGenerator
|
|
-
|
|
- LIMITATION: Current plugin version supports only "ipalocation" variable
|
|
-
|
|
-
|
|
-4.5 Record template (idnsTemplateObject)
|
|
-----------------------------------------
|
|
-Object class idnsTemplateObject provides facility for dynamic resource record
|
|
-generation. The template entry must contain idnsTemplateAttribute with
|
|
-string template.
|
|
-
|
|
-Optionally the same entry can contain statically defined resource records
|
|
-in *Record attributes. All statically defined record values are ignored
|
|
-when template is present and substitution into template is successful.
|
|
-The substitution is successful only if all variables used
|
|
-by the template string are defined.
|
|
-
|
|
-Attributes:
|
|
-* idnsTemplateAttribute
|
|
- String subtitution template. All occurrences of \{variable_name\}
|
|
- are replaced with respective strings from plugin configuration.
|
|
- Remaining parts of the original string are just copied into the output.
|
|
-
|
|
- Double-escaped strings \\{ \\} do not trigger substitution.
|
|
- Nested references will expand only innermost variable: \{\{var1\}\}
|
|
- Non-matching parentheses and other garbage will be copied verbatim
|
|
- without triggering an error.
|
|
-
|
|
- Resulting resource record type is specified as LDAP sub-type.
|
|
- (The attribute cannot be used without sub-type.
|
|
- Exactly one instance of each sub-type is required.)
|
|
-
|
|
- Example - LDIF snippet:
|
|
- idnsSubstitutionVariable;ipalocation: brno
|
|
- idnsTemplateAttribute;CNAMERecord: server.\{substitutionvariable_ipalocation\}
|
|
- will generate CNAME record: server.brno
|
|
- For further information please see
|
|
- https://fedorahosted.org/bind-dyndb-ldap/wiki/Design/RecordGenerator
|
|
-
|
|
-
|
|
-5. Configuration
|
|
-================
|
|
-
|
|
-To configure dynamic loading of back-end, you must put a "dynamic-db"
|
|
-clause into your named.conf. The clause must then be followed by a
|
|
-string denoting the name. The name is not that much important, it is
|
|
-passed to the plug-in and might be used for example, for logging
|
|
-purposes. Following after that is a set of options enclosed between
|
|
-curly brackets.
|
|
-
|
|
-The most important option here is "library". It names a shared object
|
|
-file that will be opened and loaded. The "arg" option specifies a string
|
|
-that is passed directly to the plugin. You can specify multiple "arg"
|
|
-options. The LDAP back-end follows the convention that the first word of
|
|
-this string is the name of the setting and the rest is the value.
|
|
-
|
|
-
|
|
-5.1 Configuration options
|
|
--------------------------
|
|
-List of configuration options follows:
|
|
-
|
|
-5.1.1 LDAP connection
|
|
----------------------
|
|
-uri
|
|
- The Uniform Resource Identifier pointing to the LDAP server we
|
|
- wish to connect to. This string is directly passed to the
|
|
- ldap_initialize(3) function. This option is mandatory.
|
|
- Example: ldap://ldap.example.com
|
|
-
|
|
-connections (default 2)
|
|
- Number of connections the LDAP driver should try to establish to
|
|
- the LDAP server. It's best if this matches the number of threads
|
|
- BIND creates, for performance reasons. However, your LDAP server
|
|
- configuration might only allow certain number of connections per
|
|
- client.
|
|
-
|
|
-base
|
|
- This is the search base that will be used by the LDAP back-end
|
|
- to search for DNS zones. It is mandatory.
|
|
-
|
|
-auth_method (default "none")
|
|
- The method used to authenticate to the LDAP server. Currently
|
|
- supported methods are "none", "simple" and "sasl". The none
|
|
- method is effectively a simple authentication without password.
|
|
-
|
|
-bind_dn (default "")
|
|
- Distinguished Name used to bind to the LDAP server. If this is
|
|
- empty and the auth_method is set to "simple", the LDAP back-end
|
|
- will fall-back and use the "none" authentication method.
|
|
-
|
|
-password (default "")
|
|
- Password for simple and SASL authentication. If the authentication
|
|
- method is set to "simple" and the password is empty, the LDAP
|
|
- driver will fall-back to the "none" authentication method.
|
|
-
|
|
-sasl_mech (default "GSSAPI")
|
|
- Name of the SASL mechanism to be used for negotiation.
|
|
-
|
|
-sasl_auth_name
|
|
- The user name to be used for SASL authentication.
|
|
-
|
|
-sasl_user
|
|
- The user name to be used for SASL proxy authorization.
|
|
-
|
|
-sasl_password
|
|
- The password to use for the SASL authentication.
|
|
-
|
|
-sasl_realm
|
|
- The SASL realm name.
|
|
-
|
|
-krb5_keytab
|
|
- Path to the kerberos keytab containing service credentials to be used
|
|
- for SASL authentication. Append the "FILE:" prefix to the file path.
|
|
- (FILE:/etc/named.keytab, for example)
|
|
-
|
|
-krb5_principal
|
|
- Kerberos principal of the service, used for SASL authentication.
|
|
- If not set then it is copied from "sasl_user" option. Principal
|
|
- is loaded from file specified in "krb5_keytab" option.
|
|
-
|
|
-timeout (default 10)
|
|
- Timeout (in seconds) of the queries to the LDAP server. If the LDAP
|
|
- server don't respond before this timeout then lookup is aborted and
|
|
- BIND returns SERVFAIL. Value "0" means infinite timeout (no timeout).
|
|
-
|
|
-reconnect_interval (default 60)
|
|
- Time (in seconds) after that the plugin should try to connect to LDAP
|
|
- server again in case connection is lost and immediate reconnection
|
|
- fails.
|
|
-
|
|
-ldap_hostname (default "")
|
|
- Sets hostname of the LDAP server. When it is set to "", actual
|
|
- /bin/hostname is used. Please prefer "uri" option, this option should be
|
|
- used only in special cases, for example when GSSAPI authentication
|
|
- is used and named service has Kerberos principal different from
|
|
- /bin/hostname output.
|
|
-
|
|
-
|
|
-5.1.2 Special DNS features
|
|
---------------------------
|
|
-fake_mname (default "")
|
|
- Ignore value of the idnsSOAmName (primary master DNS name) attribute
|
|
- and use this value instead. This allows multiple BIND processes to share
|
|
- one LDAP database and every BIND reports itself as a primary master in
|
|
- SOA record, for example.
|
|
-
|
|
-sync_ptr (default no)
|
|
- Set this option to "yes" if you would like to keep PTR record
|
|
- synchronized with coresponding A/AAAA record for all zones.
|
|
- If this option is set to "no", the LDAP driver will check
|
|
- the idnsAllowSyncPTR attribute which specifies the synchronization
|
|
- policy for PTR records in a zone. When an A/AAAA record is deleted
|
|
- the PTR record must point to the same hostname.
|
|
-
|
|
-dyn_update (default no)
|
|
- Set this option to "yes" if you would like to allow dynamic zone updates.
|
|
- This setting can be overridden for each zone individually
|
|
- by idnsAllowDynUpdate attribute.
|
|
-
|
|
-
|
|
-5.1.3 Plumbing
|
|
---------------
|
|
-verbose_checks (default no)
|
|
- Set this option to "yes" if you would like to log all failures
|
|
- in internal CHECK() macros. This option is recommended only for
|
|
- debugging purposes. It could produce huge amount of log messages
|
|
- on a loaded system!
|
|
-
|
|
-directory (default is
|
|
- "dyndb-ldap/<current instance name from dynamic-db directive>")
|
|
- Specifies working directory for plug-in. The path has to be writeable
|
|
- by named because plug-in will create sub-directory for each zone.
|
|
- These sub-directories will contain temporary files like zone dump, zone
|
|
- journal, zone keys etc.
|
|
- The path is relative to "directory" specified in BIND options.
|
|
- See section 6 (DNSSEC) for examples.
|
|
-
|
|
-5.2 Sample configuration
|
|
-------------------------
|
|
-Let's take a look at a sample configuration:
|
|
-
|
|
-options {
|
|
- directory "/var/named/";
|
|
-};
|
|
-
|
|
-dynamic-db "my_db_name" {
|
|
- library "ldap.so";
|
|
- arg "uri ldap://ldap.example.com";
|
|
- arg "base cn=dns, dc=example, dc=com";
|
|
- arg "auth_method none";
|
|
-};
|
|
-
|
|
-With this configuration, the LDAP back-end will try to connect to server
|
|
-ldap.example.com with simple authentication, without any password. It
|
|
-will then use RFC 4533 refresh&persist search in the "cn=dns,dc=example,dc=com"
|
|
-base for entries with object class idnsZone and idnsRecord.
|
|
-For each idnsZone entry it will find, it will register a new zone with BIND.
|
|
-For each idnsRecord entry it will create domain name in particular zone.
|
|
-The LDAP back-end will keep each record it gets from LDAP in its memory.
|
|
-
|
|
-Working directory for the plug-in will be "/var/named/dyndb-ldap/my_db_name/",
|
|
-so hypothetical zone "example.com" will use sub-directory
|
|
-"/var/named/dyndb-ldap/my_db_name/master/example.com/".
|
|
-
|
|
-5.3 Configuration in LDAP
|
|
--------------------------
|
|
-Some options can be configured in LDAP as idnsConfigObject attributes.
|
|
-Value configured in LDAP has priority over value in configuration file.
|
|
-(This behavior will change in future versions!)
|
|
-
|
|
-Following options are supported (option = attribute equivalent):
|
|
-
|
|
-forwarders = idnsForwarders (BIND native option)
|
|
-forward = idnsForwardPolicy (BIND native option)
|
|
-sync_ptr = idnsAllowSyncPTR
|
|
-
|
|
-Forward policy option cannot be set without setting forwarders at the same time.
|
|
-
|
|
-
|
|
-6. DNSSEC support
|
|
-=================
|
|
-
|
|
-In-line signing support in this plugin allows to use this BIND feature
|
|
-for zones in LDAP.
|
|
-
|
|
-Signatures are automatically generated by plugin during zone loading
|
|
-and signatures are never written back to LDAP. DNSKEY, RRSIG, NSEC and NSEC3
|
|
-records in LDAP are ignored because they are automatically managed by BIND.
|
|
-
|
|
-NSEC3 can be enabled by writting NSEC3PARAM RR to particular zone object
|
|
-in LDAP.
|
|
-
|
|
-Dynamic updates made to in-line signed zones are written back to LDAP as usual
|
|
-and respective signatures are automatically re-generated as necessary.
|
|
-
|
|
-Key management has to be handled by user, i.e. user has to
|
|
-generate/delete keys and configure key timestamps as appropriate.
|
|
-
|
|
-Key directory for particular DNS zone is automatically configured to value:
|
|
-<plugin-instance-dir>/master/<zone-name>/keys
|
|
-
|
|
-<plugin-instance-dir> is described in section 5.1.3 of this file.
|
|
-<zone-name> is (transformed) textual representation of zone name without
|
|
-trailing period.
|
|
-
|
|
-Zone name will be automatically transformed before usage:
|
|
-- root zone is translated to '@' to prevent collision with filesystem '.'
|
|
-- digits, hyphen and underscore are left intact
|
|
-- letters of English alphabet are downcased
|
|
-- all other characters are escaped using %ASCII_HEX form, e.g. '/' => '%2F'
|
|
-- final dot is omited
|
|
-- labels are separated with '.'
|
|
-
|
|
-Example:
|
|
-* BIND directory: "/var/named"
|
|
-* bind-dyndb-ldap directory: "dyndb-ldap"
|
|
-* LDAP instance name: "ipa"
|
|
-* DNS zone: "example.com."
|
|
-* Resulting keys directory: "/var/named/dyndb-ldap/ipa/master/example.com/keys"
|
|
-
|
|
-* DNS zone: "TEST.0/1.a."
|
|
-* Resulting keys directory: "/var/named/dyndb-ldap/ipa/master/test.0%2F1.a/keys"
|
|
-
|
|
-Make sure that keys directory and files is readable by user used for BIND.
|
|
-
|
|
-
|
|
-7. License
|
|
-==========
|
|
-
|
|
-This package is licensed under the GNU General Public License, version 2
|
|
-only. See file COPYING for more information.
|
|
diff --git a/README.md b/README.md
|
|
new file mode 100644
|
|
index 0000000..de9cd1f
|
|
--- /dev/null
|
|
+++ b/README.md
|
|
@@ -0,0 +1,591 @@
|
|
+1. Introduction
|
|
+===============
|
|
+The dynamic LDAP back-end is a plug-in for BIND that provides an LDAP
|
|
+database back-end capabilities. It requires dyndb interface which is present
|
|
+in BIND versions >= 9.11.0rc1.
|
|
+
|
|
+
|
|
+2. Features
|
|
+===========
|
|
+
|
|
+* support for dynamic updates
|
|
+* SASL authentication
|
|
+* SyncRepl (RFC 4533) for run-time synchronization with LDAP server
|
|
+* read-query performance nearly same as with plain BIND
|
|
+* AXFR and IXFR zone transfers are supported
|
|
+* DNSSEC in-line signing is supported, including dynamic updates
|
|
+
|
|
+
|
|
+3. Installation
|
|
+===============
|
|
+
|
|
+To install the LDAP back-end, extract the tarball and go to the unpacked
|
|
+directory. Then follow these steps:
|
|
+
|
|
+ $ ./configure --libdir=<libdir>
|
|
+ $ make
|
|
+
|
|
+Where `<libdir>` is a directory where your libdns is installed. This is
|
|
+typically going to be `/usr/lib` or `/usr/lib64` on 64 bit systems.
|
|
+
|
|
+If configure script complains that it `Can't obtain libdns version`,
|
|
+please verify you have installed bind development files (package bind9-dev
|
|
+or bind-devel) and you exported correct CPPFLAGS via
|
|
+
|
|
+ $ export CPPFLAGS=`isc-config.sh --cflags`
|
|
+
|
|
+Then, to install, run this as root:
|
|
+
|
|
+ $ make install
|
|
+
|
|
+This will install the file `ldap.so` into the `<libdir>/bind/` directory.
|
|
+
|
|
+Alternatively, the latest version can be obtained from Git repository.
|
|
+You can use following commands to prepare latest source tree for compilation:
|
|
+
|
|
+ $ git clone https://git.fedorahosted.org/git/bind-dyndb-ldap.git
|
|
+ $ cd bind-dyndb-ldap
|
|
+ $ autoreconf -fvi
|
|
+
|
|
+4. LDAP schema
|
|
+==============
|
|
+
|
|
+You can find the complete LDAP schema in the documentation directory. An
|
|
+example zone ldif is available in the doc directory.
|
|
+
|
|
+4.1 Master zone (idnsZone)
|
|
+--------------------------
|
|
+Object class `idnsZone` is equivalent to type `master` statement in `named.conf`.
|
|
+
|
|
+### Attributes
|
|
+* idnsAllowDynUpdate
|
|
+
|
|
+ Allow dynamic update of records in this zone. If attribute doesn't exist,
|
|
+ value `dyn_update` from plugin configuration will be used.
|
|
+
|
|
+* idnsAllowQuery
|
|
+
|
|
+ Specifies BIND9 zone ACL element as one string.
|
|
+
|
|
+ * Example 1: `idnsAllowQuery: 192.0.2.1;`
|
|
+
|
|
+ In the first example above, only the client with 192.0.2.1
|
|
+ IP address is allowed to query records from the zone.
|
|
+
|
|
+ * Example 2: `idnsAllowQuery: !192.0.2.33; 192.0.2.0/24;`
|
|
+
|
|
+ In the second example, queries from client 192.0.2.33
|
|
+ are refused but queries from all other clients in
|
|
+ the 192.0.2.0/24 network are allowed.
|
|
+
|
|
+ You can specify IPv4/IPv6 address, IPv4/IPv6 network address in CIDR
|
|
+ format, and `any` or `none` keywords. The `!` prefix (for example
|
|
+ `!192.0.2.33`) means negation of the ACL element.
|
|
+
|
|
+ If not set, then zone inherits global allow-query from named.conf.
|
|
+
|
|
+* idnsAllowTransfer
|
|
+
|
|
+ Uses same format as `idnsAllowQuery`. Allows zone transfers for matching
|
|
+ clients.
|
|
+
|
|
+ If not set then zone inherits global allow-transfer from named.conf.
|
|
+
|
|
+* idnsAllowSyncPTR
|
|
+
|
|
+ Allow synchronization of A/AAAA records in zone with PTR records in reverse
|
|
+ zone. Reverse zone must have Dynamic update allowed.
|
|
+ (See `idnsAllowDynUpdate` attribute and `dyn_update` configuration parameter.)
|
|
+
|
|
+* idnsForwardPolicy (default `first`)
|
|
+
|
|
+ Specifies BIND9 zone forward policy. Proprietary value `none`
|
|
+ is equivalent to `forwarders {};` in BIND configuration,
|
|
+ i.e. effectively disables forwarding and ignores `idnsForwarders`
|
|
+ attribute.
|
|
+
|
|
+ Values `first` and `only` are relevant in conjunction with a valid
|
|
+ idnsForwarders attribute. Their meaning is same as in BIND9.
|
|
+
|
|
+* idnsForwarders
|
|
+
|
|
+ Defines multiple IP addresses to which recursive queries will be
|
|
+ forwarded. This is equivalent to `forwarders` statement in `master`
|
|
+ zone configuration.
|
|
+
|
|
+ I.e. local BIND replies authoritatively to queries when possible
|
|
+ (including authoritative NXDOMAIN answers) so forwarding affects only
|
|
+ queries made by BIND to answer recursive queries which cannot be
|
|
+ answered locally. Please see
|
|
+ https://lists.isc.org/pipermail/bind-users/2006-January/060810.html
|
|
+ https://lists.isc.org/pipermail/bind-users/2011-March/083244.html
|
|
+
|
|
+ It is multi-value attribute: Each IP address (and optional port) has to
|
|
+ be in own value. BIND9 syntax for `forwarders` is required.
|
|
+ Optional port can be specified by adding ` port <number>` after IP
|
|
+ address. IPv4 and IPv6 addresses are supported.
|
|
+ Examples:
|
|
+ * `1.2.3.4`
|
|
+ * `1.2.3.4 port 553`
|
|
+ * `A::B`
|
|
+ * `A::B port 553`
|
|
+
|
|
+* idnsName
|
|
+
|
|
+ Absolute name of DNS zone. It is recommended to use names with trailing
|
|
+ period, e.g. `example.com.`
|
|
+
|
|
+* idnsSecInlineSigning (default `FALSE`)
|
|
+
|
|
+ DNSSEC in-line signing configuration. Value TRUE is equivalent to
|
|
+ following zone configuration in named.conf (default BIND values):
|
|
+
|
|
+ auto-dnssec maintain;
|
|
+ sig-validity-interval 2592000; # 30 days
|
|
+ # re-sign interval will be 648000 seconds = 7.5 days
|
|
+ sig-signing-signatures 10;
|
|
+ sig-signing-nodes 10;
|
|
+ sig-signing-type 65534;
|
|
+ update-check-ksk yes;
|
|
+ dnssec-loadkeys-interval 60; # minutes
|
|
+ key-directory "<plugin-instance-dir>/<zone-name>/keys";
|
|
+
|
|
+ There is no way to change those values at this moment.
|
|
+
|
|
+* idnsSOAserial
|
|
+
|
|
+ SOA serial number. It is automatically incremented after each change
|
|
+ in LDAP. External changes done by other LDAP clients are detected via
|
|
+ RFC 4533 (so-called syncrepl).
|
|
+
|
|
+ If serial number is lower than current UNIX timestamp, then
|
|
+ it is set to the timestamp value. If SOA serial is greater or equal
|
|
+ to current timestamp, then the serial is incremented by one.
|
|
+ (This is equivalent to BIND option 'serial-update-method unix'.)
|
|
+
|
|
+ In multi-master LDAP environments it is recommended to make
|
|
+ idnsSOAserial attribute non-replicated (locally significant).
|
|
+ It is recommended not to use multiple masters for single slave zone
|
|
+ if SOA serial is locally significant because serial numbers between
|
|
+ masters aren't synchronized. It will cause problems with zone
|
|
+ transfers from multiple masters to single slave.
|
|
+
|
|
+* idnsZoneActive
|
|
+
|
|
+ Boolean which speicifies if particular DNS zone should be visible
|
|
+ to clients or not. This attribute can be changed at run-time.
|
|
+
|
|
+ Inactive zones are loaded into memory in the same way as active zones.
|
|
+ The only difference is that inactive zones are not added to DNS view
|
|
+ used by bind-dyndb-ldap.
|
|
+
|
|
+ Zone will be re-added to DNS view if idnsActiveZone attribute is
|
|
+ changed to TRUE so the change should be almost immediate.
|
|
+
|
|
+ Usual zone maintenance (serial number maintenance, DNSSEC in-line
|
|
+ signing etc.) is done for all zones, no matter if the zone
|
|
+ is active or not. This allows us to maintain zone journal so IXFR
|
|
+ works correctly even after zone re-activation.
|
|
+
|
|
+* nSEC3PARAMRecord
|
|
+
|
|
+ NSEC3PARAM resource record definition according to RFC5155.
|
|
+ Zone without NSEC3PARAM RR will use NSEC by default.
|
|
+
|
|
+
|
|
+4.2 Forward zone (idnsForwardZone)
|
|
+----------------------------------
|
|
+Object class `idnsForwardZone` is equivalent to type `forward` statement
|
|
+in named.conf.
|
|
+
|
|
+### Attributes
|
|
+* idnsForwarders
|
|
+
|
|
+ Defines multiple IP addresses to which all queries for sub-tree of DNS
|
|
+ will be forwarded. This is equivalent to `forwarders` statement in
|
|
+ `forward` zone configuration.
|
|
+
|
|
+ It is multi-value attribute: Each IP address (and optional port) has to
|
|
+ be in own value. BIND9 syntax for `forwarders` is required.
|
|
+ Optional port can be specified by adding ` port <number>` after IP
|
|
+ address. IPv4 and IPv6 addresses are supported.
|
|
+ Examples:
|
|
+ * `1.2.3.4`
|
|
+ * `1.2.3.4 port 553`
|
|
+ * `A::B`
|
|
+ * `A::B port 553`
|
|
+
|
|
+* idnsForwardPolicy (default `first`)
|
|
+
|
|
+ Specifies BIND9 zone forward policy. Proprietary value `none`
|
|
+ is equivalent to `forwarders {};` in BIND configuration,
|
|
+ i.e. effectively disables forwarding and ignores `idnsForwarders`
|
|
+ attribute.
|
|
+
|
|
+ Values `first` and `only` are relevant in conjunction with a valid
|
|
+ `idnsForwarders` attribute. Their meaning is same as in BIND9.
|
|
+
|
|
+* idnsName
|
|
+
|
|
+ Absolute name of DNS zone. It is recommended to use names with trailing
|
|
+ period, e.g. `example.com.`
|
|
+
|
|
+Forward zones may conflict with automatic empty zones (defined in RFC 6303)
|
|
+because empty zones are authoritative and thus have higher priority
|
|
+than forwarding.
|
|
+Bind-dyndb-ldap will automatically unload empty zones which are super/sub
|
|
+domains of a forward zones if the forwarding policy is `only`.
|
|
+A warning will be issued (and zone not unloaded) if the policy is `first`
|
|
+because this policy does not guarantee that queries will not leak to
|
|
+the public Internet.
|
|
+
|
|
+Unloaded empty zones will not be loaded back even if the forward zone is later
|
|
+deleted. The empty zones will be loaded on each BIND reload.
|
|
+
|
|
+
|
|
+4.3 Global configuration object (idnsConfigObject)
|
|
+--------------------------------------------------
|
|
+Object class idnsConfigObject provides global configuration common
|
|
+for all zones.
|
|
+
|
|
+### Attributes
|
|
+* idnsAllowSyncPTR
|
|
+
|
|
+ Semantics is equivalent to `sync_ptr` option described in plugin's
|
|
+ config and to `idnsAllowSyncPTR` attribute in `idnsZone`.
|
|
+
|
|
+* idnsForwarders
|
|
+* idnsForwardPolicy
|
|
+
|
|
+ Semantics is equivalent to `forward` statement in `named.conf`.
|
|
+ Syntax is the same as in forward zone, please see previous section.
|
|
+
|
|
+
|
|
+4.4 Per-server configuration object (idnsServerConfigObject)
|
|
+------------------------------------------------------------
|
|
+Object class idnsConfigObject provides global configuration common
|
|
+for all zones. A plugin instance will read configuration
|
|
+only from entries with matching idnsServerId.
|
|
+
|
|
+### Attributes
|
|
+* idnsServerId
|
|
+
|
|
+ Configuration identifier (arbitrary string).
|
|
+ A plugin instance will use only objects whose `idnsServerId` value
|
|
+ matches `server_id` value in plugin's config.
|
|
+
|
|
+* idnsForwarders
|
|
+* idnsForwardPolicy
|
|
+
|
|
+ Same meaning as in global configuration object (`idnsConfigObject`).
|
|
+
|
|
+* idnsSOAmName
|
|
+
|
|
+ Equivalent to `fake_mname` option in plugin's config.
|
|
+
|
|
+* idnsSubstitutionVariable
|
|
+
|
|
+ This attribute associates string value with user-defined name.
|
|
+ These named variables can be used later in record template processing.
|
|
+ Variable name is specified as LDAP sub-type. (The attribute cannot be
|
|
+ used without sub-type. Exactly one instance of each sub-type
|
|
+ is required.)
|
|
+ For further information please see
|
|
+ https://fedorahosted.org/bind-dyndb-ldap/wiki/Design/RecordGenerator
|
|
+
|
|
+ LIMITATION: Current plugin version supports only `ipalocation` variable
|
|
+
|
|
+
|
|
+4.5 Record template (idnsTemplateObject)
|
|
+----------------------------------------
|
|
+Object class idnsTemplateObject provides facility for dynamic resource record
|
|
+generation. The template entry must contain idnsTemplateAttribute with
|
|
+string template.
|
|
+
|
|
+Optionally the same entry can contain statically defined resource records
|
|
+in *Record attributes. All statically defined record values are ignored
|
|
+when template is present and substitution into template is successful.
|
|
+The substitution is successful only if all variables used
|
|
+by the template string are defined.
|
|
+
|
|
+### Attributes
|
|
+* idnsTemplateAttribute
|
|
+ String subtitution template. All occurrences of \{variable_name\}
|
|
+ are replaced with respective strings from plugin configuration.
|
|
+ Remaining parts of the original string are just copied into the output.
|
|
+
|
|
+ Double-escaped strings \\{ \\} do not trigger substitution.
|
|
+ Nested references will expand only innermost variable: \{\{var1\}\}
|
|
+ Non-matching parentheses and other garbage will be copied verbatim
|
|
+ without triggering an error.
|
|
+
|
|
+ Resulting resource record type is specified as LDAP sub-type.
|
|
+ (The attribute cannot be used without sub-type.
|
|
+ Exactly one instance of each sub-type is required.)
|
|
+
|
|
+ Example - LDIF snippet:
|
|
+
|
|
+ idnsSubstitutionVariable;ipalocation: brno
|
|
+ idnsTemplateAttribute;CNAMERecord: server.\{substitutionvariable_ipalocation\}
|
|
+ will generate CNAME record: `server.brno`
|
|
+
|
|
+ For further information please see
|
|
+ https://fedorahosted.org/bind-dyndb-ldap/wiki/Design/RecordGenerator
|
|
+
|
|
+
|
|
+5. Configuration
|
|
+================
|
|
+
|
|
+To configure dynamic loading of back-end, you must put a `dyndb`
|
|
+clause into your named.conf. The clause must then be followed by a
|
|
+string denoting the name of the instance and path to dyndb library.
|
|
+
|
|
+The name is not that much important, it is passed to the plug-in
|
|
+and is used for logging purposes and for naming working directories.
|
|
+
|
|
+Library path must point to a shared object file that will be opened and loaded.
|
|
+
|
|
+Name and library path have to be followed by set of options enclosed between
|
|
+curly brackets. Example:
|
|
+
|
|
+ dyndb "example-ldap" "/usr/lib64/bind/ldap.so" {
|
|
+ uri "ldap://ldap.example.com";
|
|
+ base "cn=dns, dc=example,dc=com";
|
|
+ auth_method "none";
|
|
+ };
|
|
+
|
|
+5.1 Configuration options
|
|
+-------------------------
|
|
+List of configuration options follows:
|
|
+
|
|
+5.1.1 LDAP connection
|
|
+---------------------
|
|
+* uri
|
|
+
|
|
+ The Uniform Resource Identifier pointing to the LDAP server we
|
|
+ wish to connect to. This string is directly passed to the
|
|
+ ldap_initialize(3) function. This option is mandatory.
|
|
+ Example: "ldap://ldap.example.com"
|
|
+
|
|
+* connections (default 2)
|
|
+
|
|
+ Number of connections the LDAP driver should try to establish to
|
|
+ the LDAP server. It's best if this matches the number of threads
|
|
+ BIND creates, for performance reasons. However, your LDAP server
|
|
+ configuration might only allow certain number of connections per
|
|
+ client.
|
|
+
|
|
+* base
|
|
+ This is the search base that will be used by the LDAP back-end
|
|
+ to search for DNS zones. This option is mandatory.
|
|
+ Example: "cn=dns, dc=example,dc=com";
|
|
+
|
|
+* auth_method (default "none")
|
|
+
|
|
+ The method used to authenticate to the LDAP server. Currently
|
|
+ supported methods are "none", "simple" and "sasl". The none
|
|
+ method is effectively a simple authentication without password.
|
|
+
|
|
+* bind_dn (default "")
|
|
+
|
|
+ Distinguished Name used to bind to the LDAP server. If this is
|
|
+ empty and the auth_method is set to "simple", the LDAP back-end
|
|
+ will fall-back and use the "none" authentication method.
|
|
+
|
|
+* password (default "")
|
|
+
|
|
+ Password for simple and SASL authentication. If the authentication
|
|
+ method is set to "simple" and the password is empty, the LDAP
|
|
+ driver will fall-back to the "none" authentication method.
|
|
+
|
|
+* sasl_mech (default "GSSAPI")
|
|
+
|
|
+ Name of the SASL mechanism to be used for negotiation.
|
|
+
|
|
+* sasl_auth_name
|
|
+
|
|
+ The user name to be used for SASL authentication.
|
|
+
|
|
+* sasl_user
|
|
+
|
|
+ The user name to be used for SASL proxy authorization.
|
|
+
|
|
+* sasl_password
|
|
+
|
|
+ The password to use for the SASL authentication.
|
|
+
|
|
+* sasl_realm
|
|
+
|
|
+ The SASL realm name.
|
|
+
|
|
+* krb5_keytab
|
|
+
|
|
+ Path to the kerberos keytab containing service credentials to be used
|
|
+ for SASL authentication. Append the "FILE:" prefix to the file path.
|
|
+ Example: "FILE:/etc/named.keytab"
|
|
+
|
|
+* krb5_principal
|
|
+
|
|
+ Kerberos principal of the service, used for SASL authentication.
|
|
+ If not set then it is copied from "sasl_user" option. Principal
|
|
+ is loaded from file specified in "krb5_keytab" option.
|
|
+
|
|
+* timeout (default 10)
|
|
+
|
|
+ Timeout (in seconds) of the queries to the LDAP server. If the LDAP
|
|
+ server don't respond before this timeout then lookup is aborted and
|
|
+ BIND returns SERVFAIL. Value "0" means infinite timeout (no timeout).
|
|
+
|
|
+* reconnect_interval (default 60)
|
|
+
|
|
+ Time (in seconds) after that the plugin should try to connect to LDAP
|
|
+ server again in case connection is lost and immediate reconnection
|
|
+ fails.
|
|
+
|
|
+* ldap_hostname (default "")
|
|
+
|
|
+ Sets hostname of the LDAP server. When it is set to "", actual
|
|
+ `/bin/hostname` is used. Please prefer `uri` option, this option should be
|
|
+ used only in special cases, for example when GSSAPI authentication
|
|
+ is used and named service has Kerberos principal different from
|
|
+ `/bin/hostname` output.
|
|
+
|
|
+
|
|
+5.1.2 Special DNS features
|
|
+--------------------------
|
|
+* fake_mname
|
|
+
|
|
+ Ignore value of the idnsSOAmName (primary master DNS name) attribute
|
|
+ and use this value instead. This allows multiple BIND processes to share
|
|
+ one LDAP database and every BIND reports itself as a primary master in
|
|
+ SOA record, for example.
|
|
+
|
|
+* sync_ptr (default no)
|
|
+
|
|
+ Set this option to `yes` if you would like to keep PTR record
|
|
+ synchronized with coresponding A/AAAA record for all zones.
|
|
+ If this option is set to `no`, the LDAP driver will check
|
|
+ the idnsAllowSyncPTR attribute which specifies the synchronization
|
|
+ policy for PTR records in a zone. When an A/AAAA record is deleted
|
|
+ the PTR record must point to the same hostname.
|
|
+
|
|
+* dyn_update (default no)
|
|
+
|
|
+ Set this option to `yes` if you would like to allow dynamic zone updates.
|
|
+ This setting can be overridden for each zone individually
|
|
+ by idnsAllowDynUpdate attribute.
|
|
+
|
|
+
|
|
+5.1.3 Plumbing
|
|
+--------------
|
|
+* verbose_checks (default no)
|
|
+
|
|
+ Set this option to `yes` if you would like to log all failures
|
|
+ in internal CHECK() macros. This option is recommended only for
|
|
+ debugging purposes. It could produce huge amount of log messages
|
|
+ on a loaded system!
|
|
+
|
|
+* directory (default is
|
|
+ `dyndb-ldap/<current instance name from dynamic-db directive>`)
|
|
+
|
|
+ Specifies working directory for plug-in. The path has to be writeable
|
|
+ by named because plug-in will create sub-directory for each zone.
|
|
+ These sub-directories will contain temporary files like zone dump, zone
|
|
+ journal, zone keys etc.
|
|
+ The path is relative to `directory` specified in BIND options.
|
|
+ See section 6 (DNSSEC) for examples.
|
|
+
|
|
+5.2 Sample configuration
|
|
+------------------------
|
|
+Let's take a look at a sample configuration:
|
|
+
|
|
+ options {
|
|
+ directory "/var/named/";
|
|
+ };
|
|
+
|
|
+ dyndb "my_db_name" "/usr/lib64/bind/ldap.so" {
|
|
+ uri "ldap://ldap.example.com";
|
|
+ base "cn=dns, dc=example,dc=com";
|
|
+ auth_method "none";
|
|
+ };
|
|
+
|
|
+With this configuration, the LDAP back-end will try to connect to server
|
|
+ldap.example.com with simple authentication, without any password. It
|
|
+will then use RFC 4533 refresh&persist search in the `cn=dns,dc=example,dc=com`
|
|
+base for entries with object class `idnsZone` and `idnsRecord`.
|
|
+For each idnsZone entry it will find, it will register a new zone with BIND.
|
|
+For each idnsRecord entry it will create domain name in particular zone.
|
|
+The LDAP back-end will keep each record it gets from LDAP in its memory.
|
|
+
|
|
+Working directory for the plug-in will be `/var/named/dyndb-ldap/my_db_name/`,
|
|
+so hypothetical zone `example.com` will use sub-directory
|
|
+`/var/named/dyndb-ldap/my_db_name/master/example.com/`.
|
|
+
|
|
+5.3 Configuration in LDAP
|
|
+-------------------------
|
|
+Some options can be configured in LDAP as `idnsConfigObject` attributes.
|
|
+Value configured in LDAP has priority over value in configuration file.
|
|
+(This behavior will change in future versions!)
|
|
+
|
|
+Following options are supported (option = attribute equivalent):
|
|
+option | LDAP attribute
|
|
+-----------| --------------
|
|
+forwarders | idnsForwarders (BIND native option)
|
|
+forward | idnsForwardPolicy (BIND native option)
|
|
+sync_ptr | idnsAllowSyncPTR
|
|
+
|
|
+Forward policy option cannot be set without setting forwarders at the same time.
|
|
+
|
|
+
|
|
+6. DNSSEC support
|
|
+=================
|
|
+
|
|
+In-line signing support in this plugin allows to use this BIND feature
|
|
+for zones in LDAP.
|
|
+
|
|
+Signatures are automatically generated by plugin during zone loading
|
|
+and signatures are never written back to LDAP. DNSKEY, RRSIG, NSEC and NSEC3
|
|
+records in LDAP are ignored because they are automatically managed by BIND.
|
|
+
|
|
+NSEC3 can be enabled by writting NSEC3PARAM RR to particular zone object
|
|
+in LDAP.
|
|
+
|
|
+Dynamic updates made to in-line signed zones are written back to LDAP as usual
|
|
+and respective signatures are automatically re-generated as necessary.
|
|
+
|
|
+Key management has to be handled by user, i.e. user has to
|
|
+generate/delete keys and configure key timestamps as appropriate.
|
|
+
|
|
+Key directory for particular DNS zone is automatically configured to value:
|
|
+ <plugin-instance-dir>/master/<zone-name>/keys
|
|
+
|
|
+`<plugin-instance-dir>` is described in section 5.1.3 of this file.
|
|
+`<zone-name>` is (transformed) textual representation of zone name without
|
|
+trailing period.
|
|
+
|
|
+Zone name will be automatically transformed before usage:
|
|
+- root zone is translated to `@` to prevent collision with filesystem `.`
|
|
+- digits, hyphen and underscore are left intact
|
|
+- letters of English alphabet are downcased
|
|
+- all other characters are escaped using %ASCII_HEX form, e.g. `/` => `%2F`
|
|
+- final dot is omited
|
|
+- labels are separated with `.`
|
|
+
|
|
+Example:
|
|
+* BIND directory: `/var/named`
|
|
+* bind-dyndb-ldap directory: `dyndb-ldap`
|
|
+* LDAP instance name: `ipa`
|
|
+* DNS zone: `example.com.`
|
|
+* Resulting keys directory: `/var/named/dyndb-ldap/ipa/master/example.com/keys`
|
|
+
|
|
+* DNS zone: `TEST.0/1.a.`
|
|
+* Resulting keys directory: `/var/named/dyndb-ldap/ipa/master/test.0%2F1.a/keys`
|
|
+
|
|
+Make sure that keys directory and files is readable by user used for BIND.
|
|
+
|
|
+
|
|
+7. License
|
|
+==========
|
|
+
|
|
+This package is licensed under the GNU General Public License, version 2
|
|
+only. See file COPYING for more information.
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 9b26058..50e41f3 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -1,9 +1,9 @@
|
|
AC_PREREQ([2.59])
|
|
-AC_INIT([bind-dyndb-ldap], [10.1], [freeipa-devel@redhat.com])
|
|
+AC_INIT([bind-dyndb-ldap], [11.0], [freeipa-devel@redhat.com])
|
|
|
|
AM_INIT_AUTOMAKE([-Wall foreign dist-bzip2])
|
|
|
|
-AC_CONFIG_SRCDIR([src/zone_manager.h])
|
|
+AC_CONFIG_SRCDIR([src/ldap_driver.c])
|
|
AC_CONFIG_HEADERS([config.h])
|
|
AC_CONFIG_MACRO_DIR([m4])
|
|
|
|
@@ -105,18 +105,18 @@ int main(void) {
|
|
[AC_MSG_ERROR([Cross compiling is not supported.])]
|
|
)
|
|
|
|
-dnl isc__errno2result() is typically not present in standard header files
|
|
-AC_MSG_CHECKING([isc__errno2result availability in header files])
|
|
+dnl isc_errno_toresult() was not available in older header files
|
|
+AC_MSG_CHECKING([isc_errno_toresult availability])
|
|
AC_TRY_RUN([
|
|
-#include <isc/errno2result.h>
|
|
+#include <isc/errno.h>
|
|
int main(void) {
|
|
- isc__errno2result(0);
|
|
+ isc_errno_toresult(0);
|
|
return 0;
|
|
}],
|
|
[AC_MSG_RESULT([yes])],
|
|
[AC_MSG_ERROR([
|
|
- Can't find isc__errno2result() or header isc/errno2result.h:
|
|
- Please install bind-lite-devel package or similar.])],
|
|
+ Can't find isc_errno_toresult() or header isc/errno.h:
|
|
+ Please install bind-devel package or similar.])],
|
|
[AC_MSG_ERROR([Cross compiling is not supported.])]
|
|
)
|
|
|
|
diff --git a/doc/schema.ldif b/doc/schema.ldif
|
|
index 8fdc99f..77c5b0e 100644
|
|
--- a/doc/schema.ldif
|
|
+++ b/doc/schema.ldif
|
|
@@ -362,9 +362,16 @@ attributeTypes: ( 2.16.840.1.113730.3.8.5.31
|
|
NAME 'idnsServerId'
|
|
DESC 'DNS server identifier'
|
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
|
- EQUALITY caseIgnoreMatch
|
|
+ EQUALITY caseIgnoreMatch
|
|
SINGLE-VALUE )
|
|
#
|
|
+attributeTypes: ( 2.16.840.1.113730.3.8.5.29
|
|
+ NAME 'idnsTemplateAttribute'
|
|
+ DESC 'Template attribute for dynamic attribute generation'
|
|
+ EQUALITY caseIgnoreIA5Match
|
|
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
|
|
+ X-ORIGIN 'IPA v4.4' )
|
|
+#
|
|
attributeTypes: ( 2.16.840.1.113730.3.8.5.30
|
|
NAME 'idnsSubstitutionVariable'
|
|
DESC 'User defined variable for DNS plugin'
|
|
@@ -426,6 +433,6 @@ objectClasses: ( 2.16.840.1.113730.3.8.6.6
|
|
objectClasses: ( 2.16.840.1.113730.3.8.6.5
|
|
NAME 'idnsTemplateObject'
|
|
DESC 'Template object for dynamic DNS attribute generation'
|
|
- SUP top
|
|
+ SUP top
|
|
AUXILIARY
|
|
MUST ( idnsTemplateAttribute ) )
|
|
diff --git a/src/Makefile.am b/src/Makefile.am
|
|
index 238d8ef..e1e3968 100644
|
|
--- a/src/Makefile.am
|
|
+++ b/src/Makefile.am
|
|
@@ -4,7 +4,6 @@ bindplugindir=$(libdir)/bind
|
|
HDRS = \
|
|
acl.h \
|
|
bindcfg.h \
|
|
- compat.h \
|
|
empty_zones.h \
|
|
fs.h \
|
|
fwd.h \
|
|
@@ -27,7 +26,6 @@ HDRS = \
|
|
types.h \
|
|
util.h \
|
|
zone.h \
|
|
- zone_manager.h \
|
|
zone_register.h
|
|
|
|
ldap_la_SOURCES = \
|
|
@@ -54,7 +52,6 @@ ldap_la_SOURCES = \
|
|
syncrepl.c \
|
|
str.c \
|
|
zone.c \
|
|
- zone_manager.c \
|
|
zone_register.c
|
|
|
|
ldap_la_CFLAGS = -Wall -Wextra @WERROR@ -std=gnu99 -O2
|
|
diff --git a/src/compat.h b/src/compat.h
|
|
deleted file mode 100644
|
|
index 00e3da5..0000000
|
|
--- a/src/compat.h
|
|
+++ /dev/null
|
|
@@ -1,44 +0,0 @@
|
|
-/*
|
|
- * Copyright (C) 2009 bind-dyndb-ldap authors; see COPYING for license
|
|
- */
|
|
-
|
|
-#ifdef HAVE_CONFIG_H
|
|
-#include <config.h>
|
|
-#else
|
|
-#error "Can't compile without config.h"
|
|
-#endif
|
|
-
|
|
-/*
|
|
- * dns_rdatalist_fromrdataset() did not exist in older versions of libdns.
|
|
- * Add a substitude function here.
|
|
- */
|
|
-#if LIBDNS_VERSION_MAJOR < 40
|
|
-static inline isc_result_t
|
|
-dns_rdatalist_fromrdataset(dns_rdataset_t *rdataset,
|
|
- dns_rdatalist_t **rdatalist)
|
|
-{
|
|
- REQUIRE(rdatalist != NULL && rdataset != NULL);
|
|
-
|
|
- *rdatalist = rdataset->private1;
|
|
-
|
|
- return ISC_R_SUCCESS;
|
|
-}
|
|
-#endif /* LIBDNS_VERSION_MAJOR < 40 */
|
|
-
|
|
-/*
|
|
- * In older libdns versions, isc_refcount_init() was defined as a macro.
|
|
- * However, in newer versions, it is a function returning isc_result_t type.
|
|
- * This piece of code should take care of that problem.
|
|
- */
|
|
-#if LIBDNS_VERSION_MAJOR < 30
|
|
-#include <isc/refcount.h>
|
|
-
|
|
-static inline isc_result_t
|
|
-isc_refcount_init_func(isc_refcount_t *ref, unsigned int n)
|
|
-{
|
|
- isc_refcount_init(ref, n);
|
|
- return ISC_R_SUCCESS;
|
|
-}
|
|
-#undef isc_refcount_init
|
|
-#define isc_refcount_init isc_refcount_init_func
|
|
-#endif /* LIBDNS_VERSION_MAJOR < 30 */
|
|
diff --git a/src/fs.c b/src/fs.c
|
|
index 09b71d7..61c46b5 100644
|
|
--- a/src/fs.c
|
|
+++ b/src/fs.c
|
|
@@ -10,7 +10,7 @@
|
|
|
|
#include <isc/dir.h>
|
|
#include <isc/file.h>
|
|
-#include <isc/errno2result.h>
|
|
+#include <isc/errno.h>
|
|
#include <isc/result.h>
|
|
#include <isc/string.h>
|
|
#include <isc/util.h>
|
|
@@ -37,7 +37,7 @@ fs_dir_create(const char *dir_name)
|
|
if (ret == 0)
|
|
result = ISC_R_SUCCESS;
|
|
else
|
|
- result = isc__errno2result(errno);
|
|
+ result = isc_errno_toresult(errno);
|
|
|
|
if (result != ISC_R_SUCCESS && result != ISC_R_FILEEXISTS) {
|
|
log_error_r("unable to create directory '%s', working directory "
|
|
@@ -50,7 +50,7 @@ fs_dir_create(const char *dir_name)
|
|
* solely for this purpose. */
|
|
ret = chmod(dir_name, dir_mode);
|
|
if (ret != 0) {
|
|
- result = isc__errno2result(errno);
|
|
+ result = isc_errno_toresult(errno);
|
|
log_error_r("unable to chmod directory '%s', "
|
|
"working directory is '%s'",
|
|
dir_name, dir_curr);
|
|
diff --git a/src/fwd.c b/src/fwd.c
|
|
index 1f6a9e5..840f0e8 100644
|
|
--- a/src/fwd.c
|
|
+++ b/src/fwd.c
|
|
@@ -69,11 +69,7 @@ fwd_list_len(dns_forwarders_t *fwdrs) {
|
|
|
|
REQUIRE(fwdrs != NULL);
|
|
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
- for (isc_sockaddr_t *fwdr = ISC_LIST_HEAD(fwdrs->addrs);
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
for (dns_forwarder_t *fwdr = ISC_LIST_HEAD(fwdrs->fwdrs);
|
|
-#endif
|
|
fwdr != NULL;
|
|
fwdr = ISC_LIST_NEXT(fwdr, link)) {
|
|
len++;
|
|
@@ -169,11 +165,7 @@ fwd_print_list_buff(isc_mem_t *mctx, dns_forwarders_t *fwdrs,
|
|
const cfg_obj_t *faddresses;
|
|
const cfg_listelt_t *fwdr_cfg; /* config representation */
|
|
/* internal representation */
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
- isc_sockaddr_t *fwdr_int;
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
dns_forwarder_t *fwdr_int;
|
|
-#endif
|
|
|
|
isc_buffer_initnull(&tmp_buf);
|
|
tmp_buf.mctx = mctx;
|
|
@@ -197,20 +189,12 @@ fwd_print_list_buff(isc_mem_t *mctx, dns_forwarders_t *fwdrs,
|
|
* data from the internal one to cfg data structures.*/
|
|
faddresses = cfg_tuple_get(forwarders_cfg, "addresses");
|
|
for (fwdr_int = ISC_LIST_HEAD(
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
- fwdrs->addrs
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
fwdrs->fwdrs
|
|
-#endif
|
|
), fwdr_cfg = cfg_list_first(faddresses);
|
|
INSIST((fwdr_int == NULL) == (fwdr_cfg == NULL)), fwdr_int != NULL;
|
|
fwdr_int = ISC_LIST_NEXT(fwdr_int, link), fwdr_cfg = cfg_list_next(fwdr_cfg)) {
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
- fwdr_cfg->obj->value.sockaddr = *fwdr_int;
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
fwdr_cfg->obj->value.sockaddrdscp.sockaddr = fwdr_int->addr;
|
|
fwdr_cfg->obj->value.sockaddrdscp.dscp = fwdr_int->dscp;
|
|
-#endif
|
|
}
|
|
cfg_print(faddresses, buffer_append_str, &tmp_buf);
|
|
|
|
@@ -259,12 +243,7 @@ cleanup:
|
|
|
|
static isc_result_t
|
|
fwd_parse_str(const char *fwdrs_str, isc_mem_t *mctx,
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
- isc_sockaddrlist_t *fwdrs
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
- dns_forwarderlist_t *fwdrs
|
|
-#endif
|
|
- )
|
|
+ dns_forwarderlist_t *fwdrs)
|
|
{
|
|
isc_result_t result = ISC_R_SUCCESS;
|
|
cfg_parser_t *parser = NULL;
|
|
@@ -274,11 +253,7 @@ fwd_parse_str(const char *fwdrs_str, isc_mem_t *mctx,
|
|
const cfg_listelt_t *listel;
|
|
const cfg_obj_t *fwdr_cfg;
|
|
isc_sockaddr_t addr;
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
- isc_sockaddr_t *fwdr;
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
dns_forwarder_t *fwdr;
|
|
-#endif
|
|
|
|
in_port_t port = 53;
|
|
|
|
@@ -301,12 +276,8 @@ fwd_parse_str(const char *fwdrs_str, isc_mem_t *mctx,
|
|
if (isc_sockaddr_getport(&addr) == 0)
|
|
isc_sockaddr_setport(&addr, port);
|
|
CHECKED_MEM_GET_PTR(mctx, fwdr);
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
- *fwdr = addr;
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
fwdr->addr = addr;
|
|
fwdr->dscp = cfg_obj_getdscp(fwdr_cfg);
|
|
-#endif
|
|
ISC_LINK_INIT(fwdr, link);
|
|
ISC_LIST_APPEND(*fwdrs, fwdr, link);
|
|
}
|
|
@@ -320,18 +291,8 @@ cleanup:
|
|
}
|
|
|
|
static void
|
|
-fwdr_list_free(isc_mem_t *mctx,
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
- isc_sockaddrlist_t *fwdrs
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
- dns_forwarderlist_t *fwdrs
|
|
-#endif
|
|
- ) {
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
- isc_sockaddr_t *fwdr;
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
+fwdr_list_free(isc_mem_t *mctx, dns_forwarderlist_t *fwdrs) {
|
|
dns_forwarder_t *fwdr;
|
|
-#endif
|
|
while (!ISC_LIST_EMPTY(*fwdrs)) {
|
|
fwdr = ISC_LIST_HEAD(*fwdrs);
|
|
ISC_LIST_UNLINK(*fwdrs, fwdr, link);
|
|
@@ -357,11 +318,7 @@ fwd_setting_isexplicit(isc_mem_t *mctx, const settings_set_t *set,
|
|
isc_result_t result;
|
|
setting_t *setting = NULL;
|
|
dns_fwdpolicy_t fwdpolicy;
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
- isc_sockaddrlist_t fwdrs;
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
dns_forwarderlist_t fwdrs;
|
|
-#endif
|
|
|
|
REQUIRE(isexplicit != NULL);
|
|
ISC_LIST_INIT(fwdrs);
|
|
@@ -440,11 +397,7 @@ fwd_parse_ldap(ldap_entry_t *entry, settings_set_t *set) {
|
|
ldap_valuelist_t values;
|
|
ldap_value_t *value;
|
|
isc_buffer_t *tmp_buf = NULL; /* hack: only the base buffer is allocated */
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
- isc_sockaddrlist_t fwdrs;
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
dns_forwarderlist_t fwdrs;
|
|
-#endif
|
|
const char *setting_str = NULL;
|
|
|
|
/**
|
|
@@ -547,11 +500,7 @@ fwd_configure_zone(const settings_set_t *set, ldap_instance_t *inst,
|
|
isc_mem_t *mctx = NULL;
|
|
dns_view_t *view = NULL;
|
|
isc_result_t lock_state = ISC_R_IGNORE;
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
- isc_sockaddrlist_t fwdrs;
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
dns_forwarderlist_t fwdrs;
|
|
-#endif
|
|
isc_boolean_t is_global_config;
|
|
dns_fixedname_t foundname;
|
|
const char *msg_use_global_fwds;
|
|
@@ -630,13 +579,8 @@ fwd_configure_zone(const settings_set_t *set, ldap_instance_t *inst,
|
|
run_exclusive_enter(inst, &lock_state);
|
|
CHECK(fwd_delete_table(view, name, msg_obj_type, set->name));
|
|
if (isconfigured == ISC_TRUE) {
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
- CHECK(dns_fwdtable_add(view->fwdtable, name, &fwdrs,
|
|
- fwdpolicy));
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
CHECK(dns_fwdtable_addfwd(view->fwdtable, name, &fwdrs,
|
|
fwdpolicy));
|
|
-#endif
|
|
}
|
|
dns_view_flushcache(view);
|
|
run_exclusive_exit(inst, lock_state);
|
|
diff --git a/src/ldap_driver.c b/src/ldap_driver.c
|
|
index 83ec00a..b1b7336 100644
|
|
--- a/src/ldap_driver.c
|
|
+++ b/src/ldap_driver.c
|
|
@@ -9,13 +9,17 @@
|
|
#endif
|
|
|
|
#include <isc/buffer.h>
|
|
+#include <isc/commandline.h>
|
|
+#include <isc/hash.h>
|
|
+#include <isc/lib.h>
|
|
#include <isc/mem.h>
|
|
+#include <isc/once.h>
|
|
#include <isc/refcount.h>
|
|
#include <isc/util.h>
|
|
|
|
#include <dns/db.h>
|
|
#include <dns/diff.h>
|
|
-#include <dns/dynamic_db.h>
|
|
+#include <dns/dyndb.h>
|
|
#include <dns/dbiterator.h>
|
|
#include <dns/rdata.h>
|
|
#include <dns/rdataclass.h>
|
|
@@ -29,13 +33,12 @@
|
|
|
|
#include <string.h> /* For memcpy */
|
|
|
|
-#include "compat.h"
|
|
+#include "bindcfg.h"
|
|
#include "ldap_driver.h"
|
|
#include "ldap_helper.h"
|
|
#include "ldap_convert.h"
|
|
#include "log.h"
|
|
#include "util.h"
|
|
-#include "zone_manager.h"
|
|
#include "zone_register.h"
|
|
|
|
#ifdef HAVE_VISIBILITY
|
|
@@ -181,18 +184,9 @@ detach(dns_db_t **dbp)
|
|
|
|
/* !!! This could be required for optimizations (like on-disk cache). */
|
|
static isc_result_t
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
-beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp, dns_dbload_t **dbloadp)
|
|
-{
|
|
-
|
|
- UNUSED(db);
|
|
- UNUSED(addp);
|
|
- UNUSED(dbloadp);
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
|
|
UNUSED(db);
|
|
UNUSED(callbacks);
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
|
|
fatal_error("ldapdb: method beginload() should never be called");
|
|
|
|
@@ -207,17 +201,9 @@ beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
|
|
|
|
/* !!! This could be required for optimizations (like on-disk cache). */
|
|
static isc_result_t
|
|
-#if LIBDNS_VERSION_MAJOR < 140
|
|
-endload(dns_db_t *db, dns_dbload_t **dbloadp)
|
|
-{
|
|
-
|
|
- UNUSED(db);
|
|
- UNUSED(dbloadp);
|
|
-#else /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
|
|
UNUSED(db);
|
|
UNUSED(callbacks);
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
|
|
fatal_error("ldapdb: method endload() should never be called");
|
|
|
|
@@ -225,7 +211,6 @@ endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
|
|
return ISC_R_SUCCESS;
|
|
}
|
|
|
|
-#if LIBDNS_VERSION_MAJOR >= 140
|
|
static isc_result_t
|
|
serialize(dns_db_t *db, dns_dbversion_t *version, FILE *file)
|
|
{
|
|
@@ -235,23 +220,17 @@ serialize(dns_db_t *db, dns_dbversion_t *version, FILE *file)
|
|
|
|
return dns_db_serialize(ldapdb->rbtdb, version, file);
|
|
}
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
|
|
/* !!! This could be required for optimizations (like on-disk cache). */
|
|
static isc_result_t
|
|
-dump(dns_db_t *db, dns_dbversion_t *version, const char *filename
|
|
-#if LIBDNS_VERSION_MAJOR >= 31
|
|
- , dns_masterformat_t masterformat
|
|
-#endif
|
|
- )
|
|
+dump(dns_db_t *db, dns_dbversion_t *version, const char *filename,
|
|
+ dns_masterformat_t masterformat)
|
|
{
|
|
|
|
UNUSED(db);
|
|
UNUSED(version);
|
|
UNUSED(filename);
|
|
-#if LIBDNS_VERSION_MAJOR >= 31
|
|
UNUSED(masterformat);
|
|
-#endif
|
|
|
|
fatal_error("ldapdb: method dump() should never be called");
|
|
|
|
@@ -422,22 +401,14 @@ printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out)
|
|
}
|
|
|
|
static isc_result_t
|
|
-createiterator(dns_db_t *db,
|
|
-#if LIBDNS_VERSION_MAJOR >= 50
|
|
- unsigned int options,
|
|
-#else
|
|
- isc_boolean_t relative_names,
|
|
-#endif
|
|
+createiterator(dns_db_t *db, unsigned int options,
|
|
dns_dbiterator_t **iteratorp)
|
|
{
|
|
ldapdb_t *ldapdb = (ldapdb_t *) db;
|
|
|
|
REQUIRE(VALID_LDAPDB(ldapdb));
|
|
-#if LIBDNS_VERSION_MAJOR >= 50
|
|
+
|
|
return dns_db_createiterator(ldapdb->rbtdb, options, iteratorp);
|
|
-#else
|
|
- return dns_db_createiterator(ldapdb->rbtdb, relative_names, iteratorp);
|
|
-#endif
|
|
}
|
|
|
|
static isc_result_t
|
|
@@ -675,7 +646,6 @@ settask(dns_db_t *db, isc_task_t *task)
|
|
dns_db_settask(ldapdb->rbtdb, task);
|
|
}
|
|
|
|
-#if LIBDNS_VERSION_MAJOR >= 31
|
|
static isc_result_t
|
|
getoriginnode(dns_db_t *db, dns_dbnode_t **nodep)
|
|
{
|
|
@@ -685,9 +655,7 @@ getoriginnode(dns_db_t *db, dns_dbnode_t **nodep)
|
|
|
|
return dns_db_getoriginnode(ldapdb->rbtdb, nodep);
|
|
}
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 31 */
|
|
|
|
-#if LIBDNS_VERSION_MAJOR >= 45
|
|
static void
|
|
transfernode(dns_db_t *db, dns_dbnode_t **sourcep, dns_dbnode_t **targetp)
|
|
{
|
|
@@ -698,9 +666,7 @@ transfernode(dns_db_t *db, dns_dbnode_t **sourcep, dns_dbnode_t **targetp)
|
|
dns_db_transfernode(ldapdb->rbtdb, sourcep, targetp);
|
|
|
|
}
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 45 */
|
|
|
|
-#if LIBDNS_VERSION_MAJOR >= 50
|
|
static isc_result_t
|
|
getnsec3parameters(dns_db_t *db, dns_dbversion_t *version,
|
|
dns_hash_t *hash, isc_uint8_t *flags,
|
|
@@ -767,9 +733,7 @@ isdnssec(dns_db_t *db)
|
|
|
|
return dns_db_isdnssec(ldapdb->rbtdb);
|
|
}
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 50 */
|
|
|
|
-#if LIBDNS_VERSION_MAJOR >= 45
|
|
static dns_stats_t *
|
|
getrrsetstats(dns_db_t *db) {
|
|
ldapdb_t *ldapdb = (ldapdb_t *) db;
|
|
@@ -779,35 +743,7 @@ getrrsetstats(dns_db_t *db) {
|
|
return dns_db_getrrsetstats(ldapdb->rbtdb);
|
|
|
|
}
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 45 */
|
|
|
|
-#if LIBDNS_VERSION_MAJOR >= 82 && LIBDNS_VERSION_MAJOR < 140
|
|
-static isc_result_t
|
|
-rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
|
|
-{
|
|
- ldapdb_t *ldapdb = (ldapdb_t *) db;
|
|
-
|
|
- REQUIRE(VALID_LDAPDB(ldapdb));
|
|
-
|
|
- return dns_db_rpz_enabled(ldapdb->rbtdb, st);
|
|
-}
|
|
-
|
|
-static void
|
|
-rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
|
|
- dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
|
|
- dns_rdataset_t *ardataset, dns_rpz_st_t *st,
|
|
- dns_name_t *query_qname)
|
|
-{
|
|
- ldapdb_t *ldapdb = (ldapdb_t *) db;
|
|
-
|
|
- REQUIRE(VALID_LDAPDB(ldapdb));
|
|
-
|
|
- dns_db_rpz_findips(rpz, rpz_type, zone, ldapdb->rbtdb, version,
|
|
- ardataset, st, query_qname);
|
|
-}
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 82 && LIBDNS_VERSION_MAJOR < 140 */
|
|
-
|
|
-#if LIBDNS_VERSION_MAJOR >= 140
|
|
void
|
|
rpz_attach(dns_db_t *db, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num)
|
|
{
|
|
@@ -827,9 +763,7 @@ rpz_ready(dns_db_t *db)
|
|
|
|
return dns_db_rpz_ready(ldapdb->rbtdb);
|
|
}
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
|
|
-#if LIBDNS_VERSION_MAJOR >= 90
|
|
static isc_result_t
|
|
findnodeext(dns_db_t *db, dns_name_t *name,
|
|
isc_boolean_t create, dns_clientinfomethods_t *methods,
|
|
@@ -858,9 +792,7 @@ findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
|
nodep, foundname, methods, clientinfo, rdataset,
|
|
sigrdataset);
|
|
}
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 90 */
|
|
|
|
-#if LIBDNS_VERSION_MAJOR >= 140
|
|
isc_result_t
|
|
setcachestats(dns_db_t *db, isc_stats_t *stats)
|
|
{
|
|
@@ -871,11 +803,7 @@ setcachestats(dns_db_t *db, isc_stats_t *stats)
|
|
return dns_db_setcachestats(ldapdb->rbtdb, stats);
|
|
}
|
|
|
|
-#if LIBDNS_VERSION_MAJOR >= 164
|
|
size_t
|
|
-#else
|
|
-unsigned int
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 164 */
|
|
hashsize(dns_db_t *db)
|
|
{
|
|
ldapdb_t *ldapdb = (ldapdb_t *) db;
|
|
@@ -884,16 +812,23 @@ hashsize(dns_db_t *db)
|
|
|
|
return dns_db_hashsize(ldapdb->rbtdb);
|
|
}
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
+
|
|
+isc_result_t
|
|
+nodefullname(dns_db_t *db, dns_dbnode_t *node, dns_name_t *name)
|
|
+{
|
|
+ ldapdb_t *ldapdb = (ldapdb_t *) db;
|
|
+
|
|
+ REQUIRE(VALID_LDAPDB(ldapdb));
|
|
+
|
|
+ return dns_db_nodefullname(ldapdb->rbtdb, node, name);
|
|
+}
|
|
|
|
static dns_dbmethods_t ldapdb_methods = {
|
|
attach,
|
|
detach,
|
|
beginload,
|
|
endload,
|
|
-#if LIBDNS_VERSION_MAJOR >= 140
|
|
serialize, /* see dns_db_serialize(), implementation is not mandatory */
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
dump,
|
|
currentversion,
|
|
newversion,
|
|
@@ -917,37 +852,22 @@ static dns_dbmethods_t ldapdb_methods = {
|
|
ispersistent,
|
|
overmem,
|
|
settask,
|
|
-#if LIBDNS_VERSION_MAJOR >= 31
|
|
getoriginnode,
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 31 */
|
|
-#if LIBDNS_VERSION_MAJOR >= 45
|
|
transfernode,
|
|
-#if LIBDNS_VERSION_MAJOR >= 50
|
|
getnsec3parameters,
|
|
findnsec3node,
|
|
setsigningtime,
|
|
getsigningtime,
|
|
resigned,
|
|
isdnssec,
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 50 */
|
|
getrrsetstats,
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 45 */
|
|
-#if LIBDNS_VERSION_MAJOR >= 82 && LIBDNS_VERSION_MAJOR < 140
|
|
- rpz_enabled,
|
|
- rpz_findips,
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 82 && LIBDNS_VERSION_MAJOR < 140 */
|
|
-#if LIBDNS_VERSION_MAJOR >= 140
|
|
rpz_attach,
|
|
rpz_ready,
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
-#if LIBDNS_VERSION_MAJOR >= 90
|
|
findnodeext,
|
|
findext,
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 90 */
|
|
-#if LIBDNS_VERSION_MAJOR >= 140
|
|
setcachestats,
|
|
- hashsize
|
|
-#endif /* LIBDNS_VERSION_MAJOR >= 140 */
|
|
+ hashsize,
|
|
+ nodefullname
|
|
};
|
|
|
|
isc_result_t ATTR_NONNULLS
|
|
@@ -1002,18 +922,17 @@ ldapdb_associate(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type,
|
|
void *driverarg, dns_db_t **dbp) {
|
|
|
|
isc_result_t result;
|
|
- ldap_instance_t *ldap_inst = NULL;
|
|
+ ldap_instance_t *ldap_inst = driverarg;
|
|
zone_register_t *zr = NULL;
|
|
|
|
- UNUSED(driverarg); /* Currently we don't need any data */
|
|
-
|
|
REQUIRE(ISCAPI_MCTX_VALID(mctx));
|
|
- REQUIRE(argc == LDAP_DB_ARGC);
|
|
REQUIRE(type == LDAP_DB_TYPE);
|
|
REQUIRE(rdclass == LDAP_DB_RDATACLASS);
|
|
+ REQUIRE(argc == 0);
|
|
+ UNUSED(argv);
|
|
+ REQUIRE(driverarg != NULL);
|
|
REQUIRE(dbp != NULL && *dbp == NULL);
|
|
|
|
- CHECK(manager_get_ldap_instance(argv[0], &ldap_inst));
|
|
zr = ldap_instance_getzr(ldap_inst);
|
|
if (zr == NULL)
|
|
CLEANUP_WITH(ISC_R_NOTFOUND);
|
|
@@ -1026,19 +945,16 @@ cleanup:
|
|
|
|
isc_result_t
|
|
ldapdb_create(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type,
|
|
- dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
|
|
- void *driverarg, dns_db_t **dbp)
|
|
+ dns_rdataclass_t rdclass, void *driverarg, dns_db_t **dbp)
|
|
{
|
|
ldapdb_t *ldapdb = NULL;
|
|
isc_result_t result;
|
|
isc_boolean_t lock_ready = ISC_FALSE;
|
|
|
|
- UNUSED(driverarg); /* Currently we don't need any data */
|
|
-
|
|
/* Database instance name. */
|
|
- REQUIRE(argc == LDAP_DB_ARGC);
|
|
REQUIRE(type == LDAP_DB_TYPE);
|
|
REQUIRE(rdclass == LDAP_DB_RDATACLASS);
|
|
+ REQUIRE(driverarg != NULL);
|
|
REQUIRE(dbp != NULL && *dbp == NULL);
|
|
|
|
CHECKED_MEM_GET_PTR(mctx, ldapdb);
|
|
@@ -1060,7 +976,7 @@ ldapdb_create(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type,
|
|
CHECK(dns_name_dupwithoffsets(name, mctx, &ldapdb->common.origin));
|
|
|
|
CHECK(isc_refcount_init(&ldapdb->refs, 1));
|
|
- CHECK(manager_get_ldap_instance(argv[0], &ldapdb->ldap_inst));
|
|
+ ldapdb->ldap_inst = driverarg;
|
|
|
|
CHECK(dns_db_create(mctx, "rbt", name, dns_dbtype_zone,
|
|
dns_rdataclass_in, 0, NULL, &ldapdb->rbtdb));
|
|
@@ -1084,50 +1000,91 @@ cleanup:
|
|
return result;
|
|
}
|
|
|
|
-static dns_dbimplementation_t *ldapdb_imp;
|
|
-const char *ldapdb_impname = "dynamic-ldap";
|
|
+static void
|
|
+library_init(void)
|
|
+{
|
|
+ log_info("bind-dyndb-ldap version " VERSION
|
|
+ " compiled at " __TIME__ " " __DATE__
|
|
+ ", compiler " __VERSION__);
|
|
+ cfg_init_types();
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Driver version is called when loading the driver to ensure there
|
|
+ * is no API mismatch betwen the driver and the caller.
|
|
+ */
|
|
+VISIBLE int
|
|
+dyndb_version(unsigned int *flags) {
|
|
+ UNUSED(flags);
|
|
|
|
+ return (DNS_DYNDB_VERSION);
|
|
+}
|
|
|
|
+/*
|
|
+ * Driver init is called for each dyndb section in named.conf
|
|
+ * once during startup and then again on every reload.
|
|
+ *
|
|
+ * @code
|
|
+ * dyndb example-name "sample.so" { param1 param2 };
|
|
+ * @endcode
|
|
+ *
|
|
+ * @param[in] name User-defined string from dyndb "name" {}; definition
|
|
+ * in named.conf.
|
|
+ * The example above will have name = "example-name".
|
|
+ * @param[in] parameters User-defined parameters from dyndb section as one
|
|
+ * string. The example above will have
|
|
+ * params = "param1 param2";
|
|
+ * @param[out] instp Pointer to instance-specific data
|
|
+ * (for one dyndb section).
|
|
+ */
|
|
VISIBLE isc_result_t
|
|
-dynamic_driver_init(isc_mem_t *mctx, const char *name, const char * const *argv,
|
|
- dns_dyndb_arguments_t *dyndb_args)
|
|
+dyndb_init(isc_mem_t *mctx, const char *name, const char *parameters,
|
|
+ const char *file, unsigned long line, const dns_dyndbctx_t *dctx,
|
|
+ void **instp)
|
|
{
|
|
- dns_dbimplementation_t *ldapdb_imp_new = NULL;
|
|
+ ldap_instance_t *inst = NULL;
|
|
isc_result_t result;
|
|
+ static isc_once_t library_init_once = ISC_ONCE_INIT;
|
|
|
|
REQUIRE(name != NULL);
|
|
- REQUIRE(argv != NULL);
|
|
- REQUIRE(dyndb_args != NULL);
|
|
+ REQUIRE(parameters != NULL);
|
|
+ REQUIRE(dctx != NULL);
|
|
+ REQUIRE(instp != NULL && *instp == NULL);
|
|
|
|
- log_debug(2, "registering dynamic ldap driver for %s.", name);
|
|
+ RUNTIME_CHECK(isc_once_do(&library_init_once, library_init)
|
|
+ == ISC_R_SUCCESS);
|
|
|
|
/*
|
|
- * We need to discover what rdataset methods does
|
|
- * dns_rdatalist_tordataset use. We then make a copy for ourselves
|
|
- * with the exception that we modify the disassociate method to free
|
|
- * the rdlist we allocate for it in clone_rdatalist_to_rdataset().
|
|
+ * Depending on how dlopen() was called, we may not have
|
|
+ * access to named's global namespace, in which case we need
|
|
+ * to initialize libisc/libdns
|
|
*/
|
|
+ if (dctx->refvar != &isc_bind9) {
|
|
+ isc_lib_register();
|
|
+ isc_log_setcontext(dctx->lctx);
|
|
+ dns_log_setcontext(dctx->lctx);
|
|
+ }
|
|
|
|
- /* Register new DNS DB implementation. */
|
|
- result = dns_db_register(ldapdb_impname, &ldapdb_associate, NULL, mctx,
|
|
- &ldapdb_imp_new);
|
|
- if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS)
|
|
- return result;
|
|
- else if (result == ISC_R_SUCCESS)
|
|
- ldapdb_imp = ldapdb_imp_new;
|
|
+ isc_hash_set_initializer(dctx->hashinit);
|
|
+
|
|
+ log_debug(2, "registering dynamic ldap driver for %s.", name);
|
|
|
|
/* Finally, create the instance. */
|
|
- result = manager_create_db_instance(mctx, name, argv, dyndb_args);
|
|
+ CHECK(new_ldap_instance(mctx, name, parameters, file, line, dctx,
|
|
+ &inst));
|
|
+ *instp = inst;
|
|
|
|
+cleanup:
|
|
return result;
|
|
}
|
|
|
|
+/*
|
|
+ * Driver destroy is called for every instance on every reload and then once
|
|
+ * during shutdown.
|
|
+ *
|
|
+ * @param[out] instp Pointer to instance-specific data (for one dyndb section).
|
|
+ */
|
|
VISIBLE void
|
|
-dynamic_driver_destroy(void)
|
|
-{
|
|
- /* Only unregister the implementation if it was registered by us. */
|
|
- if (ldapdb_imp != NULL)
|
|
- dns_db_unregister(&ldapdb_imp);
|
|
-
|
|
- destroy_manager();
|
|
+dyndb_destroy(void **instp) {
|
|
+ destroy_ldap_instance((ldap_instance_t **)instp);
|
|
}
|
|
diff --git a/src/ldap_driver.h b/src/ldap_driver.h
|
|
index 73c4827..62d50f6 100644
|
|
--- a/src/ldap_driver.h
|
|
+++ b/src/ldap_driver.h
|
|
@@ -19,9 +19,13 @@ typedef struct ldapdb ldapdb_t;
|
|
|
|
isc_result_t
|
|
ldapdb_create(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type,
|
|
- dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
|
|
- void *driverarg, dns_db_t **dbp) ATTR_NONNULL(1,2,6,8);
|
|
+ dns_rdataclass_t rdclass, void *driverarg, dns_db_t **dbp)
|
|
+ ATTR_NONNULL(1,2,5,6);
|
|
|
|
+isc_result_t
|
|
+ldapdb_associate(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type,
|
|
+ dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
|
|
+ void *driverarg, dns_db_t **dbp) ATTR_NONNULL(1,2,7,8);
|
|
dns_db_t *
|
|
ldapdb_get_rbtdb(dns_db_t *db) ATTR_NONNULLS;
|
|
|
|
diff --git a/src/ldap_helper.c b/src/ldap_helper.c
|
|
index ad6e417..a11751d 100644
|
|
--- a/src/ldap_helper.c
|
|
+++ b/src/ldap_helper.c
|
|
@@ -4,7 +4,7 @@
|
|
|
|
#include "config.h"
|
|
|
|
-#include <dns/dynamic_db.h>
|
|
+#include <dns/dyndb.h>
|
|
#include <dns/diff.h>
|
|
#include <dns/journal.h>
|
|
#include <dns/rbt.h>
|
|
@@ -42,6 +42,7 @@
|
|
#include <isc/string.h>
|
|
|
|
#include <isccfg/cfg.h>
|
|
+#include <isccfg/grammar.h>
|
|
|
|
#include <alloca.h>
|
|
#define LDAP_DEPRECATED 1
|
|
@@ -77,7 +78,6 @@
|
|
#include "syncrepl.h"
|
|
#include "util.h"
|
|
#include "zone.h"
|
|
-#include "zone_manager.h"
|
|
#include "zone_register.h"
|
|
#include "rbt_helper.h"
|
|
#include "fwd_register.h"
|
|
@@ -133,7 +133,8 @@ struct ldap_instance {
|
|
isc_mem_t *mctx;
|
|
|
|
/* These are needed for zone creation. */
|
|
- const char * db_name;
|
|
+ char * db_name;
|
|
+ dns_dbimplementation_t *db_imp;
|
|
dns_view_t *view;
|
|
dns_zonemgr_t *zmgr;
|
|
|
|
@@ -184,12 +185,6 @@ struct ldap_connection {
|
|
unsigned int tries;
|
|
};
|
|
|
|
-/*
|
|
- * Constants.
|
|
- */
|
|
-
|
|
-extern const char *ldapdb_impname;
|
|
-
|
|
/* Supported authentication types. */
|
|
const ldap_auth_pair_t supported_ldap_auth[] = {
|
|
{ AUTH_NONE, "none" },
|
|
@@ -206,7 +201,6 @@ static const setting_t settings_local_default[] = {
|
|
{ "connections", no_default_uint },
|
|
{ "reconnect_interval", no_default_uint },
|
|
{ "timeout", no_default_uint },
|
|
- { "cache_ttl", no_default_string }, /* No longer supported */
|
|
{ "base", no_default_string },
|
|
{ "auth_method", no_default_string },
|
|
{ "auth_method_enum", no_default_uint },
|
|
@@ -220,12 +214,9 @@ static const setting_t settings_local_default[] = {
|
|
{ "sasl_password", no_default_string },
|
|
{ "krb5_keytab", no_default_string },
|
|
{ "fake_mname", no_default_string },
|
|
- { "zone_refresh", no_default_string }, /* No longer supported */
|
|
- { "psearch", no_default_string }, /* No longer supported */
|
|
{ "ldap_hostname", no_default_string },
|
|
{ "sync_ptr", no_default_boolean },
|
|
{ "dyn_update", no_default_boolean },
|
|
- { "serial_autoincrement", no_default_string }, /* No longer supported */
|
|
{ "verbose_checks", no_default_boolean },
|
|
{ "directory", no_default_string },
|
|
{ "nsec3param", default_string("0 0 0 00") }, /* NSEC only */
|
|
@@ -238,6 +229,50 @@ static const setting_t settings_local_default[] = {
|
|
end_of_settings
|
|
};
|
|
|
|
+/**
|
|
+ * This is list of values configurable in dyndb section of named.conf.
|
|
+ * Names and data types must match settings_local_default.
|
|
+ * Settings which are not user-configurable must be omitted from this structure.
|
|
+ */
|
|
+static cfg_clausedef_t
|
|
+dyndb_ldap_conf_clauses[] = {
|
|
+ { "auth_method", &cfg_type_qstring, 0 },
|
|
+ { "base", &cfg_type_qstring, 0 },
|
|
+ { "bind_dn", &cfg_type_qstring, 0 },
|
|
+ { "connections", &cfg_type_uint32, 0 },
|
|
+ { "directory", &cfg_type_qstring, 0 },
|
|
+ { "dyn_update", &cfg_type_boolean, 0 },
|
|
+ { "fake_mname", &cfg_type_qstring, 0 },
|
|
+ { "krb5_keytab", &cfg_type_qstring, 0 },
|
|
+ { "krb5_principal", &cfg_type_qstring, 0 },
|
|
+ { "ldap_hostname", &cfg_type_qstring, 0 },
|
|
+ { "password", &cfg_type_sstring, 0 },
|
|
+ { "reconnect_interval", &cfg_type_uint32, 0 },
|
|
+ { "sasl_auth_name", &cfg_type_qstring, 0 },
|
|
+ { "sasl_mech", &cfg_type_qstring, 0 },
|
|
+ { "sasl_password", &cfg_type_qstring, 0 },
|
|
+ { "sasl_realm", &cfg_type_qstring, 0 },
|
|
+ { "sasl_user", &cfg_type_qstring, 0 },
|
|
+ { "server_id", &cfg_type_qstring, 0 },
|
|
+ { "sync_ptr", &cfg_type_boolean, 0 },
|
|
+ { "timeout", &cfg_type_uint32, 0 },
|
|
+ { "uri", &cfg_type_qstring, 0 },
|
|
+ { "verbose_checks", &cfg_type_boolean, 0 },
|
|
+ { NULL, NULL, 0 }
|
|
+};
|
|
+
|
|
+static cfg_clausedef_t *
|
|
+dyndb_ldap_clausulesets[] = {
|
|
+ dyndb_ldap_conf_clauses,
|
|
+ NULL
|
|
+};
|
|
+
|
|
+/** Entry point for configuration parser used on dyndb section of named.conf. */
|
|
+static cfg_type_t cfg_type_dyndb_conf = {
|
|
+ "dyndb_ldap_conf", cfg_parse_mapbody, cfg_print_mapbody,
|
|
+ cfg_doc_mapbody, &cfg_rep_map, dyndb_ldap_clausulesets
|
|
+};
|
|
+
|
|
/** Global settings from idnsConfig object. */
|
|
static setting_t settings_global_default[] = {
|
|
{ "dyn_update", no_default_boolean },
|
|
@@ -351,14 +386,6 @@ validate_local_instance_settings(ldap_instance_t *inst, settings_set_t *set) {
|
|
const char *dir_name = NULL;
|
|
isc_boolean_t dir_default;
|
|
ld_string_t *buff = NULL;
|
|
-
|
|
- /* handle cache_ttl, psearch, serial_autoincrement, and zone_refresh
|
|
- * in special way */
|
|
- const char *obsolete_value = NULL;
|
|
- char *obsolete_options[] = {"cache_ttl", "psearch",
|
|
- "serial_autoincrement", "zone_refresh",
|
|
- NULL};
|
|
-
|
|
char print_buff[PRINT_BUFF_SIZE];
|
|
const char *auth_method_str = NULL;
|
|
ldap_auth_t auth_method_enum = AUTH_INVALID;
|
|
@@ -485,12 +512,6 @@ validate_local_instance_settings(ldap_instance_t *inst, settings_set_t *set) {
|
|
"are untested; expect problems");
|
|
}
|
|
|
|
- for (char **option = obsolete_options; *option != NULL; option++) {
|
|
- CHECK(setting_get_str(*option, set, &obsolete_value));
|
|
- if (memcmp("", obsolete_value, 1) != 0)
|
|
- log_error("option '%s' is not supported, ignoring", *option);
|
|
- }
|
|
-
|
|
if (settings_set_isfilled(set) != ISC_TRUE)
|
|
result = ISC_R_FAILURE;
|
|
|
|
@@ -505,13 +526,12 @@ cleanup:
|
|
|
|
#define PRINT_BUFF_SIZE 255
|
|
isc_result_t
|
|
-new_ldap_instance(isc_mem_t *mctx, const char *db_name,
|
|
- const char * const *argv, dns_dyndb_arguments_t *dyndb_args,
|
|
- isc_task_t *task, ldap_instance_t **ldap_instp)
|
|
+new_ldap_instance(isc_mem_t *mctx, const char *db_name, const char *parameters,
|
|
+ const char *file, unsigned long line,
|
|
+ const dns_dyndbctx_t *dctx, ldap_instance_t **ldap_instp)
|
|
{
|
|
isc_result_t result;
|
|
ldap_instance_t *ldap_inst;
|
|
- dns_view_t *view = NULL;
|
|
dns_forwarders_t *named_conf_forwarders = NULL;
|
|
isc_buffer_t *forwarders_list = NULL;
|
|
const char *forward_policy = NULL;
|
|
@@ -526,30 +546,31 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
|
|
ZERO_PTR(ldap_inst);
|
|
CHECK(isc_refcount_init(&ldap_inst->errors, 0));
|
|
isc_mem_attach(mctx, &ldap_inst->mctx);
|
|
+ CHECKED_MEM_STRDUP(mctx, db_name, ldap_inst->db_name);
|
|
+ dns_view_attach(dctx->view, &ldap_inst->view);
|
|
+ dns_zonemgr_attach(dctx->zmgr, &ldap_inst->zmgr);
|
|
+ isc_task_attach(dctx->task, &ldap_inst->task);
|
|
|
|
- ldap_inst->db_name = db_name;
|
|
- view = dns_dyndb_get_view(dyndb_args);
|
|
- dns_view_attach(view, &ldap_inst->view);
|
|
- ldap_inst->zmgr = dns_dyndb_get_zonemgr(dyndb_args);
|
|
- ldap_inst->task = task;
|
|
ldap_inst->watcher = 0;
|
|
CHECK(sync_ctx_init(ldap_inst->mctx, ldap_inst, &ldap_inst->sctx));
|
|
|
|
isc_string_printf_truncate(settings_name, PRINT_BUFF_SIZE,
|
|
SETTING_SET_NAME_LOCAL " for database %s",
|
|
- db_name);
|
|
+ ldap_inst->db_name);
|
|
CHECK(settings_set_create(mctx, settings_local_default,
|
|
sizeof(settings_local_default), settings_name,
|
|
&settings_default_set, &ldap_inst->local_settings));
|
|
|
|
isc_string_printf_truncate(settings_name, PRINT_BUFF_SIZE,
|
|
SETTING_SET_NAME_GLOBAL " for database %s",
|
|
- db_name);
|
|
+ ldap_inst->db_name);
|
|
CHECK(settings_set_create(mctx, settings_global_default,
|
|
sizeof(settings_global_default), settings_name,
|
|
ldap_inst->local_settings, &ldap_inst->global_settings));
|
|
|
|
- CHECK(settings_set_fill(ldap_inst->local_settings, argv));
|
|
+ CHECK(setting_set_parse_conf(mctx, ldap_inst->db_name,
|
|
+ &cfg_type_dyndb_conf, parameters, file,
|
|
+ line, ldap_inst->local_settings));
|
|
|
|
/* copy global forwarders setting for configuration roll back in
|
|
* configure_zone_forwarders() */
|
|
@@ -573,7 +594,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
|
|
*
|
|
* Warn-only semantics is implemented in BIND RT#41441,
|
|
* this code can be removed when we rebase to BIND 9.11. */
|
|
- CHECK(sync_task_add(ldap_inst->sctx, task));
|
|
+ CHECK(sync_task_add(ldap_inst->sctx, ldap_inst->task));
|
|
gfwdevent = (ldap_globalfwd_handleez_t *)isc_event_allocate(
|
|
ldap_inst->mctx, ldap_inst,
|
|
LDAPDB_EVENT_GLOBALFWD_HANDLEEZ,
|
|
@@ -586,7 +607,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
|
|
gfwdevent->warn_only = (named_conf_forwarders->fwdpolicy
|
|
== dns_fwdpolicy_first);
|
|
|
|
- isc_task_send(task, (isc_event_t **)&gfwdevent);
|
|
+ isc_task_send(ldap_inst->task, (isc_event_t **)&gfwdevent);
|
|
|
|
} else if (result == ISC_R_NOTFOUND) {
|
|
/* global forwarders are not configured */
|
|
@@ -639,6 +660,10 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
|
|
CHECK(ldap_pool_create(mctx, connections, &ldap_inst->pool));
|
|
CHECK(ldap_pool_connect(ldap_inst->pool, ldap_inst));
|
|
|
|
+ /* Register new DNS DB implementation. */
|
|
+ CHECK(dns_db_register(ldap_inst->db_name, &ldapdb_associate, ldap_inst,
|
|
+ mctx, &ldap_inst->db_imp));
|
|
+
|
|
/* Start the watcher thread */
|
|
result = isc_thread_create(ldap_syncrepl_watcher, ldap_inst,
|
|
&ldap_inst->watcher);
|
|
@@ -663,7 +688,6 @@ void
|
|
destroy_ldap_instance(ldap_instance_t **ldap_instp)
|
|
{
|
|
ldap_instance_t *ldap_inst;
|
|
- const char *db_name;
|
|
|
|
REQUIRE(ldap_instp != NULL);
|
|
|
|
@@ -671,8 +695,6 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp)
|
|
if (ldap_inst == NULL)
|
|
return;
|
|
|
|
- db_name = ldap_inst->db_name; /* points to DB instance: outside ldap_inst */
|
|
-
|
|
if (ldap_inst->watcher != 0) {
|
|
ldap_inst->exiting = ISC_TRUE;
|
|
/*
|
|
@@ -695,7 +717,14 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp)
|
|
mldap_destroy(&ldap_inst->mldapdb);
|
|
|
|
ldap_pool_destroy(&ldap_inst->pool);
|
|
- dns_view_detach(&ldap_inst->view);
|
|
+ if (ldap_inst->db_imp != NULL)
|
|
+ dns_db_unregister(&ldap_inst->db_imp);
|
|
+ if (ldap_inst->view != NULL)
|
|
+ dns_view_detach(&ldap_inst->view);
|
|
+ if (ldap_inst->zmgr != NULL)
|
|
+ dns_zonemgr_detach(&ldap_inst->zmgr);
|
|
+ if (ldap_inst->task != NULL)
|
|
+ isc_task_detach(&ldap_inst->task);
|
|
|
|
DESTROYLOCK(&ldap_inst->kinit_lock);
|
|
|
|
@@ -709,10 +738,13 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp)
|
|
ldap_instance_untaint_start(ldap_inst));
|
|
isc_refcount_destroy(&ldap_inst->errors);
|
|
|
|
+ if (ldap_inst->db_name != NULL) {
|
|
+ log_debug(1, "LDAP instance '%s' destroyed", ldap_inst->db_name);
|
|
+ isc_mem_free(ldap_inst->mctx, ldap_inst->db_name);
|
|
+ }
|
|
MEM_PUT_AND_DETACH(ldap_inst);
|
|
|
|
*ldap_instp = NULL;
|
|
- log_debug(1, "LDAP instance '%s' destroyed", db_name);
|
|
}
|
|
|
|
static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT
|
|
@@ -916,7 +948,7 @@ create_zone(ldap_instance_t * const inst, const char * const dn,
|
|
isc_result_t result;
|
|
dns_zone_t *raw = NULL;
|
|
dns_zone_t *secure = NULL;
|
|
- const char *ldap_argv[2];
|
|
+ const char *ldap_argv[1] = { inst->db_name };
|
|
const char *rbt_argv[1] = { "rbt" };
|
|
sync_state_t sync_state;
|
|
isc_task_t *task = NULL;
|
|
@@ -926,9 +958,6 @@ create_zone(ldap_instance_t * const inst, const char * const dn,
|
|
REQUIRE(name != NULL);
|
|
REQUIRE(rawp != NULL && *rawp == NULL);
|
|
|
|
- ldap_argv[0] = ldapdb_impname;
|
|
- ldap_argv[1] = inst->db_name;
|
|
-
|
|
result = zone_unload_ifempty(inst->view, name);
|
|
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
|
|
goto cleanup;
|
|
@@ -938,7 +967,8 @@ create_zone(ldap_instance_t * const inst, const char * const dn,
|
|
dns_zone_setclass(raw, dns_rdataclass_in);
|
|
dns_zone_settype(raw, dns_zone_master);
|
|
/* dns_zone_setview(raw, view); */
|
|
- CHECK(dns_zone_setdbtype(raw, 2, ldap_argv));
|
|
+ CHECK(dns_zone_setdbtype(raw, sizeof(ldap_argv)/sizeof(ldap_argv[0]),
|
|
+ ldap_argv));
|
|
CHECK(configure_paths(inst->mctx, inst, raw, ISC_FALSE));
|
|
|
|
if (want_secure == ISC_FALSE) {
|
|
@@ -3654,7 +3684,7 @@ update_zone(isc_task_t *task, isc_event_t *event)
|
|
{
|
|
ldap_syncreplevent_t *pevent = (ldap_syncreplevent_t *)event;
|
|
isc_result_t result ;
|
|
- ldap_instance_t *inst = NULL;
|
|
+ ldap_instance_t *inst = pevent->inst;
|
|
isc_mem_t *mctx;
|
|
dns_name_t prevname;
|
|
ldap_entry_t *entry = pevent->entry;
|
|
@@ -3662,7 +3692,6 @@ update_zone(isc_task_t *task, isc_event_t *event)
|
|
mctx = pevent->mctx;
|
|
dns_name_init(&prevname, NULL);
|
|
|
|
- CHECK(manager_get_ldap_instance(pevent->dbname, &inst));
|
|
INSIST(task == inst->task); /* For task-exclusive mode */
|
|
|
|
if (SYNCREPL_DEL(pevent->chgtype)) {
|
|
@@ -3673,6 +3702,9 @@ update_zone(isc_task_t *task, isc_event_t *event)
|
|
task));
|
|
else if (entry->class & LDAP_ENTRYCLASS_FORWARD)
|
|
CHECK(ldap_parse_fwd_zoneentry(entry, inst));
|
|
+ else
|
|
+ FATAL_ERROR(__FILE__, __LINE__,
|
|
+ "update_zone: unexpected entry class");
|
|
}
|
|
|
|
cleanup:
|
|
@@ -3687,7 +3719,6 @@ cleanup:
|
|
"Zones can be outdated, run `rndc reload`",
|
|
ldap_entry_logname(entry));
|
|
|
|
- isc_mem_free(mctx, pevent->dbname);
|
|
if (pevent->prevdn != NULL)
|
|
isc_mem_free(mctx, pevent->prevdn);
|
|
ldap_entry_destroy(&entry);
|
|
@@ -3701,13 +3732,12 @@ update_config(isc_task_t * task, isc_event_t *event)
|
|
{
|
|
ldap_syncreplevent_t *pevent = (ldap_syncreplevent_t *)event;
|
|
isc_result_t result;
|
|
- ldap_instance_t *inst = NULL;
|
|
+ ldap_instance_t *inst = pevent->inst;
|
|
ldap_entry_t *entry = pevent->entry;
|
|
isc_mem_t *mctx;
|
|
|
|
mctx = pevent->mctx;
|
|
|
|
- CHECK(manager_get_ldap_instance(pevent->dbname, &inst));
|
|
INSIST(task == inst->task); /* For task-exclusive mode */
|
|
CHECK(ldap_parse_configentry(entry, inst));
|
|
|
|
@@ -3722,7 +3752,6 @@ cleanup:
|
|
ldap_entry_logname(entry));
|
|
|
|
ldap_entry_destroy(&entry);
|
|
- isc_mem_free(mctx, pevent->dbname);
|
|
isc_mem_detach(&mctx);
|
|
isc_event_free(&event);
|
|
isc_task_detach(&task);
|
|
@@ -3733,13 +3762,12 @@ update_serverconfig(isc_task_t * task, isc_event_t *event)
|
|
{
|
|
ldap_syncreplevent_t *pevent = (ldap_syncreplevent_t *)event;
|
|
isc_result_t result;
|
|
- ldap_instance_t *inst = NULL;
|
|
+ ldap_instance_t *inst = pevent->inst;
|
|
ldap_entry_t *entry = pevent->entry;
|
|
isc_mem_t *mctx;
|
|
|
|
mctx = pevent->mctx;
|
|
|
|
- CHECK(manager_get_ldap_instance(pevent->dbname, &inst));
|
|
INSIST(task == inst->task); /* For task-exclusive mode */
|
|
CHECK(ldap_parse_serverconfigentry(entry, inst));
|
|
|
|
@@ -3754,7 +3782,6 @@ cleanup:
|
|
ldap_entry_logname(entry));
|
|
|
|
ldap_entry_destroy(&entry);
|
|
- isc_mem_free(mctx, pevent->dbname);
|
|
isc_mem_detach(&mctx);
|
|
isc_event_free(&event);
|
|
isc_task_detach(&task);
|
|
@@ -3774,7 +3801,7 @@ update_record(isc_task_t *task, isc_event_t *event)
|
|
/* syncrepl event */
|
|
ldap_syncreplevent_t *pevent = (ldap_syncreplevent_t *)event;
|
|
isc_result_t result;
|
|
- ldap_instance_t *inst = NULL;
|
|
+ ldap_instance_t *inst = pevent->inst;
|
|
isc_mem_t *mctx;
|
|
settings_set_t *zone_settings = NULL;
|
|
dns_zone_t *raw = NULL;
|
|
@@ -3811,7 +3838,6 @@ update_record(isc_task_t *task, isc_event_t *event)
|
|
dns_name_init(&prevname, NULL);
|
|
dns_name_init(&prevorigin, NULL);
|
|
|
|
- CHECK(manager_get_ldap_instance(pevent->dbname, &inst));
|
|
CHECK(zr_get_zone_ptr(inst->zone_register, &entry->zone_name, &raw, &secure));
|
|
zone_found = ISC_TRUE;
|
|
|
|
@@ -3984,7 +4010,6 @@ cleanup:
|
|
if (secure != NULL)
|
|
dns_zone_detach(&secure);
|
|
ldapdb_rdatalist_destroy(mctx, &rdatalist);
|
|
- isc_mem_free(mctx, pevent->dbname);
|
|
if (pevent->prevdn != NULL)
|
|
isc_mem_free(mctx, pevent->prevdn);
|
|
ldap_entry_destroy(&entry);
|
|
@@ -4055,8 +4080,6 @@ syncrepl_update(ldap_instance_t *inst, ldap_entry_t **entryp, int chgtype)
|
|
dns_name_t *zone_name = NULL;
|
|
dns_zone_t *zone_ptr = NULL;
|
|
char *dn = NULL;
|
|
- char *dbname = NULL;
|
|
- isc_mem_t *mctx = NULL;
|
|
isc_taskaction_t action = NULL;
|
|
isc_task_t *task = NULL;
|
|
isc_boolean_t synchronous;
|
|
@@ -4069,10 +4092,6 @@ syncrepl_update(ldap_instance_t *inst, ldap_entry_t **entryp, int chgtype)
|
|
SYNCREPL_ADD(chgtype), SYNCREPL_DEL(chgtype),
|
|
SYNCREPL_MOD(chgtype));
|
|
|
|
- isc_mem_attach(inst->mctx, &mctx);
|
|
-
|
|
- CHECKED_MEM_STRDUP(mctx, inst->db_name, dbname);
|
|
-
|
|
if (entry->class & LDAP_ENTRYCLASS_MASTER)
|
|
zone_name = &entry->fqdn;
|
|
else
|
|
@@ -4128,8 +4147,9 @@ syncrepl_update(ldap_instance_t *inst, ldap_entry_t **entryp, int chgtype)
|
|
goto cleanup;
|
|
}
|
|
|
|
- pevent->mctx = mctx;
|
|
- pevent->dbname = dbname;
|
|
+ pevent->mctx = NULL;
|
|
+ isc_mem_attach(inst->mctx, &pevent->mctx);
|
|
+ pevent->inst = inst;
|
|
pevent->prevdn = NULL;
|
|
pevent->chgtype = chgtype;
|
|
pevent->entry = entry;
|
|
@@ -4148,11 +4168,8 @@ cleanup:
|
|
if (pevent != NULL) {
|
|
/* Event was not sent */
|
|
sync_concurr_limit_signal(inst->sctx);
|
|
-
|
|
- if (dbname != NULL)
|
|
- isc_mem_free(mctx, dbname);
|
|
- if (mctx != NULL)
|
|
- isc_mem_detach(&mctx);
|
|
+ if (pevent->mctx != NULL)
|
|
+ isc_mem_detach(&pevent->mctx);
|
|
ldap_entry_destroy(entryp);
|
|
if (task != NULL)
|
|
isc_task_detach(&task);
|
|
@@ -4394,7 +4411,7 @@ int ldap_sync_intermediate (
|
|
|
|
sync_state_get(inst->sctx, &state);
|
|
if (state == sync_datainit) {
|
|
- result = sync_barrier_wait(inst->sctx, inst->db_name);
|
|
+ result = sync_barrier_wait(inst->sctx, inst);
|
|
if (result != ISC_R_SUCCESS) {
|
|
log_error_r("%s: sync_barrier_wait() failed for "
|
|
"instance '%s'", __func__, inst->db_name);
|
|
@@ -4447,7 +4464,7 @@ int ATTR_NONNULLS ATTR_CHECKRESULT ldap_sync_search_result (
|
|
INSIST(state == sync_configinit || state == sync_finished);
|
|
|
|
if (state == sync_configinit) {
|
|
- result = sync_barrier_wait(inst->sctx, inst->db_name);
|
|
+ result = sync_barrier_wait(inst->sctx, inst);
|
|
if (result != ISC_R_SUCCESS) {
|
|
log_error_r("%s: sync_barrier_wait() failed for "
|
|
"instance '%s'", __func__, inst->db_name);
|
|
diff --git a/src/ldap_helper.h b/src/ldap_helper.h
|
|
index a491bae..6cfece5 100644
|
|
--- a/src/ldap_helper.h
|
|
+++ b/src/ldap_helper.h
|
|
@@ -9,6 +9,7 @@
|
|
|
|
#include <isc/eventclass.h>
|
|
#include <isc/util.h>
|
|
+#include <isccfg/cfg.h>
|
|
|
|
#include <ldap.h>
|
|
|
|
@@ -40,9 +41,9 @@ void free_rdatalist(isc_mem_t *mctx, dns_rdatalist_t *rdlist) ATTR_NONNULLS;
|
|
*/
|
|
|
|
isc_result_t
|
|
-new_ldap_instance(isc_mem_t *mctx, const char *db_name,
|
|
- const char * const *argv, dns_dyndb_arguments_t *dyndb_args,
|
|
- isc_task_t *task, ldap_instance_t **ldap_instp) ATTR_NONNULLS;
|
|
+new_ldap_instance(isc_mem_t *mctx, const char *db_name, const char *parameters,
|
|
+ const char *file, unsigned long line,
|
|
+ const dns_dyndbctx_t *dctx, ldap_instance_t **ldap_instp) ATTR_NONNULLS;
|
|
void destroy_ldap_instance(ldap_instance_t **ldap_inst) ATTR_NONNULLS;
|
|
|
|
isc_result_t
|
|
diff --git a/src/settings.c b/src/settings.c
|
|
index 3692dae..37e6e5c 100644
|
|
--- a/src/settings.c
|
|
+++ b/src/settings.c
|
|
@@ -9,6 +9,7 @@
|
|
#include <isc/string.h>
|
|
#include <isc/int.h>
|
|
#include <isc/parseint.h>
|
|
+
|
|
#include <dns/name.h>
|
|
|
|
#include <ctype.h>
|
|
@@ -553,66 +554,72 @@ settings_set_free(settings_set_t **set) {
|
|
}
|
|
|
|
/**
|
|
- * Set all values specified by vector of strings to setting set. Setting name
|
|
- * is separated from it's argument with one or more characters defined by
|
|
- * @link SETTING_NAME_SEPARATORS@endlink.
|
|
- *
|
|
- * @retval ISC_R_SUCCESS All strings in argument vector were processed and set.
|
|
- * @retval Others Memory or parsing errors.
|
|
- *
|
|
- * @warning One string in argument vector is limited to
|
|
- * @link SETTING_LINE_MAXLENGTH@endlink.
|
|
- *
|
|
- * @note
|
|
- * @code{.txt}
|
|
- * Calling settings_set_fill() with argument array
|
|
+ * Append textlen bytes from text to isc_buffer pointed to by closure.
|
|
*
|
|
- * {"setting1 value 1 ",
|
|
- * "bind_dn cn=Directory manager" }
|
|
- *
|
|
- * will result in setting values to two separate settings:
|
|
+ * @pre closure is an initialized isc_buffer with autoreallocation enabled.
|
|
+ */
|
|
+static void
|
|
+cfg_printer(void *closure, const char *text, int textlen) {
|
|
+ isc_buffer_t *logbuffer = closure;
|
|
+
|
|
+ REQUIRE(logbuffer != NULL);
|
|
+ REQUIRE(logbuffer->autore == ISC_TRUE);
|
|
+
|
|
+ isc_buffer_putmem(logbuffer, (const unsigned char *)text, textlen);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * Copy values from cfg map to set of settings.
|
|
+ * Only setting names specified in set of settings are copied.
|
|
*
|
|
- * "setting1" = "value 1 "
|
|
- * "bind_dn" = "cn=Directory manager"
|
|
+ * @param[in] config
|
|
+ * @param[out] set
|
|
*
|
|
- * Please note the positions of white spaces.
|
|
- * @endcode
|
|
+ * @retval ISC_R_SUCCESS Items listed in set of settings were copied from cfg map.
|
|
+ * @retval Others Memory or parsing errors.
|
|
*/
|
|
-isc_result_t
|
|
-settings_set_fill(settings_set_t *set, const char *const *argv)
|
|
+static isc_result_t
|
|
+settings_set_fill(const cfg_obj_t *config, settings_set_t *set)
|
|
{
|
|
isc_result_t result;
|
|
- int i;
|
|
- const char *name;
|
|
- char *value;
|
|
-
|
|
- for (i = 0; argv[i] != NULL; i++) {
|
|
- char buff[SETTING_LINE_MAXLENGTH] = "";
|
|
- CHECK(isc_string_copy(buff, SETTING_LINE_MAXLENGTH, argv[i]));
|
|
- value = buff;
|
|
- name = isc_string_separate(&value, SETTING_NAME_SEPARATORS);
|
|
- if (name == NULL || value == NULL)
|
|
- CLEANUP_WITH(ISC_R_UNEXPECTEDEND);
|
|
- value += strspn(value, SETTING_NAME_SEPARATORS);
|
|
- if (setting_find(name, set, ISC_FALSE, ISC_TRUE, NULL)
|
|
- != ISC_R_NOTFOUND) {
|
|
- log_error("multiple definitions of setting '%s' in "
|
|
- "set of settings '%s'", name, set->name);
|
|
- CLEANUP_WITH(ISC_R_EXISTS);
|
|
+ setting_t *setting;
|
|
+ isc_buffer_t *buf_value = NULL;
|
|
+ const cfg_obj_t *cfg_value;
|
|
+ const char *str_value;
|
|
+
|
|
+ REQUIRE(cfg_obj_ismap(config) == ISC_TRUE);
|
|
+
|
|
+ CHECK(isc_buffer_allocate(set->mctx, &buf_value, ISC_BUFFER_INCR));
|
|
+ isc_buffer_setautorealloc(buf_value, ISC_TRUE);
|
|
+
|
|
+ for (setting = set->first_setting;
|
|
+ setting->name != NULL;
|
|
+ setting++) {
|
|
+ cfg_value = NULL;
|
|
+ result = cfg_map_get(config, setting->name, &cfg_value);
|
|
+ if (result == ISC_R_NOTFOUND)
|
|
+ continue; /* setting not configured in map */
|
|
+ else if (result != ISC_R_SUCCESS)
|
|
+ goto cleanup;
|
|
+ if (cfg_obj_isstring(cfg_value)) {
|
|
+ /* this avoids additional quotes around the string */
|
|
+ str_value = cfg_obj_asstring(cfg_value);
|
|
+ } else {
|
|
+ cfg_printx(cfg_value, 0, cfg_printer, buf_value);
|
|
+ isc_buffer_putmem(buf_value, (unsigned char *)"\0", 1);
|
|
+ str_value = isc_buffer_base(buf_value);
|
|
}
|
|
- result = setting_set(name, set, value);
|
|
+ result = set_value(set->mctx, set, setting, str_value);
|
|
if (result != ISC_R_SUCCESS && result != ISC_R_IGNORE)
|
|
goto cleanup;
|
|
+ isc_buffer_clear(buf_value);
|
|
}
|
|
|
|
- return ISC_R_SUCCESS;
|
|
-
|
|
cleanup:
|
|
- log_error_r("cannot parse settings from '%s': "
|
|
- "problematic configuration line:"
|
|
- "\n%s\n"
|
|
- "error code", set->name, argv[i]);
|
|
- /* TODO: Free memory in case of error. */
|
|
+ if (result != ISC_R_SUCCESS)
|
|
+ log_error_r("cannot parse settings for '%s'", set->name);
|
|
+ if (buf_value != NULL)
|
|
+ isc_buffer_free(&buf_value);
|
|
return result;
|
|
}
|
|
|
|
@@ -644,6 +651,75 @@ settings_set_isfilled(settings_set_t *set) {
|
|
return isfiled;
|
|
}
|
|
|
|
+/**
|
|
+ * Parse string with dyndb configuration and fill in settings_set_t structure.
|
|
+ *
|
|
+ * @param[in] name name of dyndb instance
|
|
+ * @param[in] cfg_type_conf configuration grammar for ISC parser
|
|
+ * @param[in] parameters string with complete dyndb configuration
|
|
+ * @param[in] file name of configuration file
|
|
+ * @param[in] line line on which config starts
|
|
+ * @param[out] settings set of settings filled with values from config
|
|
+ *
|
|
+ * @pre Names and data types of respective paremeters
|
|
+ * in cfg_type_conf and set of settings must match.
|
|
+ */
|
|
+isc_result_t
|
|
+setting_set_parse_conf(isc_mem_t *mctx, const char *name,
|
|
+ cfg_type_t *cfg_type_conf, const char *parameters,
|
|
+ const char *file, unsigned long line,
|
|
+ settings_set_t *settings)
|
|
+{
|
|
+ isc_result_t result;
|
|
+ cfg_obj_t *config = NULL;
|
|
+ isc_buffer_t in_buf;
|
|
+ isc_buffer_t *log_buf = NULL;
|
|
+ cfg_parser_t *parser = NULL;
|
|
+ unsigned int len;
|
|
+
|
|
+ REQUIRE(parameters != NULL);
|
|
+
|
|
+ CHECK(isc_buffer_allocate(mctx, &log_buf, ISC_BUFFER_INCR));
|
|
+ isc_buffer_setautorealloc(log_buf, ISC_TRUE);
|
|
+
|
|
+ len = strlen(parameters);
|
|
+ isc_buffer_constinit(&in_buf, parameters, len);
|
|
+ isc_buffer_add(&in_buf, len);
|
|
+
|
|
+ CHECK(cfg_parser_create(mctx, dns_lctx, &parser));
|
|
+ result = cfg_parse_buffer2(parser, &in_buf, name, cfg_type_conf,
|
|
+ &config);
|
|
+ if (result == ISC_R_SUCCESS) {
|
|
+ cfg_printx(config, CFG_PRINTER_XKEY, cfg_printer, log_buf);
|
|
+ cfg_obj_log(config, dns_lctx, ISC_LOG_DEBUG(10),
|
|
+ "configuration for dyndb instance '%s' "
|
|
+ "(starting in file %s on line %lu):\n"
|
|
+ "%.*s",
|
|
+ name, file, line, isc_buffer_usedlength(log_buf),
|
|
+ (char *)isc_buffer_base(log_buf));
|
|
+ } else {
|
|
+ log_error("configuration for dyndb instance '%s' "
|
|
+ "(starting in file %s on line %lu) is invalid",
|
|
+ name, file, line);
|
|
+ cfg_print_grammar(cfg_type_conf, cfg_printer, log_buf);
|
|
+ log_info("expected grammar:\n"
|
|
+ "%.*s", isc_buffer_usedlength(log_buf),
|
|
+ (char *)isc_buffer_base(log_buf));
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ CHECK(settings_set_fill(config, settings));
|
|
+
|
|
+cleanup:
|
|
+ if (log_buf != NULL)
|
|
+ isc_buffer_free(&log_buf);
|
|
+ if (config != NULL)
|
|
+ cfg_obj_destroy(parser, &config);
|
|
+ if (parser != NULL)
|
|
+ cfg_parser_destroy(&parser);
|
|
+ return result;
|
|
+}
|
|
+
|
|
isc_result_t
|
|
get_enum_description(const enum_txt_assoc_t *map, int value, const char **desc) {
|
|
const enum_txt_assoc_t *record;
|
|
diff --git a/src/settings.h b/src/settings.h
|
|
index 9bc4176..16a1e63 100644
|
|
--- a/src/settings.h
|
|
+++ b/src/settings.h
|
|
@@ -6,12 +6,13 @@
|
|
#define _LD_SETTINGS_H_
|
|
|
|
#include <isc/types.h>
|
|
+
|
|
+#include <isccfg/grammar.h>
|
|
+
|
|
#include "types.h"
|
|
#include "str.h"
|
|
#include "ldap_entry.h"
|
|
|
|
-#define SETTING_LINE_MAXLENGTH 255
|
|
-#define SETTING_NAME_SEPARATORS " \t"
|
|
#define SETTING_SET_NAME_LOCAL "named.conf"
|
|
#define SETTING_SET_NAME_SERVER "LDAP idnsServerConfig object"
|
|
#define SETTING_SET_NAME_GLOBAL "LDAP idnsConfig object"
|
|
@@ -82,8 +83,10 @@ void
|
|
settings_set_free(settings_set_t **set) ATTR_NONNULLS;
|
|
|
|
isc_result_t
|
|
-settings_set_fill(settings_set_t *set, const char *const *argv)
|
|
- ATTR_NONNULLS ATTR_CHECKRESULT;
|
|
+setting_set_parse_conf(isc_mem_t *mctx, const char *name,
|
|
+ cfg_type_t *cfg_type_conf, const char *parameters,
|
|
+ const char *file, unsigned long line,
|
|
+ settings_set_t *settings) ATTR_NONNULLS ATTR_CHECKRESULT;
|
|
|
|
isc_boolean_t
|
|
settings_set_isfilled(settings_set_t *set) ATTR_NONNULLS ATTR_CHECKRESULT;
|
|
diff --git a/src/syncrepl.c b/src/syncrepl.c
|
|
index 0079644..6ed8051 100644
|
|
--- a/src/syncrepl.c
|
|
+++ b/src/syncrepl.c
|
|
@@ -15,7 +15,6 @@
|
|
#include "util.h"
|
|
#include "semaphore.h"
|
|
#include "syncrepl.h"
|
|
-#include "zone_manager.h"
|
|
|
|
#define LDAPDB_EVENT_SYNCREPL_BARRIER (LDAPDB_EVENTCLASS + 2)
|
|
#define LDAPDB_EVENT_SYNCREPL_FINISH (LDAPDB_EVENTCLASS + 3)
|
|
@@ -109,7 +108,7 @@ struct sync_ctx {
|
|
*/
|
|
struct sync_barrierev {
|
|
ISC_EVENT_COMMON(sync_barrierev_t);
|
|
- const char *dbname;
|
|
+ ldap_instance_t *inst;
|
|
sync_ctx_t *sctx;
|
|
};
|
|
|
|
@@ -122,7 +121,6 @@ struct sync_barrierev {
|
|
void
|
|
finish(isc_task_t *task, isc_event_t *event) {
|
|
isc_result_t result = ISC_R_SUCCESS;
|
|
- ldap_instance_t *inst = NULL;
|
|
sync_barrierev_t *bev = NULL;
|
|
sync_state_t new_state;
|
|
|
|
@@ -130,7 +128,6 @@ finish(isc_task_t *task, isc_event_t *event) {
|
|
REQUIRE(event != NULL);
|
|
|
|
bev = (sync_barrierev_t *)event;
|
|
- CHECK(manager_get_ldap_instance(bev->dbname, &inst));
|
|
log_debug(1, "sync_barrier_wait(): finish reached");
|
|
LOCK(&bev->sctx->mutex);
|
|
switch (bev->sctx->state) {
|
|
@@ -152,9 +149,8 @@ finish(isc_task_t *task, isc_event_t *event) {
|
|
BROADCAST(&bev->sctx->cond);
|
|
UNLOCK(&bev->sctx->mutex);
|
|
if (new_state == sync_finished)
|
|
- activate_zones(task, inst);
|
|
+ activate_zones(task, bev->inst);
|
|
|
|
-cleanup:
|
|
if (result != ISC_R_SUCCESS)
|
|
log_error_r("syncrepl finish() failed");
|
|
isc_event_free(&event);
|
|
@@ -162,12 +158,12 @@ cleanup:
|
|
}
|
|
|
|
static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT
|
|
-sync_finishev_create(sync_ctx_t *sctx, const char *inst_name,
|
|
+sync_finishev_create(sync_ctx_t *sctx, ldap_instance_t *inst,
|
|
sync_barrierev_t **evp) {
|
|
sync_barrierev_t *ev = NULL;
|
|
|
|
REQUIRE(sctx != NULL);
|
|
- REQUIRE(inst_name != NULL);
|
|
+ REQUIRE(inst != NULL);
|
|
REQUIRE(evp != NULL && *evp == NULL);
|
|
|
|
ev = (sync_barrierev_t *)isc_event_allocate(sctx->mctx,
|
|
@@ -177,7 +173,7 @@ sync_finishev_create(sync_ctx_t *sctx, const char *inst_name,
|
|
if (ev == NULL)
|
|
return ISC_R_NOMEMORY;
|
|
|
|
- ev->dbname = inst_name;
|
|
+ ev->inst = inst;
|
|
ev->sctx = sctx;
|
|
*evp = ev;
|
|
|
|
@@ -203,7 +199,6 @@ sync_finishev_create(sync_ctx_t *sctx, const char *inst_name,
|
|
void
|
|
barrier_decrement(isc_task_t *task, isc_event_t *event) {
|
|
isc_result_t result = ISC_R_SUCCESS;
|
|
- ldap_instance_t *inst = NULL;
|
|
sync_barrierev_t *bev = NULL;
|
|
sync_barrierev_t *fev = NULL;
|
|
isc_event_t *ev = NULL;
|
|
@@ -214,13 +209,12 @@ barrier_decrement(isc_task_t *task, isc_event_t *event) {
|
|
REQUIRE(event != NULL);
|
|
|
|
bev = (sync_barrierev_t *)event;
|
|
- CHECK(manager_get_ldap_instance(bev->dbname, &inst));
|
|
isc_refcount_decrement(&bev->sctx->task_cnt, &cnt);
|
|
if (cnt == 0) {
|
|
log_debug(1, "sync_barrier_wait(): barrier reached");
|
|
LOCK(&bev->sctx->mutex);
|
|
locked = ISC_TRUE;
|
|
- CHECK(sync_finishev_create(bev->sctx, bev->dbname, &fev));
|
|
+ CHECK(sync_finishev_create(bev->sctx, bev->inst, &fev));
|
|
ev = (isc_event_t *)fev;
|
|
isc_task_send(ldap_instance_gettask(bev->sctx->inst), &ev);
|
|
}
|
|
@@ -235,12 +229,12 @@ cleanup:
|
|
}
|
|
|
|
static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT
|
|
-sync_barrierev_create(sync_ctx_t *sctx, const char *inst_name,
|
|
+sync_barrierev_create(sync_ctx_t *sctx, ldap_instance_t *inst,
|
|
sync_barrierev_t **evp) {
|
|
sync_barrierev_t *ev = NULL;
|
|
|
|
REQUIRE(sctx != NULL);
|
|
- REQUIRE(inst_name != NULL);
|
|
+ REQUIRE(inst != NULL);
|
|
REQUIRE(evp != NULL && *evp == NULL);
|
|
|
|
ev = (sync_barrierev_t *)isc_event_allocate(sctx->mctx,
|
|
@@ -250,7 +244,7 @@ sync_barrierev_create(sync_ctx_t *sctx, const char *inst_name,
|
|
if (ev == NULL)
|
|
return ISC_R_NOMEMORY;
|
|
|
|
- ev->dbname = inst_name;
|
|
+ ev->inst = inst;
|
|
ev->sctx = sctx;
|
|
*evp = ev;
|
|
|
|
@@ -488,7 +482,7 @@ cleanup:
|
|
* enqueued before sync_barrier_wait() call.
|
|
*/
|
|
isc_result_t
|
|
-sync_barrier_wait(sync_ctx_t *sctx, const char *inst_name) {
|
|
+sync_barrier_wait(sync_ctx_t *sctx, ldap_instance_t *inst) {
|
|
isc_result_t result;
|
|
isc_event_t *ev = NULL;
|
|
sync_barrierev_t *bev = NULL;
|
|
@@ -524,7 +518,7 @@ sync_barrier_wait(sync_ctx_t *sctx, const char *inst_name) {
|
|
taskel != NULL;
|
|
taskel = next_taskel) {
|
|
bev = NULL;
|
|
- CHECK(sync_barrierev_create(sctx, inst_name, &bev));
|
|
+ CHECK(sync_barrierev_create(sctx, inst, &bev));
|
|
next_taskel = NEXT(taskel, link);
|
|
UNLINK(sctx->tasks, taskel, link);
|
|
ev = (isc_event_t *)bev;
|
|
diff --git a/src/syncrepl.h b/src/syncrepl.h
|
|
index ba3070a..14684ea 100644
|
|
--- a/src/syncrepl.h
|
|
+++ b/src/syncrepl.h
|
|
@@ -49,7 +49,7 @@ isc_result_t
|
|
sync_task_add(sync_ctx_t *sctx, isc_task_t *task) ATTR_NONNULLS ATTR_CHECKRESULT;
|
|
|
|
isc_result_t
|
|
-sync_barrier_wait(sync_ctx_t *sctx, const char *inst_name) ATTR_NONNULLS ATTR_CHECKRESULT;
|
|
+sync_barrier_wait(sync_ctx_t *sctx, ldap_instance_t *inst) ATTR_NONNULLS ATTR_CHECKRESULT;
|
|
|
|
isc_result_t
|
|
sync_concurr_limit_wait(sync_ctx_t *sctx) ATTR_NONNULLS ATTR_CHECKRESULT;
|
|
diff --git a/src/types.h b/src/types.h
|
|
index 57d5579..25ef3b9 100644
|
|
--- a/src/types.h
|
|
+++ b/src/types.h
|
|
@@ -43,7 +43,7 @@ typedef struct ldap_syncreplevent ldap_syncreplevent_t;
|
|
struct ldap_syncreplevent {
|
|
ISC_EVENT_COMMON(ldap_syncreplevent_t);
|
|
isc_mem_t *mctx;
|
|
- char *dbname;
|
|
+ ldap_instance_t *inst;
|
|
char *prevdn;
|
|
int chgtype;
|
|
ldap_entry_t *entry;
|
|
diff --git a/src/zone_manager.c b/src/zone_manager.c
|
|
deleted file mode 100644
|
|
index 85e19fb..0000000
|
|
--- a/src/zone_manager.c
|
|
+++ /dev/null
|
|
@@ -1,205 +0,0 @@
|
|
-/*
|
|
- * Copyright (C) 2009-2014 bind-dyndb-ldap authors; see COPYING for license
|
|
- */
|
|
-
|
|
-#include <isc/mem.h>
|
|
-#include <isc/once.h>
|
|
-#include <isc/result.h>
|
|
-#include <isc/task.h>
|
|
-#include <isc/timer.h>
|
|
-#include <isc/boolean.h>
|
|
-#include <isc/util.h>
|
|
-
|
|
-#include <dns/dynamic_db.h>
|
|
-#include <dns/view.h>
|
|
-#include <dns/zone.h>
|
|
-
|
|
-#include <string.h>
|
|
-#include <unistd.h>
|
|
-
|
|
-#include "config.h"
|
|
-
|
|
-#include "bindcfg.h"
|
|
-#include "ldap_convert.h"
|
|
-#include "ldap_helper.h"
|
|
-#include "log.h"
|
|
-#include "settings.h"
|
|
-#include "util.h"
|
|
-#include "zone_manager.h"
|
|
-
|
|
-struct db_instance {
|
|
- isc_mem_t *mctx;
|
|
- char *name;
|
|
- ldap_instance_t *ldap_inst;
|
|
- isc_timer_t *timer;
|
|
- LINK(db_instance_t) link;
|
|
-};
|
|
-
|
|
-static isc_once_t initialize_once = ISC_ONCE_INIT;
|
|
-static isc_mutex_t instance_list_lock;
|
|
-static LIST(db_instance_t) instance_list;
|
|
-
|
|
-static void initialize_manager(void);
|
|
-static void destroy_db_instance(db_instance_t **db_instp) ATTR_NONNULLS;
|
|
-static isc_result_t find_db_instance(const char *name, db_instance_t **instance) ATTR_NONNULLS ATTR_CHECKRESULT;
|
|
-
|
|
-
|
|
-static void
|
|
-initialize_manager(void)
|
|
-{
|
|
- INIT_LIST(instance_list);
|
|
- isc_mutex_init(&instance_list_lock);
|
|
- log_info("bind-dyndb-ldap version " VERSION
|
|
- " compiled at " __TIME__ " " __DATE__
|
|
- ", compiler " __VERSION__);
|
|
- cfg_init_types();
|
|
-}
|
|
-
|
|
-void
|
|
-destroy_manager(void)
|
|
-{
|
|
- db_instance_t *db_inst;
|
|
- db_instance_t *next;
|
|
-
|
|
- RUNTIME_CHECK(isc_once_do(&initialize_once, initialize_manager)
|
|
- == ISC_R_SUCCESS);
|
|
-
|
|
- LOCK(&instance_list_lock);
|
|
- db_inst = HEAD(instance_list);
|
|
- while (db_inst != NULL) {
|
|
- next = NEXT(db_inst, link);
|
|
- UNLINK(instance_list, db_inst, link);
|
|
- destroy_db_instance(&db_inst);
|
|
- db_inst = next;
|
|
- }
|
|
- UNLOCK(&instance_list_lock);
|
|
-}
|
|
-
|
|
-static void ATTR_NONNULLS
|
|
-destroy_db_instance(db_instance_t **db_instp)
|
|
-{
|
|
- db_instance_t *db_inst;
|
|
-
|
|
- REQUIRE(db_instp != NULL && *db_instp != NULL);
|
|
-
|
|
- db_inst = *db_instp;
|
|
-
|
|
- if (db_inst->timer != NULL)
|
|
- isc_timer_detach(&db_inst->timer);
|
|
- if (db_inst->ldap_inst != NULL)
|
|
- destroy_ldap_instance(&db_inst->ldap_inst);
|
|
- if (db_inst->name != NULL)
|
|
- isc_mem_free(db_inst->mctx, db_inst->name);
|
|
-
|
|
- MEM_PUT_AND_DETACH(db_inst);
|
|
-
|
|
- *db_instp = NULL;
|
|
-}
|
|
-
|
|
-isc_result_t
|
|
-manager_create_db_instance(isc_mem_t *mctx, const char *name,
|
|
- const char * const *argv,
|
|
- dns_dyndb_arguments_t *dyndb_args)
|
|
-{
|
|
- isc_result_t result;
|
|
- db_instance_t *db_inst = NULL;
|
|
- isc_task_t *task;
|
|
- settings_set_t *local_settings = NULL;
|
|
-
|
|
- REQUIRE(name != NULL);
|
|
- REQUIRE(dyndb_args != NULL);
|
|
-
|
|
- RUNTIME_CHECK(isc_once_do(&initialize_once, initialize_manager)
|
|
- == ISC_R_SUCCESS);
|
|
-
|
|
- result = find_db_instance(name, &db_inst);
|
|
- if (result == ISC_R_SUCCESS) {
|
|
- db_inst = NULL;
|
|
- log_error("LDAP instance '%s' already exists", name);
|
|
- CLEANUP_WITH(ISC_R_EXISTS);
|
|
- }
|
|
-
|
|
- CHECKED_MEM_GET_PTR(mctx, db_inst);
|
|
- ZERO_PTR(db_inst);
|
|
-
|
|
- isc_mem_attach(mctx, &db_inst->mctx);
|
|
- CHECKED_MEM_STRDUP(mctx, name, db_inst->name);
|
|
- task = dns_dyndb_get_task(dyndb_args);
|
|
- CHECK(new_ldap_instance(mctx, db_inst->name, argv, dyndb_args, task,
|
|
- &db_inst->ldap_inst));
|
|
-
|
|
- local_settings = ldap_instance_getsettings_local(db_inst->ldap_inst);
|
|
- CHECK(setting_get_bool("verbose_checks", local_settings, &verbose_checks));
|
|
-
|
|
- /* instance must be in list while calling refresh_zones_from_ldap() */
|
|
- LOCK(&instance_list_lock);
|
|
- APPEND(instance_list, db_inst, link);
|
|
- UNLOCK(&instance_list_lock);
|
|
-
|
|
- return ISC_R_SUCCESS;
|
|
-
|
|
-cleanup:
|
|
- if (db_inst != NULL)
|
|
- destroy_db_instance(&db_inst);
|
|
-
|
|
- return result;
|
|
-}
|
|
-
|
|
-isc_result_t
|
|
-manager_get_ldap_instance(const char *name, ldap_instance_t **ldap_inst)
|
|
-{
|
|
- isc_result_t result;
|
|
- db_instance_t *db_inst;
|
|
-
|
|
- REQUIRE(name != NULL);
|
|
- REQUIRE(ldap_inst != NULL);
|
|
-
|
|
- RUNTIME_CHECK(isc_once_do(&initialize_once, initialize_manager)
|
|
- == ISC_R_SUCCESS);
|
|
- db_inst = NULL;
|
|
- CHECK(find_db_instance(name, &db_inst));
|
|
-
|
|
- *ldap_inst = db_inst->ldap_inst;
|
|
-
|
|
-cleanup:
|
|
- return result;
|
|
-}
|
|
-
|
|
-static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT
|
|
-find_db_instance(const char *name, db_instance_t **instance)
|
|
-{
|
|
- db_instance_t *iterator;
|
|
-
|
|
- REQUIRE(name != NULL);
|
|
- REQUIRE(instance != NULL && *instance == NULL);
|
|
-
|
|
- LOCK(&instance_list_lock);
|
|
- iterator = HEAD(instance_list);
|
|
- while (iterator != NULL) {
|
|
- if (strcmp(name, iterator->name) == 0)
|
|
- break;
|
|
- iterator = NEXT(iterator, link);
|
|
- }
|
|
- UNLOCK(&instance_list_lock);
|
|
-
|
|
- if (iterator != NULL) {
|
|
- *instance = iterator;
|
|
- return ISC_R_SUCCESS;
|
|
- }
|
|
-
|
|
- return ISC_R_NOTFOUND;
|
|
-}
|
|
-
|
|
-isc_result_t
|
|
-manager_get_db_timer(const char *name, isc_timer_t **timer) {
|
|
- isc_result_t result;
|
|
- db_instance_t *db_inst = NULL;
|
|
-
|
|
- REQUIRE(name != NULL);
|
|
-
|
|
- result = find_db_instance(name, &db_inst);
|
|
- if (result == ISC_R_SUCCESS)
|
|
- *timer = db_inst->timer;
|
|
-
|
|
- return result;
|
|
-}
|
|
diff --git a/src/zone_manager.h b/src/zone_manager.h
|
|
deleted file mode 100644
|
|
index 1e06365..0000000
|
|
--- a/src/zone_manager.h
|
|
+++ /dev/null
|
|
@@ -1,29 +0,0 @@
|
|
-/*
|
|
- * Copyright (C) 2009-2014 bind-dyndb-ldap authors; see COPYING for license
|
|
- */
|
|
-
|
|
-#ifndef _LD_ZONE_MANAGER_H_
|
|
-#define _LD_ZONE_MANAGER_H_
|
|
-
|
|
-#include <dns/types.h>
|
|
-
|
|
-#include "types.h"
|
|
-
|
|
-typedef struct db_instance db_instance_t;
|
|
-
|
|
-void destroy_manager(void);
|
|
-
|
|
-isc_result_t
|
|
-manager_create_db_instance(isc_mem_t *mctx, const char *name,
|
|
- const char * const *argv,
|
|
- dns_dyndb_arguments_t *dyndb_args) ATTR_NONNULLS ATTR_CHECKRESULT;
|
|
-
|
|
-isc_result_t
|
|
-manager_get_ldap_instance(const char *name,
|
|
- ldap_instance_t **ldap_inst) ATTR_NONNULLS ATTR_CHECKRESULT;
|
|
-
|
|
-isc_result_t
|
|
-manager_get_db_timer(const char *name,
|
|
- isc_timer_t **timer) ATTR_NONNULLS ATTR_CHECKRESULT;
|
|
-
|
|
-#endif /* !_LD_ZONE_MANAGER_H_ */
|
|
diff --git a/src/zone_register.c b/src/zone_register.c
|
|
index bde4a7c..d8525e9 100644
|
|
--- a/src/zone_register.c
|
|
+++ b/src/zone_register.c
|
|
@@ -260,15 +260,15 @@ cleanup:
|
|
static isc_result_t ATTR_NONNULL(1,2,4,5,6,8)
|
|
create_zone_info(isc_mem_t * const mctx, dns_zone_t * const raw,
|
|
dns_zone_t * const secure, const char * const dn,
|
|
- settings_set_t *global_settings, const char *db_name,
|
|
+ settings_set_t *global_settings, ldap_instance_t *inst,
|
|
dns_db_t * const ldapdb, zone_info_t **zinfop)
|
|
{
|
|
isc_result_t result;
|
|
zone_info_t *zinfo;
|
|
char settings_name[PRINT_BUFF_SIZE];
|
|
ld_string_t *zone_dir = NULL;
|
|
- char *argv[1];
|
|
|
|
+ REQUIRE(inst != NULL);
|
|
REQUIRE(raw != NULL);
|
|
REQUIRE(dn != NULL);
|
|
REQUIRE(zinfop != NULL && *zinfop == NULL);
|
|
@@ -294,11 +294,9 @@ create_zone_info(isc_mem_t * const mctx, dns_zone_t * const raw,
|
|
CHECK(fs_dirs_create(str_buf(zone_dir)));
|
|
|
|
if (ldapdb == NULL) { /* create new empty database */
|
|
- DE_CONST(db_name, argv[0]);
|
|
CHECK(ldapdb_create(mctx, dns_zone_getorigin(raw),
|
|
LDAP_DB_TYPE, LDAP_DB_RDATACLASS,
|
|
- sizeof(argv)/sizeof(argv[0]),
|
|
- argv, NULL, &zinfo->ldapdb));
|
|
+ inst, &zinfo->ldapdb));
|
|
} else { /* re-use existing database */
|
|
dns_db_attach(ldapdb, &zinfo->ldapdb);
|
|
}
|
|
@@ -396,8 +394,7 @@ zr_add_zone(zone_register_t * const zr, dns_db_t * const ldapdb,
|
|
}
|
|
|
|
CHECK(create_zone_info(zr->mctx, raw, secure, dn, zr->global_settings,
|
|
- ldap_instance_getdbname(zr->ldap_inst), ldapdb,
|
|
- &new_zinfo));
|
|
+ zr->ldap_inst, ldapdb, &new_zinfo));
|
|
CHECK(dns_rbt_addname(zr->rbt, name, new_zinfo));
|
|
|
|
cleanup:
|