|
|
05ad79 |
From 7a1a825c7b77785f256e05b1e3ac7676c7485a5c Mon Sep 17 00:00:00 2001
|
|
|
05ad79 |
From: Karel Zak <kzak@redhat.com>
|
|
|
05ad79 |
Date: Tue, 4 Jul 2017 12:50:39 +0200
|
|
|
05ad79 |
Subject: [PATCH 135/135] login: use IPv4 on IPv4-mapping-to-IPv6
|
|
|
05ad79 |
|
|
|
05ad79 |
It seems that on some systems (e.g. RHEL7) the libc function
|
|
|
05ad79 |
getaddrinfo() is not able to translate ::ffff: address to IPv4. The
|
|
|
05ad79 |
result is 0.0.0.0 host address in the last(1) and utmpdump(1) output.
|
|
|
05ad79 |
|
|
|
05ad79 |
/sbin/login -h "::ffff:192.168.1.7"
|
|
|
05ad79 |
|
|
|
05ad79 |
utmpdump:
|
|
|
05ad79 |
|
|
|
05ad79 |
[7] [03926] [1 ] [user1 ] [pts/1 ] [::ffff:192.168.1.7 ] [0.0.0.0 ] [Thu May 12 17:49:50 2016 ]
|
|
|
05ad79 |
|
|
|
05ad79 |
Not sure if this is about order of the getaddrinfo() results, system
|
|
|
05ad79 |
configuration or libc version. It's irrelevant for login(1). We have
|
|
|
05ad79 |
to be robust enough to write usable address to log files everywhere.
|
|
|
05ad79 |
|
|
|
05ad79 |
The solution is to detect IPv4-mapping-to-IPv6 and use IPv4 for utmp.
|
|
|
05ad79 |
|
|
|
05ad79 |
Upstream: http://github.com/karelzak/util-linux/commit/1c8792f1ae7fa38cf1d4418ad99c207f65dfdb1a
|
|
|
05ad79 |
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1296233
|
|
|
05ad79 |
Signed-off-by: Karel Zak <kzak@redhat.com>
|
|
|
05ad79 |
---
|
|
|
05ad79 |
login-utils/login.c | 9 ++++++++-
|
|
|
05ad79 |
1 file changed, 8 insertions(+), 1 deletion(-)
|
|
|
05ad79 |
|
|
|
05ad79 |
diff --git a/login-utils/login.c b/login-utils/login.c
|
|
|
05ad79 |
index e0e960f88..5c36953ef 100644
|
|
|
05ad79 |
--- a/login-utils/login.c
|
|
|
05ad79 |
+++ b/login-utils/login.c
|
|
|
05ad79 |
@@ -1101,8 +1101,15 @@ static void init_remote_info(struct login_context *cxt, char *remotehost)
|
|
|
05ad79 |
} else if (info->ai_family == AF_INET6) {
|
|
|
05ad79 |
struct sockaddr_in6 *sa =
|
|
|
05ad79 |
(struct sockaddr_in6 *) info->ai_addr;
|
|
|
05ad79 |
+#ifdef IN6_IS_ADDR_V4MAPPED
|
|
|
05ad79 |
+ if (IN6_IS_ADDR_V4MAPPED(&sa->sin6_addr)) {
|
|
|
05ad79 |
+ const uint8_t *bytes = sa->sin6_addr.s6_addr;
|
|
|
05ad79 |
+ struct in_addr addr = { *(const in_addr_t *) (bytes + 12) };
|
|
|
05ad79 |
|
|
|
05ad79 |
- memcpy(cxt->hostaddress, &(sa->sin6_addr), sizeof(sa->sin6_addr));
|
|
|
05ad79 |
+ memcpy(cxt->hostaddress, &addr, sizeof(struct in_addr));
|
|
|
05ad79 |
+ } else
|
|
|
05ad79 |
+#endif
|
|
|
05ad79 |
+ memcpy(cxt->hostaddress, &(sa->sin6_addr), sizeof(sa->sin6_addr));
|
|
|
05ad79 |
}
|
|
|
05ad79 |
freeaddrinfo(info);
|
|
|
05ad79 |
}
|
|
|
05ad79 |
--
|
|
|
05ad79 |
2.13.6
|
|
|
05ad79 |
|