mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
networkd/dhcp: shorten overlong hostname (#7616)
This commit updates networkd behavior to check if the hostname option received via DHCP is too long for Linux limit, and in case shorten it. An overlong hostname will be truncated to the first dot or to `HOST_MAX_LEN`, whatever comes earlier.
This commit is contained in:
parent
3ce5a5df2c
commit
2de2abad62
@ -221,6 +221,38 @@ int sethostname_idempotent(const char *s) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int shorten_overlong(const char *s, char **ret) {
|
||||||
|
char *h, *p;
|
||||||
|
|
||||||
|
/* Shorten an overlong name to HOST_NAME_MAX or to the first dot,
|
||||||
|
* whatever comes earlier. */
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
h = strdup(s);
|
||||||
|
if (!h)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (hostname_is_valid(h, false)) {
|
||||||
|
*ret = h;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = strchr(h, '.');
|
||||||
|
if (p)
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
strshorten(h, HOST_NAME_MAX);
|
||||||
|
|
||||||
|
if (!hostname_is_valid(h, false)) {
|
||||||
|
free(h);
|
||||||
|
return -EDOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = h;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int read_etc_hostname_stream(FILE *f, char **ret) {
|
int read_etc_hostname_stream(FILE *f, char **ret) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -39,5 +39,7 @@ bool is_gateway_hostname(const char *hostname);
|
|||||||
|
|
||||||
int sethostname_idempotent(const char *s);
|
int sethostname_idempotent(const char *s);
|
||||||
|
|
||||||
|
int shorten_overlong(const char *s, char **ret);
|
||||||
|
|
||||||
int read_etc_hostname_stream(FILE *f, char **ret);
|
int read_etc_hostname_stream(FILE *f, char **ret);
|
||||||
int read_etc_hostname(const char *path, char **ret);
|
int read_etc_hostname(const char *path, char **ret);
|
||||||
|
@ -462,12 +462,21 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (link->network->dhcp_use_hostname) {
|
if (link->network->dhcp_use_hostname) {
|
||||||
const char *hostname = NULL;
|
const char *dhcpname = NULL;
|
||||||
|
_cleanup_free_ char *hostname = NULL;
|
||||||
|
|
||||||
if (link->network->dhcp_hostname)
|
if (link->network->dhcp_hostname)
|
||||||
hostname = link->network->dhcp_hostname;
|
dhcpname = link->network->dhcp_hostname;
|
||||||
else
|
else
|
||||||
(void) sd_dhcp_lease_get_hostname(lease, &hostname);
|
(void) sd_dhcp_lease_get_hostname(lease, &dhcpname);
|
||||||
|
|
||||||
|
if (dhcpname) {
|
||||||
|
r = shorten_overlong(dhcpname, &hostname);
|
||||||
|
if (r < 0)
|
||||||
|
log_link_warning_errno(link, r, "Unable to shorten overlong DHCP hostname '%s', ignoring: %m", dhcpname);
|
||||||
|
if (r == 1)
|
||||||
|
log_link_notice(link, "Overlong DCHP hostname received, shortened from '%s' to '%s'", dhcpname, hostname);
|
||||||
|
}
|
||||||
|
|
||||||
if (hostname) {
|
if (hostname) {
|
||||||
r = manager_set_hostname(link->manager, hostname);
|
r = manager_set_hostname(link->manager, hostname);
|
||||||
|
@ -18,10 +18,14 @@
|
|||||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "dhcp-lease-internal.h"
|
#include "dhcp-lease-internal.h"
|
||||||
|
#include "hostname-util.h"
|
||||||
#include "network-internal.h"
|
#include "network-internal.h"
|
||||||
#include "networkd-manager.h"
|
#include "networkd-manager.h"
|
||||||
|
#include "string-util.h"
|
||||||
#include "udev-util.h"
|
#include "udev-util.h"
|
||||||
|
|
||||||
static void test_deserialize_in_addr(void) {
|
static void test_deserialize_in_addr(void) {
|
||||||
@ -186,6 +190,51 @@ static void test_address_equality(void) {
|
|||||||
assert_se(!address_equal(a1, a2));
|
assert_se(!address_equal(a1, a2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_dhcp_hostname_shorten_overlong(void) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
{
|
||||||
|
/* simple hostname, no actions, no errors */
|
||||||
|
_cleanup_free_ char *shortened = NULL;
|
||||||
|
r = shorten_overlong("name1", &shortened);
|
||||||
|
assert_se(r == 0);
|
||||||
|
assert_se(streq("name1", shortened));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* simple fqdn, no actions, no errors */
|
||||||
|
_cleanup_free_ char *shortened = NULL;
|
||||||
|
r = shorten_overlong("name1.example.com", &shortened);
|
||||||
|
assert_se(r == 0);
|
||||||
|
assert_se(streq("name1.example.com", shortened));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* overlong fqdn, cut to first dot, no errors */
|
||||||
|
_cleanup_free_ char *shortened = NULL;
|
||||||
|
r = shorten_overlong("name1.test-dhcp-this-one-here-is-a-very-very-long-domain.example.com", &shortened);
|
||||||
|
assert_se(r == 1);
|
||||||
|
assert_se(streq("name1", shortened));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* overlong hostname, cut to HOST_MAX_LEN, no errors */
|
||||||
|
_cleanup_free_ char *shortened = NULL;
|
||||||
|
r = shorten_overlong("test-dhcp-this-one-here-is-a-very-very-long-hostname-without-domainname", &shortened);
|
||||||
|
assert_se(r == 1);
|
||||||
|
assert_se(streq("test-dhcp-this-one-here-is-a-very-very-long-hostname-without-dom", shortened));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* overlong fqdn, cut to first dot, empty result error */
|
||||||
|
_cleanup_free_ char *shortened = NULL;
|
||||||
|
r = shorten_overlong(".test-dhcp-this-one-here-is-a-very-very-long-hostname.example.com", &shortened);
|
||||||
|
assert_se(r == -EDOM);
|
||||||
|
assert_se(shortened == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
_cleanup_manager_free_ Manager *manager = NULL;
|
_cleanup_manager_free_ Manager *manager = NULL;
|
||||||
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
|
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
|
||||||
@ -196,6 +245,7 @@ int main(void) {
|
|||||||
test_deserialize_in_addr();
|
test_deserialize_in_addr();
|
||||||
test_deserialize_dhcp_routes();
|
test_deserialize_dhcp_routes();
|
||||||
test_address_equality();
|
test_address_equality();
|
||||||
|
test_dhcp_hostname_shorten_overlong();
|
||||||
|
|
||||||
assert_se(sd_event_default(&event) >= 0);
|
assert_se(sd_event_default(&event) >= 0);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user