summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Lockyer <gary@catalyst.net.nz>2017-08-03 15:12:51 +1200
committerGarming Sam <garming@samba.org>2017-08-15 08:07:10 +0200
commit34acf5a99214639e5e7792a9e85d24c9fd7640ac (patch)
tree5426466e09a1e3d7f32c1b0a5b0adedf1bb05e00
parent1184770a76800897d59f1c20adaee3b0240697de (diff)
downloadsamba-34acf5a99214639e5e7792a9e85d24c9fd7640ac.tar.gz
dnsserver: Tighten DNS name checking
Add checks for the maximum permitted length, maximum number of labels and the maximum label length. These extra checks will be used by the DNS wild card handling. Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Garming Sam <garming@catalyst.net.nz> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12952
-rw-r--r--librpc/idl/dns.idl3
-rw-r--r--source4/dns_server/dnsserver_common.c35
2 files changed, 32 insertions, 6 deletions
diff --git a/librpc/idl/dns.idl b/librpc/idl/dns.idl
index aebb106b053..8e8eed5ab23 100644
--- a/librpc/idl/dns.idl
+++ b/librpc/idl/dns.idl
@@ -18,6 +18,9 @@ import "misc.idl", "dnsp.idl";
interface dns
{
const int DNS_SERVICE_PORT = 53;
+ const int DNS_MAX_LABELS = 127;
+ const int DNS_MAX_DOMAIN_LENGTH = 253;
+ const int DNS_MAX_LABEL_LENGTH = 63;
typedef [public,bitmap16bit] bitmap {
DNS_RCODE = 0x000F,
diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c
index a56ff08031b..2a81b836722 100644
--- a/source4/dns_server/dnsserver_common.c
+++ b/source4/dns_server/dnsserver_common.c
@@ -246,25 +246,48 @@ static int rec_cmp(const struct dnsp_DnssrvRpcRecord *r1,
}
/*
- * 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.
+ * Check for valid DNS names. These are names which:
+ * - are non-empty
+ * - do not start with a dot
+ * - do not have any empty labels
+ * - have no more than 127 labels
+ * - are no longer than 253 characters
+ * - none of the labels exceed 63 characters
*/
WERROR dns_name_check(TALLOC_CTX *mem_ctx, size_t len, const char *name)
{
size_t i;
+ unsigned int labels = 0;
+ unsigned int label_len = 0;
if (len == 0) {
return WERR_DS_INVALID_DN_SYNTAX;
}
+ if (len > 1 && name[0] == '.') {
+ return WERR_DS_INVALID_DN_SYNTAX;
+ }
+
+ if ((len - 1) > DNS_MAX_DOMAIN_LENGTH) {
+ 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;
+ if (name[i] == '.') {
+ labels++;
+ if (labels > DNS_MAX_LABELS) {
+ return WERR_DS_INVALID_DN_SYNTAX;
+ }
+ label_len = 0;
+ } else {
+ label_len++;
+ if (label_len > DNS_MAX_LABEL_LENGTH) {
+ return WERR_DS_INVALID_DN_SYNTAX;
+ }
+ }
}
return WERR_OK;