summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAaron Haslett <aaronhaslett@catalyst.net.nz>2018-10-23 11:52:07 +1300
committerKarolin Seeger <kseeger@samba.org>2018-11-28 08:22:23 +0100
commitc3f6085991938488b9e48611b4beb5bdc9cbfb04 (patch)
treef81bc71dba7dfb926dcc43f763e4b8d7977188c0 /source4
parent1f42e62e46f733f1df460f9427ea86bcb429462e (diff)
downloadsamba-c3f6085991938488b9e48611b4beb5bdc9cbfb04.tar.gz
dns: prevent self-referencing CNAME
Stops the user from adding a self-referencing CNAME over RPC, which is an easy mistake to make with samba-tool. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13600 Signed-off-by: Aaron Haslett <aaronhaslett@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Garming Sam <garming@catalyst.net.nz>
Diffstat (limited to 'source4')
-rw-r--r--source4/rpc_server/dnsserver/dcerpc_dnsserver.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
index b42d7c549d1..edea2b33f2d 100644
--- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
+++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
@@ -25,6 +25,7 @@
#include "dsdb/samdb/samdb.h"
#include "lib/util/dlinklist.h"
#include "librpc/gen_ndr/ndr_dnsserver.h"
+#include "dns_server/dnsserver_common.h"
#include "dnsserver.h"
#define DCESRV_INTERFACE_DNSSERVER_BIND(call, iface) \
@@ -1868,6 +1869,37 @@ static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
return WERR_OK;
}
+/*
+ * Check str1 + '.' + str2 = name, for example:
+ * ("dc0", "example.com", "dc0.example.com") = true
+ */
+static bool cname_self_reference(const char* node_name,
+ const char* zone_name,
+ struct DNS_RPC_NAME name) {
+ size_t node_len, zone_len;
+
+ if (node_name == NULL || zone_name == NULL) {
+ return false;
+ }
+
+ node_len = strlen(node_name);
+ zone_len = strlen(zone_name);
+
+ if (node_len == 0 ||
+ zone_len == 0 ||
+ (name.len != node_len + zone_len + 1)) {
+ return false;
+ }
+
+ if (strncmp(node_name, name.str, node_len) == 0 &&
+ name.str[node_len] == '.' &&
+ strncmp(zone_name, name.str + node_len + 1, zone_len) == 0) {
+ return true;
+ }
+
+ return false;
+}
+
/* dnsserver update function */
static WERROR dnsserver_update_record(struct dnsserver_state *dsstate,
@@ -1895,6 +1927,13 @@ static WERROR dnsserver_update_record(struct dnsserver_state *dsstate,
}
W_ERROR_HAVE_NO_MEMORY_AND_FREE(name, tmp_ctx);
+ /* CNAMEs can't point to themselves */
+ if (add_buf != NULL && add_buf->rec.wType == DNS_TYPE_CNAME) {
+ if (cname_self_reference(node_name, z->name, add_buf->rec.data.name)) {
+ return WERR_DNS_ERROR_CNAME_LOOP;
+ }
+ }
+
if (add_buf != NULL) {
if (del_buf == NULL) {
/* Add record */