dnsserver: Tighten DNS name checking
authorGary Lockyer <gary@catalyst.net.nz>
Thu, 3 Aug 2017 03:12:51 +0000 (15:12 +1200)
committerGarming Sam <garming@samba.org>
Tue, 15 Aug 2017 06:07:10 +0000 (08:07 +0200)
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

librpc/idl/dns.idl
source4/dns_server/dnsserver_common.c

index aebb106b053d4a4a9baf429d0b362426feb70038..8e8eed5ab23716d26e9e22f5df7b9428f2f119b8 100644 (file)
@@ -18,6 +18,9 @@ import "misc.idl", "dnsp.idl";
 interface dns
 {
        const int DNS_SERVICE_PORT       = 53;
 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,
 
        typedef [public,bitmap16bit] bitmap {
                DNS_RCODE                   = 0x000F,
index a56ff08031ba77a1a0929c8f5bad5b6a8959dddd..2a81b836722ec8f0a8baebfb096ef004999e7ef7 100644 (file)
@@ -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;
  */
 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 == 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;
                }
        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;
        }
 
        return WERR_OK;