ZERO_STRUCTP(p);
print_sockaddr(addr, sizeof(addr), ss);
- p->dc_sock_addr_size = 0x10;
- p->dc_sock_addr.sa_family = 2;
+
+ /* FIXME */
+ p->dc_sock_addr_size = 0x10; /* the w32 winsock addr size */
+ p->dc_sock_addr.family = 2; /* AF_INET */
p->dc_sock_addr.pdc_ip = talloc_strdup(mem_ctx, addr);
switch (nt_version & 0x0000001f) {
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
+ if (logon29.client_site) {
+ sitename_store(logon29.domain, logon29.client_site);
+ }
}
if (logon29.dns_domain) {
status = dsgetdcname_cache_store(mem_ctx, logon29.dns_domain, &blob);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
+ if (logon29.client_site) {
+ sitename_store(logon29.dns_domain, logon29.client_site);
+ }
}
+ status = NT_STATUS_OK;
+
done:
data_blob_free(&blob);
/****************************************************************
****************************************************************/
-static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx,
- struct messaging_context *msg_ctx,
- const char *domain_name,
- struct GUID *domain_guid,
- uint32_t flags,
- const char *site_name,
- struct netr_DsRGetDCNameInfo *info)
-{
- struct netr_DsRGetDCNameInfo *dc_info;
-
- return dsgetdcname(mem_ctx,
- msg_ctx,
- domain_name,
- domain_guid,
- site_name,
- flags | DS_FORCE_REDISCOVERY,
- &dc_info);
-}
-
-/****************************************************************
-****************************************************************/
-
static uint32_t get_cldap_reply_server_flags(union nbt_cldap_netlogon *r,
uint32_t nt_version)
{
/****************************************************************
****************************************************************/
-#define RETURN_ON_FALSE(x) if (!x) return false;
+#define RETURN_ON_FALSE(x) if (!(x)) return false;
static bool check_cldap_reply_required_flags(uint32_t ret_flags,
uint32_t req_flags)
}
if (expired) {
- status = dsgetdcname_cache_refresh(mem_ctx, msg_ctx,
- domain_name,
- domain_guid, flags,
- site_name, *info);
+ struct netr_DsRGetDCNameInfo *dc_info;
+
+ status = dsgetdcname(mem_ctx, msg_ctx, domain_name,
+ domain_guid, site_name,
+ flags | DS_FORCE_REDISCOVERY,
+ &dc_info);
+
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/****************************************************************
****************************************************************/
-static bool check_allowed_required_flags(uint32_t flags)
+static bool check_allowed_required_flags(uint32_t flags,
+ const char *site_name)
{
uint32_t return_type = flags & (DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME);
uint32_t offered_type = flags & (DS_IS_FLAT_NAME|DS_IS_DNS_NAME);
debug_dsdcinfo_flags(10, flags);
+ if ((flags & DS_TRY_NEXTCLOSEST_SITE) && site_name) {
+ return false;
+ }
+
if (return_type == (DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME)) {
return false;
}
union nbt_cldap_netlogon *r,
struct netr_DsRGetDCNameInfo **info)
{
- const char *dc_hostname, *dc_domain_name;
+ const char *dc_hostname = NULL;
+ const char *dc_domain_name = NULL;
const char *dc_address = NULL;
const char *dc_forest = NULL;
uint32_t dc_address_type = 0;
const char *dc_name = NULL;
fstring tmp_dc_name;
union nbt_cldap_netlogon *r = NULL;
+ bool store_cache = false;
uint32_t nt_version = NETLOGON_VERSION_1 |
NETLOGON_VERSION_5 |
NETLOGON_VERSION_5EX_WITH_IP;
&nt_version,
&dc_name,
&r)) {
+ store_cache = true;
namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list);
goto make_reply;
}
status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss,
nt_version, r, info);
- if (NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_IS_OK(status) && store_cache) {
return store_cldap_reply(mem_ctx, flags, &dclist[i].ss,
nt_version, r);
}
num_dcs, info);
}
+static bool is_closest_site(struct netr_DsRGetDCNameInfo *info)
+{
+ if (info->dc_flags & DS_SERVER_CLOSEST) {
+ return true;
+ }
+
+ if (!info->client_site_name) {
+ return true;
+ }
+
+ if (!info->dc_site_name) {
+ return false;
+ }
+
+ if (strcmp(info->client_site_name, info->dc_site_name) == 0) {
+ return true;
+ }
+
+ return false;
+}
+
/********************************************************************
dsgetdcname.
{
NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
struct netr_DsRGetDCNameInfo *myinfo = NULL;
+ char *query_site = NULL;
+ bool first = true;
+ struct netr_DsRGetDCNameInfo *first_info = NULL;
DEBUG(10,("dsgetdcname: domain_name: %s, "
"domain_guid: %s, site_name: %s, flags: 0x%08x\n",
*info = NULL;
- if (!check_allowed_required_flags(flags)) {
+ if (!check_allowed_required_flags(flags, site_name)) {
DEBUG(0,("invalid flags specified\n"));
return NT_STATUS_INVALID_PARAMETER;
}
+ if (!site_name) {
+ query_site = sitename_fetch(domain_name);
+ } else {
+ query_site = SMB_STRDUP(site_name);
+ }
+
if (flags & DS_FORCE_REDISCOVERY) {
goto rediscover;
}
status = dsgetdcname_cached(mem_ctx, msg_ctx, domain_name, domain_guid,
- flags, site_name, &myinfo);
+ flags, query_site, &myinfo);
if (NT_STATUS_IS_OK(status)) {
- *info = myinfo;
- return status;
+ goto done;
}
if (flags & DS_BACKGROUND_ONLY) {
- return status;
+ goto done;
}
rediscover:
status = dsgetdcname_rediscover(mem_ctx, msg_ctx, domain_name,
- domain_guid, flags, site_name,
+ domain_guid, flags, query_site,
&myinfo);
- if (NT_STATUS_IS_OK(status)) {
- *info = myinfo;
+ done:
+ SAFE_FREE(query_site);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ if (!first) {
+ *info = first_info;
+ return NT_STATUS_OK;
+ }
+ return status;
}
- return status;
+ if (!first) {
+ TALLOC_FREE(first_info);
+ } else if (!is_closest_site(myinfo)) {
+ first = false;
+ first_info = myinfo;
+ /* TODO: may use the next_closest_site here */
+ query_site = SMB_STRDUP(myinfo->client_site_name);
+ goto rediscover;
+ }
+
+ *info = myinfo;
+ return NT_STATUS_OK;
}