summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;