From ee61568be6bcb217d106c08ec915775c8476ed56 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 14 Sep 2010 17:36:23 +1000 Subject: s4-winbind: use finddcs_cldap() in winbind Pair-Programmed-With: Andrew Bartlett --- source4/winbind/wb_dom_info.c | 44 ++++++++++++++++++++++++++--------- source4/winbind/wb_dom_info_trusted.c | 28 +++++++++++----------- source4/winbind/wb_init_domain.c | 12 ++-------- source4/winbind/wb_server.h | 4 +--- source4/winbind/wb_sid2domain.c | 4 +++- 5 files changed, 52 insertions(+), 40 deletions(-) diff --git a/source4/winbind/wb_dom_info.c b/source4/winbind/wb_dom_info.c index e000d843cc..509acb1d4a 100644 --- a/source4/winbind/wb_dom_info.c +++ b/source4/winbind/wb_dom_info.c @@ -28,6 +28,7 @@ #include "smbd/service_task.h" #include "libcli/finddcs.h" #include "param/param.h" +#include "libcli/libcli.h" struct get_dom_info_state { struct composite_context *ctx; @@ -39,12 +40,15 @@ static void get_dom_info_recv_addrs(struct tevent_req *req); struct composite_context *wb_get_dom_info_send(TALLOC_CTX *mem_ctx, struct wbsrv_service *service, const char *domain_name, + const char *dns_domain_name, const struct dom_sid *sid) { struct composite_context *result; struct tevent_req *req; struct get_dom_info_state *state; struct dom_sid *dom_sid; + struct finddcs finddcs_io; + result = composite_create(mem_ctx, service->task->event_ctx); if (result == NULL) goto failed; @@ -65,13 +69,17 @@ struct composite_context *wb_get_dom_info_send(TALLOC_CTX *mem_ctx, dom_sid = dom_sid_dup(mem_ctx, sid); if (dom_sid == NULL) goto failed; - req = finddcs_send(mem_ctx, lpcfg_netbios_name(service->task->lp_ctx), - lpcfg_nbt_port(service->task->lp_ctx), - domain_name, NBT_NAME_LOGON, - dom_sid, - lpcfg_resolve_context(service->task->lp_ctx), - service->task->event_ctx, - service->task->msg_ctx); + ZERO_STRUCT(finddcs_io); + finddcs_io.in.dns_domain_name = dns_domain_name; + finddcs_io.in.domain_sid = dom_sid; + finddcs_io.in.minimum_dc_flags = NBT_SERVER_LDAP | NBT_SERVER_DS; + if (service->sec_channel_type == SEC_CHAN_RODC) { + finddcs_io.in.minimum_dc_flags |= NBT_SERVER_WRITABLE; + } + + req = finddcs_cldap_send(mem_ctx, &finddcs_io, + lpcfg_resolve_context(service->task->lp_ctx), + service->task->event_ctx); if (req == NULL) goto failed; tevent_req_set_callback(req, get_dom_info_recv_addrs, state); @@ -86,12 +94,25 @@ struct composite_context *wb_get_dom_info_send(TALLOC_CTX *mem_ctx, static void get_dom_info_recv_addrs(struct tevent_req *req) { struct get_dom_info_state *state = tevent_req_callback_data(req, struct get_dom_info_state); + struct finddcs finddcs_io; + + state->info->dc = talloc(state, struct nbt_dc_name); - state->ctx->status = finddcs_recv(req, state->info, - &state->info->num_dcs, - &state->info->dcs); + state->ctx->status = finddcs_cldap_recv(req, state->info, &finddcs_io); if (!composite_is_ok(state->ctx)) return; + if (finddcs_io.out.netlogon.ntver != NETLOGON_NT_VERSION_5EX) { + /* the finddcs code should have mapped the response to + the type we want */ + DEBUG(0,(__location__ ": unexpected ntver 0x%08x in finddcs response\n", + finddcs_io.out.netlogon.ntver)); + state->ctx->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + if (!composite_is_ok(state->ctx)) return; + } + + state->info->dc->address = finddcs_io.out.address; + state->info->dc->name = finddcs_io.out.netlogon.data.nt5_ex.pdc_dns_name; + composite_done(state->ctx); } @@ -113,10 +134,11 @@ NTSTATUS wb_get_dom_info_recv(struct composite_context *ctx, NTSTATUS wb_get_dom_info(TALLOC_CTX *mem_ctx, struct wbsrv_service *service, const char *domain_name, + const char *dns_domain_name, const struct dom_sid *sid, struct wb_dom_info **result) { struct composite_context *ctx = - wb_get_dom_info_send(mem_ctx, service, domain_name, sid); + wb_get_dom_info_send(mem_ctx, service, domain_name, dns_domain_name, sid); return wb_get_dom_info_recv(ctx, mem_ctx, result); } diff --git a/source4/winbind/wb_dom_info_trusted.c b/source4/winbind/wb_dom_info_trusted.c index 8086714a6e..af887c854c 100644 --- a/source4/winbind/wb_dom_info_trusted.c +++ b/source4/winbind/wb_dom_info_trusted.c @@ -141,17 +141,16 @@ static void trusted_dom_info_recv_dsr(struct tevent_req *subreq) } /* Hey, that was easy! */ - state->info->num_dcs = 1; - state->info->dcs = talloc(state->info, struct nbt_dc_name); - state->info->dcs[0].name = talloc_steal(state->info, + state->info->dc = talloc(state->info, struct nbt_dc_name); + state->info->dc->name = talloc_steal(state->info, (*state->d.out.info)->dc_unc); - if (*state->info->dcs[0].name == '\\') state->info->dcs[0].name++; - if (*state->info->dcs[0].name == '\\') state->info->dcs[0].name++; + if (*state->info->dc->name == '\\') state->info->dc->name++; + if (*state->info->dc->name == '\\') state->info->dc->name++; - state->info->dcs[0].address = talloc_steal(state->info, + state->info->dc->address = talloc_steal(state->info, (*state->d.out.info)->dc_address); - if (*state->info->dcs[0].address == '\\') state->info->dcs[0].address++; - if (*state->info->dcs[0].address == '\\') state->info->dcs[0].address++; + if (*state->info->dc->address == '\\') state->info->dc->address++; + if (*state->info->dc->address == '\\') state->info->dc->address++; state->info->dns_name = talloc_steal(state->info, (*state->d.out.info)->domain_name); @@ -191,14 +190,13 @@ static void trusted_dom_info_recv_dcname(struct tevent_req *subreq) if (!composite_is_ok(state->ctx)) return; /* Hey, that was easy! */ - state->info->num_dcs = 1; - state->info->dcs = talloc(state->info, struct nbt_dc_name); - state->info->dcs[0].name = talloc_steal(state->info, + state->info->dc = talloc(state->info, struct nbt_dc_name); + state->info->dc->name = talloc_steal(state->info, *(state->g.out.dcname)); - if (*state->info->dcs[0].name == '\\') state->info->dcs[0].name++; - if (*state->info->dcs[0].name == '\\') state->info->dcs[0].name++; + if (*state->info->dc->name == '\\') state->info->dc->name++; + if (*state->info->dc->name == '\\') state->info->dc->name++; - make_nbt_name(&name, state->info->dcs[0].name, 0x20); + make_nbt_name(&name, state->info->dc->name, 0x20); ctx = resolve_name_send(lpcfg_resolve_context(state->service->task->lp_ctx), state, &name, state->service->task->event_ctx); @@ -213,7 +211,7 @@ static void trusted_dom_info_recv_dcaddr(struct composite_context *ctx) struct trusted_dom_info_state); state->ctx->status = resolve_name_recv(ctx, state->info, - &state->info->dcs[0].address); + &state->info->dc->address); if (!composite_is_ok(state->ctx)) return; composite_done(state->ctx); diff --git a/source4/winbind/wb_init_domain.c b/source4/winbind/wb_init_domain.c index f07d17a64e..50a6af05fd 100644 --- a/source4/winbind/wb_init_domain.c +++ b/source4/winbind/wb_init_domain.c @@ -128,16 +128,8 @@ struct composite_context *wb_init_domain_send(TALLOC_CTX *mem_ctx, state->domain->info = talloc_reference(state->domain, dom_info); if (state->domain->info == NULL) goto failed; - /* Caller should check, but to be safe: */ - if (dom_info->num_dcs < 1) { - goto failed; - } - - /* For now, we just pick the first. The next step will be to - * walk the entire list. Also need to fix finddcs() to return - * the entire list */ - state->domain->dc_name = dom_info->dcs[0].name; - state->domain->dc_address = dom_info->dcs[0].address; + state->domain->dc_name = dom_info->dc->name; + state->domain->dc_address = dom_info->dc->address; state->domain->libnet_ctx = libnet_context_init(service->task->event_ctx, service->task->lp_ctx); diff --git a/source4/winbind/wb_server.h b/source4/winbind/wb_server.h index 7fc778a97b..ddb77d05f6 100644 --- a/source4/winbind/wb_server.h +++ b/source4/winbind/wb_server.h @@ -48,9 +48,7 @@ struct wb_dom_info { const char *name; const char *dns_name; const struct dom_sid *sid; - - int num_dcs; - struct nbt_dc_name *dcs; + struct nbt_dc_name *dc; }; struct wbsrv_domain { diff --git a/source4/winbind/wb_sid2domain.c b/source4/winbind/wb_sid2domain.c index b77044ee80..c1cf987131 100644 --- a/source4/winbind/wb_sid2domain.c +++ b/source4/winbind/wb_sid2domain.c @@ -84,7 +84,9 @@ struct composite_context *wb_sid2domain_send(TALLOC_CTX *mem_ctx, if (dom_sid_equal(service->primary_sid, sid) || dom_sid_in_domain(service->primary_sid, sid)) { - ctx = wb_get_dom_info_send(state, service, lpcfg_workgroup(service->task->lp_ctx), + ctx = wb_get_dom_info_send(state, service, + lpcfg_workgroup(service->task->lp_ctx), + lpcfg_realm(service->task->lp_ctx), service->primary_sid); if (ctx == NULL) goto failed; ctx->async.fn = sid2domain_recv_dom_info; -- cgit