{
char *key;
- if (!gencache_init()) {
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
-
key = dsgetdcname_cache_key(mem_ctx, domain_name);
if (!key) {
return NT_STATUS_NO_MEMORY;
char *key;
bool ret = false;
- if (!gencache_init()) {
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
-
key = dsgetdcname_cache_key(mem_ctx, domain_name);
if (!key) {
return NT_STATUS_NO_MEMORY;
expire_time = time(NULL) + DSGETDCNAME_CACHE_TTL;
- if (gencache_lock_entry(key) != 0) {
- return NT_STATUS_LOCK_NOT_GRANTED;
- }
-
ret = gencache_set_data_blob(key, blob, expire_time);
- gencache_unlock_entry(key);
-
return ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
}
}
+ 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(struct netlogon_samlogon_response *r,
uint32_t nt_version)
{
case 3:
case 18:
case 19:
- return r->nt5.server_type;
+ return r->data.nt5.server_type;
case 4:
case 5:
case 6:
case 7:
- return r->nt5_ex.server_type;
+ return r->data.nt5_ex.server_type;
case 8:
case 9:
case 10:
case 13:
case 14:
case 15:
- return r->nt5_ex.server_type;
+ return r->data.nt5_ex.server_type;
case 20:
case 21:
case 22:
case 26:
case 27:
case 28:
- return r->nt5_ex.server_type;
+ return r->data.nt5_ex.server_type;
case 29:
case 30:
case 31:
- return r->nt5_ex.server_type;
+ return r->data.nt5_ex.server_type;
default:
return 0;
}
/****************************************************************
****************************************************************/
-#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)
struct GUID *domain_guid,
uint32_t flags,
const char *site_name,
- struct netr_DsRGetDCNameInfo **info_p,
- bool *expired)
+ struct netr_DsRGetDCNameInfo **info_p)
{
char *key;
DATA_BLOB blob;
struct NETLOGON_SAM_LOGON_RESPONSE_EX r;
NTSTATUS status;
- if (!gencache_init()) {
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
-
key = dsgetdcname_cache_key(mem_ctx, domain_name);
if (!key) {
return NT_STATUS_NO_MEMORY;
}
- if (!gencache_get_data_blob(key, &blob, expired)) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ if (!gencache_get_data_blob(key, &blob, NULL)) {
+ return NT_STATUS_NOT_FOUND;
}
info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo);
struct netr_DsRGetDCNameInfo **info)
{
NTSTATUS status;
- bool expired = false;
status = dsgetdcname_cache_fetch(mem_ctx, domain_name, domain_guid,
- flags, site_name, info, &expired);
- if (!NT_STATUS_IS_OK(status)) {
+ flags, site_name, info);
+ if (!NT_STATUS_IS_OK(status)
+ && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
DEBUG(10,("dsgetdcname_cached: cache fetch failed with: %s\n",
nt_errstr(status)));
return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
return status;
}
- if (expired) {
- status = dsgetdcname_cache_refresh(mem_ctx, msg_ctx,
- domain_name,
- domain_guid, flags,
- site_name, *info);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+ 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;
}
struct ip_service_name *r = &dclist[count];
- r->port = dcs[count].port;
- r->hostname = dcs[count].hostname;
+ r->port = dcs[i].port;
+ r->hostname = dcs[i].hostname;
/* If we don't have an IP list for a name, lookup it up */
if (!dcs[i].ss_s) {
- interpret_string_addr(&r->ss, dcs[i].hostname, 0);
+ interpret_string_addr_prefer_ipv4(&r->ss,
+ dcs[i].hostname, 0);
i++;
j = 0;
} else {
* back to netbios lookups is that our DNS server doesn't know
* anything about the DC's -- jerry */
- if (!is_zero_addr(&r->ss)) {
+ if (!is_zero_addr((struct sockaddr *)(void *)&r->ss)) {
count++;
continue;
}
}
status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss,
- &r->nt5_ex, info);
+ &r->data.nt5_ex, info);
if (NT_STATUS_IS_OK(status)) {
return store_cldap_reply(mem_ctx, flags, &dclist[i].ss,
- nt_version, &r->nt5_ex);
+ nt_version, &r->data.nt5_ex);
}
return status;
ip_list.ss = dclist[i].ss;
ip_list.port = 0;
- if (!interpret_string_addr(&ss, dclist[i].hostname, AI_NUMERICHOST)) {
+ if (!interpret_string_addr_prefer_ipv4(&ss, dclist[i].hostname, AI_NUMERICHOST)) {
return NT_STATUS_UNSUCCESSFUL;
}
logon1.domain = talloc_strdup_upper(mem_ctx, domain_name);
NT_STATUS_HAVE_NO_MEMORY(logon1.domain);
- r->nt4 = logon1;
+ r->data.nt4 = logon1;
r->ntver = nt_version;
+ map_netlogon_samlogon_response(r);
+
namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list);
goto make_reply;
make_reply:
status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss,
- &r->nt5_ex, info);
+ &r->data.nt5_ex, info);
if (NT_STATUS_IS_OK(status) && store_cache) {
return store_cldap_reply(mem_ctx, flags, &dclist[i].ss,
- nt_version, &r->nt5_ex);
+ nt_version, &r->data.nt5_ex);
}
return status;
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",
status = dsgetdcname_cached(mem_ctx, msg_ctx, domain_name, domain_guid,
flags, query_site, &myinfo);
if (NT_STATUS_IS_OK(status)) {
- *info = myinfo;
goto done;
}
domain_guid, flags, query_site,
&myinfo);
- if (NT_STATUS_IS_OK(status)) {
- *info = myinfo;
- }
-
done:
SAFE_FREE(query_site);
- return status;
+ if (!NT_STATUS_IS_OK(status)) {
+ if (!first) {
+ *info = first_info;
+ return NT_STATUS_OK;
+ }
+ 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;
}