summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2008-05-07 21:25:05 +0200
committerGünther Deschner <gd@samba.org>2008-05-09 14:59:19 +0200
commit5e24d83e417931409eaa66a5e09dcd3b12ad162f (patch)
tree9c8ec5ce1b392885531aa1f8e36a35fb30ea6dc8 /source3/libsmb
parent5d7a60afd8ab7e84eef6b5726e162d9b861df7b9 (diff)
downloadsamba-5e24d83e417931409eaa66a5e09dcd3b12ad162f.tar.gz
samba-5e24d83e417931409eaa66a5e09dcd3b12ad162f.tar.bz2
samba-5e24d83e417931409eaa66a5e09dcd3b12ad162f.zip
dsgetdcname: fix gencache store for dsgetdcname().
While storing always a type 29 reply structure in gencache, we are now able to deliver correct data according to return flags such as DS_RETURN_FLAT_NAME and DS_RETURN_DNS_NAME out of the cached data from gencache. Guenther (This used to be commit c67b6dc0ca866781043e443177d550e23b83ae36)
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/dsgetdcname.c204
1 files changed, 184 insertions, 20 deletions
diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
index 4cafc71ff2..208daf334c 100644
--- a/source3/libsmb/dsgetdcname.c
+++ b/source3/libsmb/dsgetdcname.c
@@ -32,6 +32,13 @@ struct ip_service_name {
const char *hostname;
};
+static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx,
+ uint32_t flags,
+ struct sockaddr_storage *ss,
+ uint32_t nt_version,
+ union nbt_cldap_netlogon *r,
+ struct netr_DsRGetDCNameInfo **info);
+
/****************************************************************
****************************************************************/
@@ -148,13 +155,11 @@ static NTSTATUS dsgetdcname_cache_delete(TALLOC_CTX *mem_ctx,
static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx,
const char *domain_name,
- struct netr_DsRGetDCNameInfo *info)
+ const DATA_BLOB *blob)
{
time_t expire_time;
char *key;
bool ret = false;
- DATA_BLOB blob;
- enum ndr_err_code ndr_err;
if (!gencache_init()) {
return NT_STATUS_INTERNAL_DB_ERROR;
@@ -167,19 +172,11 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx,
expire_time = time(NULL) + DSGETDCNAME_CACHE_TTL;
- ndr_err = ndr_push_struct_blob(&blob, mem_ctx, info,
- (ndr_push_flags_fn_t)ndr_push_netr_DsRGetDCNameInfo);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- return ndr_map_error2ntstatus(ndr_err);
- }
-
if (gencache_lock_entry(key) != 0) {
- data_blob_free(&blob);
return NT_STATUS_LOCK_NOT_GRANTED;
}
- ret = gencache_set_data_blob(key, &blob, expire_time);
- data_blob_free(&blob);
+ ret = gencache_set_data_blob(key, blob, expire_time);
gencache_unlock_entry(key);
@@ -189,6 +186,149 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx,
/****************************************************************
****************************************************************/
+#define SET_STRING(x) \
+ talloc_strdup(mem_ctx, x); \
+ NT_STATUS_HAVE_NO_MEMORY(x);
+
+static NTSTATUS map_logon29_from_cldap_reply(TALLOC_CTX *mem_ctx,
+ uint32_t flags,
+ struct sockaddr_storage *ss,
+ uint32_t nt_version,
+ union nbt_cldap_netlogon *r,
+ struct nbt_cldap_netlogon_29 *p)
+{
+ char addr[INET6_ADDRSTRLEN];
+
+ ZERO_STRUCTP(p);
+
+ print_sockaddr(addr, sizeof(addr), ss);
+ p->dc_sock_addr_size = 0x10;
+ p->dc_sock_addr.sa_family = 2;
+ p->dc_sock_addr.pdc_ip = talloc_strdup(mem_ctx, addr);
+
+ switch (nt_version & 0x000000ff) {
+ case 0:
+ return NT_STATUS_INVALID_PARAMETER;
+ case 1:
+ p->pdc_name = SET_STRING(r->logon1.pdc_name);
+ p->domain = SET_STRING(r->logon1.domain_name);
+
+ if (flags & DS_PDC_REQUIRED) {
+ p->server_type = NBT_SERVER_WRITABLE |
+ NBT_SERVER_PDC;
+ }
+ break;
+ case 2:
+ case 3:
+ p->pdc_name = SET_STRING(r->logon3.pdc_name);
+ p->domain = SET_STRING(r->logon3.domain_name);
+ p->pdc_dns_name = SET_STRING(r->logon3.pdc_dns_name);
+ p->dns_domain = SET_STRING(r->logon3.dns_domain);
+ p->server_type = r->logon3.server_type;
+ p->forest = SET_STRING(r->logon3.forest);
+ p->domain_uuid = r->logon3.domain_uuid;
+
+ break;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ p->pdc_name = SET_STRING(r->logon5.pdc_name);
+ p->domain = SET_STRING(r->logon5.domain);
+ p->pdc_dns_name = SET_STRING(r->logon5.pdc_dns_name);
+ p->dns_domain = SET_STRING(r->logon5.dns_domain);
+ p->server_type = r->logon5.server_type;
+ p->forest = SET_STRING(r->logon5.forest);
+ p->domain_uuid = r->logon5.domain_uuid;
+ p->server_site = SET_STRING(r->logon5.server_site);
+ p->client_site = SET_STRING(r->logon5.client_site);
+
+ break;
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ p->pdc_name = SET_STRING(r->logon13.pdc_name);
+ p->domain = SET_STRING(r->logon13.domain);
+ p->pdc_dns_name = SET_STRING(r->logon13.pdc_dns_name);
+ p->dns_domain = SET_STRING(r->logon13.dns_domain);
+ p->server_type = r->logon13.server_type;
+ p->forest = SET_STRING(r->logon13.forest);
+ p->domain_uuid = r->logon13.domain_uuid;
+ p->server_site = SET_STRING(r->logon13.server_site);
+ p->client_site = SET_STRING(r->logon13.client_site);
+
+ break;
+ default:
+ p->pdc_name = SET_STRING(r->logon29.pdc_name);
+ p->domain = SET_STRING(r->logon29.domain);
+ p->pdc_dns_name = SET_STRING(r->logon29.pdc_dns_name);
+ p->dns_domain = SET_STRING(r->logon29.dns_domain);
+ p->server_type = r->logon29.server_type;
+ p->forest = SET_STRING(r->logon29.forest);
+ p->domain_uuid = r->logon29.domain_uuid;
+ p->server_site = SET_STRING(r->logon29.server_site);
+ p->client_site = SET_STRING(r->logon29.client_site);
+ p->next_closest_site = SET_STRING(r->logon29.next_closest_site);
+
+ break;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS store_cldap_reply(TALLOC_CTX *mem_ctx,
+ uint32_t flags,
+ struct sockaddr_storage *ss,
+ uint32_t nt_version,
+ union nbt_cldap_netlogon *r)
+{
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+ NTSTATUS status;
+ struct nbt_cldap_netlogon_29 logon29;
+
+ status = map_logon29_from_cldap_reply(mem_ctx, flags, ss,
+ nt_version, r, &logon29);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &logon29,
+ (ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon_29);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return ndr_map_error2ntstatus(ndr_err);
+ }
+
+ if (logon29.domain) {
+ status = dsgetdcname_cache_store(mem_ctx, logon29.domain, &blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+ }
+ if (logon29.dns_domain) {
+ status = dsgetdcname_cache_store(mem_ctx, logon29.dns_domain, &blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+ }
+
+ done:
+ data_blob_free(&blob);
+
+ return status;
+}
+
+/****************************************************************
+****************************************************************/
+
static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx,
const char *domain_name,
struct GUID *domain_guid,
@@ -290,6 +430,9 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx,
DATA_BLOB blob;
enum ndr_err_code ndr_err;
struct netr_DsRGetDCNameInfo *info;
+ union nbt_cldap_netlogon p;
+ struct nbt_cldap_netlogon_29 r;
+ NTSTATUS status;
if (!gencache_init()) {
return NT_STATUS_INTERNAL_DB_ERROR;
@@ -309,8 +452,8 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
- ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, info,
- (ndr_pull_flags_fn_t)ndr_pull_netr_DsRGetDCNameInfo);
+ ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
+ (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon_29);
data_blob_free(&blob);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -318,6 +461,15 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx,
return ndr_map_error2ntstatus(ndr_err);
}
+ p.logon29 = r;
+
+ status = make_dc_info_from_cldap_reply(mem_ctx, flags, NULL,
+ NETLOGON_VERSION_WITH_CLOSEST_SITE,
+ &p, &info);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
if (DEBUGLEVEL >= 10) {
NDR_PRINT_DEBUG(netr_DsRGetDCNameInfo, info);
}
@@ -869,6 +1021,7 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx,
uint32_t nt_version = NETLOGON_VERSION_5 |
NETLOGON_VERSION_5EX;
uint32_t ret_flags = 0;
+ NTSTATUS status;
nt_version |= map_ds_flags_to_nt_version(flags);
@@ -896,8 +1049,14 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx,
return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
}
- return make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss,
- nt_version, r, info);
+ status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss,
+ nt_version, r, info);
+ if (NT_STATUS_IS_OK(status)) {
+ return store_cldap_reply(mem_ctx, flags, &dclist[i].ss,
+ nt_version, r);
+ }
+
+ return status;
}
/****************************************************************
@@ -940,7 +1099,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx,
struct sockaddr_storage ss;
struct ip_service ip_list;
enum nbt_name_type name_type = NBT_NAME_LOGON;
-
+ NTSTATUS status;
int i;
const char *dc_name = NULL;
fstring tmp_dc_name;
@@ -1019,8 +1178,14 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx,
make_reply:
- return make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss,
- nt_version, r, info);
+ status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss,
+ nt_version, r, info);
+ if (NT_STATUS_IS_OK(status)) {
+ return store_cldap_reply(mem_ctx, flags, &dclist[i].ss,
+ nt_version, r);
+ }
+
+ return status;
}
/****************************************************************
@@ -1129,7 +1294,6 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx,
&myinfo);
if (NT_STATUS_IS_OK(status)) {
- dsgetdcname_cache_store(mem_ctx, domain_name, myinfo);
*info = myinfo;
}