diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2005-02-21 14:30:49 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:10:50 -0500 |
commit | 80d3047333fceb3805ccd10a08cdf95021f57ff4 (patch) | |
tree | 16ccb10ace9efe6b52d80e8bfd3f0fd483762f23 /source4 | |
parent | 6b4cac2c00bd77c34bfe47f35729a60782b8c9c2 (diff) | |
download | samba-80d3047333fceb3805ccd10a08cdf95021f57ff4.tar.gz samba-80d3047333fceb3805ccd10a08cdf95021f57ff4.tar.bz2 samba-80d3047333fceb3805ccd10a08cdf95021f57ff4.zip |
r5490: The big (D)COM commit! :-) Contains most of the changes described in the
DCOM paper in lorikeet. This is the result of 1.5 months work (mainly
figuring out how things *really* work) at the end of 2004.
In general:
- Clearer distinction between COM and DCOM. DCOM is now merely
the glue between DCE/RPC+ORPC and COM. COM can also work without
DCOM now. This makes the code a lot clearer.
- Clearer distinction between NDR and DCOM. Before, NDR had a couple of
"if"s to cope with DCOM, which are now gone.
- Use "real" arguments rather then structures for function arguments in
COM, mainly because most of these calls are local so packing/unpacking
data for every call is too much overhead (both speed- and code-wise)
- Support several mechanisms to load class objects:
- from memory (e.g. part of the current executable, registered at start-up)
- from shared object files
- remotely
- Most things are now also named COM rather then DCOM because that's what it
really is. After an object is created, it no longer matters whether it
was created locally or remotely.
There is a very simple example class that contains
both a class factory and a class that implements the IStream interface.
It can be tested (locally only, remotely is broken at the moment)
by running the COM-SIMPLE smbtorture test.
Still to-do:
- Autogenerate parts of the class implementation code (using the coclass definitions in IDL)
- Test server-side
- Implement some of the common classes, add definitions for common interfaces.
(This used to be commit 71fd3e5c3aac5f0002001ab29d2248e6c6842d6f)
Diffstat (limited to 'source4')
29 files changed, 793 insertions, 622 deletions
diff --git a/source4/build/pidl/README b/source4/build/pidl/README index c6432a8c0e..4b675ce210 100644 --- a/source4/build/pidl/README +++ b/source4/build/pidl/README @@ -13,20 +13,32 @@ After a parse tree is present, pidl will call one of it's backends (which one depends on the options given on the command-line). Here is a list of current backends: -client.pm - Generates client call functions in C +-- Generic -- dump.pm - Converts the parse tree back to an IDL file -eparser.pm - Generates a parser for the ethereal network sniffer +validator.pm - Validates the parse tree + +-- DCE/RPC+NDR -- +client.pm - Generates client call functions in C +eparser.pm - Generates a parser for the ethereal network sniffer by + applying regexes to the output of parser.pm +swig.pm - Generates SWIG interface files (.i) header.pm - Generates a header file with structures parser.pm - Generates pull/push functions for parsing server.pm - Generates server side implementation in C template.pm - Generates stubs in C for server implementation -validator.pm - Validates the parse tree -proxy.pm - Generates proxy object for DCOM (client-side) -stub.pm - Generates stub call handler for DCOM (server-side) -Other files in this directory are: +-- COM / DCOM -- +odl.pm - Generates IDL structures from ODL structures for use in + the NDR parser generator +dcom_proxy.pm - Generates proxy object for DCOM (client-side) +dcom_stub.pm - Generates stub call handler for DCOM (server-side) +com_header.pm - Generates header file for COM interface(s) + +-- Utility modules -- tables.pl - Generates a table of available interfaces from a list of IDL files util.pm - Misc utility functions used by *.pm and pidl.pl +typelist.pm - Utility functions for keeping track of known types and their + representation in C Tips for hacking on pidl: - Look at the pidl's parse tree by using the --keep option and looking diff --git a/source4/build/pidl/com_header.pm b/source4/build/pidl/com_header.pm new file mode 100644 index 0000000000..b0523c935a --- /dev/null +++ b/source4/build/pidl/com_header.pm @@ -0,0 +1,131 @@ +# COM Header generation +# (C) 2005 Jelmer Vernooij <jelmer@samba.org> + +package COMHeader; + +use typelist; + +use strict; + +sub GetArgumentProtoList($) +{ + my $f = shift; + my $res = ""; + + foreach my $a (@{$f->{ELEMENTS}}) { + + $res .= ", " . typelist::mapType($a) . " "; + + my $l = $a->{POINTERS}; + $l-- if ($a->{TYPE} eq "string"); + foreach my $i (1..$l) { + $res .= "*"; + } + + if (defined $a->{ARRAY_LEN} && + !util::is_constant($a->{ARRAY_LEN}) && + !$a->{POINTERS}) { + $res .= "*"; + } + $res .= $a->{NAME}; + if (defined $a->{ARRAY_LEN} && util::is_constant($a->{ARRAY_LEN})) { + $res .= "[$a->{ARRAY_LEN}]"; + } + } + + return $res; +} + +sub GetArgumentList($) +{ + my $f = shift; + my $res = ""; + + foreach my $a (@{$f->{ELEMENTS}}) { + $res .= ", $a->{NAME}"; + } + + return $res; +} + +##################################################################### +# generate vtable structure for COM interface +sub HeaderVTable($) +{ + my $interface = shift; + my $res; + $res .= "#define " . uc($interface->{NAME}) . "_METHODS \\\n"; + if (defined($interface->{BASE})) { + $res .= "\t" . uc($interface->{BASE} . "_METHODS") . "\\\n"; + } + + my $data = $interface->{DATA}; + foreach my $d (@{$data}) { + $res .= "\t" . typelist::mapScalarType($d->{RETURN_TYPE}) . " (*$d->{NAME}) (struct $interface->{NAME} *d, TALLOC_CTX *mem_ctx" . GetArgumentProtoList($d) . ");\\\n" if ($d->{TYPE} eq "FUNCTION"); + } + $res .= "\n"; + $res .= "struct $interface->{NAME}_vtable {\n"; + $res .= "\t" . uc($interface->{NAME}) . "_METHODS\n"; + $res .= "};\n\n"; + + return $res; +} + +sub ParseInterface($) +{ + my $if = shift; + my $res; + + $res .="\n\n/* $if->{NAME} */\n"; + + $res .="#define COM_" . uc($if->{NAME}) . "_UUID $if->{PROPERTIES}->{uuid}\n\n"; + + $res .="struct $if->{NAME}_vtable;\n\n"; + + $res .="struct $if->{NAME} { + struct com_context *ctx; + struct $if->{NAME}_vtable *vtable; + void *object_data; +};\n\n"; + + $res.=HeaderVTable($if); + + foreach my $d (@{$if->{DATA}}) { + next if ($d->{TYPE} ne "FUNCTION"); + + $res .= "#define $if->{NAME}_$d->{NAME}(interface, mem_ctx" . GetArgumentList($d) . ") "; + + $res .= "((interface)->vtable->$d->{NAME}(interface, mem_ctx" . GetArgumentList($d) . "))"; + + $res .="\n"; + } + + return $res; +} + +sub ParseCoClass($) +{ + my $c = shift; + return "#define CLSID_$c->{NAME} $c->{PROPERTIES}->{uuid}\n\n"; +} + +sub Parse($) +{ + my $idl = shift; + my $res = ""; + + foreach my $x (@{$idl}) + { + if ($x->{TYPE} eq "INTERFACE" && util::has_property($x, "object")) { + $res.=ParseInterface($x); + } + + if ($x->{TYPE} eq "COCLASS") { + $res.=ParseCoClass($x); + } + } + + return $res; +} + +1; diff --git a/source4/build/pidl/proxy.pm b/source4/build/pidl/dcom_proxy.pm index 1eef131a6c..1a1b8de064 100644 --- a/source4/build/pidl/proxy.pm +++ b/source4/build/pidl/dcom_proxy.pm @@ -1,9 +1,12 @@ ################################################### -# DCOM proxy generator -# Copyright jelmer@samba.org 2003 +# DCOM parser for Samba +# Basically the glue between COM and DCE/RPC with NDR +# Copyright jelmer@samba.org 2003-2005 # released under the GNU GPL -package IdlProxy; +package DCOMProxy; + +use com_header; use strict; @@ -15,7 +18,7 @@ sub ParseVTable($$) my $name = shift; # Generate the vtable - $res .="\tstruct dcom_$interface->{NAME}_vtable $name = {"; + $res .="\tstruct $interface->{NAME}_vtable $name = {"; if (defined($interface->{BASE})) { $res .= "\n\t\t{},"; @@ -37,36 +40,38 @@ sub ParseRegFunc($) { my $interface = shift; - $res .= "static NTSTATUS dcom_$interface->{NAME}_init(void) + $res .= "static NTSTATUS dcom_proxy_$interface->{NAME}_init(void) { - struct dcom_interface iface; -"; - - ParseVTable($interface, "proxy"); + struct GUID base_iid; + struct GUID iid; + struct $interface->{NAME}_vtable proxy_vtable;"; if (defined($interface->{BASE})) { $res.= " const void *base_vtable; - GUID_from_string(DCERPC_" . (uc $interface->{BASE}) . "_UUID, &iface.base_iid); + GUID_from_string(DCERPC_" . (uc $interface->{BASE}) . "_UUID, &base_iid); - base_vtable = dcom_proxy_vtable_by_iid(&iface.base_iid); + base_vtable = dcom_proxy_vtable_by_iid(&base_iid); if (base_vtable == NULL) { + DEBUG(0, (\"No proxy registered for base interface\n\")); return NT_STATUS_FOOBAR; } + + memcpy(&proxy_vtable, base_vtable, sizeof(struct $interface->{BASE}_vtable)); + +"; + } + foreach my $x (@{$interface->{DATA}}) { + next unless ($x->{TYPE} eq "FUNCTION"); - proxy.base = *((const struct dcom_$interface->{BASE}_vtable *)base_vtable); - "; - } else { - $res .= "\tZERO_STRUCT(iface.base_iid);\n"; + $res .= "\tproxy_vtable.$x->{NAME} = dcom_proxy_$interface->{NAME}_$x->{NAME};\n"; } $res.= " - iface.num_methods = DCERPC_" . (uc $interface->{NAME}) . "_CALL_COUNT; - GUID_from_string(DCERPC_" . (uc $interface->{NAME}) . "_UUID, &iface.iid); - iface.proxy_vtable = talloc_memdup(talloc_autofree_context(), &proxy, sizeof(struct dcom_$interface->{NAME}_vtable)); + GUID_from_string(DCERPC_" . (uc $interface->{NAME}) . "_UUID, &iid); - return dcom_register_interface(&iface); + return dcom_register_proxy(&iid, &proxy_vtable); }\n\n"; } @@ -79,86 +84,67 @@ sub ParseFunction($$) my $name = $fn->{NAME}; my $uname = uc $name; - if (util::has_property($fn, "local")) { - $res .= " -static NTSTATUS dcom_proxy_$interface->{NAME}_$name(struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r) -{ - /* FIXME */ - return NT_STATUS_NOT_SUPPORTED; -}\n"; - } else { - $res .= " -static struct rpc_request *dcom_proxy_$interface->{NAME}_$name\_send(struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r) + $res.=" +static $fn->{RETURN_TYPE} dcom_proxy_$interface->{NAME}_$name(struct $interface->{NAME} *d, TALLOC_CTX *mem_ctx" . COMHeader::GetArgumentProtoList($fn) . ") { struct dcerpc_pipe *p; NTSTATUS status = dcom_get_pipe(d, &p); + struct $name r; + struct rpc_request *req; if (NT_STATUS_IS_ERR(status)) { - return NULL; + return status; } - ZERO_STRUCT(r->in.ORPCthis); - r->in.ORPCthis.version.MajorVersion = COM_MAJOR_VERSION; - r->in.ORPCthis.version.MinorVersion = COM_MINOR_VERSION; + ZERO_STRUCT(r.in.ORPCthis); + r.in.ORPCthis.version.MajorVersion = COM_MAJOR_VERSION; + r.in.ORPCthis.version.MinorVersion = COM_MINOR_VERSION; +"; + + # Put arguments into r + foreach my $a (@{$fn->{DATA}}) { + next if ($a->{NAME} eq "ORPCthis"); + next unless (util::has_property($a, "in")); + $res .= "\tr.in.$a->{NAME} = $a->{NAME};\n"; + } + $res .=" if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) { - NDR_PRINT_IN_DEBUG($name, r); + NDR_PRINT_IN_DEBUG($name, &r); } - return dcerpc_ndr_request_send(p, &d->ipid, &dcerpc_table_$interface->{NAME}, DCERPC_$uname, mem_ctx, r); -} - -static NTSTATUS dcom_proxy_$interface->{NAME}_$name(struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r) -{ - struct dcerpc_pipe *p; - NTSTATUS status = dcom_get_pipe(d, &p); - struct rpc_request *req; + status = dcerpc_ndr_request(p, &d->ipid, &dcerpc_table_$interface->{NAME}, DCERPC_$uname, mem_ctx, &r); - if (NT_STATUS_IS_ERR(status)) { - return status; + if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) { + NDR_PRINT_OUT_DEBUG($name, r); } - req = dcom_proxy_$interface->{NAME}_$name\_send(d, mem_ctx, r); - if (req == NULL) return NT_STATUS_NO_MEMORY; - - status = dcerpc_ndr_request_recv(req); +"; - if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) { - NDR_PRINT_OUT_DEBUG($name, r); + # Put r info back into arguments + foreach my $a (@{$fn->{DATA}}) { + next if ($a->{NAME} eq "ORPCthat"); + next unless (util::has_property($a, "out")); + $res .= "\t*$a->{NAME} = r.out.$a->{NAME};\n"; } - "; + if ($fn->{RETURN_TYPE} eq "NTSTATUS") { - $res .= "\tif (NT_STATUS_IS_OK(status)) status = r->out.result;\n"; + $res .= "\tif (NT_STATUS_IS_OK(status)) status = r.out.result;\n"; } + $res .= " - return status; -}"; - } - - $res .=" -NTSTATUS dcom_$interface->{NAME}_$name (struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r) -{ - const struct dcom_$interface->{NAME}_vtable *table = d->vtable; - - if (table->$name == NULL) { - DEBUG(0, (\"Object does not implement $name of interface $interface->{NAME}\\n\")); - return NT_STATUS_NOT_IMPLEMENTED; - } - - return table->$name (d, mem_ctx, r); -} -"; + return r.out.result; +}\n\n"; } - ##################################################################### # parse the interface definitions sub ParseInterface($) { my($interface) = shift; my($data) = $interface->{DATA}; - $res = "/* DCOM proxy generated by pidl */\n\n"; + $res = "/* DCOM proxy for $interface->{NAME} generated by pidl */\n\n"; foreach my $d (@{$data}) { ($d->{TYPE} eq "FUNCTION") && ParseFunction($interface, $d); @@ -172,7 +158,7 @@ sub RegistrationFunction($$) my $idl = shift; my $basename = shift; - my $res = "NTSTATUS dcom_$basename\_init(void)\n"; + my $res = "\n\nNTSTATUS dcom_$basename\_init(void)\n"; $res .= "{\n"; $res .="\tNTSTATUS status = NT_STATUS_OK;\n"; foreach my $interface (@{$idl}) { @@ -198,4 +184,20 @@ sub RegistrationFunction($$) return $res; } +sub Parse($) +{ + my $pidl = shift; + my $res = ""; + + foreach my $x (@{$pidl}) { + next if ($x->{TYPE} ne "INTERFACE"); + next if util::has_property($x, "local"); + next unless util::has_property($x, "object"); + + $res .= ParseInterface($x); + } + + return $res; +} + 1; diff --git a/source4/build/pidl/stub.pm b/source4/build/pidl/dcom_stub.pm index 53be35b216..024037e2e8 100644 --- a/source4/build/pidl/stub.pm +++ b/source4/build/pidl/dcom_stub.pm @@ -1,11 +1,11 @@ ################################################### -# stub boilerplate generator -# Copyright jelmer@samba.org 2004 +# DCOM stub boilerplate generator +# Copyright jelmer@samba.org 2004-2005 # Copyright tridge@samba.org 2003 # Copyright metze@samba.org 2004 # released under the GNU GPL -package IdlStub; +package DCOMStub; use strict; @@ -16,7 +16,6 @@ sub pidl($) $res .= shift; } - ##################################################### # generate the switch statement for function dispatch sub gen_dispatch_switch($) @@ -290,6 +289,9 @@ NTSTATUS dcerpc_server_$name\_init(void) sub ParseInterface($) { my($interface) = shift; + + return "" if util::has_property($interface, "local"); + my($data) = $interface->{DATA}; my $count = 0; diff --git a/source4/build/pidl/header.pm b/source4/build/pidl/ndr_header.pm index eeb2886bce..c928ee1db3 100644 --- a/source4/build/pidl/header.pm +++ b/source4/build/pidl/ndr_header.pm @@ -3,7 +3,7 @@ # Copyright tridge@samba.org 2000 # released under the GNU GPL -package IdlHeader; +package NdrHeader; use strict; use needed; @@ -337,30 +337,10 @@ sub HeaderFnProto($$) pidl "void ndr_print_$name(struct ndr_print *ndr, const char *name, int flags, struct $name *r);\n"; - if (util::has_property($interface, "object")) { - pidl "NTSTATUS dcom_$interface->{NAME}_$name (struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r);\n"; - } else { - pidl "NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n"; - pidl "struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n"; - } - pidl "\n"; -} - -##################################################################### -# generate vtable structure for DCOM interface -sub HeaderVTable($) -{ - my $interface = shift; - pidl "struct dcom_$interface->{NAME}_vtable {\n"; - if (defined($interface->{BASE})) { - pidl "\tstruct dcom_$interface->{BASE}\_vtable base;\n"; - } + pidl "NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n"; + pidl "struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n"; - my $data = $interface->{DATA}; - foreach my $d (@{$data}) { - pidl "\tNTSTATUS (*$d->{NAME}) (struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $d->{NAME} *r);\n" if ($d->{TYPE} eq "FUNCTION"); - } - pidl "};\n\n"; + pidl "\n"; } ##################################################################### @@ -439,9 +419,6 @@ sub HeaderInterface($) HeaderFnProto($interface, $d); } - (util::has_property($interface, "object")) && - HeaderVTable($interface); - pidl "#endif /* _HEADER_NDR_$interface->{NAME} */\n"; } diff --git a/source4/build/pidl/pidl.pl b/source4/build/pidl/pidl.pl index b535215d03..f7b213dcb0 100755 --- a/source4/build/pidl/pidl.pl +++ b/source4/build/pidl/pidl.pl @@ -15,12 +15,13 @@ use Getopt::Long; use File::Basename; use idl; use dump; -use header; +use ndr_header; +use ndr; use server; use client; -use proxy; -use stub; -use ndr; +use dcom_proxy; +use dcom_stub; +use com_header; use odl; use eparser; use validator; @@ -41,6 +42,8 @@ my($opt_parser) = 0; my($opt_eparser) = 0; my($opt_keep) = 0; my($opt_swig) = 0; +my($opt_dcom_proxy) = 0; +my($opt_com_header) = 0; my($opt_odl) = 0; my($opt_output); @@ -62,27 +65,29 @@ sub IdlParse($) sub ShowHelp() { print " - perl IDL parser and code generator - Copyright (C) tridge\@samba.org - - Usage: pidl.pl [options] <idlfile> - - Options: - --help this help page - --output OUTNAME put output in OUTNAME.* - --parse parse a idl file to a .pidl file - --dump dump a pidl file back to idl - --header create a C header file - --parser create a C NDR parser - --client create a C client - --server create server boilerplate - --template print a template for a pipe - --eparser create an ethereal parser - --swig create swig wrapper file - --diff run diff on the idl and dumped output - --keep keep the .pidl file - --odl accept ODL input - \n"; + perl IDL parser and code generator + Copyright (C) tridge\@samba.org + + Usage: pidl.pl [options] <idlfile> + + Options: + --help this help page + --output OUTNAME put output in OUTNAME.* + --parse parse a idl file to a .pidl file + --dump dump a pidl file back to idl + --header create a C header file + --parser create a C NDR parser + --client create a C client + --server create server boilerplate + --template print a template for a pipe + --eparser create an ethereal parser + --swig create swig wrapper file + --diff run diff on the idl and dumped output + --keep keep the .pidl file + --odl accept ODL input + --dcom-proxy create DCOM proxy (implies --odl) + --com-header create header for COM interfaces (implies --odl) + \n"; exit(0); } @@ -101,7 +106,9 @@ GetOptions ( 'diff' => \$opt_diff, 'odl' => \$opt_odl, 'keep' => \$opt_keep, - 'swig' => \$opt_swig + 'swig' => \$opt_swig, + 'dcom-proxy' => \$opt_dcom_proxy, + 'com-header' => \$opt_com_header ); if ($opt_help) { @@ -113,7 +120,6 @@ sub process_file($) { my $idl_file = shift; my $output; - my $podl; my $pidl; my $basename = basename($idl_file, ".idl"); @@ -144,18 +150,48 @@ sub process_file($) print IdlDump::Dump($pidl); } - if ($opt_header || $opt_parser) { + if ($opt_diff) { + my($tempfile) = util::ChangeExtension($output, ".tmp"); + util::FileSave($tempfile, IdlDump::Dump($pidl)); + system("diff -wu $idl_file $tempfile"); + unlink($tempfile); + } + + if ($opt_header || $opt_parser || $opt_com_header || $opt_dcom_proxy) { typelist::LoadIdl($pidl); } + if ($opt_com_header) { + my $res = COMHeader::Parse($pidl); + if ($res) { + my $h_filename = dirname($output) . "/com_$basename.h"; + util::FileSave($h_filename, + "#include \"librpc/gen_ndr/ndr_orpc.h\"\n" . + "#include \"librpc/gen_ndr/ndr_$basename.h\"\n" . + $res); + } + $opt_odl = 1; + } + + if ($opt_dcom_proxy) { + my $res = DCOMProxy::Parse($pidl); + if ($res) { + my ($client) = util::ChangeExtension($output, "_p.c"); + util::FileSave($client, + "#include \"includes.h\"\n" . + "#include \"librpc/gen_ndr/com_$basename.h\"\n" . + "#include \"lib/dcom/common/orpc.h\"\n". $res); + } + $opt_odl = 1; + } + if ($opt_odl) { - $podl = $pidl; - $pidl = ODL::ODL2IDL($podl); + $pidl = ODL::ODL2IDL($pidl); } if ($opt_header) { my($header) = util::ChangeExtension($output, ".h"); - util::FileSave($header, IdlHeader::Parse($pidl)); + util::FileSave($header, NdrHeader::Parse($pidl)); if ($opt_eparser) { my($eparserhdr) = dirname($output) . "/packet-dcerpc-$basename.h"; IdlEParser::RewriteHeader($pidl, $header, $eparserhdr); @@ -172,23 +208,14 @@ sub process_file($) my ($client) = util::ChangeExtension($output, "_c.c"); my $res = ""; my $h_filename = util::ChangeExtension($output, ".h"); - my $need_dcom_register = 0; $res .= "#include \"includes.h\"\n"; $res .= "#include \"$h_filename\"\n\n"; foreach my $x (@{$pidl}) { - if (util::has_property($x, "object")) { - $res .= IdlProxy::ParseInterface($x); - $need_dcom_register = 1; - } else { - $res .= IdlClient::ParseInterface($x); - } + $res .= IdlClient::ParseInterface($x); } - if ($need_dcom_register) { - $res .= IdlProxy::RegistrationFunction($pidl, $basename); - } util::FileSave($client, $res); } @@ -201,7 +228,7 @@ sub process_file($) next if ($x->{TYPE} ne "INTERFACE"); if (util::has_property($x, "object")) { - $dcom .= IdlStub::ParseInterface($x); + $dcom .= DCOMStub::ParseInterface($x); } else { $plain .= IdlServer::ParseInterface($x); } @@ -233,13 +260,6 @@ $dcom } } - if ($opt_diff) { - my($tempfile) = util::ChangeExtension($output, ".tmp"); - util::FileSave($tempfile, IdlDump::Dump($pidl)); - system("diff -wu $idl_file $tempfile"); - unlink($tempfile); - } - if ($opt_template) { print IdlTemplate::Parse($pidl); } diff --git a/source4/build/smb_build/main.pm b/source4/build/smb_build/main.pm index 76b7b3d210..c401bc8de6 100644 --- a/source4/build/smb_build/main.pm +++ b/source4/build/smb_build/main.pm @@ -30,7 +30,6 @@ sub smb_build_main($) "auth/config.mk", "nsswitch/config.mk", "lib/basic.mk", - "lib/dcom/config.mk", "lib/socket/config.mk", "lib/ldb/config.mk", "lib/talloc/config.mk", @@ -58,6 +57,8 @@ sub smb_build_main($) "libcli/libsmb.mk", "libcli/config.mk", "libcli/security/config.mk", + "lib/dcom/config.mk", + "lib/com/config.mk", "scripting/swig/config.mk", ); diff --git a/source4/include/includes.h b/source4/include/includes.h index 2e04e365eb..be100c6390 100644 --- a/source4/include/includes.h +++ b/source4/include/includes.h @@ -127,11 +127,11 @@ extern int errno; #include "librpc/gen_ndr/ndr_misc.h" #include "librpc/gen_ndr/ndr_dcerpc.h" #include "librpc/rpc/dcerpc.h" -#include "lib/dcom/common/dcom.h" -#include "librpc/gen_ndr/ndr_dcom.h" #include "smb_interfaces.h" #include "ntvfs/ntvfs.h" #include "cli_context.h" +#include "lib/com/com.h" +#include "lib/dcom/common/dcom.h" #define malloc_p(type) (type *)malloc(sizeof(type)) #define malloc_array_p(type, count) (type *)realloc_array(NULL, sizeof(type), count) diff --git a/source4/lib/com/classes/simple.c b/source4/lib/com/classes/simple.c new file mode 100644 index 0000000000..2c72d56f94 --- /dev/null +++ b/source4/lib/com/classes/simple.c @@ -0,0 +1,116 @@ +/* + Unix SMB/CIFS implementation. + Simple class + Copyright (C) 2004-2005 Jelmer Vernooij <jelmer@samba.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/com/com.h" +#include "librpc/gen_ndr/com_dcom.h" + + +static WERROR simple_QueryInterface (struct IUnknown *d, TALLOC_CTX *mem_ctx, struct GUID *iid, struct IUnknown **iun) +{ + *iun = d; + return WERR_OK; +} + +static uint32_t simple_AddRef (struct IUnknown *d, TALLOC_CTX *mem_ctx) +{ + return 1; +} + +static uint32_t simple_Release (struct IUnknown *d, TALLOC_CTX *mem_ctx) +{ + return 1; +} + +static WERROR simple_Read (struct IStream *d, TALLOC_CTX *mem_ctx, uint8_t *pv, uint32_t num_requested, uint32_t *num_readx, uint32_t num_read) +{ + printf("%d bytes are being read\n", num_read); + return WERR_OK; +} + +static WERROR simple_Write (struct IStream *d, TALLOC_CTX *mem_ctx, uint8_t *data, uint32_t num_requested, uint32_t num_written) +{ + printf("%d bytes are being written\n", num_requested); + return WERR_OK; +} + +static struct IStream_vtable simple_istream_vtable = { + simple_QueryInterface, + simple_AddRef, + simple_Release, + simple_Read, + simple_Write +}; + +static WERROR simpleclass_QueryInterface (struct IUnknown *d, TALLOC_CTX *mem_ctx, struct GUID *iid, struct IUnknown **iun) +{ + /* FIXME: Return WERR_IFACE_NOT_SUPPORTED if IID != IID_IUNKNOWN and IID != IID_CLASSFACTORY */ + *iun = d; + return WERR_OK; +} + +static WERROR simpleclass_CreateInstance (struct IClassFactory *d, TALLOC_CTX *mem_ctx, struct IUnknown *iunk, struct GUID *iid, struct IUnknown **ppv) +{ + struct IStream *ret; + /* FIXME: Check whether IID == ISTREAM_IID */ + ret = talloc(mem_ctx, struct IStream); + ret->ctx = NULL; + ret->vtable = &simple_istream_vtable; + ret->object_data = NULL; + + *ppv = ret; + + return WERR_OK; +} + +static uint32_t simpleclass_AddRef (struct IUnknown *d, TALLOC_CTX *mem_ctx) +{ + return 1; +} + +static uint32_t simpleclass_Release (struct IUnknown *d, TALLOC_CTX *mem_ctx) +{ + return 1; +} + +/* Everything below this line should be autogenerated later on */ +static struct IClassFactory_vtable simple_classobject_vtable = { + simpleclass_QueryInterface, + simpleclass_AddRef, + simpleclass_Release, + simpleclass_CreateInstance, + NULL, + NULL, + NULL +}; + +NTSTATUS com_simple_init(void) +{ + struct GUID clsid; + struct IUnknown *class_object = talloc(talloc_autofree_context(), struct IUnknown); + + class_object->ctx = NULL; + class_object->object_data = NULL; + class_object->vtable = (struct IUnknown_vtable *)&simple_classobject_vtable; + + GUID_from_string("5e9ddec7-5767-11cf-beab-00aa006c3606", &clsid); + + return com_register_running_class(&clsid, "Samba.Simple", class_object); +} diff --git a/source4/lib/com/com.h b/source4/lib/com/com.h new file mode 100644 index 0000000000..be7dcde5b5 --- /dev/null +++ b/source4/lib/com/com.h @@ -0,0 +1,30 @@ +/* + Unix SMB/CIFS implementation. + COM standard objects + Copyright (C) Jelmer Vernooij 2004-2005. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _COM_H /* _COM_H */ +#define _COM_H + +struct com_context +{ +}; + +typedef struct IUnknown *(*get_class_object_function) (const struct GUID *clsid); + +#endif /* _COM_H */ diff --git a/source4/lib/com/config.mk b/source4/lib/com/config.mk new file mode 100644 index 0000000000..006ea212c1 --- /dev/null +++ b/source4/lib/com/config.mk @@ -0,0 +1,10 @@ +[SUBSYSTEM::LIBCOM] +INIT_OBJ_FILES = \ + lib/com/tables.o \ + lib/com/rot.o \ + lib/com/main.o + +[MODULE::com_simple] +SUBSYSTEM = LIBCOM +INIT_OBJ_FILES = lib/com/classes/simple.o +INIT_FUNCTION = com_simple_init diff --git a/source4/lib/com/main.c b/source4/lib/com/main.c new file mode 100644 index 0000000000..378c3738b9 --- /dev/null +++ b/source4/lib/com/main.c @@ -0,0 +1,85 @@ +/* + Unix SMB/CIFS implementation. + Main COM functionality + Copyright (C) 2004 Jelmer Vernooij <jelmer@samba.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "dlinklist.h" +#include "lib/com/com.h" +#include "librpc/gen_ndr/com_dcom.h" + +WERROR com_init(struct com_context **ctx) +{ + *ctx = talloc(NULL, struct com_context); + return WERR_OK; +} + +WERROR com_create_object(struct com_context *ctx, struct GUID *clsid, int num_ifaces, struct GUID *iid, struct IUnknown **ip, WERROR *results) +{ + struct IUnknown *iunk = NULL; + struct IClassFactory *factory; + WERROR error; + int i; + struct GUID classfact_iid; + + GUID_from_string(DCERPC_ICLASSFACTORY_UUID, &classfact_iid); + + /* Obtain class object */ + error = com_get_class_object(ctx, clsid, &classfact_iid, (struct IUnknown **)&factory); + if (!W_ERROR_IS_OK(error)) { + DEBUG(3, ("Unable to obtain class object for %s\n", GUID_string(NULL, clsid))); + return error; + } + + /* Run IClassFactory::CreateInstance() */ + error = IClassFactory_CreateInstance(factory, ctx, NULL, &classfact_iid, &iunk); + if (!W_ERROR_IS_OK(error)) { + DEBUG(3, ("Error while calling IClassFactory::CreateInstance : %s\n", win_errstr(error))); + return error; + } + + if (!iunk) { + DEBUG(0, ("IClassFactory_CreateInstance returned success but result pointer is still NULL!\n")); + return WERR_GENERAL_FAILURE; + } + + /* Release class object */ + IUnknown_Release(factory, ctx); + + error = WERR_OK; + + /* Do one or more QueryInterface calls */ + for (i = 0; i < num_ifaces; i++) { + results[i] = IUnknown_QueryInterface(iunk, ctx, &iid[i], &ip[i]); + if (!W_ERROR_IS_OK(results[i])) error = results[i]; + } + + return error; +} + +WERROR com_get_class_object(struct com_context *ctx, struct GUID *clsid, struct GUID *iid, struct IUnknown **ip) +{ + struct IUnknown *iu; + + iu = com_class_by_clsid(ctx, clsid); + if (!iu) { + return WERR_CLASS_NOT_REGISTERED; + } + + return IUnknown_QueryInterface(iu, ctx, iid, ip); +} diff --git a/source4/lib/dcom/common/rot.c b/source4/lib/com/rot.c index 7acdbe066e..34a5671f5b 100644 --- a/source4/lib/dcom/common/rot.c +++ b/source4/lib/com/rot.c @@ -3,7 +3,7 @@ Running object table functions - Copyright (C) Jelmer Vernooij 2004 + Copyright (C) Jelmer Vernooij 2004-2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source4/lib/com/tables.c b/source4/lib/com/tables.c new file mode 100644 index 0000000000..cf63e7e9a2 --- /dev/null +++ b/source4/lib/com/tables.c @@ -0,0 +1,107 @@ +/* + Unix SMB/CIFS implementation. + COM class tables + Copyright (C) 2004 Jelmer Vernooij <jelmer@samba.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "dlinklist.h" + +/* Specific implementation of one or more interfaces */ +struct com_class +{ + const char *progid; + struct GUID clsid; + + struct IUnknown *class_object; + struct com_class *prev, *next; +} * running_classes = NULL; + +static struct IUnknown *get_com_class_running(const struct GUID *clsid) +{ + struct com_class *c = running_classes; + + while(c) { + + if (GUID_equal(clsid, &c->clsid)) { + return c->class_object; + } + + c = c->next; + } + + return NULL; +} + +static struct IUnknown *get_com_class_so(TALLOC_CTX *mem_ctx, const struct GUID *clsid) +{ + char *mod_name; + char *clsid_str; + void *mod; + get_class_object_function f; + + clsid_str = GUID_string(mem_ctx, clsid); + mod_name = talloc_asprintf(mem_ctx, "%s.so", clsid_str); + talloc_free(clsid_str); + + mod = sys_dlopen(mod_name, 0); + + if (!mod) { + return NULL; + } + + f = sys_dlsym(mod, "get_class_object"); + + if (!f) { + return NULL; + } + + return f(clsid); +} + +struct IUnknown *com_class_by_clsid(struct com_context *ctx, const struct GUID *clsid) +{ + struct IUnknown *c; + + /* Check list of running COM classes first */ + c = get_com_class_running(clsid); + + if (c != NULL) { + return c; + } + + c = get_com_class_so(ctx, clsid); + + if (c != NULL) { + return c; + } + + return NULL; +} + +NTSTATUS com_register_running_class(struct GUID *clsid, const char *progid, struct IUnknown *p) +{ + struct com_class *l = talloc_zero(running_classes?running_classes:talloc_autofree_context(), struct com_class); + + l->clsid = *clsid; + l->progid = talloc_strdup(l, progid); + l->class_object = p; + + DLIST_ADD(running_classes, l); + + return NT_STATUS_OK; +} diff --git a/source4/lib/dcom/classes/simple.c b/source4/lib/dcom/classes/simple.c deleted file mode 100644 index 13cf4616b2..0000000000 --- a/source4/lib/dcom/classes/simple.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Simple class - Copyright (C) 2004 Jelmer Vernooij <jelmer@samba.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#include "lib/dcom/common/dcom.h" - -NTSTATUS simple_QueryInterface (struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct QueryInterface *r) -{ - return NT_STATUS_NOT_SUPPORTED; -} - -static NTSTATUS simple_CreateInstance (struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct CreateInstance *r) -{ - return NT_STATUS_NOT_SUPPORTED; -} - -/* Everything below this line should be autogenerated later on */ - -static struct dcom_IClassFactory_vtable simple_classobject = { - { simple_QueryInterface, NULL, NULL }, - simple_CreateInstance, - NULL, - NULL, - NULL -}; - -NTSTATUS dcom_simple_init(void) -{ - struct GUID iid; - struct dcom_class simple_class = { - "Samba.Simple", - }; - - GUID_from_string(DCERPC_IUNKNOWN_UUID, &iid); - - simple_class.class_object = dcom_new_local_ifacep( - talloc_autofree_context(), - &iid, - &simple_classobject, NULL); - - if (!simple_class.class_object) { - DEBUG(1, ("Unable to create class object for simple class\n")); - return NT_STATUS_OK; - } - - GUID_from_string("5e9ddec7-5767-11cf-beab-00aa006c3606", &simple_class.clsid); - - return dcom_register_class(&simple_class); -} diff --git a/source4/lib/dcom/common/dcom.h b/source4/lib/dcom/common/dcom.h index 0bc4a256f1..dd21bb9d29 100644 --- a/source4/lib/dcom/common/dcom.h +++ b/source4/lib/dcom/common/dcom.h @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. DCOM standard objects - Copyright (C) Jelmer Vernooij 2004. + Copyright (C) Jelmer Vernooij 2004-2005. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,11 +23,6 @@ #include "librpc/ndr/ndr_dcom.h" -struct IUnknown_AddRef; -struct IUnknown_Release; -struct IUnknown_QueryInterface; -struct dcom_interface_p; - struct dcom_context { struct dcom_object_exporter { @@ -49,34 +44,16 @@ struct dcom_context uint32_t dcerpc_flags; }; -/* Specific implementation of one or more interfaces */ -struct dcom_class -{ - const char *prog_id; - struct GUID clsid; - - /* IUnknown */ - struct dcom_interface_p *class_object; -}; - -struct dcom_interface -{ - struct GUID iid; - int num_methods; - struct GUID base_iid; - const void *proxy_vtable; -}; - struct dcom_interface_p { - struct dcom_context *ctx; - const struct dcom_interface *interface; + struct com_context *ctx; + const struct com_interface *interface; const void *vtable; /* Points to one of the available implementations */ struct GUID ipid; - struct dcom_object *object; + struct com_object *object; int objref_flags; int orpc_flags; - struct dcom_object_exporter *ox; + struct com_object_exporter *ox; uint32_t private_references; }; diff --git a/source4/lib/dcom/common/main.c b/source4/lib/dcom/common/main.c index a8324606f1..315912ba3c 100644 --- a/source4/lib/dcom/common/main.c +++ b/source4/lib/dcom/common/main.c @@ -117,7 +117,7 @@ WERROR dcom_init(struct dcom_context **ctx, const char *domain, const char *user return WERR_OK; } -static struct dcom_object_exporter *oxid_mapping_by_oxid (struct dcom_context *ctx, uint64_t oxid) +struct dcom_object_exporter *oxid_mapping_by_oxid (struct dcom_context *ctx, uint64_t oxid) { struct dcom_object_exporter *m; @@ -144,7 +144,7 @@ WERROR dcom_ping(struct dcom_context *ctx) return WERR_OK; } -static WERROR dcom_create_object_remote(struct dcom_context *ctx, struct GUID *clsid, const char *server, int num_ifaces, struct GUID *iid, struct dcom_interface_p ***ip, WERROR *results) +static WERROR dcom_create_object(struct dcom_context *ctx, struct GUID *clsid, const char *server, int num_ifaces, struct GUID *iid, struct dcom_interface_p ***ip, WERROR *results) { uint16_t protseq[] = DCOM_NEGOTIATED_PROTOCOLS; struct dcerpc_pipe *p; @@ -154,6 +154,10 @@ static WERROR dcom_create_object_remote(struct dcom_context *ctx, struct GUID *c struct DUALSTRINGARRAY dualstring; int i; + if (!server) { + return com_create_object(ctx, clsid, num_ifaces, iid, ip, results); + } + status = dcom_connect_host(ctx, &p, server); if (NT_STATUS_IS_ERR(status)) { DEBUG(1, ("Unable to connect to %s - %s\n", server, nt_errstr(status))); @@ -208,60 +212,7 @@ static WERROR dcom_create_object_remote(struct dcom_context *ctx, struct GUID *c return WERR_OK; } -WERROR dcom_create_object(struct dcom_context *ctx, struct GUID *clsid, const char *server, int num_ifaces, struct GUID *iid, struct dcom_interface_p ***ip, WERROR *results) -{ - struct dcom_interface_p *factory, *iunk = NULL; - struct QueryInterface qr; - struct Release rr; - struct CreateInstance cr; - WERROR error; - int i; - NTSTATUS status; - - if (server != NULL) { - return dcom_create_object_remote(ctx, clsid, server, num_ifaces, iid, ip, results); - } - - /* Obtain class object */ - error = dcom_get_class_object(ctx, clsid, server, iid, &factory); - if (!W_ERROR_IS_OK(error)) { - DEBUG(3, ("Unable to obtain class object for %s\n", GUID_string(NULL, clsid))); - return error; - } - - dcom_OBJREF_from_ifacep(ctx, &cr.in.pUnknown->obj, factory); - - GUID_from_string(DCERPC_ICLASSFACTORY_UUID, cr.in.iid); - - /* Run IClassFactory::CreateInstance() */ - status = dcom_IClassFactory_CreateInstance(factory, ctx, &cr); - if (NT_STATUS_IS_ERR(status)) { - DEBUG(3, ("Error while calling IClassFactory::CreateInstance : %s\n", nt_errstr(status))); - return ntstatus_to_werror(status); - } - - /* Release class object */ - status = dcom_IUnknown_Release(factory, ctx, &rr); - if (NT_STATUS_IS_ERR(status)) { - DEBUG(3, ("Error freeing class factory: %s\n", nt_errstr(status))); - return ntstatus_to_werror(status); - } - - /* Do one or more QueryInterface calls */ - for (i = 0; i < num_ifaces; i++) { - qr.in.iid = &iid[i]; - status = dcom_IUnknown_QueryInterface(iunk, ctx, &qr); - if (NT_STATUS_IS_ERR(status)) { - DEBUG(4, ("Error obtaining interface %s : %s\n", GUID_string(NULL, &iid[i]), nt_errstr(status))); - return ntstatus_to_werror(status); - } - results[i] = qr.out.result; - } - - return WERR_OK; -} - -WERROR dcom_get_class_object_remote(struct dcom_context *ctx, struct GUID *clsid, const char *server, struct GUID *iid, struct dcom_interface_p **ip) +WERROR dcom_get_class_object(struct dcom_context *ctx, struct GUID *clsid, const char *server, struct GUID *iid, struct dcom_interface_p **ip) { struct dcom_object_exporter *m; struct RemoteActivation r; @@ -271,6 +222,10 @@ WERROR dcom_get_class_object_remote(struct dcom_context *ctx, struct GUID *clsid struct pMInterfacePointer pm; uint16_t protseq[] = DCOM_NEGOTIATED_PROTOCOLS; + if (!server) { + return com_get_class_object(ctx, clsid, iid, ip); + } + status = dcom_connect_host(ctx, &p, server); if (NT_STATUS_IS_ERR(status)) { DEBUG(1, ("Unable to connect to %s - %s\n", server, nt_errstr(status))); @@ -312,36 +267,6 @@ WERROR dcom_get_class_object_remote(struct dcom_context *ctx, struct GUID *clsid return WERR_OK; } -WERROR dcom_get_class_object(struct dcom_context *ctx, struct GUID *clsid, const char *server, struct GUID *iid, struct dcom_interface_p **ip) -{ - const struct dcom_class *c; - struct QueryInterface qi; - NTSTATUS status; - - if (server != NULL) { - return dcom_get_class_object_remote(ctx, clsid, server, iid, ip); - } - - c = dcom_class_by_clsid(clsid); - if (!c) { - /* FIXME: Better error code.. */ - return WERR_DEST_NOT_FOUND; - } - - qi.in.iid = iid; - - status = dcom_IUnknown_QueryInterface(c->class_object, ctx, &qi ); - if (NT_STATUS_IS_ERR(status)) { - return ntstatus_to_werror(status); - } - - if (!W_ERROR_IS_OK(qi.out.result)) { return qi.out.result; } - - dcom_ifacep_from_OBJREF(ctx, ip, &qi.out.data->obj); - - return WERR_OK; -} - NTSTATUS dcom_get_pipe (struct dcom_interface_p *iface, struct dcerpc_pipe **pp) { struct dcerpc_binding binding; @@ -549,26 +474,3 @@ uint64_t dcom_get_current_oxid(void) { return getpid(); } - -struct dcom_interface_p *dcom_new_local_ifacep(struct dcom_context *ctx, const struct GUID *iid, void *vtable, struct dcom_object *object) -{ - struct dcom_interface_p *ip = talloc(ctx, struct dcom_interface_p); - const struct dcom_interface *iface = dcom_interface_by_iid(iid); - - if (!iface) { - DEBUG (1, ("Unable to find interface with IID %s\n", GUID_string(ctx, iid))); - return NULL; - } - - ip->ctx = ctx; - ip->interface = iface; - ip->vtable = vtable; - ip->ipid = GUID_random(); - ip->object = object; - ip->objref_flags = 0; - ip->orpc_flags = 0; - ip->ox = NULL; - ip->private_references = 1; - - return ip; -} diff --git a/source4/lib/dcom/common/tables.c b/source4/lib/dcom/common/tables.c deleted file mode 100644 index cd7e0867ee..0000000000 --- a/source4/lib/dcom/common/tables.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - Unix SMB/CIFS implementation. - DCOM interface and class tables - Copyright (C) 2004 Jelmer Vernooij <jelmer@samba.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#include "dlinklist.h" - -static struct class_list { - struct class_list *prev, *next; - struct dcom_class class; -} *classes = NULL; - -static struct interface_list { - struct interface_list *prev, *next; - struct dcom_interface interface; -} *interfaces = NULL; - -const struct dcom_interface *dcom_interface_by_iid(const struct GUID *iid) -{ - struct interface_list *l = interfaces; - - while(l) { - - if (GUID_equal(iid, &l->interface.iid)) - return &l->interface; - - l = l->next; - } - - return NULL; -} - -const struct dcom_class *dcom_class_by_clsid(const struct GUID *clsid) -{ - struct class_list *c = classes; - - while(c) { - - if (GUID_equal(clsid, &c->class.clsid)) { - return &c->class; - } - - c = c->next; - } - - return NULL; -} - -const void *dcom_proxy_vtable_by_iid(const struct GUID *iid) -{ - const struct dcom_interface *iface = dcom_interface_by_iid(iid); - - if (!iface) { - return NULL; - } - - return iface->proxy_vtable; -} - -NTSTATUS dcom_register_interface(const void *_iface) -{ - const struct dcom_interface *iface = _iface; - struct interface_list *l; - TALLOC_CTX *lcl_ctx = talloc_init("dcom_register_interface"); - - DEBUG(5, ("Adding DCOM interface %s\n", GUID_string(lcl_ctx, &iface->iid))); - - talloc_free(lcl_ctx); - - l = talloc_zero(interfaces?interfaces:talloc_autofree_context(), - struct interface_list); - - l->interface = *iface; - - DLIST_ADD(interfaces, l); - - return NT_STATUS_OK; -} - -NTSTATUS dcom_register_class(const void *_class) -{ - const struct dcom_class *class = _class; - struct class_list *l = talloc_zero(classes?classes:talloc_autofree_context(), - struct class_list); - - l->class = *class; - - DLIST_ADD(classes, l); - - return NT_STATUS_OK; -} diff --git a/source4/lib/dcom/config.mk b/source4/lib/dcom/config.mk index ca280884ea..ae8fe9c4b0 100644 --- a/source4/lib/dcom/config.mk +++ b/source4/lib/dcom/config.mk @@ -1,19 +1,19 @@ ################################################ # Start SUBSYSTEM LIBDCOM -[SUBSYSTEM::LIBDCOM] -INIT_OBJ_FILES = \ - lib/dcom/common/main.o \ - lib/dcom/common/tables.o \ - lib/dcom/common/rot.o -REQUIRED_SUBSYSTEMS = DCOM_PROXY_DCOM RPC_NDR_REMACT \ - RPC_NDR_OXIDRESOLVER +#[SUBSYSTEM::LIBDCOM] +#ENABLE = NO +#INIT_OBJ_FILES = \ +# lib/dcom/common/main.o +#REQUIRED_SUBSYSTEMS = LIBCOM DCOM_PROXY_DCOM RPC_NDR_REMACT \ +# RPC_NDR_OXIDRESOLVER -[MODULE::DCOM_SIMPLE] -SUBSYSTEM = LIBDCOM -REQUIRED_SUBSYSTEMS = DCOM_PROXY_DCOM -INIT_FUNCTION = dcom_simple_init -INIT_OBJ_FILES = \ - lib/dcom/classes/simple.o +#[MODULE::DCOM_SIMPLE] +#ENABLE = NO +#SUBSYSTEM = LIBDCOM +#REQUIRED_SUBSYSTEMS = DCOM_PROXY_DCOM +#INIT_FUNCTION = dcom_simple_init +#INIT_OBJ_FILES = \ +# lib/dcom/classes/simple.o # # End SUBSYSTEM LIBDCOM ################################################ diff --git a/source4/librpc/idl/dcom.idl b/source4/librpc/idl/dcom.idl index 855fbfce8f..b4ce03e5aa 100644 --- a/source4/librpc/idl/dcom.idl +++ b/source4/librpc/idl/dcom.idl @@ -159,10 +159,10 @@ interface IRemUnknown : IUnknown interface ISystemActivator : IClassActivator { WERROR ISystemActivatorRemoteCreateInstance([in] hyper unknown1, /* OXID ? */ - [in] MInterfacePointer iface, + [in] MInterfacePointer iface1, [in] hyper unknown2, [out] uint32 unknown3, - [out] MInterfacePointer iface); + [out] MInterfacePointer iface2); } @@ -270,7 +270,7 @@ object, object ] interface ICoffeeMachine : IUnknown { - [helpstring("method MakeCoffee")] WERROR MakeCoffee(BSTR *flavor); + [helpstring("method MakeCoffee")] WERROR MakeCoffee(unistr *flavor); } [ diff --git a/source4/librpc/idl/rot.idl b/source4/librpc/idl/rot.idl index 28aae60036..aa257dcf2f 100644 --- a/source4/librpc/idl/rot.idl +++ b/source4/librpc/idl/rot.idl @@ -4,6 +4,7 @@ uuid("b9e79e60-3d52-11ce-aaa1-00006901293f"), version(0.2), pointer_default(unique), + depends(orpc), endpoint("ncacn_np:[\\pipe\\epmapper]", "ncacn_ip_tcp:[135]", "ncalrpc:[EPMAPPER]", "ncacn_unix_stream:[/tmp/epmapper]") ] interface rot @@ -42,16 +43,3 @@ [out] MInterfacePointer *EnumMoniker ); } - -/* -[ - object, -] interface IRotData : IUnknown -{ - WERROR irotdata_getdata( - [out,size_is(max),length_is(ret)] uint8 *data, - [in] uint32 max, - [out] uint32 ret - ); -} -*/ diff --git a/source4/librpc/ndr/ndr_orpc.c b/source4/librpc/ndr/ndr_orpc.c index 2a28db4178..ccfd48e099 100644 --- a/source4/librpc/ndr/ndr_orpc.c +++ b/source4/librpc/ndr/ndr_orpc.c @@ -22,6 +22,7 @@ #include "includes.h" +#include "librpc/gen_ndr/ndr_orpc.h" NTSTATUS ndr_pull_DUALSTRINGARRAY(struct ndr_pull *ndr, int ndr_flags, struct DUALSTRINGARRAY *ar) { diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk index f58cbd0ac3..e50aa58c35 100644 --- a/source4/rpc_server/config.mk +++ b/source4/rpc_server/config.mk @@ -27,7 +27,7 @@ REQUIRED_SUBSYSTEMS = \ DCERPC_COMMON \ NDR_OXIDRESOLVER \ NDR_REMACT \ - LIBDCOM + LIBCOM # End MODULE dcerpc_dcom ################################################ diff --git a/source4/rpc_server/dcom/rodb.c b/source4/rpc_server/dcom/rodb.c index 5008e105ba..76f3d2da80 100644 --- a/source4/rpc_server/dcom/rodb.c +++ b/source4/rpc_server/dcom/rodb.c @@ -31,7 +31,7 @@ struct tdb_wrap *openrodb(TALLOC_CTX *mem_ctx) struct tdb_wrap *wrap; char *rodb_name = NULL; - asprintf(&rodb_name, "%s/rot.tdb", lp_lockdir()); + rodb_name = smbd_tmp_path(mem_ctx, "rot.tdb"); wrap = tdb_wrap_open(mem_ctx, rodb_name, 0, 0, O_RDWR|O_CREAT, 0600); SAFE_FREE(rodb_name); diff --git a/source4/script/build_idl.sh b/source4/script/build_idl.sh index 7b49721a5c..d15a9add31 100755 --- a/source4/script/build_idl.sh +++ b/source4/script/build_idl.sh @@ -4,7 +4,7 @@ FULLBUILD=$1 [ -d librpc/gen_ndr ] || mkdir -p librpc/gen_ndr || exit 1 -PIDL="$PERL ./build/pidl/pidl.pl --output librpc/gen_ndr/ndr_ --parse --header --parser --server --client --swig --odl" +PIDL="$PERL ./build/pidl/pidl.pl --output librpc/gen_ndr/ndr_ --parse --header --parser --server --client --dcom-proxy --com-header --swig --odl" if [ x$FULLBUILD = xFULL ]; then echo Rebuilding all idl files in librpc/idl @@ -14,7 +14,7 @@ fi list="" -for f in librpc/idl/*.idl; do +for f in librpc/idl/*.idl ; do basename=`basename $f .idl` ndr="librpc/gen_ndr/ndr_$basename.c" # blergh - most shells don't have the -nt function diff --git a/source4/torture/com/simple.c b/source4/torture/com/simple.c new file mode 100644 index 0000000000..369b03f151 --- /dev/null +++ b/source4/torture/com/simple.c @@ -0,0 +1,93 @@ +/* + Unix SMB/CIFS implementation. + run the "simple" example (D)COM program + + Copyright (C) Jelmer Vernooij 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/com/com.h" +#include "librpc/gen_ndr/com_dcom.h" + +#define CLSID_SIMPLE "5e9ddec7-5767-11cf-beab-00aa006c3606" +#define DEFAULT_TRANS 4096 + +static BOOL test_readwrite(TALLOC_CTX *mem_ctx, const char *host) +{ + struct dcerpc_pipe *p = NULL; + BOOL ret = True; + struct GUID IID[2]; + struct GUID clsid; + WERROR error; + struct IUnknown *interfaces[3]; + WERROR results[2]; + struct com_context *ctx; + char test_data[5]; + int i; + + com_init(&ctx); + + GUID_from_string(COM_ISTREAM_UUID, &IID[0]); + GUID_from_string(COM_IUNKNOWN_UUID, &IID[1]); + GUID_from_string(CLSID_SIMPLE, &clsid); +/* error = dcom_create_object(ctx, &clsid, + host, 2, IID, + &interfaces, + results);*/ + + error = com_create_object(ctx, &clsid, 2, IID, interfaces, results); + + if (!W_ERROR_IS_OK(error)) { + printf("(d)com_create_object failed - %s\n", win_errstr(error)); + return False; + } + + error = IStream_Read((struct IStream *)interfaces[0], mem_ctx, NULL, 20, 20, 30); + if (!W_ERROR_IS_OK(error)) { + printf("IStream::Read() failed - %s\n", win_errstr(error)); + ret = False; + } + + for (i = 0; i < 5; i++) { + test_data[i] = i+1; + } + + error = IStream_Write((struct IStream *)interfaces[0], mem_ctx, &test_data, 5, NULL); + if (!W_ERROR_IS_OK(error)) { + printf("IStream::Write() failed - %s\n", win_errstr(error)); + ret = False; + } + + IUnknown_Release((struct IUnknown *)interfaces[1], mem_ctx); + + torture_rpc_close(p); + + return True; +} + +BOOL torture_com_simple(void) +{ + BOOL ret = True; + TALLOC_CTX *mem_ctx = talloc_init("torture_dcom_simple"); + + ret &= test_readwrite(mem_ctx, NULL); + ret &= test_readwrite(mem_ctx, lp_parm_string(-1, "torture", "dcomhost")); + + talloc_free(mem_ctx); + + return ret; +} diff --git a/source4/torture/config.mk b/source4/torture/config.mk index 2a81ac1c7c..5ac33bb556 100644 --- a/source4/torture/config.mk +++ b/source4/torture/config.mk @@ -59,11 +59,11 @@ REQUIRED_SUBSYSTEMS = \ ################################# # Start SUBSYSTEM TORTURE_DCOM -[SUBSYSTEM::TORTURE_DCOM] +[SUBSYSTEM::TORTURE_COM] ADD_OBJ_FILES = \ - torture/dcom/simple.o + torture/com/simple.o REQUIRED_SUBSYSTEMS = \ - LIBDCOM + LIBCOM # End SUBSYSTEM TORTURE_DCOM ################################# @@ -196,6 +196,7 @@ REQUIRED_SUBSYSTEMS = \ TORTURE_LOCAL \ TORTURE_NBENCH \ TORTURE_LDAP \ + TORTURE_COM \ TORTURE_NBT \ CONFIG \ LIBCMDLINE \ diff --git a/source4/torture/dcom/simple.c b/source4/torture/dcom/simple.c deleted file mode 100644 index 4e9ae1be28..0000000000 --- a/source4/torture/dcom/simple.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - Unix SMB/CIFS implementation. - run the "simple" example DCOM program - - Copyright (C) Jelmer Vernooij 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#include "librpc/gen_ndr/ndr_dcom.h" -#include "librpc/gen_ndr/ndr_oxidresolver.h" - -#define CLSID_SIMPLE "5e9ddec7-5767-11cf-beab-00aa006c3606" -#define DEFAULT_TRANS 4096 - -static BOOL test_readwrite(TALLOC_CTX *mem_ctx, const char *host) -{ - NTSTATUS status; - struct dcerpc_pipe *p = NULL; - BOOL ret = True; - struct GUID IID[2]; - struct GUID clsid; - WERROR error; - struct dcom_interface_p **interfaces; - struct Read r_read; - struct Write r_write; - WERROR results[2]; - struct dcom_context *ctx; - char test_data[5]; - int i; - extern NTSTATUS dcom_IUnknown_init(void); - extern NTSTATUS dcom_IStream_init(void); - - torture_dcom_init(&ctx); - - GUID_from_string(DCERPC_ISTREAM_UUID, &IID[0]); - GUID_from_string(DCERPC_IUNKNOWN_UUID, &IID[1]); - GUID_from_string(CLSID_SIMPLE, &clsid); - error = dcom_create_object(ctx, &clsid, - host, 2, IID, - &interfaces, - results); - - if (!W_ERROR_IS_OK(error)) { - printf("dcom_create_object failed - %s\n", win_errstr(error)); - return False; - } - - if (!W_ERROR_IS_OK(results[0])) { - printf("dcom_create_object didn't return IStream interface - %s\n", win_errstr(results[0])); - return False; - } - - ZERO_STRUCT(r_read); - r_read.in.num_requested = 20; /* Give me 20 0xFF bytes... */ - status = dcom_IStream_Read(interfaces[0], mem_ctx, &r_read); - if (NT_STATUS_IS_ERR(status)) { - printf("IStream::Read() failed - %s\n", nt_errstr(status)); - ret = False; - } else if (!W_ERROR_IS_OK(r_read.out.result)) { - printf("IStream::Read() failed - %s\n", win_errstr(r_read.out.result)); - ret = False; - } - - for (i = 0; i < 5; i++) { - test_data[i] = i+1; - } - r_write.in.num_requested = 5; - r_write.in.data = (uint8_t *)&test_data; - status = dcom_IStream_Write(interfaces[0], mem_ctx, &r_write); - if (NT_STATUS_IS_ERR(status)) { - printf("IStream::Write() failed - %s\n", nt_errstr(status)); - ret = False; - } else if (!W_ERROR_IS_OK(r_write.out.result)) { - printf("IStream::Write() failed - %s\n", win_errstr(r_write.out.result)); - ret = False; - } - - status = dcom_IUnknown_Release(interfaces[1], mem_ctx, NULL); - if (NT_STATUS_IS_ERR(status)) { - printf("IUnknown::Release() failed - %s\n", nt_errstr(status)); - return False; - } - - talloc_free(mem_ctx); - - torture_rpc_close(p); - - return True; -} - -BOOL torture_dcom_simple(void) -{ - BOOL ret = True; - TALLOC_CTX *mem_ctx = talloc_init("torture_dcom_simple"); - - ret &= test_readwrite(mem_ctx, NULL); - ret &= test_readwrite(mem_ctx, lp_parm_string(-1, "torture", "dcomhost")); - - return ret; -} diff --git a/source4/torture/torture.c b/source4/torture/torture.c index ac9af7ed4b..b589902b66 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -2416,6 +2416,9 @@ static struct { {"LOCAL-IDTREE", torture_local_idtree, 0}, {"LOCAL-SOCKET", torture_local_socket, 0}, + /* COM (Component Object Model) testers */ + {"COM-SIMPLE", torture_com_simple, 0 }, + /* ldap testers */ {"LDAP-BASIC", torture_ldap_basic, 0}, |