1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

r5490: The big (D)COM commit! :-) Contains most of the changes described in the

DCOM paper in lorikeet. This is the result of 1.5 months work (mainly
figuring out how things *really* work) at the end of 2004.

In general:
- Clearer distinction between COM and DCOM. DCOM is now merely
  the glue between DCE/RPC+ORPC and COM. COM can also work without
  DCOM now. This makes the code a lot clearer.
- Clearer distinction between NDR and DCOM. Before, NDR had a couple of
  "if"s to cope with DCOM, which are now gone.
- Use "real" arguments rather then structures for function arguments in
  COM, mainly because most of these calls are local so packing/unpacking
  data for every call is too much overhead (both speed- and code-wise)
- Support several mechanisms to load class objects:
  - from memory (e.g. part of the current executable, registered at start-up)
  - from shared object files
  - remotely
- Most things are now also named COM rather then DCOM because that's what it
  really is. After an object is created, it no longer matters whether it
  was created locally or remotely.

There is a very simple example class that contains
both a class factory and a class that implements the IStream interface.
It can be tested (locally only, remotely is broken at the moment)
by running the COM-SIMPLE smbtorture test.

Still to-do:
 - Autogenerate parts of the class implementation code (using the coclass definitions in IDL)
 - Test server-side
 - Implement some of the common classes, add definitions for common interfaces.
This commit is contained in:
Jelmer Vernooij 2005-02-21 14:30:49 +00:00 committed by Gerald (Jerry) Carter
parent bfcc86e706
commit 71fd3e5c3a
29 changed files with 793 additions and 622 deletions

View File

@ -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

View File

@ -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;

View File

@ -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));
proxy.base = *((const struct dcom_$interface->{BASE}_vtable *)base_vtable);
";
} else {
$res .= "\tZERO_STRUCT(iface.base_iid);\n";
";
}
foreach my $x (@{$interface->{DATA}}) {
next unless ($x->{TYPE} eq "FUNCTION");
$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,78 +84,59 @@ 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)
{
struct dcerpc_pipe *p;
NTSTATUS status = dcom_get_pipe(d, &p);
if (NT_STATUS_IS_ERR(status)) {
return NULL;
}
ZERO_STRUCT(r->in.ORPCthis);
r->in.ORPCthis.version.MajorVersion = COM_MAJOR_VERSION;
r->in.ORPCthis.version.MinorVersion = COM_MINOR_VERSION;
if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) {
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)
$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 status;
}
req = dcom_proxy_$interface->{NAME}_$name\_send(d, mem_ctx, r);
if (req == NULL) return NT_STATUS_NO_MEMORY;
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";
}
status = dcerpc_ndr_request_recv(req);
$res .="
if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) {
NDR_PRINT_IN_DEBUG($name, &r);
}
status = dcerpc_ndr_request(p, &d->ipid, &dcerpc_table_$interface->{NAME}, DCERPC_$uname, mem_ctx, &r);
if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
NDR_PRINT_OUT_DEBUG($name, r);
}
";
if ($fn->{RETURN_TYPE} eq "NTSTATUS") {
$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;
# 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";
}
return table->$name (d, mem_ctx, r);
}
";
}
if ($fn->{RETURN_TYPE} eq "NTSTATUS") {
$res .= "\tif (NT_STATUS_IS_OK(status)) status = r.out.result;\n";
}
$res .=
"
return r.out.result;
}\n\n";
}
#####################################################################
# parse the interface definitions
@ -158,7 +144,7 @@ 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;

View File

@ -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;

View File

@ -3,7 +3,7 @@
# Copyright tridge@samba.org 2000
# released under the GNU GPL
package IdlHeader;
package NdrHeader;
use strict;
use needed;
@ -337,32 +337,12 @@ 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 "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";
}
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";
}
#####################################################################
# parse the interface definitions
sub HeaderInterface($)
@ -439,9 +419,6 @@ sub HeaderInterface($)
HeaderFnProto($interface, $d);
}
(util::has_property($interface, "object")) &&
HeaderVTable($interface);
pidl "#endif /* _HEADER_NDR_$interface->{NAME} */\n";
}

View File

@ -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
perl IDL parser and code generator
Copyright (C) tridge\@samba.org
Usage: pidl.pl [options] <idlfile>
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";
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);
}

View File

@ -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",
);

View File

@ -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)

View File

@ -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);
}

30
source/lib/com/com.h Normal file
View File

@ -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 */

10
source/lib/com/config.mk Normal file
View File

@ -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

85
source/lib/com/main.c Normal file
View File

@ -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);
}

View File

@ -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

107
source/lib/com/tables.c Normal file
View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
################################################

View File

@ -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);
}
[

View File

@ -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
);
}
*/

View File

@ -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)
{

View File

@ -27,7 +27,7 @@ REQUIRED_SUBSYSTEMS = \
DCERPC_COMMON \
NDR_OXIDRESOLVER \
NDR_REMACT \
LIBDCOM
LIBCOM
# End MODULE dcerpc_dcom
################################################

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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 \

View File

@ -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;
}

View File

@ -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},