mirror of
https://gitlab.nic.cz/knot/knot-dns.git
synced 2026-06-04 14:13:08 -04:00
catalog: enforce single label for PTR defining member
This commit is contained in:
parent
4401ec71a5
commit
9b1bcb9487
4 changed files with 26 additions and 29 deletions
|
|
@ -602,8 +602,8 @@ multiple catalog zones.
|
|||
existing zones configured on the server as it would effectively "shadow"
|
||||
part of your DNS subtree.
|
||||
|
||||
Upon catalog zone (re)load or change, all the PTR records in the zone
|
||||
sub-tree *zones* (e.g. ``unique-id1.zones.catalog. 0 IN PTR member.com.``)
|
||||
Upon catalog zone (re)load or change, all the PTR records in the format
|
||||
``unique-id.zones.catalog. 0 IN PTR member.com.`` (but not ``too.deep.zones.catalog.``!)
|
||||
are processed and member zones created, with zone names taken from the
|
||||
PTR records' RData, and zone settings taken from the configuration
|
||||
template specified by :ref:`zone_catalog-template`.
|
||||
|
|
@ -612,11 +612,10 @@ The owner names of the PTR records shall follow this scheme:
|
|||
|
||||
.. code-block:: console
|
||||
|
||||
<any-junk>.<unique-id>.zones.<catalog-zone>.
|
||||
<unique-id>.zones.<catalog-zone>.
|
||||
|
||||
where the mentioned group of labels shall match:
|
||||
|
||||
- *<any-junk>* — (optional) Any additional labels with no particular meaning.
|
||||
- *<unique-id>* — Single label that is recommended to be unique among member zones.
|
||||
- ``zones`` — Required label.
|
||||
- *<catalog-zone>* — Name of the catalog zone.
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
typedef struct {
|
||||
catalog_update_t *u;
|
||||
const knot_dname_t *apex;
|
||||
int apex_labels;
|
||||
bool remove;
|
||||
catalog_t *check;
|
||||
} cat_upd_ctx_t;
|
||||
|
|
@ -52,6 +53,13 @@ static bool check_zone_version(const zone_contents_t *zone)
|
|||
static int cat_update_add_node(zone_node_t *node, void *data)
|
||||
{
|
||||
cat_upd_ctx_t *ctx = data;
|
||||
int labels_diff = knot_dname_labels(node->owner, NULL) - ctx->apex_labels
|
||||
- 1 /* "zones" label */ - 1 /* unique-N label */;
|
||||
assert(labels_diff >= 0);
|
||||
if (labels_diff > 0) {
|
||||
return KNOT_EOK;
|
||||
}
|
||||
|
||||
const knot_rdataset_t *ptr = node_rdataset(node, KNOT_RRTYPE_PTR);
|
||||
if (ptr == NULL || ptr->count == 0) {
|
||||
return KNOT_EOK;
|
||||
|
|
@ -84,9 +92,9 @@ int catalog_update_from_zone(catalog_update_t *u, struct zone_contents *zone,
|
|||
return KNOT_EOK;
|
||||
}
|
||||
|
||||
cat_upd_ctx_t ctx = { u, zone->apex->owner, remove, check };
|
||||
cat_upd_ctx_t ctx = { u, zone->apex->owner, knot_dname_labels(zone->apex->owner, NULL), remove, check };
|
||||
pthread_mutex_lock(&u->mutex);
|
||||
int ret = zone_tree_sub_apply(zone->nodes, sub, false, cat_update_add_node, &ctx);
|
||||
int ret = zone_tree_sub_apply(zone->nodes, sub, true, cat_update_add_node, &ctx);
|
||||
pthread_mutex_unlock(&u->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,5 +5,7 @@ $TTL 0
|
|||
NS ns
|
||||
ns AAAA ::0
|
||||
version TXT "2"
|
||||
foo.bar.zones PTR cataloged1.
|
||||
foo.zones PTR cataloged1.
|
||||
not.zones.in PTR not-cataloged1.
|
||||
too.deep.zones PTR not-cataloged2.
|
||||
zones PTR not-cataloged3.
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ resp.check_count(2, "DNSKEY")
|
|||
resp.check_count(1, "RRSIG")
|
||||
resp = master.dig("not-cataloged1.", "SOA")
|
||||
resp.check(rcode="REFUSED")
|
||||
resp = master.dig("not-cataloged2.", "SOA")
|
||||
resp.check(rcode="REFUSED")
|
||||
resp = master.dig("not-cataloged3.", "SOA")
|
||||
resp.check(rcode="REFUSED")
|
||||
|
||||
# Udating a cataloged zone
|
||||
subprocess.run(["sed", "-i", "s/10001/10002/;$s/$/\\nxyz A 1.2.3.4/", master.dir + "/master/cataloged1.zone"])
|
||||
|
|
@ -66,7 +70,7 @@ check_keys(slave, "cataloged1", 2)
|
|||
|
||||
# Check adding cataloged zone.
|
||||
up = master.update(zone[1])
|
||||
up.add("junk.bar.zones.catalog1.", 0, "PTR", "cataloged2.")
|
||||
up.add("bar.zones.catalog1.", 0, "PTR", "cataloged2.")
|
||||
up.send("NOERROR")
|
||||
t.sleep(6)
|
||||
resp = master.dig("cataloged2.", "NS")
|
||||
|
|
@ -88,8 +92,8 @@ resp0 = slave.dig("cataloged2.", "DNSKEY")
|
|||
resp0.check_count(2, "DNSKEY")
|
||||
dnskey0 = resp0.resp.answer[0].to_rdataset()[0]
|
||||
up = master.update(zone[1])
|
||||
up.delete("junk.bar.zones.catalog1.", "PTR", "cataloged2.")
|
||||
up.add("junk.bar.zones.catalog1.", 0, "PTR", "cataloged2.")
|
||||
up.delete("bar.zones.catalog1.", "PTR", "cataloged2.")
|
||||
up.add("bar.zones.catalog1.", 0, "PTR", "cataloged2.")
|
||||
up.send("NOERROR")
|
||||
t.sleep(4)
|
||||
resp1 = slave.dig("cataloged2.", "DNSKEY")
|
||||
|
|
@ -107,8 +111,8 @@ else:
|
|||
|
||||
# Check remove-adding the zone: shall effectively purge it
|
||||
up = master.update(zone[1])
|
||||
up.delete("junk.bar.zones.catalog1.", "PTR", "cataloged2.")
|
||||
up.add("junk.bar2.zones.catalog1.", 0, "PTR", "cataloged2.")
|
||||
up.delete("bar.zones.catalog1.", "PTR", "cataloged2.")
|
||||
up.add("bar2.zones.catalog1.", 0, "PTR", "cataloged2.")
|
||||
up.send("NOERROR")
|
||||
t.sleep(4)
|
||||
shutil.copy(t.data_dir + "/cataloged2.zone", master.dir + "/master") # because the purge deletes even zonefile
|
||||
|
|
@ -122,22 +126,6 @@ if resp2.count("DNSKEY") > 0:
|
|||
set_err("ZONE NOT PURGED")
|
||||
dnskey2 = resp2.resp.answer[0].to_rdataset()[0]
|
||||
|
||||
# Check remove-adding while keeping the 'uniq' label
|
||||
up = master.update(zone[1])
|
||||
up.delete("junk.bar2.zones.catalog1.", "PTR", "cataloged2.")
|
||||
up.add("jang.bar2.zones.catalog1.", 0, "PTR", "cataloged2.")
|
||||
up.send("NOERROR")
|
||||
t.sleep(4)
|
||||
resp3 = slave.dig("cataloged2.", "DNSKEY")
|
||||
resp3.check_count(2, "DNSKEY")
|
||||
match = 0
|
||||
if resp3.count("DNSKEY") > 0:
|
||||
for dnskey3 in resp3.resp.answer[0].to_rdataset():
|
||||
if dnskey3.to_text() == dnskey2.to_text():
|
||||
match = match + 1
|
||||
if match < 1:
|
||||
set_err("ZONE PURGED2")
|
||||
|
||||
# Check persistence after server restart
|
||||
slave.stop()
|
||||
slave.start()
|
||||
|
|
@ -171,7 +159,7 @@ check_keys(slave, "cataloged2", 2)
|
|||
master.ctl("zone-backup +journal +backupdir %s/backup %s" % (master.dir, zone[1].name))
|
||||
# Check removing cataloged zone
|
||||
up = master.update(zone[1])
|
||||
up.delete("foo.bar.zones.catalog1.", "PTR")
|
||||
up.delete("foo.zones.catalog1.", "PTR")
|
||||
up.send("NOERROR")
|
||||
t.sleep(6)
|
||||
resp = master.dig("cataloged1.", "SOA")
|
||||
|
|
|
|||
Loading…
Reference in a new issue