From 98d58722933a2929fb8564f9c8526f7ae45f6059 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Dec 2018 22:41:56 +0100 Subject: [PATCH] s4:rpc_server: make it possible to specify ncacn_np_secondary_endpoint Even a connect to \\pipe\lsarpc should return a secondary_address of '\\pipe\\lsass'. But that will be implemented in a following commit. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm | 12 +++++++++- source4/rpc_server/dcerpc_server.c | 27 ++++++++++++++++++++++- source4/rpc_server/dcerpc_server.h | 3 +++ source4/rpc_server/lsa/dcesrv_lsa.c | 1 + source4/rpc_server/remote/dcesrv_remote.c | 2 +- source4/torture/rpc/spoolss_notify.c | 6 ++++- 6 files changed, 47 insertions(+), 4 deletions(-) diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm index e228a762591..945c0ffcee0 100644 --- a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm +++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm @@ -223,12 +223,22 @@ sub Boilerplate_Ep_Server($) static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server) { int i; +#ifdef DCESRV_INTERFACE_$uname\_NCACN_NP_SECONDARY_ENDPOINT + const char *ncacn_np_secondary_endpoint = + DCESRV_INTERFACE_$uname\_NCACN_NP_SECONDARY_ENDPOINT; +#else + const char *ncacn_np_secondary_endpoint = NULL; +#endif for (i=0;icount;i++) { NTSTATUS ret; const char *name = ndr_table_$name.endpoints->names[i]; - ret = dcesrv_interface_register(dce_ctx, name, &dcesrv_$name\_interface, NULL); + ret = dcesrv_interface_register(dce_ctx, + name, + ncacn_np_secondary_endpoint, + &dcesrv_$name\_interface, + NULL); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,(\"$name\_op_init_server: failed to register endpoint \'%s\'\\n\",name)); return ret; diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 96886eaa76e..75e1dfea1c7 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -284,12 +284,14 @@ static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_conne */ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, const char *ep_name, + const char *ncacn_np_secondary_endpoint, const struct dcesrv_interface *iface, const struct security_descriptor *sd) { struct dcesrv_endpoint *ep; struct dcesrv_if_list *ifl; struct dcerpc_binding *binding; + struct dcerpc_binding *binding2 = NULL; bool add_ep = false; NTSTATUS status; enum dcerpc_transport_t transport; @@ -354,6 +356,22 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, } } + if (transport == NCACN_NP && ncacn_np_secondary_endpoint != NULL) { + enum dcerpc_transport_t transport2; + + status = dcerpc_parse_binding(dce_ctx, + ncacn_np_secondary_endpoint, + &binding2); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Trouble parsing 2nd binding string '%s'\n", + ncacn_np_secondary_endpoint)); + return status; + } + + transport2 = dcerpc_binding_get_transport(binding2); + SMB_ASSERT(transport2 == transport); + } + /* see if the interface is already registered on the endpoint */ if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) { DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n", @@ -395,6 +413,7 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, } ZERO_STRUCTP(ep); ep->ep_description = talloc_move(ep, &binding); + ep->ep_2nd_description = talloc_move(ep, &binding2); add_ep = true; /* add mgmt interface */ @@ -978,6 +997,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32_t extra_flags = 0; uint16_t max_req = 0; uint16_t max_rep = 0; + struct dcerpc_binding *ep_2nd_description = NULL; const char *endpoint = NULL; struct dcesrv_auth *auth = call->auth_state; struct dcerpc_ack_ctx *ack_ctx_list = NULL; @@ -1187,8 +1207,13 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag; pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id; + ep_2nd_description = call->conn->endpoint->ep_2nd_description; + if (ep_2nd_description == NULL) { + ep_2nd_description = call->conn->endpoint->ep_description; + } + endpoint = dcerpc_binding_get_string_option( - call->conn->endpoint->ep_description, + ep_2nd_description, "endpoint"); if (endpoint == NULL) { endpoint = ""; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 312721824ae..25a3aedc2e1 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -383,6 +383,8 @@ struct dcesrv_context { struct dcesrv_endpoint *next, *prev; /* the type and location of the endpoint */ struct dcerpc_binding *ep_description; + /* the secondary endpoint description for the BIND_ACK */ + struct dcerpc_binding *ep_2nd_description; /* the security descriptor for smb named pipes */ struct security_descriptor *sd; /* the list of interfaces available on this endpoint */ @@ -424,6 +426,7 @@ struct model_ops; NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, const char *ep_name, + const char *ncacn_np_secondary_endpoint, const struct dcesrv_interface *iface, const struct security_descriptor *sd); NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server); diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index ec3be02bf87..c1bc78aa9d0 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -55,6 +55,7 @@ static NTSTATUS dcesrv_interface_lsarpc_init_server(struct dcesrv_context *dce_c if (lpcfg_lsa_over_netlogon(dce_ctx->lp_ctx)) { NTSTATUS ret = dcesrv_interface_register(dce_ctx, "ncacn_np:[\\pipe\\netlogon]", + NULL, &dcesrv_lsarpc_interface, NULL); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("lsarpc_op_init_server: failed to register endpoint '\\pipe\\netlogon'\n")); diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index 0d3b123bcd2..d34643a68db 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -406,7 +406,7 @@ static NTSTATUS remote_register_one_iface(struct dcesrv_context *dce_ctx, const NTSTATUS ret; const char *name = table->endpoints->names[i]; - ret = dcesrv_interface_register(dce_ctx, name, iface, NULL); + ret = dcesrv_interface_register(dce_ctx, name, NULL, iface, NULL); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("remote_op_init_server: failed to register endpoint '%s'\n",name)); return ret; diff --git a/source4/torture/rpc/spoolss_notify.c b/source4/torture/rpc/spoolss_notify.c index 2dd12994e8d..fb01f71d53f 100644 --- a/source4/torture/rpc/spoolss_notify.c +++ b/source4/torture/rpc/spoolss_notify.c @@ -247,7 +247,11 @@ static NTSTATUS spoolss__op_init_server(struct dcesrv_context *dce_ctx, const st NTSTATUS ret; const char *name = ndr_table_spoolss.endpoints->names[i]; - ret = dcesrv_interface_register(dce_ctx, name, ¬ify_test_spoolss_interface, NULL); + ret = dcesrv_interface_register(dce_ctx, + name, + NULL, + ¬ify_test_spoolss_interface, + NULL); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("spoolss_op_init_server: failed to register endpoint '%s'\n",name)); return ret;