s4-winbind: use finddcs_cldap() in winbind
authorAndrew Tridgell <tridge@samba.org>
Tue, 14 Sep 2010 07:36:23 +0000 (17:36 +1000)
committerAndrew Tridgell <tridge@samba.org>
Wed, 15 Sep 2010 05:39:35 +0000 (15:39 +1000)
Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>

source4/winbind/wb_dom_info.c
source4/winbind/wb_dom_info_trusted.c
source4/winbind/wb_init_domain.c
source4/winbind/wb_server.h
source4/winbind/wb_sid2domain.c

index e000d843cc8bab5da029851b82518856b02dc41c..509acb1d4af6688db5817d4a04934796ed4b4181 100644 (file)
@@ -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);
 }
index 8086714a6edbf5f9cf46aba4d25288fe0111272e..af887c854c750c265aec3bce6694ffd6c2b167d2 100644 (file)
@@ -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);
index f07d17a64e209db67d2900689bbfbabf8841ee74..50a6af05fd6e48c0580fca659ec0b964a19d7f8a 100644 (file)
@@ -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);
index 7fc778a97bf398b28490ada6aa829d6b88fe6ecf..ddb77d05f66afdd40d1b8c255f63dd2f98a69036 100644 (file)
@@ -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 {
index b77044ee8042ee95290b691f2666bcbd4690d846..c1cf98713183065426bd05447ed9d6f973a06a18 100644 (file)
@@ -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;