From cfde79fec8f6fc14b10fabed6280777b4a0de525 Mon Sep 17 00:00:00 2001 From: Petr Spacek Date: Jun 17 2016 14:03:27 +0000 Subject: Support default TTL configuration at zone level: dNSdefaultTTL attribute. Limitations: - Changes to the dNSdefaultTTL attribute will propagate only to records which were updated after the change. Reload is necessary to ensure that all TTL values in zone were updated. https://fedorahosted.org/bind-dyndb-ldap/ticket/70 --- diff --git a/doc/schema.ldif b/doc/schema.ldif index de0702e..2420b1a 100644 --- a/doc/schema.ldif +++ b/doc/schema.ldif @@ -76,6 +76,13 @@ attributeTypes: ( 1.3.6.1.4.1.2428.20.0.0 SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 EQUALITY integerMatch ) # +attributeTypes: ( 1.3.6.1.4.1.2428.20.0.2 + NAME 'dNSdefaultTTL' + DESC 'An integer denoting default time to live, RFC 2308' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 + EQUALITY integerMatch + ORDERING integerOrderingMatch ) +# # # UNINETT and FreeIPA attributes # dnsClass attribute is in fact unsupported by bind-dyndb-ldap @@ -389,7 +396,7 @@ objectClasses: ( 2.16.840.1.113730.3.8.6.1 ) MAY ( idnsUpdatePolicy $ idnsAllowQuery $ idnsAllowTransfer $ idnsAllowSyncPTR $ idnsForwardPolicy $ idnsForwarders $ - idnsSecInlineSigning $ nSEC3PARAMRecord + idnsSecInlineSigning $ nSEC3PARAMRecord $ dNSdefaultTTL ) ) # objectClasses: ( 2.16.840.1.113730.3.8.6.2 diff --git a/src/ldap_entry.c b/src/ldap_entry.c index 8f19b0b..96a6ef8 100644 --- a/src/ldap_entry.c +++ b/src/ldap_entry.c @@ -516,7 +516,7 @@ cleanup: } dns_ttl_t -ldap_entry_getttl(ldap_entry_t *entry) +ldap_entry_getttl(ldap_entry_t *entry, const settings_set_t * settings) { const char *ttl_attr = "dnsTTL"; isc_textregion_t ttl_text; @@ -526,21 +526,20 @@ ldap_entry_getttl(ldap_entry_t *entry) REQUIRE(entry != NULL); - result = ldap_entry_getvalues(entry, ttl_attr, &values); - if (result == ISC_R_NOTFOUND) - return DEFAULT_TTL; + CHECK(ldap_entry_getvalues(entry, ttl_attr, &values)); ttl_text.base = HEAD(values)->value; ttl_text.length = strlen(ttl_text.base); - result = dns_ttl_fromtext(&ttl_text, &ttl); - if (result != ISC_R_SUCCESS) - return DEFAULT_TTL; - else if (ttl > 0x7fffffffUL) { + CHECK(dns_ttl_fromtext(&ttl_text, &ttl)); + if (ttl > 0x7fffffffUL) { log_error("%s: entry TTL %u > MAXTTL, setting TTL to 0", ldap_entry_logname(entry), ttl); ttl = 0; } + return ttl; +cleanup: + INSIST(setting_get_uint("default_ttl", settings, &ttl) == ISC_R_SUCCESS); return ttl; } diff --git a/src/ldap_entry.h b/src/ldap_entry.h index 357aa9f..6498c79 100644 --- a/src/ldap_entry.h +++ b/src/ldap_entry.h @@ -70,8 +70,6 @@ struct ldap_attribute { #define LDAP_ENTRYCLASS_SERVERCONFIG 0x10 #define LDAP_ENTRYCLASS_TEMPLATE 0x20 -#define DEFAULT_TTL 86400 - /* Max type length definitions, from lib/dns/master.c */ #define TOKENSIZ (8*1024) @@ -124,7 +122,7 @@ isc_result_t ldap_attr_nextvalue(ldap_attribute_t *attr, ld_string_t *value) ATTR_NONNULLS ATTR_CHECKRESULT; dns_ttl_t -ldap_entry_getttl(ldap_entry_t *entry) ATTR_NONNULLS ATTR_CHECKRESULT; +ldap_entry_getttl(ldap_entry_t *entry, const settings_set_t * settings) ATTR_NONNULLS ATTR_CHECKRESULT; const char * ldap_entry_logname(ldap_entry_t * const entry) ATTR_NONNULLS ATTR_CHECKRESULT; diff --git a/src/ldap_helper.c b/src/ldap_helper.c index f75c900..daf5f0c 100644 --- a/src/ldap_helper.c +++ b/src/ldap_helper.c @@ -287,7 +287,7 @@ static isc_result_t findrdatatype_or_create(isc_mem_t *mctx, ldapdb_rdatalist_t *rdatalist, dns_rdataclass_t rdclass, dns_rdatatype_t rdtype, dns_ttl_t ttl, dns_rdatalist_t **rdlistp) ATTR_NONNULLS ATTR_CHECKRESULT; static isc_result_t add_soa_record(isc_mem_t *mctx, dns_name_t *origin, - ldap_entry_t *entry, ldapdb_rdatalist_t *rdatalist, + ldap_entry_t *entry, dns_ttl_t ttl, ldapdb_rdatalist_t *rdatalist, const char *fake_mname) ATTR_NONNULLS ATTR_CHECKRESULT; static isc_result_t parse_rdata(isc_mem_t *mctx, ldap_entry_t *entry, dns_rdataclass_t rdclass, dns_rdatatype_t rdtype, @@ -1767,6 +1767,13 @@ zone_master_reconfigure(ldap_entry_t *entry, settings_set_t *zone_settings, if (result != ISC_R_SUCCESS && result != ISC_R_IGNORE) goto cleanup; + result = setting_update_from_ldap_entry("default_ttl", zone_settings, + "DNSdefaultTTL", entry); + if (result == ISC_R_SUCCESS) + log_bug("default TTL cannot be changed at run-time"); + else if (result != ISC_R_IGNORE) + goto cleanup; + result = setting_update_from_ldap_entry("update_policy", zone_settings, "idnsUpdatePolicy", entry); if (result != ISC_R_SUCCESS && result != ISC_R_IGNORE) @@ -1889,7 +1896,9 @@ zone_sync_apex(const ldap_instance_t * const inst, ldap_entry_t * const entry, dns_name_t name, const sync_state_t sync_state, const isc_boolean_t new_zone, dns_db_t * const ldapdb, dns_db_t * const rbtdb, - dns_dbversion_t * const version, dns_diff_t * const diff, + dns_dbversion_t * const version, + const settings_set_t * const zone_settings, + dns_diff_t * const diff, isc_uint32_t * const new_serial, isc_boolean_t * const ldap_writeback, isc_boolean_t * const data_changed) { @@ -1908,7 +1917,7 @@ zone_sync_apex(const ldap_instance_t * const inst, *ldap_writeback = ISC_FALSE; /* GCC */ CHECK(ldap_parse_rrentry(inst->mctx, entry, &name, - inst->server_ldap_settings, &rdatalist)); + zone_settings, &rdatalist)); CHECK(dns_db_getoriginnode(rbtdb, &node)); result = dns_db_allrdatasets(rbtdb, node, version, 0, @@ -2095,7 +2104,7 @@ ldap_parse_master_zoneentry(ldap_entry_t * const entry, dns_db_t * const olddb, CHECK(dns_db_newversion(ldapdb, &version)); sync_state_get(inst->sctx, &sync_state); CHECK(zone_sync_apex(inst, entry, entry->fqdn, sync_state, new_zone, - ldapdb, rbtdb, version, + ldapdb, rbtdb, version, zone_settings, &diff, &new_serial, &ldap_writeback, &data_changed)); @@ -2419,7 +2428,7 @@ ldap_parse_rrentry_template(isc_mem_t *mctx, ldap_entry_t *entry, CHECK(str_new(mctx, &orig_val)); rdclass = ldap_entry_getrdclass(entry); - ttl = ldap_entry_getttl(entry); + ttl = ldap_entry_getttl(entry, settings); while ((attr = ldap_entry_nextattr(entry)) != NULL) { if (strncasecmp(prefix, attr->name, prefix_len) != 0) @@ -2492,14 +2501,14 @@ ldap_parse_rrentry(isc_mem_t *mctx, ldap_entry_t *entry, dns_name_t *origin, REQUIRE(EMPTY(*rdatalist)); + ttl = ldap_entry_getttl(entry, settings); + rdclass = ldap_entry_getrdclass(entry); if ((entry->class & LDAP_ENTRYCLASS_MASTER) != 0) { CHECK(setting_get_str("fake_mname", settings, &fake_mname)); - CHECK(add_soa_record(mctx, origin, entry, rdatalist, fake_mname)); + CHECK(add_soa_record(mctx, origin, entry, ttl, rdatalist, + fake_mname)); } - rdclass = ldap_entry_getrdclass(entry); - ttl = ldap_entry_getttl(entry); - if ((entry->class & LDAP_ENTRYCLASS_TEMPLATE) != 0) { result = ldap_parse_rrentry_template(mctx, entry, origin, settings, rdatalist); @@ -2547,7 +2556,7 @@ cleanup: static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT add_soa_record(isc_mem_t *mctx, dns_name_t *origin, - ldap_entry_t *entry, ldapdb_rdatalist_t *rdatalist, + ldap_entry_t *entry, dns_ttl_t ttl, ldapdb_rdatalist_t *rdatalist, const char *fake_mname) { isc_result_t result; @@ -2564,7 +2573,7 @@ add_soa_record(isc_mem_t *mctx, dns_name_t *origin, str_buf(string), &rdata)); CHECK(findrdatatype_or_create(mctx, rdatalist, rdclass, dns_rdatatype_soa, - ldap_entry_getttl(entry), &rdlist)); + ttl, &rdlist)); APPEND(rdlist->rdata, rdata, link); @@ -3785,6 +3794,7 @@ update_record(isc_task_t *task, isc_event_t *event) isc_result_t result; ldap_instance_t *inst = NULL; isc_mem_t *mctx; + settings_set_t *zone_settings = NULL; dns_zone_t *raw = NULL; dns_zone_t *secure = NULL; isc_boolean_t zone_found = ISC_FALSE; @@ -3878,8 +3888,10 @@ update_restart: /* Parse new data from LDAP. */ log_debug(5, "syncrepl_update: updating name in rbtdb, " "%s", ldap_entry_logname(entry)); + CHECK(zr_get_zone_settings(inst->zone_register, + &entry->zone_name, &zone_settings)); CHECK(ldap_parse_rrentry(mctx, entry, &entry->zone_name, - inst->server_ldap_settings, &rdatalist)); + zone_settings, &rdatalist)); } if (rbt_rds_iterator != NULL) { diff --git a/src/settings.c b/src/settings.c index 7dc5d4b..3692dae 100644 --- a/src/settings.c +++ b/src/settings.c @@ -28,6 +28,7 @@ isc_boolean_t verbose_checks = ISC_FALSE; /* log each failure in CHECK() macro * /** Built-in defaults. */ static const setting_t settings_default[] = { + { "default_ttl", default_uint(86400) }, /* Seconds */ { "uri", no_default_string }, /* User have to set this */ { "connections", default_uint(2) }, { "reconnect_interval", default_uint(60) }, diff --git a/src/zone_register.c b/src/zone_register.c index be9265e..3f8c070 100644 --- a/src/zone_register.c +++ b/src/zone_register.c @@ -70,6 +70,7 @@ static void delete_zone_info(void *arg1, void *arg2); */ static const setting_t zone_settings[] = { { "active", default_boolean(0) }, + { "default_ttl", no_default_uint }, { "dyn_update", no_default_boolean }, { "update_policy", no_default_string }, { "allow_query", no_default_string },