summaryrefslogtreecommitdiff
path: root/source4/build/pidl
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2004-12-20 14:37:54 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:07:32 -0500
commitbb072199b14c0e877360475eefb89021e7ec0bcf (patch)
tree58be480b14d6340d9a758a5613f7c878e34aa3cd /source4/build/pidl
parent545c190d2a655a3d96ea6cd19f8fecb4b63555db (diff)
downloadsamba-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.pm104
-rw-r--r--source4/build/pidl/stub.pm109
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);