From e73890eaf0f6f287132de882df8462e45ffe4987 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Fri, 11 Jan 2013 12:06:37 -0500
Subject: [PATCH] Clean up k5_locate_server error handling

profile_get_values() cannot return success with an empty list of
values, so don't bother counting them.  Return 0 from
locate_srv_conf_1 if no profile values exist and from
dns_locate_server if we decide not to make a SRV query.  Adjust
k5_locate_server to match the new helper behavior, and return
KRB5_REALM_UNKNOWN if neither profile nor DNS come up with any answers
(not KRB5_REALM_CANT_RESOLVE, which doesn't make sense now that we're
deferring KDC hostname resolution).
---
 src/lib/krb5/os/locate_kdc.c | 35 ++++++++++-------------------------
 1 file changed, 10 insertions(+), 25 deletions(-)

Index: krb5-1.6.3/src/lib/krb5/os/locate_kdc.c
===================================================================
--- krb5-1.6.3.orig/src/lib/krb5/os/locate_kdc.c
+++ krb5-1.6.3/src/lib/krb5/os/locate_kdc.c
@@ -309,7 +309,7 @@ krb5_locate_srv_conf_1(krb5_context cont
     const char	*realm_srv_names[4];
     char **masterlist, **hostlist, *host, *port, *cp;
     krb5_error_code code;
-    int i, j, count, ismaster;
+    int i, j, ismaster;
 
     Tprintf ("looking in krb5.conf for realm %s entry %s; ports %d,%d\n",
 	     realm->data, name, ntohs (udpport), ntohs (sec_udpport));
@@ -334,65 +334,11 @@ krb5_locate_srv_conf_1(krb5_context cont
 	Tprintf ("config file lookup failed: %s\n",
 		 error_message(code));
         if (code == PROF_NO_SECTION || code == PROF_NO_RELATION)
-	    code = KRB5_REALM_UNKNOWN;
+	    code = 0;
  	krb5_xfree(host);
   	return code;
      }
 
-    count = 0;
-    while (hostlist && hostlist[count])
-	    count++;
-    Tprintf ("found %d entries under 'kdc'\n", count);
-    
-    if (count == 0) {
-        profile_free_list(hostlist);
-	krb5_xfree(host);
-	addrlist->naddrs = 0;
-	return 0;
-    }
-    
-    if (get_masters) {
-	realm_srv_names[0] = "realms";
-	realm_srv_names[1] = host;
-	realm_srv_names[2] = "admin_server";
-	realm_srv_names[3] = 0;
-
-	code = profile_get_values(context->profile, realm_srv_names,
-				  &masterlist);
-
-	krb5_xfree(host);
-
-	if (code == 0) {
-	    for (i=0; masterlist[i]; i++) {
-		host = masterlist[i];
-
-		/*
-		 * Strip off excess whitespace
-		 */
-		cp = strchr(host, ' ');
-		if (cp)
-		    *cp = 0;
-		cp = strchr(host, '\t');
-		if (cp)
-		    *cp = 0;
-		cp = strchr(host, ':');
-		if (cp)
-		    *cp = 0;
-	    }
-	}
-    } else {
-	krb5_xfree(host);
-    }
-
-    /* at this point, if master is non-NULL, then either the master kdc
-       is required, and there is one, or the master kdc is not required,
-       and there may or may not be one. */
-
-#ifdef HAVE_NETINET_IN_H
-    if (sec_udpport)
-	    count = count * 2;
-#endif
-
     for (i=0; hostlist[i]; i++) {
 	int p1, p2;
 
@@ -746,7 +692,7 @@ dns_locate_server (krb5_context context,
     krb5_error_code code;
 
     if (!use_dns)
-	return KRB5_PLUGIN_NO_HANDLE;
+	return 0;
 
     switch (svc) {
     case locate_service_kdc:
@@ -765,7 +711,7 @@ dns_locate_server (krb5_context context,
 	dnsname = "_kpasswd";
 	break;
     default:
-	return KRB5_PLUGIN_NO_HANDLE;
+	return 0;
     }
 
     code = 0;
@@ -809,13 +755,8 @@ krb5int_locate_server (krb5_context cont
 	code = prof_locate_server(context, realm, &al, svc, socktype, family);
 
 #ifdef KRB5_DNS_LOOKUP
-	if (code) {		/* Try DNS for all profile errors?  */
-	    krb5_error_code code2;
-	    code2 = dns_locate_server(context, realm, &al, svc, socktype,
-				      family);
-	    if (code2 != KRB5_PLUGIN_NO_HANDLE)
-		code = code2;
-	}
+         if (code == 0 && al.naddrs == 0)
+	   code = dns_locate_server(context, realm, &al, svc, socktype, family);
 #endif /* KRB5_DNS_LOOKUP */
 
 	/* We could put more heuristics here, like looking up a hostname
@@ -832,14 +773,12 @@ krb5int_locate_server (krb5_context cont
 	    free_list (&al);
 	return code;
     }
-    if (al.naddrs == 0) {	/* No good servers */
-	if (al.space)
-	    free_list (&al);
-	krb5_set_error_message(context, KRB5_REALM_CANT_RESOLVE,
-			       "Cannot resolve network address for KDC in realm %.*s",
-			       realm->length, realm->data);
-			       
-	return KRB5_REALM_CANT_RESOLVE;
+      if (al.naddrs == 0) {       /* No good servers */
+          free_list(&al);
+          krb5_set_error_message(context, KRB5_REALM_UNKNOWN,
+                                _("Cannot find KDC for realm \"%.*s\""),
+                                realm->length, realm->data);
+         return KRB5_REALM_UNKNOWN;
     }
     *addrlist = al;
     return 0;
