abd5972
diff -up netkit-rsh-0.17/rexecd/rexecd.c.ipv6-rexec netkit-rsh-0.17/rexecd/rexecd.c
abd5972
--- netkit-rsh-0.17/rexecd/rexecd.c.ipv6-rexec	2013-07-15 17:31:07.678365071 +0200
abd5972
+++ netkit-rsh-0.17/rexecd/rexecd.c	2013-07-15 17:32:17.010346615 +0200
abd5972
@@ -114,7 +114,7 @@ int deny_severity = LOG_WARNING;
abd5972
  */
abd5972
 
abd5972
 static void fatal(const char *);
abd5972
-static void doit(struct sockaddr_in *fromp);
abd5972
+static void doit(struct sockaddr_storage *fromp);
abd5972
 static void getstr(char *buf, int cnt, const char *err);
abd5972
 
abd5972
 static const char *remote = NULL;
abd5972
@@ -122,7 +122,7 @@ static const char *remote = NULL;
abd5972
 int
abd5972
 main(int argc, char **argv)
abd5972
 {
abd5972
-	struct sockaddr_in from;
abd5972
+	struct sockaddr_storage from;
abd5972
 	socklen_t fromlen;
abd5972
 
abd5972
 	(void)argc;
abd5972
@@ -136,6 +136,29 @@ main(int argc, char **argv)
abd5972
 
abd5972
 	openlog(argv[0], LOG_PID, LOG_DAEMON);
abd5972
 
abd5972
+        /* handle situation when connected peer *doesn't have* native IPv6 address but systemd/xinetd
abd5972
+         * is listening on AF_INET6 socket on our behalf and fds we are given corresponds to AF_INET6 socket
abd5972
+         */
abd5972
+	if (from.ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *) &from)->sin6_addr)) {
abd5972
+		struct addrinfo *res, hints = {};
abd5972
+		char client_addr[INET6_ADDRSTRLEN] = {};
abd5972
+		char client_port[6] = {};
abd5972
+
abd5972
+		inet_ntop(AF_INET6, &((struct sockaddr_in6 *) &from)->sin6_addr,
abd5972
+			client_addr, sizeof(client_addr));
abd5972
+
abd5972
+		sprintf(client_port, "%d", ntohs(((struct sockaddr_in6 *) &from)->sin6_port));
abd5972
+
abd5972
+		hints.ai_family = AF_INET;
abd5972
+		hints.ai_socktype = SOCK_STREAM;
abd5972
+		hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
abd5972
+
abd5972
+		getaddrinfo(client_addr, client_port, &hints, &res;;
abd5972
+
abd5972
+		memcpy(&from, res->ai_addr, sizeof(struct sockaddr_in));
abd5972
+		freeaddrinfo(res);
abd5972
+	}
abd5972
+
abd5972
 #ifdef	TCP_WRAPPER
abd5972
 	/* Find out and report the remote host name. */
abd5972
 	/* I don't think this works. -- dholland */
abd5972
@@ -146,19 +169,42 @@ main(int argc, char **argv)
abd5972
 	if (argc > 1 && argv[1] && strcmp(argv[1], "-D")==0)
abd5972
 	{
abd5972
 		/* use IP in logs -- this is workaround */
abd5972
-		remote = strdup(inet_ntoa(from.sin_addr));
abd5972
+		char remote_addr[INET6_ADDRSTRLEN] = {};
abd5972
+
abd5972
+		if (from.ss_family == AF_INET)
abd5972
+			remote = inet_ntop(AF_INET, &from, remote_addr, INET_ADDRSTRLEN);
abd5972
+		else
abd5972
+			remote = inet_ntop(AF_INET6, &from, remote_addr, INET6_ADDRSTRLEN);
abd5972
+
abd5972
+		if (remote) {
abd5972
+			remote = strdup(remote);
abd5972
+			if (!remote) {
abd5972
+				fprintf(stderr, "rexecd: strdup: %s\n", strerror(errno));
abd5972
+				return 1;
abd5972
+			}
abd5972
+		} else {
abd5972
+			fprintf(stderr, "rexecd: inet_ntop: %s\n", strerror(errno));
abd5972
+			return 1;
abd5972
+		}
abd5972
 	}
abd5972
 	else
abd5972
 	{
abd5972
-		struct hostent *h = gethostbyaddr((const char *)&from.sin_addr,
abd5972
-				  sizeof(struct in_addr),
abd5972
-				  AF_INET);
abd5972
-		if (!h || !h->h_name) {
abd5972
-			write(0, "\1Where are you?\n", 16);
abd5972
+		int r;
abd5972
+		char remote_hostname[NI_MAXHOST] = {};
abd5972
+
abd5972
+		r = getnameinfo((struct sockaddr *) &from, sizeof(struct sockaddr_storage), remote_hostname, NI_MAXHOST, NULL, NULL, 0);
abd5972
+
abd5972
+		if (r) {
abd5972
+			fprintf(stderr, "rexecd: getnameinfo: %s\n", gai_strerror(r));
abd5972
+			return 1;
abd5972
+		}
abd5972
+
abd5972
+		remote = strdup(remote_hostname);
abd5972
+		if (!remote) {
abd5972
+			fprintf(stderr, "rexecd: strdup: %s\n", strerror(errno));
abd5972
 			return 1;
abd5972
 		}
abd5972
-		/* Be advised that this may be utter nonsense. */
abd5972
-		remote = strdup(h->h_name);
abd5972
+
abd5972
 	}
abd5972
 #endif
abd5972
 	syslog(allow_severity, "connect from %.128s", remote);
abd5972
@@ -233,7 +279,7 @@ static struct pam_conv PAM_conversation
abd5972
 
abd5972
 
abd5972
 static void
abd5972
-doit(struct sockaddr_in *fromp)
abd5972
+doit(struct sockaddr_storage *fromp)
abd5972
 {
abd5972
 	char *cmdbuf;
abd5972
 	long cmdbuflen;
abd5972
@@ -298,7 +344,7 @@ doit(struct sockaddr_in *fromp)
abd5972
  We must connect back to the client here if a port was provided. KRH
abd5972
 */
abd5972
 	if (port != 0) {
abd5972
-		s = socket(AF_INET, SOCK_STREAM, 0);
abd5972
+		s = socket(fromp->ss_family, SOCK_STREAM, 0);
abd5972
 		if (s < 0)
abd5972
 			exit(1);
abd5972
 
abd5972
@@ -308,7 +354,12 @@ doit(struct sockaddr_in *fromp)
abd5972
 			exit(1);
abd5972
 #endif
abd5972
 		alarm(60);
abd5972
-		fromp->sin_port = htons(port);
abd5972
+
abd5972
+		if (fromp->ss_family == AF_INET)
abd5972
+			((struct sockaddr_in *) fromp)->sin_port = htons(port);
abd5972
+		else
abd5972
+			((struct sockaddr_in6 *) fromp)->sin6_port = htons(port);
abd5972
+
abd5972
 		if (connect(s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0)
abd5972
 			exit(1);
abd5972
 		alarm(0);
abd5972
diff -up netkit-rsh-0.17/rexec/rexec.c.ipv6-rexec netkit-rsh-0.17/rexec/rexec.c
abd5972
--- netkit-rsh-0.17/rexec/rexec.c.ipv6-rexec	2013-07-15 17:31:07.686365068 +0200
abd5972
+++ netkit-rsh-0.17/rexec/rexec.c	2013-07-15 17:31:07.698365065 +0200
abd5972
@@ -194,8 +194,8 @@ int main(int argc, char *argv[])
abd5972
     exit(1);
abd5972
   }
abd5972
 
abd5972
-  if ( (sock = rexec(&host, port_exec, user_name, passwd, command, 
abd5972
-		     p_to_aux_sock)) < 0 )
abd5972
+  if ( (sock = rexec_af(&host, port_exec, user_name, passwd, command, 
abd5972
+		     p_to_aux_sock, AF_UNSPEC)) < 0 )
abd5972
   {
abd5972
     fprintf(stderr,"%s: Error in rexec system call,\n",argv[0]);
abd5972
     fprintf(stderr,"%s: (The following system error may itself be in error)\n",argv[0]);