diff options
author | Stefan Metzmacher <metze@samba.org> | 2004-12-20 14:37:54 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:07:32 -0500 |
commit | bb072199b14c0e877360475eefb89021e7ec0bcf (patch) | |
tree | 58be480b14d6340d9a758a5613f7c878e34aa3cd /source4/build/pidl | |
parent | 545c190d2a655a3d96ea6cd19f8fecb4b63555db (diff) | |
download | samba-bb072199b14c0e877360475eefb89021e7ec0bcf.tar.gz samba-bb072199b14c0e877360475eefb89021e7ec0bcf.tar.bz2 samba-bb072199b14c0e877360475eefb89021e7ec0bcf.zip |
r4288: don't use struct dcerpc_interface_table anymore in the
main rpc server code. let the backends specify a ndr_push/ndr_pull function
like we already do with the dispatch() function.
this allows an interface implmentation to work as real proxy
without needing to know the idl for an interface that means
just the plain decrypted payload can be forwarded
If someone want to write such a backend, patches are wellcome
metze
(This used to be commit a150bdf140d9165a05cbc7cac40b6e3c03a7bd3c)
Diffstat (limited to 'source4/build/pidl')
-rw-r--r-- | source4/build/pidl/server.pm | 104 | ||||
-rw-r--r-- | source4/build/pidl/stub.pm | 109 |
2 files changed, 158 insertions, 55 deletions
diff --git a/source4/build/pidl/server.pm b/source4/build/pidl/server.pm index 4deca54ac5..9c72df105b 100644 --- a/source4/build/pidl/server.pm +++ b/source4/build/pidl/server.pm @@ -54,17 +54,10 @@ sub Boilerplate_Iface($) { my($interface) = shift; my($data) = $interface->{DATA}; - my $count = 0; my $name = $interface->{NAME}; my $uname = uc $name; - - foreach my $d (@{$data}) { - if ($d->{TYPE} eq "FUNCTION") { $count++; } - } - - if ($count == 0) { - return; - } + my $uuid = util::make_str($interface->{PROPERTIES}->{uuid}); + my $if_version = $interface->{PROPERTIES}->{version}; pidl " static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) @@ -85,6 +78,35 @@ static void $name\__op_unbind(struct dcesrv_connection *dce_conn, const struct d #endif } +static NTSTATUS $name\__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r) +{ + NTSTATUS status; + uint16 opnum = dce_call->pkt.u.request.opnum; + + dce_call->fault_code = 0; + + if (opnum >= dcerpc_table_$name.num_calls) { + dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR; + return NT_STATUS_NET_WRITE_FAULT; + } + + *r = talloc(mem_ctx, dcerpc_table_$name.calls[opnum].struct_size); + if (!*r) { + return NT_STATUS_NO_MEMORY; + } + + /* unravel the NDR for the packet */ + status = dcerpc_table_$name.calls[opnum].ndr_pull(pull, NDR_IN, *r); + if (!NT_STATUS_IS_OK(status)) { + dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN, + &dce_call->pkt.u.request.stub_and_verifier); + dce_call->fault_code = DCERPC_FAULT_NDR; + return NT_STATUS_NET_WRITE_FAULT; + } + + return NT_STATUS_OK; +} + static NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { uint16 opnum = dce_call->pkt.u.request.opnum; @@ -104,14 +126,33 @@ pidl " if (dce_call->fault_code != 0) { return NT_STATUS_NET_WRITE_FAULT; } + + return NT_STATUS_OK; +} + +static NTSTATUS $name\__op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, void *r) +{ + NTSTATUS status; + uint16 opnum = dce_call->pkt.u.request.opnum; + + status = dcerpc_table_$name.calls[opnum].ndr_push(push, NDR_OUT, r); + if (!NT_STATUS_IS_OK(status)) { + dce_call->fault_code = DCERPC_FAULT_NDR; + return NT_STATUS_NET_WRITE_FAULT; + } + return NT_STATUS_OK; } static const struct dcesrv_interface $name\_interface = { - &dcerpc_table_$name, + \"$name\", + $uuid, + $if_version, $name\__op_bind, $name\__op_unbind, - $name\__op_dispatch + $name\__op_ndr_pull, + $name\__op_dispatch, + $name\__op_ndr_push }; "; @@ -122,27 +163,17 @@ static const struct dcesrv_interface $name\_interface = { sub Boilerplate_Ep_Server($) { my($interface) = shift; - my($data) = $interface->{DATA}; - my $count = 0; my $name = $interface->{NAME}; my $uname = uc $name; - foreach my $d (@{$data}) { - if ($d->{TYPE} eq "FUNCTION") { $count++; } - } - - if ($count == 0) { - return; - } - pidl " static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server) { int i; - for (i=0;i<$name\_interface.ndr->endpoints->count;i++) { + for (i=0;i<dcerpc_table_$name.endpoints->count;i++) { NTSTATUS ret; - const char *name = $name\_interface.ndr->endpoints->names[i]; + const char *name = dcerpc_table_$name.endpoints->names[i]; ret = dcesrv_interface_register(dce_ctx, name, &$name\_interface, NULL); if (!NT_STATUS_IS_OK(ret)) { @@ -156,8 +187,8 @@ static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const str static BOOL $name\__op_interface_by_uuid(struct dcesrv_interface *iface, const char *uuid, uint32 if_version) { - if ($name\_interface.ndr->if_version == if_version && - strcmp($name\_interface.ndr->uuid, uuid)==0) { + if ($name\_interface.if_version == if_version && + strcmp($name\_interface.uuid, uuid)==0) { memcpy(iface,&$name\_interface, sizeof(*iface)); return True; } @@ -167,7 +198,7 @@ static BOOL $name\__op_interface_by_uuid(struct dcesrv_interface *iface, const c static BOOL $name\__op_interface_by_name(struct dcesrv_interface *iface, const char *name) { - if (strcmp($name\_interface.ndr->name, name)==0) { + if (strcmp($name\_interface.name, name)==0) { memcpy(iface,&$name\_interface, sizeof(*iface)); return True; } @@ -208,6 +239,27 @@ NTSTATUS dcerpc_server_$name\_init(void) sub ParseInterface($) { my($interface) = shift; + my($data) = $interface->{DATA}; + my $count = 0; + + $res = ""; + + if (!defined $interface->{PROPERTIES}->{uuid}) { + return $res; + } + + if (!defined $interface->{PROPERTIES}->{version}) { + $interface->{PROPERTIES}->{version} = "0.0"; + } + + foreach my $d (@{$data}) { + if ($d->{TYPE} eq "FUNCTION") { $count++; } + } + + if ($count == 0) { + return $res; + } + $res = "/* dcerpc server boilerplate generated by pidl */\n\n"; Boilerplate_Iface($interface); Boilerplate_Ep_Server($interface); diff --git a/source4/build/pidl/stub.pm b/source4/build/pidl/stub.pm index fde239219f..42c83a467e 100644 --- a/source4/build/pidl/stub.pm +++ b/source4/build/pidl/stub.pm @@ -60,14 +60,8 @@ sub Boilerplate_Iface($) my $count = 0; my $name = $interface->{NAME}; my $uname = uc $name; - - foreach my $d (@{$data}) { - if ($d->{TYPE} eq "FUNCTION") { $count++; } - } - - if ($count == 0) { - return; - } + my $uuid = util::make_str($interface->{PROPERTIES}->{uuid}); + my $if_version = $interface->{PROPERTIES}->{version}; pidl " static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface) @@ -88,6 +82,35 @@ static void $name\__op_unbind(struct dcesrv_connection *dce_conn, const struct d #endif } +static NTSTATUS $name\__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r) +{ + NTSTATUS status; + uint16 opnum = dce_call->pkt.u.request.opnum; + + dce_call->fault_code = 0; + + if (opnum >= dcerpc_table_$name.num_calls) { + dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR; + return NT_STATUS_NET_WRITE_FAULT; + } + + *r = talloc(mem_ctx, dcerpc_table_$name.calls[opnum].struct_size); + if (!*r) { + return NT_STATUS_NO_MEMORY; + } + + /* unravel the NDR for the packet */ + status = dcerpc_table_$name.calls[opnum].ndr_pull(pull, NDR_IN, *r); + if (!NT_STATUS_IS_OK(status)) { + dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN, + &dce_call->pkt.u.request.stub_and_verifier); + dce_call->fault_code = DCERPC_FAULT_NDR; + return NT_STATUS_NET_WRITE_FAULT; + } + + return NT_STATUS_OK; +} + static NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { uint16 opnum = dce_call->pkt.u.request.opnum; @@ -113,11 +136,29 @@ pidl " return NT_STATUS_OK; } +static NTSTATUS $name\__op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, void *r) +{ + NTSTATUS status; + uint16 opnum = dce_call->pkt.u.request.opnum; + + status = dcerpc_table_$name.calls[opnum].ndr_push(push, NDR_OUT, r); + if (!NT_STATUS_IS_OK(status)) { + dce_call->fault_code = DCERPC_FAULT_NDR; + return NT_STATUS_NET_WRITE_FAULT; + } + + return NT_STATUS_OK; +} + static const struct dcesrv_interface $name\_interface = { - &dcerpc_table_$name, + \"$name\", + $uuid, + $if_version, $name\__op_bind, $name\__op_unbind, - $name\__op_dispatch + $name\__op_ndr_pull, + $name\__op_dispatch, + $name\__op_ndr_push }; "; @@ -128,27 +169,17 @@ static const struct dcesrv_interface $name\_interface = { sub Boilerplate_Ep_Server($) { my($interface) = shift; - my($data) = $interface->{DATA}; - my $count = 0; my $name = $interface->{NAME}; my $uname = uc $name; - foreach my $d (@{$data}) { - if ($d->{TYPE} eq "FUNCTION") { $count++; } - } - - if ($count == 0) { - return; - } - pidl " static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server) { int i; - for (i=0;i<$name\_interface.ndr->endpoints->count;i++) { + for (i=0;i<dcerpc_table_$name.endpoints->count;i++) { NTSTATUS ret; - const char *name = $name\_interface.ndr->endpoints->names[i]; + const char *name = dcerpc_table_$name.endpoints->names[i]; ret = dcesrv_interface_register(dce_ctx, name, &$name\_interface, NULL); if (!NT_STATUS_IS_OK(ret)) { @@ -162,9 +193,9 @@ static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const str static BOOL $name\__op_interface_by_uuid(struct dcesrv_interface *iface, const char *uuid, uint32 if_version) { - if ($name\_interface.ndr->if_version == if_version && - strcmp($name\_interface.ndr->uuid, uuid)==0) { - memcpy(iface,&$name\_interface, sizeof(*iface)); + if (dcerpc_table_$name.if_version == if_version && + strcmp(dcerpc_table_$name.uuid, uuid)==0) { + memcpy(iface,&dcerpc_table_$name, sizeof(*iface)); return True; } @@ -173,8 +204,8 @@ static BOOL $name\__op_interface_by_uuid(struct dcesrv_interface *iface, const c static BOOL $name\__op_interface_by_name(struct dcesrv_interface *iface, const char *name) { - if (strcmp($name\_interface.ndr->name, name)==0) { - memcpy(iface,&$name\_interface, sizeof(*iface)); + if (strcmp(dcerpc_table_$name.name, name)==0) { + memcpy(iface,&dcerpc_table_$name, sizeof(*iface)); return True; } @@ -196,7 +227,7 @@ NTSTATUS dcerpc_server_$name\_init(void) ep_server.interface_by_name = $name\__op_interface_by_name; /* register ourselves with the DCERPC subsystem. */ - ret = dcerpc_register_ep_server(&ep_server); + ret = dcerpc_register_ep_server(&ep_server); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,(\"Failed to register \'$name\' endpoint server!\\n\")); @@ -212,8 +243,28 @@ NTSTATUS dcerpc_server_$name\_init(void) sub ParseInterface($) { my($interface) = shift; - $res = "/* dcom interface stub generated by pidl */\n\n"; + my($data) = $interface->{DATA}; + my $count = 0; + + $res = ""; + + if (!defined $interface->{PROPERTIES}->{uuid}) { + return $res; + } + + if (!defined $interface->{PROPERTIES}->{version}) { + $interface->{PROPERTIES}->{version} = "0.0"; + } + + foreach my $d (@{$data}) { + if ($d->{TYPE} eq "FUNCTION") { $count++; } + } + if ($count == 0) { + return $res; + } + + $res = "/* dcom interface stub generated by pidl */\n\n"; Boilerplate_Iface($interface); Boilerplate_Ep_Server($interface); |