summaryrefslogtreecommitdiff
path: root/src/nss-myhostname
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-04-22 10:31:22 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-04-23 04:18:51 +0900
commitdb50d326a46beca3cc24b6354b6e1b3591902d45 (patch)
tree3cdb0df0124e473cd14a3432c482cdbea4777635 /src/nss-myhostname
parent70e723c000e46e2304e54f8063572d7fa0cdad46 (diff)
downloadsystemd-db50d326a46beca3cc24b6354b6e1b3591902d45.tar.gz
nss-myhostname: do not return IPv6 local address if IPv6 is disabled
Diffstat (limited to 'src/nss-myhostname')
-rw-r--r--src/nss-myhostname/nss-myhostname.c66
1 files changed, 36 insertions, 30 deletions
diff --git a/src/nss-myhostname/nss-myhostname.c b/src/nss-myhostname/nss-myhostname.c
index 67b1554d27..120e76be45 100644
--- a/src/nss-myhostname/nss-myhostname.c
+++ b/src/nss-myhostname/nss-myhostname.c
@@ -13,6 +13,7 @@
#include "macro.h"
#include "nss-util.h"
#include "signal-util.h"
+#include "socket-util.h"
#include "string-util.h"
/* We use 127.0.0.2 as IPv4 address. This has the advantage over
@@ -95,7 +96,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
}
l = strlen(canonical);
- ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * (n_addresses > 0 ? n_addresses : 2);
+ ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * (n_addresses > 0 ? n_addresses : 1 + socket_ipv6_is_enabled());
if (buflen < ms) {
UNPROTECT_ERRNO;
*errnop = ERANGE;
@@ -111,15 +112,17 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
assert(n_addresses >= 0);
if (n_addresses == 0) {
/* Second, fill in IPv6 tuple */
- r_tuple = (struct gaih_addrtuple*) (buffer + idx);
- r_tuple->next = r_tuple_prev;
- r_tuple->name = r_name;
- r_tuple->family = AF_INET6;
- memcpy(r_tuple->addr, LOCALADDRESS_IPV6, 16);
- r_tuple->scopeid = 0;
-
- idx += ALIGN(sizeof(struct gaih_addrtuple));
- r_tuple_prev = r_tuple;
+ if (socket_ipv6_is_enabled()) {
+ r_tuple = (struct gaih_addrtuple*) (buffer + idx);
+ r_tuple->next = r_tuple_prev;
+ r_tuple->name = r_name;
+ r_tuple->family = AF_INET6;
+ memcpy(r_tuple->addr, LOCALADDRESS_IPV6, 16);
+ r_tuple->scopeid = 0;
+
+ idx += ALIGN(sizeof(struct gaih_addrtuple));
+ r_tuple_prev = r_tuple;
+ }
/* Third, fill in IPv4 tuple */
r_tuple = (struct gaih_addrtuple*) (buffer + idx);
@@ -189,6 +192,7 @@ static enum nss_status fill_in_hostent(
unsigned n, c;
assert(canonical);
+ assert(IN_SET(af, AF_INET, AF_INET6));
assert(result);
assert(buffer);
assert(errnop);
@@ -208,8 +212,8 @@ static enum nss_status fill_in_hostent(
(additional ? ALIGN(l_additional+1) : 0) +
sizeof(char*) +
(additional ? sizeof(char*) : 0) +
- (c > 0 ? c : 1) * ALIGN(alen) +
- (c > 0 ? c+1 : 2) * sizeof(char*);
+ (c > 0 ? c : af == AF_INET ? 1 : socket_ipv6_is_enabled()) * ALIGN(alen) +
+ (c > 0 ? c+1 : af == AF_INET ? 2 : (unsigned) socket_ipv6_is_enabled() + 1) * sizeof(char*);
if (buflen < ms) {
UNPROTECT_ERRNO;
@@ -255,12 +259,12 @@ static enum nss_status fill_in_hostent(
assert(i == c);
idx += c*ALIGN(alen);
- } else {
- if (af == AF_INET)
- *(uint32_t*) r_addr = local_address_ipv4;
- else
- memcpy(r_addr, LOCALADDRESS_IPV6, 16);
+ } else if (af == AF_INET) {
+ *(uint32_t*) r_addr = local_address_ipv4;
+ idx += ALIGN(alen);
+ } else if (socket_ipv6_is_enabled()) {
+ memcpy(r_addr, LOCALADDRESS_IPV6, 16);
idx += ALIGN(alen);
}
@@ -275,10 +279,13 @@ static enum nss_status fill_in_hostent(
((char**) r_addr_list)[i] = NULL;
idx += (c+1) * sizeof(char*);
- } else {
+ } else if (af == AF_INET || socket_ipv6_is_enabled()) {
((char**) r_addr_list)[0] = r_addr;
((char**) r_addr_list)[1] = NULL;
idx += 2 * sizeof(char*);
+ } else {
+ ((char**) r_addr_list)[0] = NULL;
+ idx += sizeof(char*);
}
/* Verify the size matches */
@@ -339,6 +346,9 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
}
if (is_localhost(name)) {
+ if (af == AF_INET6 && !socket_ipv6_is_enabled())
+ goto not_found;
+
canonical = "localhost";
local_address_ipv4 = htobe32(INADDR_LOOPBACK);
@@ -450,6 +460,9 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r(
} else {
assert(af == AF_INET6);
+ if (socket_ipv6_is_enabled())
+ goto not_found;
+
if (memcmp(addr, LOCALADDRESS_IPV6, 16) == 0) {
canonical = "localhost";
additional_from_hostname = true;
@@ -457,28 +470,21 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r(
}
}
- n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
- for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) {
- if (af != a->family)
- continue;
-
+ n_addresses = local_addresses(NULL, 0, af, &addresses);
+ for (a = addresses, n = 0; (int) n < n_addresses; n++, a++)
if (memcmp(addr, &a->address, FAMILY_ADDRESS_SIZE(af)) == 0)
goto found;
- }
addresses = mfree(addresses);
- n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses);
- for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) {
- if (af != a->family)
- continue;
-
+ n_addresses = local_gateways(NULL, 0, af, &addresses);
+ for (a = addresses, n = 0; (int) n < n_addresses; n++, a++)
if (memcmp(addr, &a->address, FAMILY_ADDRESS_SIZE(af)) == 0) {
canonical = "_gateway";
goto found;
}
- }
+not_found:
*h_errnop = HOST_NOT_FOUND;
return NSS_STATUS_NOTFOUND;