]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
DHCP: Add support to emit and retrieve POP3 server
authorSusant Sahani <ssahani@vmware.com>
Fri, 27 Mar 2020 20:12:07 +0000 (21:12 +0100)
committerSusant Sahani <ssahani@vmware.com>
Sat, 28 Mar 2020 02:34:27 +0000 (03:34 +0100)
man/systemd.network.xml
src/network/networkd-dhcp-server.c
src/network/networkd-dhcp-server.h
src/network/networkd-link.c
src/network/networkd-manager.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.h
test/fuzz/fuzz-network-parser/directives.network

index 5457e668dd282a7aed9cd974859f10ad395aeb9f..4b2e8b8614964a715401a285b339bbfa0576ec6a 100644 (file)
             read via <function>sd_network_link_get_sip_servers()</function> function.</para>
           </listitem>
         </varlistentry>
+
         <varlistentry>
           <term><varname>UseMTU=</varname></term>
           <listitem>
         <varname>DNS=</varname>.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>POP3Servers=</varname></term>
+
+        <listitem><para>Similar to the <varname>DNS=</varname> settings described above, these
+        settings configure whether and what POP3 server information shall be emitted as part of
+        the DHCP lease. The same syntax, propagation semantics and defaults apply as for
+        <varname>DNS=</varname>.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>EmitRouter=</varname></term>
 
index 2ec742b5e3289e7ffcf525b04ea2a46a72fbf6d2..83caef6fc0d2f28f28cbe64e35a7ac79dd16c1a1 100644 (file)
@@ -140,6 +140,55 @@ static int link_push_uplink_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
         return sd_dhcp_server_set_ntp(s, addresses, n_addresses);
 }
 
+static int link_push_uplink_pop3_to_dhcp_server(Link *link, sd_dhcp_server *s) {
+        _cleanup_free_ struct in_addr *addresses = NULL;
+        size_t n_addresses = 0, n_allocated = 0;
+        char **a;
+
+        if (!link->network)
+                return 0;
+
+        log_link_debug(link, "Copying POP3 server information from link");
+
+        STRV_FOREACH(a, link->network->pop3) {
+                union in_addr_union ia;
+
+                /* Only look for IPv4 addresses */
+                if (in_addr_from_string(AF_INET, *a, &ia) <= 0)
+                        continue;
+
+                /* Never propagate obviously borked data */
+                if (in4_addr_is_null(&ia.in) || in4_addr_is_localhost(&ia.in))
+                        continue;
+
+                if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
+                        return log_oom();
+
+                addresses[n_addresses++] = ia.in;
+        }
+
+        if (link->dhcp_lease) {
+                const struct in_addr *da = NULL;
+                int j, n;
+
+                n = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &da);
+                if (n > 0) {
+
+                        if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
+                                return log_oom();
+
+                        for (j = 0; j < n; j++)
+                                if (in4_addr_is_non_local(&da[j]))
+                                        addresses[n_addresses++] = da[j];
+                }
+        }
+
+        if (n_addresses <= 0)
+                return 0;
+
+        return sd_dhcp_server_set_pop3_server(s, addresses, n_addresses);
+}
+
 static int link_push_uplink_sip_to_dhcp_server(Link *link, sd_dhcp_server *s) {
         _cleanup_free_ struct in_addr *addresses = NULL;
         size_t n_addresses = 0, n_allocated = 0;
@@ -281,6 +330,22 @@ int dhcp4_server_configure(Link *link) {
                         log_link_warning_errno(link, r, "Failed to set SIP server for DHCP server, ignoring: %m");
         }
 
+                if (link->network->n_dhcp_server_pop3 > 0)
+                        r = sd_dhcp_server_set_pop3_server(link->dhcp_server, link->network->dhcp_server_pop3, link->network->n_dhcp_server_pop3);
+                else {
+                        if (!acquired_uplink)
+                                uplink = manager_find_uplink(link->manager, link);
+
+                        if (!uplink) {
+                                log_link_debug(link, "Not emitting POP3 server information on link, couldn't find suitable uplink.");
+                                r = 0;
+                        } else
+                                r = link_push_uplink_pop3_to_dhcp_server(uplink, link->dhcp_server);
+
+                }
+                if (r < 0)
+                        log_link_warning_errno(link, r, "Failed to set POP3 server for DHCP server, ignoring: %m");
+
         r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router);
         if (r < 0)
                 return log_link_error_errno(link, r, "Failed to set router emission for DHCP server: %m");
@@ -486,3 +551,55 @@ int config_parse_dhcp_server_sip(
                 n->dhcp_server_sip = m;
         }
 }
+
+int config_parse_dhcp_server_pop3_servers(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Network *n = data;
+        const char *p = rvalue;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        for (;;) {
+                _cleanup_free_ char *w = NULL;
+                union in_addr_union a;
+                struct in_addr *m;
+
+                r = extract_first_word(&p, &w, NULL, 0);
+                if (r == -ENOMEM)
+                        return log_oom();
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r,
+                                   "Failed to extract word, ignoring: %s", rvalue);
+                        return 0;
+                }
+                if (r == 0)
+                        return 0;
+
+                r = in_addr_from_string(AF_INET, w, &a);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r,
+                                   "Failed to parse POP3 server address '%s', ignoring: %m", w);
+                        continue;
+                }
+
+                m = reallocarray(n->dhcp_server_pop3, n->n_dhcp_server_pop3 + 1, sizeof(struct in_addr));
+                if (!m)
+                        return log_oom();
+
+                m[n->n_dhcp_server_pop3++] = a.in;
+                n->dhcp_server_pop3 = m;
+        }
+}
index c90d48ec002bb2104a33e91300f8607921afe7a1..a388f6b81c74059bfb1f520c034be33b14cede50 100644 (file)
@@ -12,3 +12,4 @@ int dhcp4_server_configure(Link *link);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_dns);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_sip);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_pop3_servers);
index f38cc9f3cfda30ef2e13b09022464eebc92edded..376596bf57bd16326b5fbf81a6a36c36697f6f1a 100644 (file)
@@ -4100,6 +4100,21 @@ int link_save(Link *link) {
                                         space = true;
                 }
 
+                fputc('\n', f);
+
+                fputs("POP3_SERVERS=", f);
+                space = false;
+                fputstrv(f, link->network->pop3, NULL, &space);
+
+                if (link->dhcp_lease) {
+                        const struct in_addr *addresses;
+
+                        r = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &addresses);
+                        if (r > 0)
+                                if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
+                                        space = true;
+                }
+
                 if (link->network->dhcp6_use_ntp && dhcp6_lease) {
                         struct in6_addr *in6_addrs;
                         char **hosts;
index 804f33d6cb4896c21247a79d982e3816cfb89fee..656f52b4402c82ebe9ff217e0a7db2da5181f51c 100644 (file)
@@ -1488,7 +1488,8 @@ static int ordered_set_put_in4_addrv(OrderedSet *s,
 }
 
 static int manager_save(Manager *m) {
-        _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *search_domains = NULL, *route_domains = NULL;
+        _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *pop3 = NULL,
+                     *search_domains = NULL, *route_domains = NULL;
         const char *operstate_str, *carrier_state_str, *address_state_str;
         LinkOperationalState operstate = LINK_OPERSTATE_OFF;
         LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF;
@@ -1496,6 +1497,7 @@ static int manager_save(Manager *m) {
         _cleanup_free_ char *temp_path = NULL;
         _cleanup_strv_free_ char **p = NULL;
         _cleanup_fclose_ FILE *f = NULL;
+        const struct in_addr *addresses;
         Link *link;
         Iterator i;
         int r;
@@ -1512,10 +1514,14 @@ static int manager_save(Manager *m) {
         if (!ntp)
                 return -ENOMEM;
 
-       sip = ordered_set_new(&string_hash_ops);
-       if (!sip)
+        sip = ordered_set_new(&string_hash_ops);
+        if (!sip)
                 return -ENOMEM;
 
+        pop3 = ordered_set_new(&string_hash_ops);
+        if (!pop3)
+               return -ENOMEM;
+
         search_domains = ordered_set_new(&dns_name_hash_ops);
         if (!search_domains)
                 return -ENOMEM;
@@ -1562,8 +1568,6 @@ static int manager_save(Manager *m) {
 
                 /* Secondly, add the entries acquired via DHCP */
                 if (link->network->dhcp_use_dns) {
-                        const struct in_addr *addresses;
-
                         r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
                         if (r > 0) {
                                 r = ordered_set_put_in4_addrv(dns, addresses, r, in4_addr_is_non_local);
@@ -1574,8 +1578,6 @@ static int manager_save(Manager *m) {
                 }
 
                 if (link->network->dhcp_use_ntp) {
-                        const struct in_addr *addresses;
-
                         r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
                         if (r > 0) {
                                 r = ordered_set_put_in4_addrv(ntp, addresses, r, in4_addr_is_non_local);
@@ -1586,8 +1588,6 @@ static int manager_save(Manager *m) {
                 }
 
                 if (link->network->dhcp_use_sip) {
-                        const struct in_addr *addresses;
-
                         r = sd_dhcp_lease_get_sip(link->dhcp_lease, &addresses);
                         if (r > 0) {
                                 r = ordered_set_put_in4_addrv(sip, addresses, r, in4_addr_is_non_local);
@@ -1597,6 +1597,15 @@ static int manager_save(Manager *m) {
                                 return r;
                 }
 
+
+                r = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &addresses);
+                if (r > 0) {
+                        r = ordered_set_put_in4_addrv(pop3, addresses, r, in4_addr_is_non_local);
+                        if (r < 0)
+                                return r;
+                } else if (r < 0 && r != -ENODATA)
+                        return r;
+
                 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
                         const char *domainname;
                         char **domains = NULL;
@@ -1648,6 +1657,7 @@ static int manager_save(Manager *m) {
         ordered_set_print(f, "DNS=", dns);
         ordered_set_print(f, "NTP=", ntp);
         ordered_set_print(f, "SIP=", sip);
+        ordered_set_print(f, "POP3_SERVERS=", pop3);
         ordered_set_print(f, "DOMAINS=", search_domains);
         ordered_set_print(f, "ROUTE_DOMAINS=", route_domains);
 
index fd996327a55fc5e3e729057de682e493c63b9f69..25730b58f795fb868491e34991d69d9ed765d475 100644 (file)
@@ -207,6 +207,7 @@ DHCPServer.EmitNTP,                          config_parse_bool,
 DHCPServer.NTP,                              config_parse_dhcp_server_ntp,                             0,                             0
 DHCPServer.EmitSIP,                          config_parse_bool,                                        0,                             offsetof(Network, dhcp_server_emit_sip)
 DHCPServer.SIP,                              config_parse_dhcp_server_sip,                             0,                             0
+DHCPServer.POP3Servers,                      config_parse_dhcp_server_pop3_servers,                    0,                             0
 DHCPServer.EmitRouter,                       config_parse_bool,                                        0,                             offsetof(Network, dhcp_server_emit_router)
 DHCPServer.EmitTimezone,                     config_parse_bool,                                        0,                             offsetof(Network, dhcp_server_emit_timezone)
 DHCPServer.Timezone,                         config_parse_timezone,                                    0,                             offsetof(Network, dhcp_server_timezone)
index f747ccaf101812633f0badc35fe88856e2f31e15..58b310f59ea1066e7cd303ff72ba76bab1f40748 100644 (file)
@@ -147,6 +147,9 @@ struct Network {
         struct in_addr *dhcp_server_sip;
         unsigned n_dhcp_server_sip;
 
+        struct in_addr *dhcp_server_pop3;
+        unsigned n_dhcp_server_pop3;
+
         bool dhcp_server_emit_router;
         bool dhcp_server_emit_timezone;
         char *dhcp_server_timezone;
@@ -296,6 +299,7 @@ struct Network {
 
         char **ntp;
         char **sip;
+        char **pop3;
         char **bind_carrier;
 };
 
index 4418fc01495b92e2b16902e4488939f8c0fee072..01cc490c96d8f80cfb0db1b2f0bea5a55c49d387 100644 (file)
@@ -268,6 +268,7 @@ EmitDNS=
 NTP=
 EmitSIP=
 SIP=
+POP3Servers=
 EmitRouter=
 MaxLeaseTimeSec=
 DefaultLeaseTimeSec=