$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");
$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:");
$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;");
$self->pidl("#include \"$header\"");
$self->pidl("#include \"$h_scompat\"");
$self->pidl("#include <rpc_server/srv_pipe_register.h>");
+ $self->pidl("#include <rpc_server/srv_pipe_internal.h>");
$self->pidl("#include <librpc/rpc/dcesrv_core.h>");
$self->pidl("#include <rpc_server/rpc_config.h>");
+ $self->pidl("#include <rpc_server/rpc_server.h>");
$self->pidl("#include <util/debug.h>");
$self->pidl("");