summaryrefslogtreecommitdiff
path: root/pidl
diff options
context:
space:
mode:
authorSamuel Cabrero <scabrero@samba.org>2019-11-18 14:01:52 +0100
committerAndrew Bartlett <abartlet@samba.org>2020-04-08 22:23:05 +0000
commit03f79a3bd71bc7a0a401d5f19560e831251d32b7 (patch)
tree8a15bcfb6d0c1d50277ded4c626c69887c8a06ac /pidl
parentbce570cfd751fe2348e62cd8e06d64760d769611 (diff)
downloadsamba-03f79a3bd71bc7a0a401d5f19560e831251d32b7.tar.gz
s3:rpc_server: Improve local dispatching
Craft core structures to dispatch local calls in the same way as remote ones, removing the special handling in the autogenerated code. This is also necessary to drop s3 rpc handles implementation. Signed-off-by: Samuel Cabrero <scabrero@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org> Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> Autobuild-Date(master): Wed Apr 8 22:23:05 UTC 2020 on sn-devel-184
Diffstat (limited to 'pidl')
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm193
1 files changed, 25 insertions, 168 deletions
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm
index a1729d86d77..14f6ad9a1a0 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm
@@ -212,67 +212,6 @@ sub gen_reply_switch($)
}
}
-# generate the switch statement for local function dispatch
-sub gen_local_dispatch_switch($)
-{
- my ($self, $interface) = @_;
-
- my @alloc_error_block = ("p->fault_state = DCERPC_FAULT_CANT_PERFORM;",
- "return NT_STATUS_NO_MEMORY;");
-
- foreach my $fn (@{$interface->{FUNCTIONS}}) {
- next if not defined($fn->{OPNUM});
-
- $self->pidl("case $fn->{OPNUM}: { /* $fn->{NAME} */");
- $self->indent();
- $self->pidl("struct $fn->{NAME} *r2 = (struct $fn->{NAME} *)r;");
- $self->pidl("if (DEBUGLEVEL >= 10) {\n");
- $self->indent();
- $self->pidl("NDR_PRINT_FUNCTION_DEBUG($fn->{NAME}, NDR_IN, r2);");
- $self->deindent();
- $self->pidl("}");
-
- $self->gen_fn_out($fn, \@alloc_error_block);
-
- if ($fn->{RETURN_TYPE} && $fn->{RETURN_TYPE} ne "void") {
- $self->pidl("r2->out.result = _$fn->{NAME}(p, r2);");
- } else {
- $self->pidl("_$fn->{NAME}(p, r2);");
- }
- $self->pidl("break;");
- $self->deindent();
- $self->pidl("}");
- }
-}
-
-#####################################################
-# generate the switch statement for local function reply
-sub gen_local_reply_switch($)
-{
- my ($self, $interface) = @_;
-
- foreach my $fn (@{$interface->{FUNCTIONS}}) {
- next if not defined($fn->{OPNUM});
-
- $self->pidl("case $fn->{OPNUM}: { /* $fn->{NAME} */");
- $self->indent();
- $self->pidl("struct $fn->{NAME} *r2 = (struct $fn->{NAME} *)r;");
- $self->pidl("if (DEBUGLEVEL >= 10 && p->fault_state == 0) {");
- $self->indent();
- $self->pidl("NDR_PRINT_FUNCTION_DEBUG($fn->{NAME}, NDR_OUT | NDR_SET_VALUES, r2);");
- $self->deindent();
- $self->pidl("}");
- $self->pidl("if (p->fault_state != 0) {\n");
- $self->indent();
- $self->pidl("DBG_WARNING(\"dcerpc_fault %s in $fn->{NAME}\\n\", dcerpc_errstr(mem_ctx, p->fault_state));");
- $self->deindent();
- $self->pidl("}");
- $self->pidl("break;");
- $self->deindent();
- $self->pidl("}");
- }
-}
-
#####################################################################
# produce boilerplate code for a interface
sub boilerplate_iface($)
@@ -392,15 +331,14 @@ sub boilerplate_iface($)
$self->pidl("}");
$self->pidl("");
- $self->pidl_hdr("NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r);");
- $self->pidl("NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)");
+ $self->pidl("static NTSTATUS $name\__op_dispatch_internal(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, enum s3compat_rpc_dispatch dispatch)");
$self->pidl("{");
$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("bool impersonated = false;");
$self->pidl("");
$self->pidl("/* Retrieve pipes struct */");
$self->pidl("p = dcesrv_get_pipes_struct(dce_call->conn);");
@@ -417,6 +355,8 @@ sub boilerplate_iface($)
$self->pidl("");
$self->pidl("/* Impersonate */");
+ $self->pidl("if (dispatch == S3COMPAT_RPC_DISPATCH_EXTERNAL) {");
+ $self->indent();
$self->pidl("impersonated = become_authenticated_pipe_user(p->session_info);");
$self->pidl("if (!impersonated) {");
$self->indent();
@@ -425,6 +365,8 @@ sub boilerplate_iface($)
$self->pidl("goto fail;");
$self->deindent();
$self->pidl("}");
+ $self->deindent();
+ $self->pidl("}");
$self->pidl("");
$self->pidl("switch (opnum) {");
@@ -469,6 +411,15 @@ sub boilerplate_iface($)
$self->pidl("}");
$self->pidl("");
+ $self->pidl_hdr("NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r);");
+ $self->pidl("NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)");
+ $self->pidl("{");
+ $self->indent();
+ $self->pidl("return $name\__op_dispatch_internal(dce_call, mem_ctx, r, S3COMPAT_RPC_DISPATCH_EXTERNAL);");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
$self->pidl_hdr("NTSTATUS $name\__op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r);");
$self->pidl("NTSTATUS $name\__op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)");
$self->pidl("{");
@@ -519,112 +470,11 @@ sub boilerplate_iface($)
##############################
#### LOCAL DISPATCH ####
##############################
- $self->pidl_hdr("NTSTATUS $name\__op_local(void *q, int opnum, TALLOC_CTX *mem_ctx, const DATA_BLOB *in, DATA_BLOB *out);");
- $self->pidl("NTSTATUS $name\__op_local(void *q, int opnum, TALLOC_CTX *mem_ctx, const DATA_BLOB *in, DATA_BLOB *out)");
+ $self->pidl_hdr("NTSTATUS $name\__op_local(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r);");
+ $self->pidl("NTSTATUS $name\__op_local(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)");
$self->pidl("{");
$self->indent();
- $self->pidl("struct pipes_struct *p = talloc_get_type_abort(q, struct pipes_struct);");
- $self->pidl("void *r;");
- $self->pidl("struct ndr_pull *pull;");
- $self->pidl("struct ndr_push *push;");
- $self->pidl("enum ndr_err_code ndr_err;");
- $self->pidl("");
- $self->pidl("p->fault_state = 0;");
- $self->pidl("if (opnum >= ndr_table_$name.num_calls) {");
- $self->indent();
- $self->pidl("p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;");
- $self->pidl("return NT_STATUS_NET_WRITE_FAULT;");
- $self->deindent();
- $self->pidl("}");
- $self->pidl("");
- $self->pidl("r = talloc_named(mem_ctx, ndr_table_$name.calls[opnum].struct_size, \"struct %s\", ndr_table_$name.calls[opnum].name);");
- $self->pidl("if (r == NULL) {");
- $self->indent();
- $self->pidl("p->fault_state = DCERPC_FAULT_CANT_PERFORM;");
- $self->pidl("return NT_STATUS_NO_MEMORY;");
- $self->deindent();
- $self->pidl("}");
- $self->pidl("");
- $self->pidl("pull = ndr_pull_init_blob(in, r);");
- $self->pidl("if (pull == NULL) {");
- $self->indent();
- $self->pidl("talloc_free(r);");
- $self->pidl("p->fault_state = DCERPC_FAULT_CANT_PERFORM;");
- $self->pidl("return NT_STATUS_NO_MEMORY;");
- $self->deindent();
- $self->pidl("}");
- $self->pidl("");
- $self->pidl("pull->flags |= LIBNDR_FLAG_REF_ALLOC;");
- $self->pidl("if (p->endian) {");
- $self->indent();
- $self->pidl("pull->flags |= LIBNDR_FLAG_BIGENDIAN;");
- $self->deindent();
- $self->pidl("}");
- $self->pidl("");
- $self->pidl("ndr_err = ndr_table_$name.calls[opnum].ndr_pull(pull, NDR_IN, r);");
- $self->pidl("if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {");
- $self->indent();
- $self->pidl("p->fault_state = DCERPC_FAULT_NDR;");
- $self->pidl("talloc_free(r);");
- $self->pidl("return NT_STATUS_NET_WRITE_FAULT;");
- $self->deindent();
- $self->pidl("}");
- $self->pidl("");
- $self->pidl("switch (opnum) {");
- $self->gen_local_dispatch_switch($interface);
- $self->pidl("default:");
- $self->indent();
- $self->pidl("p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;");
- $self->pidl("break;");
- $self->deindent();
- $self->pidl("}");
- $self->pidl("");
- $self->pidl("if (p->fault_state != 0) {");
- $self->indent();
- $self->pidl("talloc_free(r);");
- $self->pidl("return NT_STATUS_NET_WRITE_FAULT;");
- $self->deindent();
- $self->pidl("}");
- $self->pidl("");
- $self->pidl("switch (opnum) {");
- $self->gen_local_reply_switch($interface);
- $self->pidl("default:");
- $self->indent();
- $self->pidl("p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;");
- $self->pidl("break;");
- $self->deindent();
- $self->pidl("}");
- $self->pidl("");
- $self->pidl("push = ndr_push_init_ctx(r);");
- $self->pidl("if (push == NULL) {");
- $self->indent();
- $self->pidl("talloc_free(r);");
- $self->pidl("p->fault_state = DCERPC_FAULT_CANT_PERFORM;");
- $self->pidl("return NT_STATUS_NO_MEMORY;");
- $self->deindent();
- $self->pidl("}");
- $self->pidl("");
- $self->pidl("/*");
- $self->pidl(" * carry over the pointer count to the reply in case we are");
- $self->pidl(" * using full pointer. See NDR specification for full pointers");
- $self->pidl(" */");
- $self->pidl("push->ptr_count = pull->ptr_count;");
- $self->pidl("");
- $self->pidl("ndr_err = ndr_table_$name.calls[opnum].ndr_push(push, NDR_OUT, r);");
- $self->pidl("if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {");
- $self->indent();
- $self->pidl("p->fault_state = DCERPC_FAULT_NDR;");
- $self->pidl("talloc_free(r);");
- $self->pidl("return NT_STATUS_NET_WRITE_FAULT;");
- $self->deindent();
- $self->pidl("}");
- $self->pidl("");
- $self->pidl("*out = ndr_push_blob(push);");
- $self->pidl("talloc_steal(mem_ctx, out->data);");
- $self->pidl("");
- $self->pidl("talloc_free(r);");
- $self->pidl("");
- $self->pidl("return NT_STATUS_OK;");
+ $self->pidl("return $name\__op_dispatch_internal(dce_call, mem_ctx, r, S3COMPAT_RPC_DISPATCH_INTERNAL);");
$self->deindent();
$self->pidl("}");
$self->pidl("");
@@ -854,6 +704,13 @@ sub Parse($$)
$self->pidl("#include <rpc_server/rpc_server.h>");
$self->pidl("#include <util/debug.h>");
$self->pidl("");
+ $self->pidl("enum s3compat_rpc_dispatch {");
+ $self->indent();
+ $self->pidl("S3COMPAT_RPC_DISPATCH_EXTERNAL = 0x00000001,");
+ $self->pidl("S3COMPAT_RPC_DISPATCH_INTERNAL = 0x00000002,");
+ $self->deindent();
+ $self->pidl("};");
+ $self->pidl("");
foreach my $x (@{$ndr}) {
$self->parse_interface($x) if ($x->{TYPE} eq "INTERFACE" and not defined($x->{PROPERTIES}{object}));