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;