summaryrefslogtreecommitdiff
path: root/source4/dns_server
diff options
context:
space:
mode:
authorBob Campbell <bobcampbell@catalyst.net.nz>2016-12-06 15:34:23 +1300
committerGarming Sam <garming@samba.org>2016-12-12 05:00:18 +0100
commit4408df249349581654c5a77f4f8fa38bbae11b4f (patch)
tree9a798137582b544b505f4cc7a6d5a584fb90988f /source4/dns_server
parent3ba40f6eb194d773a2d369f6dc3472390fe248ea (diff)
downloadsamba-4408df249349581654c5a77f4f8fa38bbae11b4f.tar.gz
dnsserver: add dns name checking
This may also prevent deletion of existing corrupted records through DNS, but should be resolvable through RPC, or at worst LDAP. Signed-off-by: Bob Campbell <bobcampbell@catalyst.net.nz> Pair-programmed-with: Garming Sam <garming@catalyst.net.nz> Reviewed-by: Garming Sam <garming@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source4/dns_server')
-rw-r--r--source4/dns_server/dnsserver_common.c91
-rw-r--r--source4/dns_server/dnsserver_common.h4
2 files changed, 94 insertions, 1 deletions
diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c
index db42bcb5981..4982d3a37b1 100644
--- a/source4/dns_server/dnsserver_common.c
+++ b/source4/dns_server/dnsserver_common.c
@@ -214,6 +214,91 @@ static int rec_cmp(const struct dnsp_DnssrvRpcRecord *r1,
return r1->dwTimeStamp - r2->dwTimeStamp;
}
+/*
+ * Check for valid DNS names. These are names which are non-empty, do not
+ * start with a dot and do not have any empty segments.
+ */
+WERROR dns_name_check(TALLOC_CTX *mem_ctx, size_t len, const char *name)
+{
+ size_t i;
+
+ if (len == 0) {
+ return WERR_DS_INVALID_DN_SYNTAX;
+ }
+
+ for (i = 0; i < len - 1; i++) {
+ if (name[i] == '.' && name[i+1] == '.') {
+ return WERR_DS_INVALID_DN_SYNTAX;
+ }
+ }
+
+ if (len > 1 && name[0] == '.') {
+ return WERR_DS_INVALID_DN_SYNTAX;
+ }
+
+ return WERR_OK;
+}
+
+static WERROR check_name_list(TALLOC_CTX *mem_ctx, uint16_t rec_count,
+ struct dnsp_DnssrvRpcRecord *records)
+{
+ WERROR werr;
+ uint16_t i;
+ size_t len;
+ struct dnsp_DnssrvRpcRecord record;
+
+ werr = WERR_OK;
+ for (i = 0; i < rec_count; i++) {
+ record = records[i];
+
+ switch (record.wType) {
+
+ case DNS_TYPE_NS:
+ len = strlen(record.data.ns);
+ werr = dns_name_check(mem_ctx, len, record.data.ns);
+ break;
+ case DNS_TYPE_CNAME:
+ len = strlen(record.data.cname);
+ werr = dns_name_check(mem_ctx, len, record.data.cname);
+ break;
+ case DNS_TYPE_SOA:
+ len = strlen(record.data.soa.mname);
+ werr = dns_name_check(mem_ctx, len, record.data.soa.mname);
+ if (!W_ERROR_IS_OK(werr)) {
+ break;
+ }
+ len = strlen(record.data.soa.rname);
+ werr = dns_name_check(mem_ctx, len, record.data.soa.rname);
+ break;
+ case DNS_TYPE_PTR:
+ len = strlen(record.data.ptr);
+ werr = dns_name_check(mem_ctx, len, record.data.ptr);
+ break;
+ case DNS_TYPE_MX:
+ len = strlen(record.data.mx.nameTarget);
+ werr = dns_name_check(mem_ctx, len, record.data.mx.nameTarget);
+ break;
+ case DNS_TYPE_SRV:
+ len = strlen(record.data.srv.nameTarget);
+ werr = dns_name_check(mem_ctx, len,
+ record.data.srv.nameTarget);
+ break;
+ /*
+ * In the default case, the record doesn't have a DN, so it
+ * must be ok.
+ */
+ default:
+ break;
+ }
+
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+ }
+
+ return WERR_OK;
+}
+
WERROR dns_common_replace(struct ldb_context *samdb,
TALLOC_CTX *mem_ctx,
struct ldb_dn *dn,
@@ -225,6 +310,7 @@ WERROR dns_common_replace(struct ldb_context *samdb,
struct ldb_message_element *el;
uint16_t i;
int ret;
+ WERROR werr;
struct ldb_message *msg = NULL;
bool was_tombstoned = false;
bool become_tombstoned = false;
@@ -234,6 +320,11 @@ WERROR dns_common_replace(struct ldb_context *samdb,
msg->dn = dn;
+ werr = check_name_list(mem_ctx, rec_count, records);
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+
ret = ldb_msg_add_empty(msg, "dnsRecord", LDB_FLAG_MOD_REPLACE, &el);
if (ret != LDB_SUCCESS) {
return DNS_ERR(SERVER_FAILURE);
diff --git a/source4/dns_server/dnsserver_common.h b/source4/dns_server/dnsserver_common.h
index ad91f617be7..57d5d9f3c15 100644
--- a/source4/dns_server/dnsserver_common.h
+++ b/source4/dns_server/dnsserver_common.h
@@ -46,7 +46,9 @@ WERROR dns_common_lookup(struct ldb_context *samdb,
struct dnsp_DnssrvRpcRecord **records,
uint16_t *num_records,
bool *tombstoned);
-
+WERROR dns_name_check(TALLOC_CTX *mem_ctx,
+ size_t len,
+ const char *name);
WERROR dns_common_replace(struct ldb_context *samdb,
TALLOC_CTX *mem_ctx,
struct ldb_dn *dn,