From: Samuel Cabrero Date: Wed, 27 Feb 2019 22:28:25 +0000 (+0100) Subject: pidl:NDR/ServerCompat: Retrieve and setup pipes struct before dispatch X-Git-Tag: ldb-2.2.0~1319 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d1afa40c3cae7969b99f2d0a0cc78902138c0f15;p=thirdparty%2Fsamba.git pidl:NDR/ServerCompat: Retrieve and setup pipes struct before dispatch Signed-off-by: Samuel Cabrero Reviewed-by: Andrew Bartlett --- diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm index 14e2cc811da..f9e9f6a14fd 100644 --- a/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm +++ b/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm @@ -117,9 +117,59 @@ sub boilerplate_iface($) $self->pidl("static NTSTATUS $name\__op_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)"); $self->pidl("{"); $self->indent(); - $self->pidl("/* TODO Retrieve pipes struct */"); - $self->pidl("/* TODO Init pipe handles */"); - $self->pidl("/* TODO Init pipe context */"); + $self->pidl("struct pipes_struct *p = NULL;"); + $self->pidl("struct pipe_rpc_fns *context_fns = NULL;"); + $self->pidl("bool ok = false;"); + $self->pidl(""); + $self->pidl("/* Retrieve pipes struct */"); + $self->pidl("p = dcesrv_get_pipes_struct(context->conn);"); + $self->pidl("/* Init pipe handles */"); + $self->pidl("ok = init_pipe_handles(p, &iface->syntax_id);"); + $self->pidl("if (!ok) {"); + $self->indent(); + $self->pidl("DBG_ERR(\"Failed to init pipe handles\\n\");"); + $self->pidl("return NT_STATUS_UNSUCCESSFUL;"); + $self->deindent(); + $self->pidl("}"); + $self->pidl(""); + + $self->pidl("/* TODO check loop */"); + + $self->pidl("/* Init pipe context */"); + $self->pidl("p->pipe_bound = true;"); + $self->pidl("for (context_fns = p->contexts; context_fns != NULL; context_fns = context_fns->next) {"); + $self->indent(); + $self->pidl("if (context_fns->context_id != context->context_id) {"); + $self->indent(); + $self->pidl("continue;"); + $self->deindent(); + $self->pidl("}"); + $self->pidl("ok = ndr_syntax_id_equal(&context_fns->syntax, &iface->syntax_id);"); + $self->pidl("if (ok) {"); + $self->indent(); + $self->pidl("break;"); + $self->deindent(); + $self->pidl("}"); + $self->pidl("return NT_STATUS_UNSUCCESSFUL;"); + $self->deindent(); + $self->pidl("}"); + $self->pidl("if (context_fns == NULL) {"); + $self->indent(); + $self->pidl("context_fns = talloc_zero(p, struct pipe_rpc_fns);"); + $self->pidl("if (context_fns == NULL) {"); + $self->indent(); + $self->pidl("return NT_STATUS_NO_MEMORY;"); + $self->deindent(); + $self->pidl("}"); + $self->pidl(""); + $self->pidl("context_fns->next = context_fns->prev = NULL;"); + $self->pidl("context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(&iface->syntax_id);"); + $self->pidl("context_fns->cmds = rpc_srv_get_pipe_cmds(&iface->syntax_id);"); + $self->pidl("context_fns->context_id = context->context_id;"); + $self->pidl("context_fns->syntax = iface->syntax_id;"); + $self->pidl("DLIST_ADD( p->contexts, context_fns);"); + $self->deindent(); + $self->pidl("}"); $self->pidlnoindent("#ifdef DCESRV_INTERFACE_$uname\_BIND"); $self->pidl("return DCESRV_INTERFACE_$uname\_BIND(context,iface);"); $self->pidlnoindent("#else"); @@ -178,13 +228,35 @@ sub boilerplate_iface($) $self->indent(); $self->pidl("uint16_t opnum = dce_call->pkt.u.request.opnum;"); $self->pidl("struct pipes_struct *p = NULL;"); + $self->pidl("struct auth_session_info *pipe_session_info = NULL;"); $self->pidl("NTSTATUS status = NT_STATUS_OK;"); + $self->pidl("bool impersonated;"); + $self->pidl(""); + $self->pidl("/* Retrieve pipes struct */"); + $self->pidl("p = dcesrv_get_pipes_struct(dce_call->conn);"); + $self->pidl("/* Update pipes struct opnum */"); + $self->pidl("p->opnum = opnum;"); + $self->pidl("/* Update pipes struct session info */"); + $self->pidl("pipe_session_info = p->session_info;"); + $self->pidl("p->session_info = dce_call->auth_state->session_info;"); + $self->pidl("p->auth.auth_type = dce_call->auth_state->auth_type;"); + $self->pidl("p->auth.auth_level = dce_call->auth_state->auth_level;"); + $self->pidl("p->auth.auth_context_id = dce_call->auth_state->auth_context_id;"); + $self->pidl("/* Reset pipes struct fault state */"); + $self->pidl("p->fault_state = 0;"); + $self->pidl(""); + + $self->pidl("/* Impersonate */"); + $self->pidl("impersonated = become_authenticated_pipe_user(p->session_info);"); + $self->pidl("if (!impersonated) {"); + $self->indent(); + $self->pidl("dce_call->fault_code = DCERPC_FAULT_ACCESS_DENIED;"); + $self->pidl("status = NT_STATUS_NET_WRITE_FAULT;"); + $self->pidl("goto fail;"); + $self->deindent(); + $self->pidl("}"); $self->pidl(""); - $self->pidl("/* TODO Retrieve pipes struct */"); - $self->pidl("/* TODO Update pipes struct opnum */"); - $self->pidl("/* TODO Update pipes struct session info */"); - $self->pidl("/* TODO Reset pipes struct fault state */"); - $self->pidl(""); + $self->pidl("switch (opnum) {"); $self->gen_dispatch_switch($interface); $self->pidl("default:"); @@ -194,7 +266,27 @@ sub boilerplate_iface($) $self->deindent(); $self->pidl("}"); $self->pidl(""); - $self->pidl("/* TODO Check pipes struct fault state */"); + + $self->pidlnoindent("fail:"); + $self->pidl("/* Unimpersonate */"); + $self->pidl("if (impersonated) {"); + $self->indent(); + $self->pidl("unbecome_authenticated_pipe_user();"); + $self->deindent(); + $self->pidl("}"); + $self->pidl(""); + + $self->pidl("/* Restore session info */"); + $self->pidl("p->session_info = pipe_session_info;"); + $self->pidl("p->auth.auth_type = 0;"); + $self->pidl("p->auth.auth_level = 0;"); + $self->pidl("p->auth.auth_context_id = 0;"); + $self->pidl("/* Check pipes struct fault state */"); + $self->pidl("if (p->fault_state != 0) {"); + $self->indent(); + $self->pidl("dce_call->fault_code = p->fault_state;"); + $self->deindent(); + $self->pidl("}"); $self->pidl("if (dce_call->fault_code != 0) {"); $self->indent(); $self->pidl("status = NT_STATUS_NET_WRITE_FAULT;"); @@ -501,9 +593,11 @@ sub Parse($$) $self->pidl("#include \"$header\""); $self->pidl("#include \"$h_scompat\""); $self->pidl("#include "); + $self->pidl("#include "); $self->pidl("#include "); $self->pidl("#include "); + $self->pidl("#include "); $self->pidl("#include "); $self->pidl(""); diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c index dbb4ce836d7..704dcb8a5fb 100644 --- a/source3/rpc_server/rpc_server.c +++ b/source3/rpc_server/rpc_server.c @@ -1450,4 +1450,13 @@ NTSTATUS dcesrv_endpoint_by_ncacn_np_name(struct dcesrv_context *dce_ctx, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } +struct pipes_struct *dcesrv_get_pipes_struct(struct dcesrv_connection *conn) +{ + struct dcerpc_ncacn_conn *ncacn_conn = talloc_get_type_abort( + conn->transport.private_data, + struct dcerpc_ncacn_conn); + + return ncacn_conn->p; +} + /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */ diff --git a/source3/rpc_server/rpc_server.h b/source3/rpc_server/rpc_server.h index 58d5263b641..62d219ee7e5 100644 --- a/source3/rpc_server/rpc_server.h +++ b/source3/rpc_server/rpc_server.h @@ -124,4 +124,6 @@ NTSTATUS dcesrv_endpoint_by_ncacn_np_name(struct dcesrv_context *dce_ctx, const char *endpoint, struct dcesrv_endpoint **out); +struct pipes_struct *dcesrv_get_pipes_struct(struct dcesrv_connection *conn); + #endif /* _PRC_SERVER_H_ */