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