r20874: We need to distinguish client sitenames per realm. We were overwriting
authorGünther Deschner <gd@samba.org>
Thu, 18 Jan 2007 09:58:57 +0000 (09:58 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:17:16 +0000 (12:17 -0500)
the stored client sitename with the sitename from each sucessfull CLDAP
connection.

Guenther
(This used to be commit 6a13e878b5d299cb3b3d7cb33ee0d51089d9228d)

source3/libads/dns.c
source3/libads/ldap.c
source3/libsmb/namequery.c
source3/libsmb/namequery_dc.c
source3/nsswitch/winbindd_cm.c
source3/utils/net_lookup.c

index bd280fea62608e461403f334b73641e06146c38c..b405d29d963aaab0d26c508a0b9ed9186e76e46f 100644 (file)
@@ -577,7 +577,19 @@ NTSTATUS ads_dns_lookup_ns( TALLOC_CTX *ctx, const char *dnsdomain, struct dns_r
  Store and fetch the AD client sitename.
 ****************************************************************************/
 
-#define SITENAME_KEY   "AD_SITENAME"
+#define SITENAME_KEY   "AD_SITENAME/DOMAIN/%s"
+
+static char *sitename_key(const char *realm)
+{
+       char *keystr;
+       
+       if (asprintf(&keystr, SITENAME_KEY, strupper_static(realm)) == -1) {
+               return NULL;
+       }
+
+       return keystr;
+}
+
 
 /****************************************************************************
  Store the AD client sitename.
@@ -586,26 +598,37 @@ NTSTATUS ads_dns_lookup_ns( TALLOC_CTX *ctx, const char *dnsdomain, struct dns_r
  as this isn't a valid DNS name.
 ****************************************************************************/
 
-BOOL sitename_store(const char *sitename)
+BOOL sitename_store(const char *realm, const char *sitename)
 {
        time_t expire;
        BOOL ret = False;
+       char *key;
 
        if (!gencache_init()) {
                return False;
        }
+
+       if (!realm || (strlen(realm) == 0)) {
+               DEBUG(0,("no realm\n"));
+               return False;
+       }
        
+       key = sitename_key(realm);
+
        if (!sitename || (sitename && !*sitename)) {
                DEBUG(5,("sitename_store: deleting empty sitename!\n"));
-               return gencache_del(SITENAME_KEY);
+               ret = gencache_del(sitename_key(realm));
+               SAFE_FREE(key);
+               return ret;
        }
 
        expire = get_time_t_max(); /* Store indefinately. */
        
-       DEBUG(10,("sitename_store: sitename = [%s], expire = [%u]\n",
-               sitename, (unsigned int)expire ));
+       DEBUG(10,("sitename_store: realm = [%s], sitename = [%s], expire = [%u]\n",
+               realm, sitename, (unsigned int)expire ));
 
-       ret = gencache_set( SITENAME_KEY, sitename, expire );
+       ret = gencache_set( key, sitename, expire );
+       SAFE_FREE(key);
        return ret;
 }
 
@@ -614,22 +637,34 @@ BOOL sitename_store(const char *sitename)
  Caller must free.
 ****************************************************************************/
 
-char *sitename_fetch(void)
+char *sitename_fetch(const char *realm)
 {
        char *sitename = NULL;
        time_t timeout;
        BOOL ret = False;
+       const char *query_realm;
+       char *key;
        
        if (!gencache_init()) {
                return False;
        }
-       
-       ret = gencache_get( SITENAME_KEY, &sitename, &timeout );
+
+       if (!realm || (strlen(realm) == 0)) {
+               query_realm = lp_realm(); 
+       } else {
+               query_realm = realm;
+       }
+
+       key = sitename_key(query_realm);
+
+       ret = gencache_get( key, &sitename, &timeout );
+       SAFE_FREE(key);
        if ( !ret ) {
-               DEBUG(5,("sitename_fetch: No stored sitename\n"));
+               DEBUG(5,("sitename_fetch: No stored sitename for %s\n",
+                       query_realm));
        } else {
-               DEBUG(5,("sitename_fetch: Returning sitename \"%s\"\n",
-                       sitename ));
+               DEBUG(5,("sitename_fetch: Returning sitename for %s: \"%s\"\n",
+                       query_realm, sitename ));
        }
        return sitename;
 }
@@ -638,10 +673,18 @@ char *sitename_fetch(void)
  Did the sitename change ?
 ****************************************************************************/
 
-BOOL stored_sitename_changed(const char *sitename)
+BOOL stored_sitename_changed(const char *realm, const char *sitename)
 {
        BOOL ret = False;
-       char *new_sitename = sitename_fetch();
+
+       char *new_sitename;
+
+       if (!realm || (strlen(realm) == 0)) {
+               DEBUG(0,("no realm\n"));
+               return False;
+       }
+
+       new_sitename = sitename_fetch(realm);
 
        if (sitename && new_sitename && !strequal(sitename, new_sitename)) {
                ret = True;
index 2ceae4d957f9dd6f0e1e1e481f7c8bf9719f973e..4802f79d3e8534ed8235a052e79ca6c6aaf2931a 100644 (file)
@@ -230,7 +230,7 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server )
        SAFE_FREE(srv);
        
        /* Store our site name. */
-       sitename_store( cldap_reply.client_site_name );
+       sitename_store( cldap_reply.domain, cldap_reply.client_site_name );
 
        return True;
 }
@@ -249,7 +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();
+       char *sitename;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
 
        /* if the realm and workgroup are both empty, assume they are ours */
@@ -268,7 +268,6 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
        if (c_realm && *c_realm) 
                got_realm = True;
                   
-again:
        /* we need to try once with the realm name and fallback to the 
           netbios domain name if we fail (if netbios has not been disabled */
           
@@ -280,7 +279,6 @@ 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 ... */
                }
@@ -288,6 +286,10 @@ again:
        
        pstrcpy( realm, c_realm );
 
+       sitename = sitename_fetch(realm);
+
+ again:
+
        DEBUG(6,("ads_find_dc: looking for %s '%s'\n", 
                (got_realm ? "realm" : "domain"), realm));
 
index 1f32d3bc371e6dcfc605743c4b8fc52fc955f48c..cbd94ff5672885e749a3ecd90b9abaaec12ab4ca 100644 (file)
@@ -1311,7 +1311,7 @@ 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();
+       char *sitename = sitename_fetch(lp_realm()); /* wild guess */
        int count = 0;
 
        if (is_ipaddress(name)) {
index a240510b772a18c1e1ac4d0744b5d50f5064eb87..110b9986b7fe12a1c0efaada75ed2a6a20d0547d 100644 (file)
@@ -53,13 +53,15 @@ static BOOL ads_dc_name(const char *domain,
                        fstring srv_name)
 {
        ADS_STRUCT *ads;
-       char *sitename = sitename_fetch();
+       char *sitename;
        int i;
 
        if (!realm && strequal(domain, lp_workgroup())) {
                realm = lp_realm();
        }
 
+       sitename = sitename_fetch(realm);
+
        /* Try this 3 times then give up. */
        for( i =0 ; i < 3; i++) {
                ads = ads_init(realm, domain, NULL);
@@ -86,9 +88,9 @@ static BOOL ads_dc_name(const char *domain,
                   has changed. If so, we need to re-do the DNS query
                   to ensure we only find servers in our site. */
 
-               if (stored_sitename_changed(sitename)) {
+               if (stored_sitename_changed(realm, sitename)) {
                        SAFE_FREE(sitename);
-                       sitename = sitename_fetch();
+                       sitename = sitename_fetch(realm);
                        ads_destroy(&ads);
                        /* Ensure we don't cache the DC we just connected to. */
                        namecache_delete(realm, 0x1C);
index c854efd9b2533a41018e3b93d1bcf77208bf433f..2f913081e82e0375b6da489bc325a771f97a7b1a 100644 (file)
@@ -1031,7 +1031,7 @@ 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();
+                               char *sitename = sitename_fetch(ads->config.realm);
 
                                /* We're going to use this KDC for this realm/domain.
                                   If we are using sites, then force the krb5 libs
@@ -1120,7 +1120,7 @@ static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
 
                get_dc_name(domain->name, lp_realm(), dcname, &ip);
 
-               sitename = sitename_fetch();
+               sitename = sitename_fetch(lp_realm());
                if (sitename) {
 
                        /* Do the site-specific AD dns lookup first. */
index 8e223e67f3ba398a2f78037f48640235e3599ce5..19ba5ae7f46bf91289d23561c863c263f7d88f7d 100644 (file)
@@ -84,7 +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();
+       char *sitename;
        TALLOC_CTX *ctx;
        NTSTATUS status;
 
@@ -93,6 +93,8 @@ static int net_lookup_ldap(int argc, const char **argv)
        else
                domain = opt_target_workgroup;
 
+       sitename = sitename_fetch(domain);
+
        if ( (ctx = talloc_init("net_lookup_ldap")) == NULL ) {
                d_fprintf(stderr, "net_lookup_ldap: talloc_inti() failed!\n");
                SAFE_FREE(sitename);
@@ -171,7 +173,7 @@ static int net_lookup_dc(int argc, const char **argv)
        asprintf(&pdc_str, "%s", inet_ntoa(addr));
        d_printf("%s\n", pdc_str);
 
-       sitename = sitename_fetch();
+       sitename = sitename_fetch(domain);
        if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, sitename, &ip_list, &count, False))) {
                SAFE_FREE(pdc_str);
                SAFE_FREE(sitename);