r19651: Fix interesting bug with the automatic site coverage in Active Directory:
authorGünther Deschner <gd@samba.org>
Fri, 10 Nov 2006 12:42:50 +0000 (12:42 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:15:44 +0000 (12:15 -0500)
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

source/libads/ldap.c
source/libsmb/namequery_dc.c
source/nsswitch/winbindd_cm.c
source/utils/net_ads.c

index 927b86fe935c5c75277f35e045d449b381529059..5dcc3c33ba1d8fd5472bb74ea10830a04ca7cbd7 100644 (file)
@@ -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));
        }
index 5280118ab85d592f8d0cd6cee1525276d98da1c0..ceb8bbd7e6d086d5a7bd917ebbad79e9958f3049 100644 (file)
@@ -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. */
index f2d264b2b458914eb83280ee2980558b302f5026..bf23af5b338e1b973c767e9e5f648c7033c4ccd5 100644 (file)
@@ -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. */
index 377bfa22b70d78dcbcde337e531f15643dab127b..e1762da2f785ce548fe53d53f15b808e24a8790d 100644 (file)
@@ -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);