From bfd099e148ed97394bc858e746a1a998a71ac43c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Jan 2007 18:25:35 +0000 Subject: r20857: Silence gives assent :-). Checking in the fix for site support in a network where many DC's are down. I heard via Volker there is still a bug w.r.t the wrong site being chosen with trusted domains but we'll have to layer that fix on top of this. Gd - complain if this doesn't work for you. Jeremy. (This used to be commit 97e248f89ac6548274f03f2ae7583a255da5ddb3) --- source3/libads/kerberos.c | 65 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 14 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 76866a8093..95eed6fe27 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -470,10 +470,11 @@ int kerberos_kinit_password(const char *principal, Does DNS queries. ************************************************************************/ -static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr primary_ip) +static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sitename, struct in_addr primary_ip) { - struct ip_service *ip_srv; - int count, i; + struct ip_service *ip_srv_site; + struct ip_service *ip_srv_nonsite; + int count_site, count_nonsite, i; char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n", inet_ntoa(primary_ip)); @@ -481,26 +482,61 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr return NULL; } - if (!NT_STATUS_IS_OK(get_kdc_list(realm, &ip_srv, &count))) { - DEBUG(10,("get_kdc_ip_string: get_kdc_list failed. Returning %s\n", - kdc_str )); - return kdc_str; + /* Get the KDC's only in this site. */ + + get_kdc_list(realm, sitename, &ip_srv_site, &count_site); + + for (i = 0; i < count_site; i++) { + if (ip_equal(ip_srv_site[i].ip, primary_ip)) { + continue; + } + /* Append to the string - inefficient but not done often. */ + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + kdc_str, inet_ntoa(ip_srv_site[i].ip)); + if (!kdc_str) { + SAFE_FREE(ip_srv_site); + return NULL; + } } - for (i = 0; i < count; i++) { - if (ip_equal(ip_srv[i].ip, primary_ip)) { + /* Get all KDC's. */ + + get_kdc_list(realm, NULL, &ip_srv_nonsite, &count_nonsite); + + for (i = 0; i < count_nonsite; i++) { + int j; + + if (ip_equal(ip_srv_nonsite[i].ip, primary_ip)) { + continue; + } + + /* Ensure this isn't an IP already seen (YUK! this is n*n....) */ + for (j = 0; j < count_site; j++) { + if (ip_equal(ip_srv_nonsite[i].ip, ip_srv_site[j].ip)) { + break; + } + /* As the lists are sorted we can break early if nonsite > site. */ + if (ip_service_compare(&ip_srv_nonsite[i], &ip_srv_site[j]) > 0) { + break; + } + } + if (j != i) { continue; } + /* Append to the string - inefficient but not done often. */ kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", - kdc_str, inet_ntoa(ip_srv[i].ip)); + kdc_str, inet_ntoa(ip_srv_nonsite[i].ip)); if (!kdc_str) { - SAFE_FREE(ip_srv); + SAFE_FREE(ip_srv_site); + SAFE_FREE(ip_srv_nonsite); return NULL; } } - SAFE_FREE(ip_srv); + + SAFE_FREE(ip_srv_site); + SAFE_FREE(ip_srv_nonsite); DEBUG(10,("get_kdc_ip_string: Returning %s\n", kdc_str )); @@ -515,7 +551,8 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr run as root or will fail (which is a good thing :-). ************************************************************************/ -BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, struct in_addr ip) +BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, + const char *sitename, struct in_addr ip) { char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir()); char *tmpname = NULL; @@ -556,7 +593,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do realm_upper = talloc_strdup(fname, realm); strupper_m(realm_upper); - kdc_ip_string = get_kdc_ip_string(dname, realm, ip); + kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, ip); if (!kdc_ip_string) { TALLOC_FREE(dname); return False; -- cgit