libads: Keep 'good' server at the head of custom KDC list
authorUri Simchoni <urisimchoni@gmail.com>
Mon, 18 May 2015 10:36:46 +0000 (13:36 +0300)
committerJeremy Allison <jra@samba.org>
Mon, 15 Jun 2015 23:29:24 +0000 (01:29 +0200)
When creating a custom krb.conf file for a domain, make sure
that the DC which already answered the ldap ping is not queried
again, and is always first in the custom KDC list. This has two
advantages:
1. Avoid re-sending an ldap ping to this server
2. The generated list is made up of the servers that answered
   first. Since the DC which already answered an LDAP ping
   is typically the "last good server", this change keeps it
   out of the contest and guarantees that we keep using last
   good server as long as it works.

Signed-off-by: Uri Simchoni <urisimchoni@gmail.com>
Reviewed-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
source3/libads/kerberos.c

index 65a8f24b46ef91c3c6ddbe357f4b7743ba8226c3..1c2d8a256439e9f23f1aafd708d41cfecb7e131d 100644 (file)
@@ -676,34 +676,51 @@ static char *get_kdc_ip_string(char *mem_ctx,
 
        if (sitename) {
                get_kdc_list(realm, sitename, &ip_srv_site, &count_site);
+               DEBUG(10, ("got %d addresses from site %s search\n", count_site,
+                          sitename));
        }
 
        /* Get all KDC's. */
 
        get_kdc_list(realm, NULL, &ip_srv_nonsite, &count_nonsite);
+       DEBUG(10, ("got %d addresses from site-less search\n", count_nonsite));
 
        dc_addrs = talloc_array(talloc_tos(), struct sockaddr_storage,
-                               1 + count_site + count_nonsite);
+                               count_site + count_nonsite);
        if (dc_addrs == NULL) {
-               goto fail;
+               goto out;
        }
 
-       dc_addrs[0] = *pss;
-       num_dcs = 1;
+       num_dcs = 0;
 
-       for (i=0; i<count_site; i++) {
-               add_sockaddr_unique(dc_addrs, &num_dcs, &ip_srv_site[i].ss);
+       for (i = 0; i < count_site; i++) {
+               if (!sockaddr_equal(
+                       (const struct sockaddr *)pss,
+                       (const struct sockaddr *)&ip_srv_site[i].ss)) {
+                       add_sockaddr_unique(dc_addrs, &num_dcs,
+                                           &ip_srv_site[i].ss);
+               }
        }
 
-       for (i=0; i<count_nonsite; i++) {
-               add_sockaddr_unique(dc_addrs, &num_dcs, &ip_srv_nonsite[i].ss);
+       for (i = 0; i < count_nonsite; i++) {
+               if (!sockaddr_equal(
+                       (const struct sockaddr *)pss,
+                       (const struct sockaddr *)&ip_srv_nonsite[i].ss)) {
+                       add_sockaddr_unique(dc_addrs, &num_dcs,
+                                           &ip_srv_nonsite[i].ss);
+               }
        }
 
        dc_addrs2 = talloc_zero_array(talloc_tos(),
                                      struct tsocket_address *,
                                      num_dcs);
+
+       DEBUG(10, ("%d additional KDCs to test\n", num_dcs));
+       if (num_dcs == 0) {
+               goto out;
+       }
        if (dc_addrs2 == NULL) {
-               goto fail;
+               goto out;
        }
 
        for (i=0; i<num_dcs; i++) {
@@ -719,7 +736,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
                        status = map_nt_error_from_unix(errno);
                        DEBUG(2,("Failed to create tsocket_address for %s - %s\n",
                                 addr, nt_errstr(status)));
-                       goto fail;
+                       goto out;
                }
        }
 
@@ -736,12 +753,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(10,("get_kdc_ip_string: cldap_multi_netlogon failed: "
                          "%s\n", nt_errstr(status)));
-               goto fail;
-       }
-
-       kdc_str = talloc_strdup(mem_ctx, "");
-       if (kdc_str == NULL) {
-               goto fail;
+               goto out;
        }
 
        for (i=0; i<num_dcs; i++) {
@@ -756,17 +768,16 @@ static char *get_kdc_ip_string(char *mem_ctx,
                                              kdc_str,
                                              print_canonical_sockaddr_with_port(mem_ctx, &dc_addrs[i]));
                if (new_kdc_str == NULL) {
-                       goto fail;
+                       goto out;
                }
                TALLOC_FREE(kdc_str);
                kdc_str = new_kdc_str;
        }
 
-       DEBUG(10,("get_kdc_ip_string: Returning %s\n",
-               kdc_str ));
+out:
+       DEBUG(10, ("get_kdc_ip_string: Returning %s\n", kdc_str));
 
        result = kdc_str;
-fail:
        SAFE_FREE(ip_srv_site);
        SAFE_FREE(ip_srv_nonsite);
        TALLOC_FREE(frame);