1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

s3:rpc_server: Retrieve dcesrv_context from parent context to open NP

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>
This commit is contained in:
Samuel Cabrero 2019-02-27 21:36:22 +01:00 committed by Samuel Cabrero
parent 0d37a00be7
commit 06a913a269
10 changed files with 123 additions and 38 deletions

View 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,

View 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,

View 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: */

View 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_ */

View 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;
}

View File

@ -22,13 +22,16 @@
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_ */

View 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,

View 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,

View 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,

View 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);
teardown(state);
unsetenv("UNITTEST_DUMMY_MODULE_LOADED");
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;
NTSTATUS status;
status = is_known_pipename("samr", &syntax_id);
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;
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(s->dce_ctx, "samr", &ep);
assert_true(NT_STATUS_IS_OK(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);