]> git.samba.org - samba.git/commitdiff
r20857: Silence gives assent :-). Checking in the fix for
authorJeremy Allison <jra@samba.org>
Wed, 17 Jan 2007 18:25:35 +0000 (18:25 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:17:14 +0000 (12:17 -0500)
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/include/ads.h
source3/libads/dns.c
source3/libads/kerberos.c
source3/libads/ldap.c
source3/libsmb/namequery.c
source3/libsmb/namequery_dc.c
source3/nsswitch/winbindd_cm.c
source3/utils/net_ads.c
source3/utils/net_lookup.c

index 58fac36920636826ad94f92adc244df885319760..1d8b1f3d322082aa6d1e02a8b23f9e1b9e102acf 100644 (file)
@@ -55,6 +55,7 @@ typedef struct {
                char *server_site_name;
                char *client_site_name;
                time_t current_time;
+               int tried_closest_dc;
        } config;
 
        /* info derived from the servers schema */
index c8b3f2950721b6e8b26363ec6f74512950360575..b67d802bdc739070dd537dd4188f869de3234986 100644 (file)
@@ -673,16 +673,16 @@ NTSTATUS ads_dns_query_internal(TALLOC_CTX *ctx,
 }
 
 /********************************************************************
- Query for AD DC's. Transparently use sitename.
+ Query for AD DC's.
 ********************************************************************/
 
 NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx,
                        const char *realm,
+                       const char *sitename,
                        struct dns_rr_srv **dclist,
                        int *numdcs )
 {
        NTSTATUS status;
-       char *sitename = sitename_fetch();
 
        status = ads_dns_query_internal(ctx, "_ldap", realm, sitename,
                                        dclist, numdcs);
@@ -691,23 +691,22 @@ NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx,
                status = ads_dns_query_internal(ctx, "_ldap", realm, NULL,
                                                dclist, numdcs);
        }
-       SAFE_FREE(sitename);
        return status;
 }
 
 /********************************************************************
- Query for AD KDC's. Transparently use sitename.
+ Query for AD KDC's.
  Even if our underlying kerberos libraries are UDP only, this
  is pretty safe as it's unlikely that a KDC supports TCP and not UDP.
 ********************************************************************/
 
 NTSTATUS ads_dns_query_kdcs(TALLOC_CTX *ctx,
                        const char *realm,
+                       const char *sitename,
                        struct dns_rr_srv **dclist,
                        int *numdcs )
 {
        NTSTATUS status;
-       char *sitename = sitename_fetch();
 
        status = ads_dns_query_internal(ctx, "_kerberos", realm, sitename,
                                        dclist, numdcs);
@@ -716,6 +715,5 @@ NTSTATUS ads_dns_query_kdcs(TALLOC_CTX *ctx,
                status = ads_dns_query_internal(ctx, "_kerberos", realm, NULL,
                                                dclist, numdcs);
        }
-       SAFE_FREE(sitename);
        return status;
 }
index 76866a8093b200cc7b59329bbc90c64330c51916..95eed6fe27f3a8ce216551ce776f921c5d03230c 100644 (file)
@@ -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;
index c263e8e133bcef34c9b99eeb438eaea5224c5a97..2ceae4d957f9dd6f0e1e1e481f7c8bf9719f973e 100644 (file)
@@ -249,6 +249,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
        pstring realm;
        BOOL got_realm = False;
        BOOL use_own_domain = False;
+       char *sitename = sitename_fetch();
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
 
        /* if the realm and workgroup are both empty, assume they are ours */
@@ -279,6 +280,7 @@ again:
                }
                
                if ( !c_realm || !*c_realm ) {
+                       SAFE_FREE(sitename);
                        DEBUG(0,("ads_find_dc: no realm or workgroup!  Don't know what to do\n"));
                        return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */
                }
@@ -289,7 +291,7 @@ again:
        DEBUG(6,("ads_find_dc: looking for %s '%s'\n", 
                (got_realm ? "realm" : "domain"), realm));
 
-       status = get_sorted_dc_list(realm, &ip_list, &count, got_realm);
+       status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm);
        if (!NT_STATUS_IS_OK(status)) {
                /* fall back to netbios if we can */
                if ( got_realm && !lp_disable_netbios() ) {
@@ -331,6 +333,7 @@ again:
                        
                if ( ads_try_connect(ads, server) ) {
                        SAFE_FREE(ip_list);
+                       SAFE_FREE(sitename);
                        return NT_STATUS_OK;
                }
                
@@ -339,7 +342,19 @@ again:
        }
 
        SAFE_FREE(ip_list);
-       
+
+       /* In case we failed to contact one of our closest DC on our site we
+        * need to try to find another DC, retry with a site-less SRV DNS query
+        * - Guenther */
+
+       if (sitename) {
+               DEBUG(1,("ads_find_dc: failed to find a valid DC on our site (%s), "
+                               "trying to find another DC\n", sitename));
+               SAFE_FREE(sitename);
+               namecache_delete(realm, 0x1C);
+               goto again;
+       }
+
        return NT_STATUS_NO_LOGON_SERVERS;
 }
 
index 065bb810c5e193697c7f40c1d9a52c6aa720e989..6ebc26b8cbb960d116a0c212a842e9fe14b1ac28 100644 (file)
@@ -384,7 +384,7 @@ static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
  compare 2 ldap IPs by nearness to our interfaces - used in qsort
 *******************************************************************/
 
-static int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2)
+int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2)
 {
        int result;
        
@@ -1049,6 +1049,7 @@ static BOOL resolve_hosts(const char *name, int name_type,
 *********************************************************/
 
 static BOOL resolve_ads(const char *name, int name_type,
+                       const char *sitename,
                          struct ip_service **return_iplist, int *return_count)
 {
        int                     i, j;
@@ -1070,9 +1071,9 @@ static BOOL resolve_ads(const char *name, int name_type,
        }
 
        if (name_type == KDC_NAME_TYPE) {
-               status = ads_dns_query_kdcs(ctx, name, &dcs, &numdcs);
+               status = ads_dns_query_kdcs(ctx, name, sitename, &dcs, &numdcs);
        } else {
-               status = ads_dns_query_dcs(ctx, name, &dcs, &numdcs);
+               status = ads_dns_query_dcs(ctx, name, sitename, &dcs, &numdcs);
        }
        if ( !NT_STATUS_IS_OK( status ) ) {
                talloc_destroy(ctx);
@@ -1145,6 +1146,7 @@ static BOOL resolve_ads(const char *name, int name_type,
 **********************************************************************/
 
 BOOL internal_resolve_name(const char *name, int name_type,
+                          const char *sitename,
                           struct ip_service **return_iplist, 
                           int *return_count, const char *resolve_order)
 {
@@ -1160,7 +1162,8 @@ BOOL internal_resolve_name(const char *name, int name_type,
        *return_iplist = NULL;
        *return_count = 0;
 
-       DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
+       DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
+                       name, name_type, sitename ? sitename : NULL));
 
        if (allzeros || allones || is_address) {
   
@@ -1223,7 +1226,7 @@ BOOL internal_resolve_name(const char *name, int name_type,
                } else if(strequal( tok, "kdc")) {
                        /* deal with KDC_NAME_TYPE names here.  This will result in a
                                SRV record lookup */
-                       if (resolve_ads(name, KDC_NAME_TYPE, return_iplist, return_count)) {
+                       if (resolve_ads(name, KDC_NAME_TYPE, sitename, return_iplist, return_count)) {
                                result = True;
                                /* Ensure we don't namecache this with the KDC port. */
                                name_type = KDC_NAME_TYPE;
@@ -1232,7 +1235,7 @@ BOOL internal_resolve_name(const char *name, int name_type,
                } else if(strequal( tok, "ads")) {
                        /* deal with 0x1c names here.  This will result in a
                                SRV record lookup */
-                       if (resolve_ads(name, name_type, return_iplist, return_count)) {
+                       if (resolve_ads(name, name_type, sitename, return_iplist, return_count)) {
                                result = True;
                                goto done;
                        }
@@ -1308,14 +1311,16 @@ BOOL internal_resolve_name(const char *name, int name_type,
 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
 {
        struct ip_service *ip_list = NULL;
+       char *sitename = sitename_fetch();
        int count = 0;
 
        if (is_ipaddress(name)) {
                *return_ip = *interpret_addr2(name);
+               SAFE_FREE(sitename);
                return True;
        }
 
-       if (internal_resolve_name(name, name_type, &ip_list, &count, lp_name_resolve_order())) {
+       if (internal_resolve_name(name, name_type, sitename, &ip_list, &count, lp_name_resolve_order())) {
                int i;
                
                /* only return valid addresses for TCP connections */
@@ -1327,12 +1332,14 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
                        {
                                *return_ip = ip_list[i].ip;
                                SAFE_FREE(ip_list);
+                               SAFE_FREE(sitename);
                                return True;
                        }
                }
        }
        
        SAFE_FREE(ip_list);
+       SAFE_FREE(sitename);
        return False;
 }
 
@@ -1350,12 +1357,12 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip)
                return False;
        }
 
-       if (internal_resolve_name(group, 0x1D, &ip_list, &count, lp_name_resolve_order())) {
+       if (internal_resolve_name(group, 0x1D, NULL, &ip_list, &count, lp_name_resolve_order())) {
                *master_ip = ip_list[0].ip;
                SAFE_FREE(ip_list);
                return True;
        }
-       if(internal_resolve_name(group, 0x1B, &ip_list, &count, lp_name_resolve_order())) {
+       if(internal_resolve_name(group, 0x1B, NULL, &ip_list, &count, lp_name_resolve_order())) {
                *master_ip = ip_list[0].ip;
                SAFE_FREE(ip_list);
                return True;
@@ -1372,15 +1379,19 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip)
 
 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
 {
-       struct ip_service *ip_list;
-       int count;
+       char *sitename = sitename_fetch();
+       struct ip_service *ip_list = NULL;
+       int count = 0;
 
        /* Look up #1B name */
 
-       if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order())) {
+       if (!internal_resolve_name(domain, 0x1b, sitename, &ip_list, &count, lp_name_resolve_order())) {
+               SAFE_FREE(sitename);
                return False;
        }
 
+       SAFE_FREE(sitename);
+
        /* if we get more than 1 IP back we have to assume it is a
           multi-homed PDC and not a mess up */
 
@@ -1405,7 +1416,7 @@ enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
  a domain.
 *********************************************************/
 
-static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list, 
+static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_service **ip_list, 
                             int *count, enum dc_lookup_type lookup_type, int *ordered)
 {
        fstring resolve_order;
@@ -1452,7 +1463,7 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list,
        /* fetch the server we have affinity for.  Add the 
           'password server' list to a search for our domain controllers */
        
-       saf_servername = saf_fetch( domain );
+       saf_servername = saf_fetch( domain);
        
        if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
                pstr_sprintf( pserver, "%s, %s", 
@@ -1471,7 +1482,7 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list,
                DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
                /* TODO: change return type of internal_resolve_name to
                 * NTSTATUS */
-               if (internal_resolve_name(domain, 0x1C, ip_list, count,
+               if (internal_resolve_name(domain, 0x1C, sitename, ip_list, count,
                                          resolve_order)) {
                        return NT_STATUS_OK;
                } else {
@@ -1491,7 +1502,7 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list,
        p = pserver;
        while (next_token(&p,name,LIST_SEP,sizeof(name))) {
                if (strequal(name, "*")) {
-                       if (internal_resolve_name(domain, 0x1C, &auto_ip_list,
+                       if (internal_resolve_name(domain, 0x1C, sitename, &auto_ip_list,
                                                  &auto_count, resolve_order))
                                num_addresses += auto_count;
                        done_auto_lookup = True;
@@ -1510,7 +1521,7 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list,
                        SAFE_FREE(auto_ip_list);
                        return NT_STATUS_NO_LOGON_SERVERS;
                }
-               if (internal_resolve_name(domain, 0x1C, ip_list, count,
+               if (internal_resolve_name(domain, 0x1C, sitename, ip_list, count,
                                          resolve_order)) {
                        return NT_STATUS_OK;
                } else {
@@ -1606,20 +1617,23 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list,
  Small wrapper function to get the DC list and sort it if neccessary.
 *********************************************************************/
 
-NTSTATUS get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only )
+NTSTATUS get_sorted_dc_list( const char *domain, const char *sitename, struct ip_service **ip_list, int *count, BOOL ads_only )
 {
        BOOL ordered;
        NTSTATUS status;
        enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
 
-       DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n",
+       DEBUG(8,("get_sorted_dc_list: attempting lookup for name %s (sitename %s) "
+               "using [%s]\n",
+               domain,
+               sitename ? sitename : "NULL",
                (ads_only ? "ads" : lp_name_resolve_order())));
        
        if (ads_only) {
                lookup_type = DC_ADS_ONLY;
        }
 
-       status = get_dc_list(domain, ip_list, count, lookup_type, &ordered);
+       status = get_dc_list(domain, sitename, ip_list, count, lookup_type, &ordered);
        if (!NT_STATUS_IS_OK(status)) {
                return status; 
        }
@@ -1636,7 +1650,7 @@ NTSTATUS get_sorted_dc_list( const char *domain, struct ip_service **ip_list, in
  Get the KDC list - re-use all the logic in get_dc_list.
 *********************************************************************/
 
-NTSTATUS get_kdc_list( const char *realm, struct ip_service **ip_list, int *count)
+NTSTATUS get_kdc_list( const char *realm, const char *sitename, struct ip_service **ip_list, int *count)
 {
        BOOL ordered;
        NTSTATUS status;
@@ -1644,7 +1658,7 @@ NTSTATUS get_kdc_list( const char *realm, struct ip_service **ip_list, int *coun
        *count = 0;
        *ip_list = NULL;
 
-       status = get_dc_list(realm, ip_list, count, DC_KDC_ONLY, &ordered);
+       status = get_dc_list(realm, sitename, ip_list, count, DC_KDC_ONLY, &ordered);
 
        if (!NT_STATUS_IS_OK(status)) {
                return status; 
index 375d39a5fd8dab03be9d0b5087be56f75f5d2e6b..a240510b772a18c1e1ac4d0744b5d50f5064eb87 100644 (file)
@@ -104,6 +104,7 @@ static BOOL ads_dc_name(const char *domain,
 
                        create_local_private_krb5_conf_for_domain(realm,
                                                                domain,
+                                                               sitename,
                                                                ads->ldap_ip);
                }
 #endif
@@ -146,7 +147,7 @@ static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip
 
        /* get a list of all domain controllers */
        
-       if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, &ip_list, &count,
+       if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, NULL, &ip_list, &count,
                                                False))) {
                DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
                return False;
index 19b60c1c1731ffd3eaa7e3dbd721c3dd79729fd9..70ab9b0582503bb5e4543aac0ae1da64369fb6bb 100644 (file)
@@ -1031,14 +1031,18 @@ static BOOL dcip_to_name(const struct winbindd_domain *domain, struct in_addr ip
                        DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
 
                        if (domain->primary && (ads->config.flags & ADS_KDC) && ads_closest_dc(ads)) {
+                               char *sitename = sitename_fetch();
+
                                /* 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. */
 
                                create_local_private_krb5_conf_for_domain(domain->alt_name,
                                                                domain->name,
+                                                               sitename,
                                                                ip);
 
+                               SAFE_FREE(sitename);
                                /* Ensure we contact this DC also. */
                                saf_store( domain->name, name);
                                saf_store( domain->alt_name, name);
@@ -1103,6 +1107,8 @@ static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
        }
 
        if (sec == SEC_ADS) {
+               char *sitename = NULL;
+
                /* We need to make sure we know the local site before
                   doing any DNS queries, as this will restrict the
                   get_sorted_dc_list() call below to only fetching
@@ -1111,16 +1117,37 @@ static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
                /* Find any DC to get the site record.
                   We deliberately don't care about the
                   return here. */
+
                get_dc_name(domain->name, lp_realm(), dcname, &ip);
 
-               /* Now do the site-specific AD dns lookup. */
-               get_sorted_dc_list(domain->alt_name, &ip_list, &iplist_size, True);
+               sitename = sitename_fetch();
+
+               /* Do the site-specific AD dns lookup first. */
+               get_sorted_dc_list(domain->alt_name, sitename, &ip_list, &iplist_size, True);
+
+               for ( i=0; i<iplist_size; i++ ) {
+                       add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
+                                               ip_list[i].ip, dcs, num_dcs);
+               }
+
+               SAFE_FREE(ip_list);
+               SAFE_FREE(sitename);
+               iplist_size = 0;
+
+               /* Now we add DCs from the main AD dns lookup. */
+               get_sorted_dc_list(domain->alt_name, NULL, &ip_list, &iplist_size, True);
+
+               for ( i=0; i<iplist_size; i++ ) {
+                       add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
+                                               ip_list[i].ip, dcs, num_dcs);
+               }
         }
 
        /* try standard netbios queries if no ADS */
 
-       if (iplist_size==0) 
-               get_sorted_dc_list(domain->name, &ip_list, &iplist_size, False);
+       if (iplist_size==0) {
+               get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size, False);
+       }
 
        /* FIXME!! this is where we should re-insert the GETDC requests --jerry */
 
index 8c35f201ad733298e09add68baeeafd3e63f2268..bd67983954635af73296a159c0acc351d761219a 100644 (file)
@@ -218,8 +218,6 @@ static ADS_STATUS ads_startup_int(BOOL only_own_domain, uint32 auth_flags, ADS_S
        char *cp;
        const char *realm = NULL;
        BOOL tried_closest_dc = False;
-       BOOL closest_dc = False;
-       BOOL site_matches = False;
 
        /* lp_realm() should be handled by a command line param, 
           However, the join requires that realm be set in smb.conf
@@ -290,7 +288,7 @@ retry:
                        return status;
                }
        
-               if (!need_password && !second_time) {
+               if (!need_password && !second_time && !(auth_flags & ADS_AUTH_NO_BIND)) {
                        need_password = True;
                        second_time = True;
                        goto retry;
@@ -304,17 +302,11 @@ retry:
         * This is done by reconnecting to ADS because only the first call to
         * ads_connect will give us our own sitename */
 
-       closest_dc = (ads->config.flags & ADS_CLOSEST);
-       site_matches = ads_sitename_match(ads);
-
-       DEBUG(10,("ads_startup_int: DC %s closest DC\n", closest_dc ? "is":"is *NOT*"));
-       DEBUG(10,("ads_startup_int: sitenames %s match\n", site_matches ? "do":"do *NOT*"));
-
        if ((only_own_domain || !opt_host) && !tried_closest_dc) {
 
                tried_closest_dc = True; /* avoid loop */
 
-               if (!ads_closest_dc(ads)) {
+               if (!ads->config.tried_closest_dc) {
 
                        namecache_delete(ads->server.realm, 0x1C);
                        namecache_delete(ads->server.workgroup, 0x1C);
index b768089fff576fcedb0ed776f76cfcca6689a48c..8e223e67f3ba398a2f78037f48640235e3599ce5 100644 (file)
@@ -84,6 +84,7 @@ static int net_lookup_ldap(int argc, const char **argv)
        struct hostent *hostent;
        struct dns_rr_srv *dcs = NULL;
        int numdcs = 0;
+       char *sitename = sitename_fetch();
        TALLOC_CTX *ctx;
        NTSTATUS status;
 
@@ -94,22 +95,24 @@ static int net_lookup_ldap(int argc, const char **argv)
 
        if ( (ctx = talloc_init("net_lookup_ldap")) == NULL ) {
                d_fprintf(stderr, "net_lookup_ldap: talloc_inti() failed!\n");
+               SAFE_FREE(sitename);
                return -1;
        }
 
        DEBUG(9, ("Lookup up ldap for domain %s\n", domain));
 
-       status = ads_dns_query_dcs( ctx, domain, &dcs, &numdcs );
+       status = ads_dns_query_dcs( ctx, domain, sitename, &dcs, &numdcs );
        if ( NT_STATUS_IS_OK(status) && numdcs ) {
                print_ldap_srvlist(dcs, numdcs);
                TALLOC_FREE( ctx );
-
+               SAFE_FREE(sitename);
                return 0;
        }
 
        DEBUG(9, ("Looking up DC for domain %s\n", domain));
        if (!get_pdc_ip(domain, &addr)) {
                TALLOC_FREE( ctx );
+               SAFE_FREE(sitename);
                return -1;
        }
 
@@ -117,6 +120,7 @@ static int net_lookup_ldap(int argc, const char **argv)
                                AF_INET);
        if (!hostent) {
                TALLOC_FREE( ctx );
+               SAFE_FREE(sitename);
                return -1;
        }
 
@@ -124,22 +128,23 @@ static int net_lookup_ldap(int argc, const char **argv)
        domain = strchr(hostent->h_name, '.');
        if (!domain) {
                TALLOC_FREE( ctx );
+               SAFE_FREE(sitename);
                return -1;
        }
        domain++;
 
        DEBUG(9, ("Looking up ldap for domain %s\n", domain));
 
-       status = ads_dns_query_dcs( ctx, domain, &dcs, &numdcs );
+       status = ads_dns_query_dcs( ctx, domain, sitename, &dcs, &numdcs );
        if ( NT_STATUS_IS_OK(status) && numdcs ) {
                print_ldap_srvlist(dcs, numdcs);
                TALLOC_FREE( ctx );
-
+               SAFE_FREE(sitename);
                return 0;
        }
 
        TALLOC_FREE( ctx );
-
+       SAFE_FREE(sitename);
 
        return -1;
 #endif
@@ -153,6 +158,7 @@ static int net_lookup_dc(int argc, const char **argv)
        struct in_addr addr;
        char *pdc_str = NULL;
        const char *domain=opt_target_workgroup;
+       char *sitename = NULL;
        int count, i;
 
        if (argc > 0)
@@ -165,10 +171,13 @@ static int net_lookup_dc(int argc, const char **argv)
        asprintf(&pdc_str, "%s", inet_ntoa(addr));
        d_printf("%s\n", pdc_str);
 
-       if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, &ip_list, &count, False))) {
+       sitename = sitename_fetch();
+       if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, sitename, &ip_list, &count, False))) {
                SAFE_FREE(pdc_str);
+               SAFE_FREE(sitename);
                return 0;
        }
+       SAFE_FREE(sitename);
        for (i=0;i<count;i++) {
                char *dc_str = inet_ntoa(ip_list[i].ip);
                if (!strequal(pdc_str, dc_str))