s4:rpc_server: make it possible to specify ncacn_np_secondary_endpoint
authorStefan Metzmacher <metze@samba.org>
Wed, 12 Dec 2018 21:41:56 +0000 (22:41 +0100)
committerJeremy Allison <jra@samba.org>
Sat, 12 Jan 2019 02:13:41 +0000 (03:13 +0100)
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 <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
source4/rpc_server/dcerpc_server.c
source4/rpc_server/dcerpc_server.h
source4/rpc_server/lsa/dcesrv_lsa.c
source4/rpc_server/remote/dcesrv_remote.c
source4/torture/rpc/spoolss_notify.c

index e228a762591348101c4153de9f078b704f1560f7..945c0ffcee0f5e9ddea2ed183d09bf711b9e80eb 100644 (file)
@@ -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;i<ndr_table_$name.endpoints->count;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;
index 96886eaa76e7ff52d51a65d35edc8338ada4fe0c..75e1dfea1c786c9ebe4b184d8e97b1a47708ad9d 100644 (file)
@@ -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 = "";
index 312721824aec337c9869815126c3f2473310fd5a..25a3aedc2e1ae879e8ba3c0d2602f9157ac831c6 100644 (file)
@@ -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);
index ec3be02bf876e307579ba3fa635233e5878704b8..c1bc78aa9d057e717534bcdd0c58e6d0f75c5af3 100644 (file)
@@ -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"));
index 0d3b123bcd243e3e3b93954dc4b514a4f76aa931..d34643a68db3714d4df817caf282dd6585268416 100644 (file)
@@ -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;
index 2dd12994e8da47a33f5d34014e34abbd6787e262..fb01f71d53f795f35ad5422b249a8982cd154a27 100644 (file)
@@ -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, &notify_test_spoolss_interface, NULL);
+               ret = dcesrv_interface_register(dce_ctx,
+                                               name,
+                                               NULL,
+                                               &notify_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;