Skip to content
Snippets Groups Projects
Commit 8ca97c3e authored by Daniel Salzman's avatar Daniel Salzman
Browse files

Merge branch 'catalog_ptr_one_label' into 'master'

catalog: enforce single label for PTR defining member

See merge request !1275
parents 4803d29c 9b1bcb94
No related branches found
No related tags found
1 merge request!1275catalog: enforce single label for PTR defining member
Pipeline #78623 passed
......@@ -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")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment