s3:winbindd: Dispatch RPC calls through interface local handler
authorSamuel Cabrero <scabrero@samba.org>
Tue, 22 Oct 2019 16:28:44 +0000 (18:28 +0200)
committerSamuel Cabrero <scabrero@sn-devel-184>
Fri, 20 Mar 2020 15:36:35 +0000 (15:36 +0000)
Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source3/winbindd/winbindd.c
source3/winbindd/winbindd_dual_ndr.c
source3/winbindd/winbindd_dual_srv.c

index dd8e53e29a52a636088e816fba93ca0818c6d314..4397a1bc0d12699e006ba62b0d79b791a30f34f2 100644 (file)
@@ -31,6 +31,7 @@
 #include "librpc/rpc/dcesrv_core.h"
 #include "librpc/gen_ndr/ndr_lsa_scompat.h"
 #include "librpc/gen_ndr/ndr_samr_scompat.h"
+#include "librpc/gen_ndr/ndr_winbind_scompat.h"
 #include "secrets.h"
 #include "rpc_client/cli_netlogon.h"
 #include "idmap.h"
@@ -1965,6 +1966,18 @@ int main(int argc, const char **argv)
                exit(1);
        }
 
+       ep_server = winbind_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'winbind' endpoint server\n");
+               exit(1);
+       }
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register 'winbind' endpoint "
+                       "server: %s\n", nt_errstr(status));
+               exit(1);
+       }
+
        dce_ctx = global_dcesrv_context();
 
        DBG_INFO("Initializing DCE/RPC registered endpoint servers\n");
index 25e7445edc6aac532dc05e7809019000ddca99ae..f615ada1fca8cb4a9ae9b393ad2e1aba050bf228 100644 (file)
@@ -30,7 +30,8 @@
 #include "winbindd/winbindd.h"
 #include "winbindd/winbindd_proto.h"
 #include "ntdomain.h"
-#include "librpc/gen_ndr/srv_winbind.h"
+#include "librpc/rpc/dcesrv_core.h"
+#include "librpc/gen_ndr/ndr_winbind.h"
 
 struct wbint_bh_state {
        struct winbindd_domain *domain;
@@ -346,41 +347,67 @@ struct dcerpc_binding_handle *wbint_binding_handle(TALLOC_CTX *mem_ctx,
 enum winbindd_result winbindd_dual_ndrcmd(struct winbindd_domain *domain,
                                          struct winbindd_cli_state *state)
 {
-       struct pipes_struct p;
-       const struct api_struct *fns;
-       int num_fns;
-       bool ret;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
+       struct dcesrv_interface iface;
+       const struct ndr_syntax_id *abstract_syntax;
+       bool ok;
+       uint32_t opnum = state->request->data.ndrcmd;
+       struct pipes_struct *p;
+       TALLOC_CTX *mem_ctx;
+       DATA_BLOB in;
+       DATA_BLOB out;
+       NTSTATUS status;
+
+       DBG_DEBUG("Running command %s (domain '%s')\n",
+                 ndr_table_winbind.calls[opnum].name,
+                 domain ? domain->name : "(null)");
+
+       ep_server = dcesrv_ep_server_byname(ndr_table_winbind.name);
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get DCE/RPC endpoint server '%s'\n",
+                       ndr_table_winbind.name);
+               return WINBINDD_ERROR;
+       }
 
-       fns = winbind_get_pipe_fns(&num_fns);
+       abstract_syntax = &ndr_table_winbind.syntax_id;
+       ok = ep_server->interface_by_uuid(&iface, &abstract_syntax->uuid,
+                                         abstract_syntax->if_version);
+       if (!ok) {
+               DBG_ERR("Failed to get DCE/RPC interface\n");
+               return WINBINDD_ERROR;
+       }
 
-       if (state->request->data.ndrcmd >= num_fns) {
+       mem_ctx = talloc_stackframe();
+       if (mem_ctx == NULL) {
+               DBG_ERR("No memory");
                return WINBINDD_ERROR;
        }
 
-       DEBUG(10, ("winbindd_dual_ndrcmd: Running command %s (%s)\n",
-                  fns[state->request->data.ndrcmd].name,
-                  domain ? domain->name : "no domain"));
+       p = talloc_zero(mem_ctx, struct pipes_struct);
+       if (p == NULL) {
+               DBG_ERR("No memory\n");
+               return WINBINDD_ERROR;
+       }
+       p->mem_ctx = mem_ctx;
 
-       ZERO_STRUCT(p);
-       p.mem_ctx = talloc_stackframe();
-       p.in_data.data = data_blob_const(state->request->extra_data.data,
-                                        state->request->extra_len);
+       in = data_blob_const(state->request->extra_data.data,
+                            state->request->extra_len);
 
-       ret = fns[state->request->data.ndrcmd].fn(&p);
-       if (!ret) {
-               TALLOC_FREE(p.mem_ctx);
+       status = iface.local(p, opnum, mem_ctx, &in, &out);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(mem_ctx);
                return WINBINDD_ERROR;
        }
 
        state->response->extra_data.data =
-               talloc_move(state->mem_ctx, &p.out_data.rdata.data);
-       state->response->length += p.out_data.rdata.length;
-       p.out_data.rdata.length = 0;
+               talloc_steal(state->mem_ctx, out.data);
+       state->response->length += out.length;
 
-       TALLOC_FREE(p.mem_ctx);
+       TALLOC_FREE(mem_ctx);
 
        if (state->response->extra_data.data == NULL) {
                return WINBINDD_ERROR;
        }
+
        return WINBINDD_OK;
 }
index 13345caa41b7e919b7afcc47a9976598f453328c..a41177ae871d1287f42c69886979e78c203b3abe 100644 (file)
@@ -1899,3 +1899,5 @@ reconnect:
 
        return status;
 }
+
+#include "librpc/gen_ndr/ndr_winbind_scompat.c"