diff options
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}, |