summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2006-08-30 04:40:03 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:38:59 -0500
commit2abab7ee6d04a62017d99578c274244a1cdd27b2 (patch)
treecaba5392b1f1ba24f7af17b94cb2d85f643b874b /source3
parent3bc4fd1bb9bfbd0e0efd89d47c50bf798e5a1481 (diff)
downloadsamba-2abab7ee6d04a62017d99578c274244a1cdd27b2.tar.gz
samba-2abab7ee6d04a62017d99578c274244a1cdd27b2.tar.bz2
samba-2abab7ee6d04a62017d99578c274244a1cdd27b2.zip
r17928: Implement the basic store for CLDAP sitename
support when looking up DC's. On every CLDAP call store the returned client sitename (if present, delete store if not) in gencache with infinate timeout. On AD DNS DC lookup, try looking for sitename DC's first, only try generic if sitename DNS lookup failed. I still haven't figured out yet how to ensure we fetch the sitename with a CLDAP query before doing the generic DC list lookup. This code is difficult to understand. I'll do some experiments and backtraces tomorrow to try and work out where to force a CLDAP site query first. Jeremy. (This used to be commit ab3f0c5b1e9c5fd192c5514cbe9451b938f9cd5d)
Diffstat (limited to 'source3')
-rw-r--r--source3/include/ads_cldap.h4
-rw-r--r--source3/lib/gencache.c2
-rw-r--r--source3/libads/cldap.c4
-rw-r--r--source3/libads/dns.c99
-rw-r--r--source3/libads/ldap.c3
-rw-r--r--source3/libsmb/namequery.c6
-rw-r--r--source3/utils/net_ads.c4
7 files changed, 106 insertions, 16 deletions
diff --git a/source3/include/ads_cldap.h b/source3/include/ads_cldap.h
index 65feb072e0..e5df892a40 100644
--- a/source3/include/ads_cldap.h
+++ b/source3/include/ads_cldap.h
@@ -35,8 +35,8 @@ struct cldap_netlogon_reply {
char unk[MAX_DNS_LABEL];
char user_name[MAX_DNS_LABEL];
- char site_name[MAX_DNS_LABEL];
- char site_name_2[MAX_DNS_LABEL];
+ char server_site_name[MAX_DNS_LABEL];
+ char client_site_name[MAX_DNS_LABEL];
uint32 version;
uint16 lmnt_token;
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index d4582b34f9..fe038011d8 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -431,5 +431,3 @@ void gencache_unlock_entry( const char *key )
tdb_unlock_bystring(cache, key);
return;
}
-
-
diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c
index 2e96270e90..3a6083558f 100644
--- a/source3/libads/cldap.c
+++ b/source3/libads/cldap.c
@@ -260,8 +260,8 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply)
*reply->user_name = 0;
}
- p += pull_netlogon_string(reply->site_name, p, (const char *)os3.data);
- p += pull_netlogon_string(reply->site_name_2, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->server_site_name, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->client_site_name, p, (const char *)os3.data);
reply->version = IVAL(p, 0);
reply->lmnt_token = SVAL(p, 4);
diff --git a/source3/libads/dns.c b/source3/libads/dns.c
index 8cc68a0c14..937cd9213f 100644
--- a/source3/libads/dns.c
+++ b/source3/libads/dns.c
@@ -565,16 +565,105 @@ NTSTATUS ads_dns_lookup_ns( TALLOC_CTX *ctx, const char *dnsdomain, struct dns_r
return NT_STATUS_OK;
}
+/****************************************************************************
+ Store and fetch the AD client sitename.
+****************************************************************************/
-/********************************************************************
-********************************************************************/
+#define SITENAME_KEY "AD_SITENAME"
+
+/****************************************************************************
+ Store the AD client sitename.
+ We store indefinately as every new CLDAP query will re-write this.
+****************************************************************************/
-NTSTATUS ads_dns_query_dcs( TALLOC_CTX *ctx, const char *domain, struct dns_rr_srv **dclist, int *numdcs )
+BOOL sitename_store(const char *sitename)
{
- pstring name;
+ time_t expire;
+ BOOL ret = False;
+
+ if ( !sitename || (sitename && !*sitename)) {
+ DEBUG(2,("sitename_store: deleting empty sitename!\n"));
+ return gencache_del(SITENAME_KEY);
+ }
+
+ if (!gencache_init()) {
+ return False;
+ }
+
+ expire = get_time_t_max(); /* Store indefinately. */
+
+ DEBUG(10,("sitename_store: sitename = [%s], expire = [%u]\n",
+ sitename, (unsigned int)expire ));
+
+ ret = gencache_set( SITENAME_KEY, sitename, expire );
+ return ret;
+}
- snprintf( name, sizeof(name), "_ldap._tcp.dc._msdcs.%s", domain );
+/****************************************************************************
+ Fetch the AD client sitename.
+ Caller must free.
+****************************************************************************/
+static char *sitename_fetch(void)
+{
+ char *sitename = NULL;
+ time_t timeout;
+ BOOL ret = False;
+
+ if (!gencache_init()) {
+ return False;
+ }
+
+ ret = gencache_get( SITENAME_KEY, &sitename, &timeout );
+ if ( !ret ) {
+ DEBUG(5,("sitename_fetch: No stored sitename\n"));
+ } else {
+ DEBUG(5,("sitename_fetch: Returning sitename \"%s\"\n",
+ sitename ));
+ }
+ return sitename;
+}
+
+/********************************************************************
+ Query with optional sitename.
+********************************************************************/
+
+NTSTATUS ads_dns_query_dcs_internal(TALLOC_CTX *ctx,
+ const char *domain,
+ const char *sitename,
+ struct dns_rr_srv **dclist,
+ int *numdcs )
+{
+ char *name;
+ if (sitename) {
+ name = talloc_asprintf(ctx, "_ldap._tcp.%s._sites.dc._msdcs.%s",
+ sitename, domain );
+ } else {
+ name = talloc_asprintf(ctx, "_ldap._tcp.dc._msdcs.%s", domain );
+ }
+ if (!name) {
+ return NT_STATUS_NO_MEMORY;
+ }
return ads_dns_lookup_srv( ctx, name, dclist, numdcs );
}
+/********************************************************************
+ Query for AD DC's. Transparently use sitename.
+********************************************************************/
+
+NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx,
+ const char *domain,
+ struct dns_rr_srv **dclist,
+ int *numdcs )
+{
+ NTSTATUS status;
+ char *sitename = sitename_fetch();
+
+ status = ads_dns_query_dcs_internal(ctx, domain, sitename, dclist, numdcs);
+ if (sitename && !NT_STATUS_IS_OK(status)) {
+ /* Sitename DNS query may have failed. Try without. */
+ status = ads_dns_query_dcs_internal(ctx, domain, NULL, dclist, numdcs);
+ }
+ SAFE_FREE(sitename);
+ return status;
+}
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index c6d1fc9c60..c943558bd3 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -173,6 +173,9 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server )
saf_store( ads->server.workgroup, server );
+ /* Store our site name. */
+ sitename_store( cldap_reply.client_site_name );
+
return True;
}
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index dcb7dbf070..4c361a3716 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -111,7 +111,6 @@ char *saf_fetch( const char *domain )
return server;
}
-
/****************************************************************************
Generate a random trn_id.
****************************************************************************/
@@ -1044,6 +1043,7 @@ static BOOL resolve_ads(const char *name, int name_type,
status = ads_dns_query_dcs( ctx, name, &dcs, &numdcs );
if ( !NT_STATUS_IS_OK( status ) ) {
+ talloc_destroy(ctx);
return False;
}
@@ -1053,6 +1053,7 @@ static BOOL resolve_ads(const char *name, int name_type,
if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) == NULL ) {
DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numaddrs ));
+ talloc_destroy(ctx);
return False;
}
@@ -1096,8 +1097,7 @@ static BOOL resolve_ads(const char *name, int name_type,
(*return_count)++;
}
- TALLOC_FREE( dcs );
-
+ talloc_destroy(ctx);
return True;
}
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index e6ad7c21b3..83e2114135 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -135,8 +135,8 @@ static int net_ads_cldap_netlogon(ADS_STRUCT *ads)
if (*reply.unk) printf("Unk:\t\t\t%s\n", reply.unk);
if (*reply.user_name) printf("User name:\t%s\n", reply.user_name);
- printf("Site Name:\t\t%s\n", reply.site_name);
- printf("Site Name (2):\t\t%s\n", reply.site_name_2);
+ printf("Server Site Name :\t\t%s\n", reply.server_site_name);
+ printf("Client Site Name (2):\t\t%s\n", reply.client_site_name);
d_printf("NT Version: %d\n", reply.version);
d_printf("LMNT Token: %.2x\n", reply.lmnt_token);