summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/build/pidl/README24
-rw-r--r--source4/build/pidl/com_header.pm131
-rw-r--r--source4/build/pidl/dcom_proxy.pm (renamed from source4/build/pidl/proxy.pm)146
-rw-r--r--source4/build/pidl/dcom_stub.pm (renamed from source4/build/pidl/stub.pm)10
-rw-r--r--source4/build/pidl/ndr_header.pm (renamed from source4/build/pidl/header.pm)31
-rwxr-xr-xsource4/build/pidl/pidl.pl118
-rw-r--r--source4/build/smb_build/main.pm3
-rw-r--r--source4/include/includes.h4
-rw-r--r--source4/lib/com/classes/simple.c116
-rw-r--r--source4/lib/com/com.h30
-rw-r--r--source4/lib/com/config.mk10
-rw-r--r--source4/lib/com/main.c85
-rw-r--r--source4/lib/com/rot.c (renamed from source4/lib/dcom/common/rot.c)2
-rw-r--r--source4/lib/com/tables.c107
-rw-r--r--source4/lib/dcom/classes/simple.c66
-rw-r--r--source4/lib/dcom/common/dcom.h33
-rw-r--r--source4/lib/dcom/common/main.c120
-rw-r--r--source4/lib/dcom/common/tables.c107
-rw-r--r--source4/lib/dcom/config.mk26
-rw-r--r--source4/librpc/idl/dcom.idl6
-rw-r--r--source4/librpc/idl/rot.idl14
-rw-r--r--source4/librpc/ndr/ndr_orpc.c1
-rw-r--r--source4/rpc_server/config.mk2
-rw-r--r--source4/rpc_server/dcom/rodb.c2
-rwxr-xr-xsource4/script/build_idl.sh4
-rw-r--r--source4/torture/com/simple.c93
-rw-r--r--source4/torture/config.mk7
-rw-r--r--source4/torture/dcom/simple.c114
-rw-r--r--source4/torture/torture.c3
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},