Subject: Re: Heimdal kpasswd incompatible with MIT kdc?
To: Ed Ravin <eravin@panix.com>
From: Johan Danielsson <joda@pdc.kth.se>
List: tech-userlevel
Date: 08/07/2002 18:07:47
"Ed Ravin" <eravin@panix.com> writes:

> Anybody have any guesses what might be going wrong?  

This is a problem in krb5_change_password(), it doesn't properly set
the source address in the packet, as expected by the kadmind. The
error message is not very descriptive though.

I suppose the solution is to make and import a new Heimdal
release. It's been almost a year since the previous...

If you're really interested, the following patch should improve the
situation. You might still get strange output from kpasswd, but the
actual password changing should work.

/Johan

--- crypto/dist/heimdal/lib/krb5/changepw.c	2001/09/17 12:32:38	1.6
+++ crypto/dist/heimdal/lib/krb5/changepw.c	2002/08/07 16:05:28
@@ -40,8 +40,6 @@
 	      krb5_auth_context *auth_context,
 	      krb5_creds *creds,
 	      int sock,
-	      struct sockaddr *sa,
-	      int sa_size,
 	      char *passwd,
 	      const char *host)
 {
@@ -89,8 +87,8 @@
     *p++ = (ap_req_data.length >> 0) & 0xFF;
 
     memset(&msghdr, 0, sizeof(msghdr));
-    msghdr.msg_name       = (void *)sa;
-    msghdr.msg_namelen    = sa_size;
+    msghdr.msg_name       = NULL;
+    msghdr.msg_namelen    = 0;
     msghdr.msg_iov        = iov;
     msghdr.msg_iovlen     = sizeof(iov)/sizeof(*iov);
 #if 0
@@ -266,11 +264,14 @@
     if (ret)
 	return ret;
 
+    krb5_auth_con_setflags (context, auth_context,
+			    KRB5_AUTH_CONTEXT_DO_SEQUENCE);
+
     ret = krb5_krbhst_init (context, realm, KRB5_KRBHST_CHANGEPW, &handle);
     if (ret)
 	goto out;
 
-    while (krb5_krbhst_next(context, handle, &hi) == 0) {
+    while (!done && (ret = krb5_krbhst_next(context, handle, &hi)) == 0) {
 	struct addrinfo *ai, *a;
 
 	ret = krb5_krbhst_get_addrinfo(context, hi, &ai);
@@ -284,6 +285,19 @@
 	    if (sock < 0)
 		continue;
 
+	    ret = connect(sock, a->ai_addr, a->ai_addrlen);
+	    if (ret < 0) {
+		close (sock);
+		goto out;
+	    }
+
+	    ret = krb5_auth_con_genaddrs (context, auth_context, sock,
+					  KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR);
+	    if (ret) {
+		close (sock);
+		goto out;
+	    }
+
 	    for (i = 0; !done && i < 5; ++i) {
 		fd_set fdset;
 		struct timeval tv;
@@ -294,8 +308,6 @@
 					&auth_context,
 					creds,
 					sock,
-					a->ai_addr,
-					a->ai_addrlen,
 					newpw,
 					hi->hostname);
 		    if (ret) {