s4:winbind: use ncalrpc for connections to ourself
authorStefan Metzmacher <metze@samba.org>
Fri, 24 Feb 2012 14:58:40 +0000 (15:58 +0100)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 29 Feb 2012 09:41:07 +0000 (10:41 +0100)
That avoids recursion if "smbd" is used as file server.

metze

source4/winbind/wb_dom_info.c
source4/winbind/wb_init_domain.c

index 5402c1cf62d11880594b97cbee83aa953908888d..e2b5defa525bbeb96397a94b0143e12ede02d08a 100644 (file)
@@ -27,6 +27,8 @@
 #include "winbind/wb_server.h"
 #include "smbd/service_task.h"
 #include "libcli/finddc.h"
+#include "lib/socket/netif.h"
+#include "param/param.h"
 
 struct get_dom_info_state {
        struct composite_context *ctx;
@@ -65,6 +67,24 @@ struct composite_context *wb_get_dom_info_send(TALLOC_CTX *mem_ctx,
        state->info->sid = dom_sid_dup(state->info, sid);
        if (state->info->sid == NULL) goto failed;
 
+       if ((lpcfg_server_role(service->task->lp_ctx) != ROLE_DOMAIN_MEMBER) &&
+           dom_sid_equal(sid, service->primary_sid) &&
+           service->sec_channel_type != SEC_CHAN_RODC) {
+               struct interface *ifaces = NULL;
+
+               load_interface_list(state, service->task->lp_ctx, &ifaces);
+
+               state->info->dc = talloc(state->info, struct nbt_dc_name);
+
+               state->info->dc->address = talloc_strdup(state->info->dc,
+                                               iface_list_n_ip(ifaces, 0));
+               state->info->dc->name = talloc_strdup(state->info->dc,
+                                               lpcfg_netbios_name(service->task->lp_ctx));
+
+               composite_done(state->ctx);
+               return result;
+       }
+
        dom_sid = dom_sid_dup(mem_ctx, sid);
        if (dom_sid == NULL) goto failed;
 
index 9d807d87764d98bcbb50c3b2342bcccf5ef56e5f..4d6177bdc7629255a377350d71453ca901440238 100644 (file)
@@ -78,23 +78,34 @@ static struct dcerpc_binding *init_domain_binding(struct init_domain_state *stat
                                                  const struct ndr_interface_table *table) 
 {
        struct dcerpc_binding *binding;
+       char *s;
        NTSTATUS status;
 
        /* Make a binding string */
-       {
-               char *s = talloc_asprintf(state, "ncacn_np:%s", state->domain->dc_name);
+       if ((lpcfg_server_role(state->service->task->lp_ctx) != ROLE_DOMAIN_MEMBER) &&
+           dom_sid_equal(state->domain->info->sid, state->service->primary_sid) &&
+           state->service->sec_channel_type != SEC_CHAN_RODC) {
+               s = talloc_asprintf(state, "ncalrpc:%s", state->domain->dc_name);
                if (s == NULL) return NULL;
-               status = dcerpc_parse_binding(state, s, &binding);
-               talloc_free(s);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return NULL;
-               }
+       } else {
+               s = talloc_asprintf(state, "ncacn_np:%s", state->domain->dc_name);
+               if (s == NULL) return NULL;
+
+       }
+       status = dcerpc_parse_binding(state, s, &binding);
+       talloc_free(s);
+       if (!NT_STATUS_IS_OK(status)) {
+               return NULL;
        }
 
        /* Alter binding to contain hostname, but also address (so we don't look it up twice) */
        binding->target_hostname = state->domain->dc_name;
        binding->host = state->domain->dc_address;
 
+       if (binding->transport == NCALRPC) {
+               return binding;
+       }
+
        /* This shouldn't make a network call, as the mappings for named pipes are well known */
        status = dcerpc_epm_map_binding(binding, binding, table, state->service->task->event_ctx,
                                        state->service->task->lp_ctx);