]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:rpc_server: Retrieve dcesrv_context from parent context to open NP
authorSamuel Cabrero <scabrero@suse.de>
Wed, 27 Feb 2019 20:36:22 +0000 (21:36 +0100)
committerSamuel Cabrero <scabrero@sn-devel-184>
Fri, 20 Mar 2020 15:36:35 +0000 (15:36 +0000)
Get the dcesrv_context from parent context and use it to search the
endpoint serving the named pipe. Once we have the endpoint pass it to
the make_internal_rpc_pipe_socketpair function.

Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source3/rpc_server/rpc_ncacn_np.c
source3/rpc_server/rpc_ncacn_np.h
source3/rpc_server/rpc_server.c
source3/rpc_server/rpc_server.h
source3/rpc_server/srv_pipe.c
source3/rpc_server/srv_pipe.h
source3/rpc_server/srv_pipe_hnd.c
source3/rpc_server/srv_pipe_hnd.h
source3/smbd/pipes.c
testsuite/unittests/test_sambafs_srv_pipe.c

index 6f28ba13c643436d2de4bf19f865883b24a0ac56..a0a880985e101adab4289aed6649ed14f3ee62fc 100644 (file)
@@ -97,8 +97,8 @@ NTSTATUS make_internal_rpc_pipe_socketpair(
        TALLOC_CTX *mem_ctx,
        struct tevent_context *ev_ctx,
        struct messaging_context *msg_ctx,
-       const char *pipe_name,
-       const struct ndr_syntax_id *syntax,
+       struct dcesrv_context *dce_ctx,
+       struct dcesrv_endpoint *endpoint,
        const struct tsocket_address *remote_address,
        const struct tsocket_address *local_address,
        const struct auth_session_info *session_info,
@@ -111,6 +111,10 @@ NTSTATUS make_internal_rpc_pipe_socketpair(
        NTSTATUS status;
        int error;
        int rc;
+       enum dcerpc_transport_t transport = dcerpc_binding_get_transport(
+                       endpoint->ep_description);
+       const char *pipe_name = dcerpc_binding_get_string_option(
+                       endpoint->ep_description, "endpoint");
 
        DEBUG(4, ("Create of internal pipe %s requested\n", pipe_name));
 
@@ -184,8 +188,8 @@ NTSTATUS make_internal_rpc_pipe_socketpair(
 
        rc = make_server_pipes_struct(ncacn_conn,
                                      ncacn_conn->msg_ctx,
-                                     ncacn_conn->name,
-                                     ncacn_conn->transport,
+                                     pipe_name,
+                                     transport,
                                      ncacn_conn->remote_client_addr,
                                      ncacn_conn->local_server_addr,
                                      &ncacn_conn->session_info,
index 705306c7793463396067fc9eb81a8f78e41d45fc..25565f521598253384f059f71b42259091a892b7 100644 (file)
@@ -23,6 +23,8 @@
 struct dcerpc_binding_handle;
 struct ndr_interface_table;
 struct tsocket_address;
+struct dcesrv_context;
+struct dcesrv_endpoint;
 
 struct npa_state {
        struct tstream_context *stream;
@@ -48,8 +50,8 @@ NTSTATUS make_internal_rpc_pipe_socketpair(
        TALLOC_CTX *mem_ctx,
        struct tevent_context *ev_ctx,
        struct messaging_context *msg_ctx,
-       const char *pipe_name,
-       const struct ndr_syntax_id *syntax,
+       struct dcesrv_context *dce_ctx,
+       struct dcesrv_endpoint *endpoint,
        const struct tsocket_address *remote_address,
        const struct tsocket_address *local_address,
        const struct auth_session_info *session_info,
index 0a170e96989bbdcdadd4d7cd44a7cf21571e3603..713d9cf634254547815f0b5d01cc5c9c17bef1a1 100644 (file)
@@ -1419,4 +1419,38 @@ static void ncacn_terminate_connection(struct dcerpc_ncacn_conn *conn,
        talloc_free(conn);
 }
 
+NTSTATUS dcesrv_endpoint_by_ncacn_np_name(struct dcesrv_context *dce_ctx,
+                                         const char *pipe_name,
+                                         struct dcesrv_endpoint **out)
+{
+       struct dcesrv_endpoint *e = NULL;
+
+       for (e = dce_ctx->endpoint_list; e; e = e->next) {
+               enum dcerpc_transport_t transport =
+                       dcerpc_binding_get_transport(e->ep_description);
+               const char *endpoint = NULL;
+
+               if (transport != NCACN_NP) {
+                       continue;
+               }
+
+               endpoint = dcerpc_binding_get_string_option(e->ep_description,
+                                                           "endpoint");
+               if (endpoint == NULL) {
+                       continue;
+               }
+
+               if (strncmp(endpoint, "\\pipe\\", 6) == 0) {
+                       endpoint += 6;
+               }
+
+               if (strequal(endpoint, pipe_name)) {
+                       *out = e;
+                       return NT_STATUS_OK;
+               }
+       }
+
+       return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+}
+
 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */
index 832b6bba4230db07ed4aaecc24ddf83159968cd0..f91f561dc3c17f74dd63f0d08c981952a449102a 100644 (file)
@@ -121,4 +121,8 @@ NTSTATUS dcesrv_auth_gensec_prepare(TALLOC_CTX *mem_ctx,
 void dcesrv_log_successful_authz(struct dcesrv_call_state *call);
 NTSTATUS dcesrv_assoc_group_find(struct dcesrv_call_state *call);
 
+NTSTATUS dcesrv_endpoint_by_ncacn_np_name(struct dcesrv_context *dce_ctx,
+                                         const char *endpoint,
+                                         struct dcesrv_endpoint **out);
+
 #endif /* _PRC_SERVER_H_ */
index 3bc291fb0c98ad3038a4e6e1c29d447b25f512cf..446ac95e5cca13a0ccee77b5478269f7e96b2216 100644 (file)
@@ -474,10 +474,14 @@ static bool check_bind_req(struct pipes_struct *p,
 
 /**
  * Is a named pipe known?
+ * @param[in] dce_ctx          The rpc server context
  * @param[in] pipename         Just the filename
+ * @param[out] endpoint                The DCERPC endpoint serving the pipe name
  * @result                     NT error code
  */
-NTSTATUS is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
+NTSTATUS is_known_pipename(struct dcesrv_context *dce_ctx,
+                          const char *pipename,
+                          struct dcesrv_endpoint **ep)
 {
        NTSTATUS status;
 
@@ -491,7 +495,8 @@ NTSTATUS is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
-       if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
+       status = dcesrv_endpoint_by_ncacn_np_name(dce_ctx, pipename, ep);
+       if (NT_STATUS_IS_OK(status)) {
                return NT_STATUS_OK;
        }
 
@@ -505,7 +510,8 @@ NTSTATUS is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
        /*
         * Scan the list again for the interface id
         */
-       if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
+       status = dcesrv_endpoint_by_ncacn_np_name(dce_ctx, pipename, ep);
+       if (NT_STATUS_IS_OK(status)) {
                return NT_STATUS_OK;
        }
 
index 0a28f72d2412b098115f68ee9a8a0252c0aabc58..d9d15adbf4e650d42dda05d3abe0ff13c062c5b9 100644 (file)
 
 struct ncacn_packet;
 struct pipes_struct;
+struct dcesrv_context;
+struct dcesrv_endpoint;
 
 /* The following definitions come from rpc_server/srv_pipe.c  */
 
 bool create_next_pdu(struct pipes_struct *p);
 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt);
 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS status);
-NTSTATUS is_known_pipename(const char *cli_filename,
-                          struct ndr_syntax_id *syntax);
+NTSTATUS is_known_pipename(struct dcesrv_context *dce_ctx,
+                          const char *pipename,
+                          struct dcesrv_endpoint **ep);
 
 #endif /* _RPC_SERVER_SRV_PIPE_H_ */
index 963af1486a1ec5bd08aad8c2d729a360576ab811..29d393b51dcaeb12590da372a8ef6f620a77f1b7 100644 (file)
@@ -54,12 +54,13 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
                 struct auth_session_info *session_info,
                 struct tevent_context *ev_ctx,
                 struct messaging_context *msg_ctx,
+                struct dcesrv_context *dce_ctx,
                 struct fake_file_handle **phandle)
 {
        enum rpc_service_mode_e pipe_mode;
        const char **proxy_list;
        struct fake_file_handle *handle;
-       struct ndr_syntax_id syntax;
+       struct dcesrv_endpoint *endpoint = NULL;
        struct npa_state *npa = NULL;
        NTSTATUS status;
 
@@ -98,7 +99,7 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
                break;
        case RPC_SERVICE_MODE_EMBEDDED:
                /* Check if we handle this pipe internally */
-               status = is_known_pipename(name, &syntax);
+               status = is_known_pipename(dce_ctx, name, &endpoint);
                if (!NT_STATUS_IS_OK(status)) {
                        DBG_WARNING("'%s' is not a registered pipe!\n", name);
                        talloc_free(handle);
@@ -109,8 +110,8 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
                        handle,
                        ev_ctx,
                        msg_ctx,
-                       name,
-                       &syntax,
+                       dce_ctx,
+                       endpoint,
                        remote_client_address,
                        local_server_address,
                        session_info,
index 26fc351043e2e666aae7b048d16a78bd642a90ae..ba351357b6965b1772281beaa90092ebaf7ea81a 100644 (file)
@@ -34,6 +34,7 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
                 struct auth_session_info *session_info,
                 struct tevent_context *ev_ctx,
                 struct messaging_context *msg_ctx,
+                struct dcesrv_context *dce_ctx,
                 struct fake_file_handle **phandle);
 bool np_read_in_progress(struct fake_file_handle *handle);
 struct tevent_req *np_write_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
index 4be57bc2a5f0dea80515419bdaa2d8763be60958..dd72d16313496e985c9dc0e289f7bf23d71ed074 100644 (file)
@@ -69,6 +69,7 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
                         conn->session_info,
                         conn->sconn->ev_ctx,
                         conn->sconn->msg_ctx,
+                        conn->sconn->dce_ctx,
                         &fsp->fake_file_handle);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(10, ("np_open(%s) returned %s\n", name,
index 161f7131e8e3a14af1c81d13e8f7c2e14d551639..40798b588c7f8f7322771c26b9a560e1c2c30b1f 100644 (file)
@@ -9,55 +9,86 @@
 
 #include "include/config.h"
 #include "librpc/gen_ndr/ndr_samr.h"
+#include "librpc/gen_ndr/ndr_samr_scompat.h"
 #include "source3/rpc_server/srv_pipe.h"
-#include "librpc/gen_ndr/srv_samr.h"
+#include "librpc/rpc/rpc_common.h"
+#include "librpc/rpc/dcesrv_core.h"
+#include "talloc.h"
+
+struct test_state {
+       TALLOC_CTX *mem_ctx;
+       struct loadparm_context *lp_ctx;
+       struct dcesrv_context *dce_ctx;
+};
 
 static int setup_samr(void **state)
 {
-       rpc_samr_init(NULL);
+       TALLOC_CTX *mem_ctx;
+       struct test_state *s;
+       const struct dcesrv_endpoint_server *ep_server;
+       NTSTATUS status;
 
-       return 0;
-}
+       mem_ctx = talloc_new(NULL);
+       assert_non_null(mem_ctx);
 
-static int teardown(void **state)
-{
-       unsetenv("UNITTEST_DUMMY_MODULE_LOADED");
+       s = talloc_zero(mem_ctx, struct test_state);
+       assert_non_null(s);
+
+       s->mem_ctx = mem_ctx;
+
+       ep_server = samr_get_ep_server();
+       assert_non_null(ep_server);
+
+       status = dcerpc_register_ep_server(ep_server);
+       assert_true(NT_STATUS_IS_OK(status));
+
+       status = dcesrv_init_context(s, NULL, NULL, &s->dce_ctx);
+       assert_true(NT_STATUS_IS_OK(status));
+
+       status = dcesrv_init_ep_server(s->dce_ctx, "samr");
+       assert_true(NT_STATUS_IS_OK(status));
+
+       *state = s;
 
        return 0;
 }
 
 static int teardown_samr(void **state)
 {
-       rpc_samr_shutdown();
+       struct test_state *s = talloc_get_type_abort(*state,
+                       struct test_state);
+
+       unsetenv("UNITTEST_DUMMY_MODULE_LOADED");
 
-       teardown(state);
+       dcesrv_shutdown_ep_server(s->dce_ctx, "samr");
+
+       talloc_free(s->mem_ctx);
 
        return 0;
 }
 
 static void test_is_known_pipename(void **state)
 {
-       struct ndr_syntax_id syntax_id = ndr_table_samr.syntax_id;
+       struct test_state *s = talloc_get_type_abort(*state,
+                       struct test_state);
+       struct dcesrv_endpoint *ep;
+       char dummy_module_path[4096] = {0};
+       const char *module_env;
        NTSTATUS status;
 
-       status = is_known_pipename("samr", &syntax_id);
+       status = is_known_pipename(s->dce_ctx, "samr", &ep);
        assert_true(NT_STATUS_IS_OK(status));
-}
 
-static void test_is_known_pipename_slash(void **state)
-{
-       struct ndr_syntax_id syntax_id = ndr_table_samr.syntax_id;
-       char dummy_module_path[4096] = {0};
-       const char *module_env;
-       NTSTATUS status;
+       status = is_known_pipename(s->dce_ctx, "SAMR", &ep);
+       assert_true(NT_STATUS_IS_OK(status));
 
        snprintf(dummy_module_path,
                 sizeof(dummy_module_path),
                 "%s/bin/modules/rpc/test_dummy_module.so",
                 SRCDIR);
 
-       status = is_known_pipename(dummy_module_path, &syntax_id);
-       assert_true(NT_STATUS_IS_ERR(status));
+       status = is_known_pipename(s->dce_ctx, dummy_module_path, &ep);
+       assert_false(NT_STATUS_IS_OK(status));
 
        module_env = getenv("UNITTEST_DUMMY_MODULE_LOADED");
        assert_null(module_env);
@@ -68,8 +99,6 @@ int main(void) {
                cmocka_unit_test_setup_teardown(test_is_known_pipename,
                                                setup_samr,
                                                teardown_samr),
-               cmocka_unit_test_teardown(test_is_known_pipename_slash,
-                                         teardown),
        };
 
        cmocka_set_message_output(CM_OUTPUT_SUBUNIT);