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:
parent
0d37a00be7
commit
06a913a269
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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: */
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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_ */
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user