summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2007-01-18 09:58:57 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:17:16 -0500
commite9c294b926c0b831fd936194342ec0564f935798 (patch)
tree3a418a506576d1dbfc12438608293a1e7b708989
parentfd37f98158161406229b728a7c767121a30e254f (diff)
downloadsamba-e9c294b926c0b831fd936194342ec0564f935798.tar.gz
samba-e9c294b926c0b831fd936194342ec0564f935798.tar.bz2
samba-e9c294b926c0b831fd936194342ec0564f935798.zip
r20874: We need to distinguish client sitenames per realm. We were overwriting
the stored client sitename with the sitename from each sucessfull CLDAP connection. Guenther (This used to be commit 6a13e878b5d299cb3b3d7cb33ee0d51089d9228d)
-rw-r--r--source3/libads/dns.c71
-rw-r--r--source3/libads/ldap.c10
-rw-r--r--source3/libsmb/namequery.c2
-rw-r--r--source3/libsmb/namequery_dc.c8
-rw-r--r--source3/nsswitch/winbindd_cm.c4
-rw-r--r--source3/utils/net_lookup.c6
6 files changed, 75 insertions, 26 deletions
diff --git a/source3/libads/dns.c b/source3/libads/dns.c
index bd280fea62..b405d29d96 100644
--- a/source3/libads/dns.c
+++ b/source3/libads/dns.c
@@ -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;
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 2ceae4d957..4802f79d3e 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -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));
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 1f32d3bc37..cbd94ff567 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -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)) {
diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c
index a240510b77..110b9986b7 100644
--- a/source3/libsmb/namequery_dc.c
+++ b/source3/libsmb/namequery_dc.c
@@ -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);
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
index c854efd9b2..2f913081e8 100644
--- a/source3/nsswitch/winbindd_cm.c
+++ b/source3/nsswitch/winbindd_cm.c
@@ -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. */
diff --git a/source3/utils/net_lookup.c b/source3/utils/net_lookup.c
index 8e223e67f3..19ba5ae7f4 100644
--- a/source3/utils/net_lookup.c
+++ b/source3/utils/net_lookup.c
@@ -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);