zbyszek / rpms / krb5

Forked from rpms/krb5 2 years ago
Clone
Blob Blame History Raw
Get the client libraries to correctly attempt password changes when using IPv6,
tweaked to apply to older releases.  Original patch by Sumit Bose, RT#6661

Index: src/lib/krb5/os/changepw.c
===================================================================
--- src/lib/krb5/os/changepw.c	(revision 23766)
+++ src/lib/krb5/os/changepw.c	(revision 23767)
@@ -65,20 +65,23 @@
     int sockType = (useTcp ? SOCK_STREAM : SOCK_DGRAM);
 
     code = krb5int_locate_server (context, realm, addrlist,
-				  locate_service_kpasswd, sockType, AF_INET);
+				  locate_service_kpasswd, sockType, AF_UNSPEC);
 
     if (code == KRB5_REALM_CANT_RESOLVE || code == KRB5_REALM_UNKNOWN) {
 	code = krb5int_locate_server (context, realm, addrlist,
 				      locate_service_kadmin, SOCK_STREAM,
-				      AF_INET);
+				      AF_UNSPEC);
 	if (!code) {
 	    /* Success with admin_server but now we need to change the
 	       port number to use DEFAULT_KPASSWD_PORT and the socktype.  */
 	    int i;
 	    for (i=0; i<addrlist->naddrs; i++) {
 		struct addrinfo *a = addrlist->addrs[i].ai;
+		krb5_ui_2 kpasswd_port = htons(DEFAULT_KPASSWD_PORT);
 		if (a->ai_family == AF_INET)
-		    sa2sin (a->ai_addr)->sin_port = htons(DEFAULT_KPASSWD_PORT);
+		    sa2sin (a->ai_addr)->sin_port = kpasswd_port;
+		if (a->ai_family == AF_INET6)
+		    sa2sin6 (a->ai_addr)->sin6_port = kpasswd_port;
 		if (sockType != SOCK_STREAM)
 		    a->ai_socktype = sockType;
 	    }
@@ -131,10 +134,16 @@
     /* some brain-dead OS's don't return useful information from
      * the getsockname call.  Namely, windows and solaris.  */
 
-    if (ss2sin(&local_addr)->sin_addr.s_addr != 0) {
+    if (local_addr.ss_family == AF_INET &&
+	ss2sin(&local_addr)->sin_addr.s_addr != 0) {
 	local_kaddr.addrtype = ADDRTYPE_INET;
 	local_kaddr.length = sizeof(ss2sin(&local_addr)->sin_addr);
 	local_kaddr.contents = (krb5_octet *) &ss2sin(&local_addr)->sin_addr;
+    } else if (local_addr.ss_family == AF_INET6 &&
+	ss2sin6(&local_addr)->sin6_addr.s6_addr != 0) {
+	local_kaddr.addrtype = ADDRTYPE_INET6;
+	local_kaddr.length = sizeof(ss2sin6(&local_addr)->sin6_addr);
+	local_kaddr.contents = (krb5_octet *) &ss2sin6(&local_addr)->sin6_addr;
     } else {
 	krb5_address **addrs;
 
@@ -278,9 +287,19 @@
 	    break;
 	}
 
-	remote_kaddr.addrtype = ADDRTYPE_INET;
-	remote_kaddr.length = sizeof(ss2sin(&remote_addr)->sin_addr);
-	remote_kaddr.contents = (krb5_octet *) &ss2sin(&remote_addr)->sin_addr;
+	if (remote_addr.ss_family == AF_INET) {
+	    remote_kaddr.addrtype = ADDRTYPE_INET;
+	    remote_kaddr.length = sizeof(ss2sin(&remote_addr)->sin_addr);
+	    remote_kaddr.contents =
+		(krb5_octet *) &ss2sin(&remote_addr)->sin_addr;
+	} else if (remote_addr.ss_family == AF_INET6) {
+	    remote_kaddr.addrtype = ADDRTYPE_INET6;
+	    remote_kaddr.length = sizeof(ss2sin6(&remote_addr)->sin6_addr);
+	    remote_kaddr.contents =
+		(krb5_octet *) &ss2sin6(&remote_addr)->sin6_addr;
+	} else {
+	    break;
+	}
 
 	if ((code = krb5_auth_con_setaddrs(callback_ctx.context,  
 					   callback_ctx.auth_context,