From 61a38bd4b83b7f72b479e84daa5ea89164a92f85 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 10 Nov 2006 12:42:50 +0000 Subject: r19651: Fix interesting bug with the automatic site coverage in Active Directory: When having DC-less sites, AD assigns DCs from other sites to that site that does not have it's own DC. The most reliable way for us to identify the nearest DC - in that and all other cases - is the closest_dc flag in the CLDAP reply. Guenther (This used to be commit ff004f7284cb047e738ba3d3ad6602e8aa84e883) --- source3/libads/ldap.c | 26 +++++++++++++++++++++++++- source3/libsmb/namequery_dc.c | 2 +- source3/nsswitch/winbindd_cm.c | 2 +- source3/utils/net_ads.c | 2 +- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 927b86fe93..5dcc3c33ba 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -139,6 +139,30 @@ BOOL ads_sitename_match(ADS_STRUCT *ads) return False; } +/********************************************** + Is this the closest DC ? +**********************************************/ + +BOOL ads_closest_dc(ADS_STRUCT *ads) +{ + if (ads->config.flags & ADS_CLOSEST) { + DEBUG(10,("ads_closest_dc: ADS_CLOSEST flag set\n")); + return True; + } + + /* not sure if this can ever happen */ + if (ads_sitename_match(ads)) { + DEBUG(10,("ads_closest_dc: ADS_CLOSEST flag not set but sites match\n")); + return True; + } + + DEBUG(10,("ads_closest_dc: %s is not the closest DC\n", + ads->config.ldap_server_name)); + + return False; +} + + /* try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful @@ -392,7 +416,7 @@ got_connection: } /* cache the successful connection for workgroup and realm */ - if (ads_sitename_match(ads)) { + if (ads_closest_dc(ads)) { saf_store( ads->server.workgroup, inet_ntoa(ads->ldap_ip)); saf_store( ads->server.realm, inet_ntoa(ads->ldap_ip)); } diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 5280118ab8..ceb8bbd7e6 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -79,7 +79,7 @@ static BOOL ads_dc_name(const char *domain, } #ifdef HAVE_KRB5 - if ((ads->config.flags & ADS_KDC) && ads_sitename_match(ads)) { + if ((ads->config.flags & ADS_KDC) && ads_closest_dc(ads)) { /* We're going to use this KDC for this realm/domain. If we are using sites, then force the krb5 libs to use this KDC. */ diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index f2d264b2b4..bf23af5b33 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -822,7 +822,7 @@ static BOOL dcip_to_name( const char *domainname, const char *realm, DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags)); - if ((ads->config.flags & ADS_KDC) && ads_sitename_match(ads)) { + if ((ads->config.flags & ADS_KDC) && ads_closest_dc(ads)) { /* We're going to use this KDC for this realm/domain. If we are using sites, then force the krb5 libs to use this KDC. */ diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 377bfa22b7..e1762da2f7 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -314,7 +314,7 @@ retry: tried_closest_dc = True; /* avoid loop */ - if (!closest_dc || !site_matches) { + if (!ads_closest_dc(ads)) { namecache_delete(ads->server.realm, 0x1C); namecache_delete(ads->server.workgroup, 0x1C); -- cgit