]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolvectl: Take empty string argument to clear lists in "dns", "domain" and "nta...
authorFilipe Brandenburger <filbranden@google.com>
Mon, 16 Jul 2018 22:16:37 +0000 (15:16 -0700)
committerLennart Poettering <lennart@poettering.net>
Tue, 17 Jul 2018 19:20:52 +0000 (21:20 +0200)
The current CLI does not support a way to clear these lists, since without any
additional arguments, the command will list the current values.

Introduce a new way to clear the lists by passing a single '' argument to these
subcommands.

Update the man page to document this.

Tested:
  $ build/resolvectl domain eth1
  Link 3 (eth1): ~.
  $ build/resolvectl domain eth1 ''
  $ build/resolvectl domain eth1
  Link 3 (eth1):
  $ build/resolvectl domain eth1 '~.' '~example.com'
  $ build/resolvectl domain eth1
  Link 3 (eth1): ~. ~example.com
  $ build/resolvectl domain eth1 ''
  $ build/resolvectl domain eth1
  Link 3 (eth1):
  $ build/resolvectl domain eth1 '~.'
  $ build/resolvectl domain eth1
  Link 3 (eth1): ~.

And similar for "dns" and "nta".

man/resolvectl.xml
src/resolve/resolvectl.c

index ff5b8ad1018c394c43e18fc9b6eb911ea40aac45..cf97628f86be2c8064d1a51d87d7f76793a6f4a6 100644 (file)
         <literal>~</literal>, and configures a per-interface search or route-only domain. The <option>llmnr</option>,
         <option>mdns</option>, <option>dnssec</option> and <option>dnsovertls</option> commands may be used to configure
         the per-interface LLMNR, MulticastDNS, DNSSEC and DNSOverTLS settings. Finally, <option>nta</option> command
-        may be used to configure additional per-interface DNSSEC NTA domains. For details about these settings, their
-        possible values and their effect, see the corresponding options in
+        may be used to configure additional per-interface DNSSEC NTA domains.</para></listitem>
+
+        <listitem><para>Options <option>dns</option>, <option>domain</option> and <option>nta</option> can take
+        a single empty string argument to clear their respective value lists.</para></listitem>
+
+        <listitem><para>For details about these settings, their possible values and their effect, see the corresponding options in
         <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
         </listitem>
       </varlistentry>
index d04c756d73868ded97647567576e61c9aff301fa..7f29546de1aec21eaca5eb1b784dc219ec1bd961 100644 (file)
@@ -1930,28 +1930,32 @@ static int verb_dns(int argc, char **argv, void *userdata) {
         if (r < 0)
                 return bus_log_create_error(r);
 
-        STRV_FOREACH(p, argv + 2) {
-                struct in_addr_data data;
+        /* If only argument is the empty string, then call SetLinkDNS() with an
+         * empty list, which will clear the list of domains for an interface. */
+        if (!strv_equal(argv + 2, STRV_MAKE(""))) {
+                STRV_FOREACH(p, argv + 2) {
+                        struct in_addr_data data;
 
-                r = in_addr_from_string_auto(*p, &data.family, &data.address);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to parse DNS server address: %s", *p);
+                        r = in_addr_from_string_auto(*p, &data.family, &data.address);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse DNS server address: %s", *p);
 
-                r = sd_bus_message_open_container(req, 'r', "iay");
-                if (r < 0)
-                        return bus_log_create_error(r);
+                        r = sd_bus_message_open_container(req, 'r', "iay");
+                        if (r < 0)
+                                return bus_log_create_error(r);
 
-                r = sd_bus_message_append(req, "i", data.family);
-                if (r < 0)
-                        return bus_log_create_error(r);
+                        r = sd_bus_message_append(req, "i", data.family);
+                        if (r < 0)
+                                return bus_log_create_error(r);
 
-                r = sd_bus_message_append_array(req, 'y', &data.address, FAMILY_ADDRESS_SIZE(data.family));
-                if (r < 0)
-                        return bus_log_create_error(r);
+                        r = sd_bus_message_append_array(req, 'y', &data.address, FAMILY_ADDRESS_SIZE(data.family));
+                        if (r < 0)
+                                return bus_log_create_error(r);
 
-                r = sd_bus_message_close_container(req);
-                if (r < 0)
-                        return bus_log_create_error(r);
+                        r = sd_bus_message_close_container(req);
+                        if (r < 0)
+                                return bus_log_create_error(r);
+                }
         }
 
         r = sd_bus_message_close_container(req);
@@ -2010,22 +2014,26 @@ static int verb_domain(int argc, char **argv, void *userdata) {
         if (r < 0)
                 return bus_log_create_error(r);
 
-        STRV_FOREACH(p, argv + 2) {
-                const char *n;
+        /* If only argument is the empty string, then call SetLinkDomains() with an
+         * empty list, which will clear the list of domains for an interface. */
+        if (!strv_equal(argv + 2, STRV_MAKE(""))) {
+                STRV_FOREACH(p, argv + 2) {
+                        const char *n;
 
-                n = **p == '~' ? *p + 1 : *p;
+                        n = **p == '~' ? *p + 1 : *p;
 
-                r = dns_name_is_valid(n);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to validate specified domain %s: %m", n);
-                if (r == 0) {
-                        log_error("Domain not valid: %s", n);
-                        return -EINVAL;
-                }
+                        r = dns_name_is_valid(n);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to validate specified domain %s: %m", n);
+                        if (r == 0) {
+                                log_error("Domain not valid: %s", n);
+                                return -EINVAL;
+                        }
 
-                r = sd_bus_message_append(req, "(sb)", n, **p == '~');
-                if (r < 0)
-                        return bus_log_create_error(r);
+                        r = sd_bus_message_append(req, "(sb)", n, **p == '~');
+                        if (r < 0)
+                                return bus_log_create_error(r);
+                }
         }
 
         r = sd_bus_message_close_container(req);
@@ -2209,6 +2217,7 @@ static int verb_nta(int argc, char **argv, void *userdata) {
         sd_bus *bus = userdata;
         char **p;
         int r;
+        bool clear;
 
         assert(bus);
 
@@ -2222,15 +2231,20 @@ static int verb_nta(int argc, char **argv, void *userdata) {
         if (argc == 2)
                 return status_ifindex(bus, arg_ifindex, NULL, STATUS_NTA, NULL);
 
-        STRV_FOREACH(p, argv + 2) {
-                r = dns_name_is_valid(*p);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to validate specified domain %s: %m", *p);
-                if (r == 0) {
-                        log_error("Domain not valid: %s", *p);
-                        return -EINVAL;
+        /* If only argument is the empty string, then call SetLinkDNSSECNegativeTrustAnchors()
+         * with an empty list, which will clear the list of domains for an interface. */
+        clear = strv_equal(argv + 2, STRV_MAKE(""));
+
+        if (!clear)
+                STRV_FOREACH(p, argv + 2) {
+                        r = dns_name_is_valid(*p);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to validate specified domain %s: %m", *p);
+                        if (r == 0) {
+                                log_error("Domain not valid: %s", *p);
+                                return -EINVAL;
+                        }
                 }
-        }
 
         r = sd_bus_message_new_method_call(
                         bus,
@@ -2246,7 +2260,7 @@ static int verb_nta(int argc, char **argv, void *userdata) {
         if (r < 0)
                 return bus_log_create_error(r);
 
-        r = sd_bus_message_append_strv(req, argv + 2);
+        r = sd_bus_message_append_strv(req, clear ? NULL : argv + 2);
         if (r < 0)
                 return bus_log_create_error(r);