winbind_krb5_locator bug when the Domain Controller has multiple network IPs (smb3.5.8)

Jeremy Allison jra at samba.org
Mon Apr 23 17:00:38 MDT 2012


On Mon, Apr 23, 2012 at 08:52:14AM +0100, Dina_Fine at Dell.com wrote:
> Hello
> It seems the winbind_krb5_locator doesn't function correctly when the Domain Controller has multiple network IPs and some of IPs are not reachable from the samba server system.
> The reason seems to be that only the winbind_krb5_locator uses the WBC_LOOKUP_DC_IP_REQUIRED flag for dsgetdcname request.
> 
> All other flows (like join domain) use only the DNS name and then resolve the name->IP in a smart way (taking an IP which responds to ldap request).
> 
> P.S. We have a customer environment where this bug actually takes place. Sometimes the net join fails and sometime net ads testjoin fails due to Kerberos error: Cannot contact any KDC for requested realm
> Debugging the winbind_krb5_locator showed it replies with incorrect IP for the Kerberos Domain Controller request which leads to Kerberos error.

Ok Dina, I think this patch will fix the winbind_krb5_locator
to do what you need. It removes the WBC_LOOKUP_DC_IP_REQUIRED
flag from the winbindd request, which means we'll only get
the KDC DNS name back. Then we call the standard getaddinfo
on that name but instead of just calling the plugin callback
once, we call it for all addresses that the getaddrinfo
returned, allowing the krb5 library to collect a list of
all returned addresses.

The list will still contain the unreachable IP's but at
least one of them should be reachable, and the krb5 library
should be able to work with this.

Let me know if it fixes your problem and if so I'll get
it into the next releases for 3.5.x and 3.6.x. The patch
should apply cleanly to the 3.5.8 version you have.

Thanks,

	Jeremy.
-------------- next part --------------
diff --git a/nsswitch/winbind_krb5_locator.c b/nsswitch/winbind_krb5_locator.c
index e921cae..10e61cf 100644
--- a/nsswitch/winbind_krb5_locator.c
+++ b/nsswitch/winbind_krb5_locator.c
@@ -182,7 +182,8 @@ static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name,
 						    void *cbdata)
 {
 	struct addrinfo *out = NULL;
-	int ret;
+	int ret = 0;
+	struct addrinfo *res = NULL;
 	int count = 3;
 
 	while (count) {
@@ -206,16 +207,25 @@ static krb5_error_code smb_krb5_locator_call_cbfunc(const char *name,
 		return KRB5_PLUGIN_NO_HANDLE;
 	}
 
-	ret = cbfunc(cbdata, out->ai_socktype, out->ai_addr);
+	for (res = out; res; res = res->ai_next) {
+		if (!res->ai_addr || res->ai_addrlen == 0) {
+			continue;
+		}
+
+		ret = cbfunc(cbdata, res->ai_socktype, res->ai_addr);
 #ifdef DEBUG_KRB5
-	if (ret) {
-		fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: "
-			"failed to call callback: %s (%d)\n",
-			(unsigned int)getpid(), error_message(ret), ret);
-	}
+		if (ret) {
+			fprintf(stderr, "[%5u]: smb_krb5_locator_lookup: "
+				"failed to call callback: %s (%d)\n",
+				(unsigned int)getpid(), error_message(ret), ret);
+			break;
+		}
 #endif
+	}
 
-	freeaddrinfo(out);
+	if (out) {
+		freeaddrinfo(out);
+	}
 	return ret;
 }
 
@@ -257,8 +267,7 @@ static bool ask_winbind(const char *realm, char **dcname)
 
 	flags = WBC_LOOKUP_DC_KDC_REQUIRED |
 		WBC_LOOKUP_DC_IS_DNS_NAME |
-		WBC_LOOKUP_DC_RETURN_DNS_NAME |
-		WBC_LOOKUP_DC_IP_REQUIRED;
+		WBC_LOOKUP_DC_RETURN_DNS_NAME;
 
 	wbc_status = wbcLookupDomainControllerEx(realm, NULL, NULL, flags, &dc_info);
 
@@ -270,12 +279,6 @@ static bool ask_winbind(const char *realm, char **dcname)
 		return false;
 	}
 
-	if (dc_info->dc_address) {
-		dc = dc_info->dc_address;
-		if (dc[0] == '\\') dc++;
-		if (dc[0] == '\\') dc++;
-	}
-
 	if (!dc && dc_info->dc_unc) {
 		dc = dc_info->dc_unc;
 		if (dc[0] == '\\') dc++;


More information about the samba-technical mailing list