diff options
author | Bob Campbell <bobcampbell@catalyst.net.nz> | 2016-12-06 15:34:23 +1300 |
---|---|---|
committer | Garming Sam <garming@samba.org> | 2016-12-12 05:00:18 +0100 |
commit | 4408df249349581654c5a77f4f8fa38bbae11b4f (patch) | |
tree | 9a798137582b544b505f4cc7a6d5a584fb90988f /source4/dns_server | |
parent | 3ba40f6eb194d773a2d369f6dc3472390fe248ea (diff) | |
download | samba-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.c | 91 | ||||
-rw-r--r-- | source4/dns_server/dnsserver_common.h | 4 |
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, |