[systemd-devel] [PATCH 1/2] networkd: accept a trailing '.' on the end of domains

Michael Marineau michael.marineau at coreos.com
Thu Jan 15 13:24:59 PST 2015


While not common outside of BIND configs the implied top level '.' in
domains is commonly accepted and crops up in random places. Starting
with commit 784d9b9c networkd began validating domains as hostnames
which rejects trailing dots, breaking short name resolution in some
environments such as Google Compute Engine. This change splits the
validation code into two functions to be more tolerant for domains.
---
 src/libsystemd-network/sd-dhcp-lease.c |  2 +-
 src/network/networkd-network.c         |  2 +-
 src/shared/util.c                      | 13 ++++++++++---
 src/shared/util.h                      |  1 +
 src/test/test-util.c                   | 14 ++++++++++++++
 5 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c
index 00fef16..53a329e 100644
--- a/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/libsystemd-network/sd-dhcp-lease.c
@@ -502,7 +502,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
                 if (r < 0)
                         return r;
 
-                if (!hostname_is_valid(domainname) || is_localhost(domainname))
+                if (!domainname_is_valid(domainname) || is_localhost(domainname))
                         break;
 
                 free(lease->domainname);
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 34a06d3..1c4c1ff 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -407,7 +407,7 @@ int config_parse_domains(const char *unit,
         STRV_FOREACH(domain, *domains) {
                 if (is_localhost(*domain))
                         log_syntax(unit, LOG_ERR, filename, line, EINVAL, "'localhost' domain names may not be configured, ignoring assignment: %s", *domain);
-                else if (!hostname_is_valid(*domain)) {
+                else if (!domainname_is_valid(*domain)) {
                         if (!streq(*domain, "*"))
                                 log_syntax(unit, LOG_ERR, filename, line, EINVAL, "domain name is not valid, ignoring assignment: %s", *domain);
                 } else
diff --git a/src/shared/util.c b/src/shared/util.c
index 884e782..9e03da4 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -4231,7 +4231,7 @@ static bool hostname_valid_char(char c) {
                 c == '.';
 }
 
-bool hostname_is_valid(const char *s) {
+bool domainname_is_valid(const char *s) {
         const char *p;
         bool dot;
 
@@ -4252,10 +4252,17 @@ bool hostname_is_valid(const char *s) {
                 }
         }
 
-        if (dot)
+        if (p-s > HOST_NAME_MAX)
                 return false;
 
-        if (p-s > HOST_NAME_MAX)
+        return true;
+}
+
+bool hostname_is_valid(const char *s) {
+        if (!domainname_is_valid(s))
+                return false;
+
+        if (s[strlen(s)-1] == '.')
                 return false;
 
         return true;
diff --git a/src/shared/util.h b/src/shared/util.h
index fdb9fb6..e332239 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -547,6 +547,7 @@ bool nulstr_contains(const char*nulstr, const char *needle);
 bool plymouth_running(void);
 
 bool hostname_is_valid(const char *s) _pure_;
+bool domainname_is_valid(const char *s) _pure_;
 char* hostname_cleanup(char *s, bool lowercase);
 
 bool machine_name_is_valid(const char *s) _pure_;
diff --git a/src/test/test-util.c b/src/test/test-util.c
index 4bb5154..010d93b 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -539,6 +539,20 @@ static void test_hostname_is_valid(void) {
         assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
 }
 
+static void test_domainname_is_valid(void) {
+        assert_se(domainname_is_valid("foobar"));
+        assert_se(domainname_is_valid("foobar."));
+        assert_se(domainname_is_valid("foobar.com"));
+        assert_se(domainname_is_valid("foobar.com."));
+        assert_se(!domainname_is_valid("fööbar"));
+        assert_se(!domainname_is_valid(""));
+        assert_se(!domainname_is_valid("."));
+        assert_se(!domainname_is_valid(".."));
+        assert_se(!domainname_is_valid(".foobar"));
+        assert_se(!domainname_is_valid("foo..bar"));
+        assert_se(!domainname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
+}
+
 static void test_u64log2(void) {
         assert_se(u64log2(0) == 0);
         assert_se(u64log2(8) == 3);
-- 
2.0.5



More information about the systemd-devel mailing list