mirror of
https://github.com/samba-team/samba.git
synced 2025-11-09 20:23:51 +03:00
r3513: Add (the infrastructure for) DCOM support. Contents:
- Support for sending over the object UUID in DCERPC calls - Simple torture test for the DCOM "Simple" object - Generate extra argument for "object" interfaces in pidl - Some stubs for common DCOM functions
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
f631069582
commit
c052f2e1ed
@@ -19,15 +19,22 @@ sub ParseFunction($)
|
||||
|
||||
return if (util::has_property($fn, "local"));
|
||||
|
||||
my $objargdef = "";
|
||||
my $objarg = ", NULL";
|
||||
if (util::has_property($fn, "object")) {
|
||||
$objargdef = ", struct GUID *object";
|
||||
$objarg = ", object";
|
||||
}
|
||||
|
||||
$res .=
|
||||
"
|
||||
struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r)
|
||||
struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p$objargdef, TALLOC_CTX *mem_ctx, struct $name *r)
|
||||
{
|
||||
if (p->flags & DCERPC_DEBUG_PRINT_IN) {
|
||||
NDR_PRINT_IN_DEBUG($name, r);
|
||||
}
|
||||
|
||||
return dcerpc_ndr_request_send(p, DCERPC_$uname, mem_ctx,
|
||||
return dcerpc_ndr_request_send(p$objarg, DCERPC_$uname, mem_ctx,
|
||||
(ndr_push_flags_fn_t) ndr_push_$name,
|
||||
(ndr_pull_flags_fn_t) ndr_pull_$name,
|
||||
r, sizeof(*r));
|
||||
@@ -35,11 +42,12 @@ struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
|
||||
|
||||
";
|
||||
|
||||
$objarg = "" unless (util::has_property($fn, "object"));
|
||||
$res .=
|
||||
"
|
||||
NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r)
|
||||
NTSTATUS dcerpc_$name(struct dcerpc_pipe *p$objargdef, TALLOC_CTX *mem_ctx, struct $name *r)
|
||||
{
|
||||
struct rpc_request *req = dcerpc_$name\_send(p, mem_ctx, r);
|
||||
struct rpc_request *req = dcerpc_$name\_send(p$objarg, mem_ctx, r);
|
||||
NTSTATUS status;
|
||||
if (req == NULL) return NT_STATUS_NO_MEMORY;
|
||||
|
||||
|
||||
@@ -305,9 +305,14 @@ sub HeaderFnProto($)
|
||||
|
||||
return if (util::has_property($fn, "call_as") );
|
||||
|
||||
my $objarg = "";
|
||||
if (util::has_property($fn, "object")) {
|
||||
$objarg = ", struct GUID *";
|
||||
}
|
||||
|
||||
$res .= "void ndr_print_$name(struct ndr_print *, const char *, int, struct $name *);\n";
|
||||
$res .= "struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *, TALLOC_CTX *, struct $name *);\n";
|
||||
$res .= "NTSTATUS dcerpc_$name(struct dcerpc_pipe *, TALLOC_CTX *, struct $name *);\n";
|
||||
$res .= "struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *$objarg, TALLOC_CTX *, struct $name *);\n";
|
||||
$res .= "NTSTATUS dcerpc_$name(struct dcerpc_pipe *$objarg, TALLOC_CTX *, struct $name *);\n";
|
||||
$res .= "\n";
|
||||
}
|
||||
|
||||
|
||||
@@ -2055,6 +2055,7 @@ sub parse_idl($$)
|
||||
if (defined($x->{PROPERTIES}->{object})) {
|
||||
foreach my $e (@{$x->{DATA}}) {
|
||||
if($e->{TYPE} eq "FUNCTION") {
|
||||
$e->{PROPERTIES}->{object} = 1;
|
||||
unshift(@{$e->{DATA}},
|
||||
{ 'NAME' => 'ORPCthis',
|
||||
'POINTERS' => 0,
|
||||
|
||||
@@ -343,6 +343,7 @@ sub parse_idl($$)
|
||||
if (defined($x->{PROPERTIES}->{object})) {
|
||||
foreach my $e (@{$x->{DATA}}) {
|
||||
if($e->{TYPE} eq "FUNCTION") {
|
||||
$e->{PROPERTIES}->{object} = 1;
|
||||
unshift(@{$e->{DATA}},
|
||||
{ 'NAME' => 'ORPCthis',
|
||||
'POINTERS' => 0,
|
||||
|
||||
@@ -162,7 +162,10 @@ sub struct_alignment
|
||||
for my $e (@{$s->{ELEMENTS}}) {
|
||||
my $a = 1;
|
||||
|
||||
if (!util::need_wire_pointer($e)
|
||||
if (util::has_property($e, "align"))
|
||||
{
|
||||
$a = $e->{PROPERTIES}->{align};
|
||||
} elsif (!util::need_wire_pointer($e)
|
||||
&& defined $structs{$e->{TYPE}}) {
|
||||
if ($structs{$e->{TYPE}}->{DATA}->{TYPE} eq "STRUCT") {
|
||||
$a = struct_alignment($structs{$e->{TYPE}}->{DATA});
|
||||
@@ -1315,6 +1318,11 @@ sub ParseFunctionPush($)
|
||||
pidl $static . "NTSTATUS ndr_push_$fn->{NAME}(struct ndr_push *ndr, int flags, struct $fn->{NAME} *r)\n{\n";
|
||||
|
||||
pidl "\n\tif (!(flags & NDR_IN)) goto ndr_out;\n\n";
|
||||
|
||||
if (util::has_property($fn, "object")) {
|
||||
# FIXME: Set COM version and possibly causality ID
|
||||
}
|
||||
|
||||
foreach my $e (@{$fn->{DATA}}) {
|
||||
if (util::has_property($e, "in")) {
|
||||
ParseFunctionElementPush($e, "in");
|
||||
@@ -1323,6 +1331,7 @@ sub ParseFunctionPush($)
|
||||
|
||||
pidl "\nndr_out:\n";
|
||||
pidl "\tif (!(flags & NDR_OUT)) goto done;\n\n";
|
||||
|
||||
foreach my $e (@{$fn->{DATA}}) {
|
||||
if (util::has_property($e, "out")) {
|
||||
ParseFunctionElementPush($e, "out");
|
||||
@@ -1449,6 +1458,7 @@ sub ParseFunctionPull($)
|
||||
|
||||
pidl "\nndr_out:\n";
|
||||
pidl "\tif (!(flags & NDR_OUT)) goto done;\n\n";
|
||||
|
||||
foreach my $e (@{$fn->{DATA}}) {
|
||||
if (util::has_property($e, "out")) {
|
||||
ParseFunctionElementPull($e, "out");
|
||||
|
||||
@@ -182,6 +182,7 @@ 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 "smb_interfaces.h"
|
||||
#include "smbd/server.h"
|
||||
#include "smbd/service.h"
|
||||
|
||||
30
source/lib/dcom/common/dcom.h
Normal file
30
source/lib/dcom/common/dcom.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
DCOM standard objects
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef _DCOM_H /* _DCOM_H */
|
||||
#define _DCOM_H
|
||||
|
||||
struct dcom_interface
|
||||
{
|
||||
struct dcerpc_pipe *pipe;
|
||||
struct GUID ipid; /* Appears in object field */
|
||||
};
|
||||
|
||||
#endif /* _DCOM_H */
|
||||
@@ -34,39 +34,6 @@ static WERROR dcom_tower_from_oxid(TALLOC_CTX *mem_ctx, HYPER_T oxid, struct epm
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static WERROR dcom_get_class_object (struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct GUID clsid)
|
||||
{
|
||||
struct RemoteActivation r;
|
||||
NTSTATUS status;
|
||||
struct GUID iids[2];
|
||||
uint16 protseq[3] = { EPM_PROTOCOL_TCP, EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_UUID };
|
||||
|
||||
ZERO_STRUCT(r.in);
|
||||
r.in.this.version.MajorVersion = 5;
|
||||
r.in.this.version.MinorVersion = 1;
|
||||
uuid_generate_random(&r.in.this.cid);
|
||||
r.in.Clsid = clsid;
|
||||
r.in.ClientImpLevel = RPC_C_IMP_LEVEL_IDENTIFY;
|
||||
r.in.num_protseqs = 3;
|
||||
r.in.protseq = protseq;
|
||||
r.in.Interfaces = 1;
|
||||
GUID_from_string(DCERPC_IUNKNOWN_UUID, &iids[0]);
|
||||
r.in.pIIDs = iids;
|
||||
r.in.Mode = MODE_GET_CLASS_OBJECT;
|
||||
|
||||
status = dcerpc_RemoteActivation(p, mem_ctx, &r);
|
||||
if(NT_STATUS_IS_ERR(status)) {
|
||||
fprintf(stderr, "RemoteActivation: %s\n", nt_errstr(status));
|
||||
return ntstatus_to_werror(status);
|
||||
}
|
||||
|
||||
if(!W_ERROR_IS_OK(r.out.result)) { return r.out.result; }
|
||||
if(!W_ERROR_IS_OK(r.out.hr)) { return r.out.hr; }
|
||||
if(!W_ERROR_IS_OK(r.out.results[0])) { return r.out.results[0]; }
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static WERROR dcom_create_instance (struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct GUID clsid)
|
||||
{
|
||||
return WERR_NOT_SUPPORTED;
|
||||
@@ -90,3 +57,43 @@ static WERROR IUnknown_QueryInterface(struct GUID *riid, void **data)
|
||||
* call RemQueryInterface if necessary */
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
WERROR dcom_create_object(TALLOC_CTX *mem_ctx, struct GUID *clsid, const char *server, int num_ifaces, struct GUID *iid, struct dcom_interface **ip)
|
||||
{
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
WERROR dcom_get_class_object(TALLOC_CTX *mem_ctx, struct GUID *clsid, const char *server, struct GUID *iid, struct dcom_interface **ip)
|
||||
{
|
||||
struct RemoteActivation r;
|
||||
struct dcerpc_pipe *p = NULL; /* FIXME */
|
||||
NTSTATUS status;
|
||||
struct GUID iids[2];
|
||||
uint16 protseq[3] = { EPM_PROTOCOL_TCP, EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_UUID };
|
||||
|
||||
ZERO_STRUCT(r.in);
|
||||
r.in.this.version.MajorVersion = 5;
|
||||
r.in.this.version.MinorVersion = 1;
|
||||
uuid_generate_random(&r.in.this.cid);
|
||||
r.in.Clsid = *clsid;
|
||||
r.in.ClientImpLevel = RPC_C_IMP_LEVEL_IDENTIFY;
|
||||
r.in.num_protseqs = 3;
|
||||
r.in.protseq = protseq;
|
||||
r.in.Interfaces = 1;
|
||||
GUID_from_string(DCERPC_IUNKNOWN_UUID, &iids[0]);
|
||||
r.in.pIIDs = iids;
|
||||
r.in.Mode = MODE_GET_CLASS_OBJECT;
|
||||
|
||||
status = dcerpc_RemoteActivation(p, mem_ctx, &r);
|
||||
if(NT_STATUS_IS_ERR(status)) {
|
||||
fprintf(stderr, "RemoteActivation: %s\n", nt_errstr(status));
|
||||
return ntstatus_to_werror(status);
|
||||
}
|
||||
|
||||
if(!W_ERROR_IS_OK(r.out.result)) { return r.out.result; }
|
||||
if(!W_ERROR_IS_OK(r.out.hr)) { return r.out.hr; }
|
||||
if(!W_ERROR_IS_OK(r.out.results[0])) { return r.out.results[0]; }
|
||||
|
||||
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
@@ -169,6 +169,13 @@ interface dcerpc
|
||||
[case(DCERPC_PKT_BIND_NAK)] dcerpc_bind_nak bind_nak;
|
||||
} dcerpc_payload;
|
||||
|
||||
typedef struct {
|
||||
} dcerpc_empty;
|
||||
|
||||
typedef [nodiscriminant] union {
|
||||
[default] dcerpc_empty empty;
|
||||
[case(DCERPC_PFC_FLAG_ORPC)] GUID object;
|
||||
} dcerpc_object;
|
||||
|
||||
/* pfc_flags values */
|
||||
const uint8 DCERPC_PFC_FLAG_FIRST = 0x01;
|
||||
@@ -193,7 +200,7 @@ interface dcerpc
|
||||
uint16 frag_length; /* Total length of fragment */
|
||||
uint16 auth_length; /* authenticator length */
|
||||
uint32 call_id; /* Call identifier */
|
||||
|
||||
[switch_is(pfc_flags & DCERPC_PFC_FLAG_ORPC)] dcerpc_object object;
|
||||
[switch_is(ptype)] dcerpc_payload u;
|
||||
} dcerpc_packet;
|
||||
}
|
||||
|
||||
@@ -513,11 +513,11 @@ uuid(DB7C21F8-FE33-4C11-AEA5-CEB56F076FBB),
|
||||
]
|
||||
interface IStream : IUnknown
|
||||
{
|
||||
WERROR Read([in] uint32 num_requested,
|
||||
WERROR IStream_Read([in] uint32 num_requested,
|
||||
[out,size_is(*num_read)] uint8 *data,
|
||||
[out] uint32 *num_read);
|
||||
|
||||
WERROR Write([in,size_is(num_requested)] uint8 *data,
|
||||
WERROR IStream_Write([in,size_is(num_requested)] uint8 *data,
|
||||
[in] uint32 num_requested,
|
||||
[out] uint32 *num_written);
|
||||
}
|
||||
|
||||
@@ -835,6 +835,7 @@ static int dcerpc_req_destructor(void *ptr)
|
||||
perform the send size of a async dcerpc request
|
||||
*/
|
||||
struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
|
||||
struct GUID *object,
|
||||
uint16_t opnum,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
DATA_BLOB *stub_data)
|
||||
@@ -875,6 +876,11 @@ struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
|
||||
pkt.u.request.alloc_hint = remaining;
|
||||
pkt.u.request.context_id = 0;
|
||||
pkt.u.request.opnum = opnum;
|
||||
if (object) {
|
||||
pkt.object.object = *object;
|
||||
pkt.pfc_flags |= DCERPC_PFC_FLAG_ORPC;
|
||||
/* FIXME: pfc_cflags is reset below! */
|
||||
}
|
||||
|
||||
DLIST_ADD(p->pending, req);
|
||||
|
||||
@@ -962,6 +968,7 @@ NTSTATUS dcerpc_request_recv(struct rpc_request *req,
|
||||
perform a full request/response pair on a dcerpc pipe
|
||||
*/
|
||||
NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
|
||||
struct GUID *object,
|
||||
uint16_t opnum,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
DATA_BLOB *stub_data_in,
|
||||
@@ -969,7 +976,7 @@ NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
|
||||
{
|
||||
struct rpc_request *req;
|
||||
|
||||
req = dcerpc_request_send(p, opnum, mem_ctx, stub_data_in);
|
||||
req = dcerpc_request_send(p, object, opnum, mem_ctx, stub_data_in);
|
||||
if (req == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
@@ -1128,6 +1135,7 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_pipe *p,
|
||||
call dcerpc_ndr_request_recv() to receive the answer
|
||||
*/
|
||||
struct rpc_request *dcerpc_ndr_request_send(struct dcerpc_pipe *p,
|
||||
struct GUID *object,
|
||||
uint32_t opnum,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
NTSTATUS (*ndr_push)(struct ndr_push *, int, void *),
|
||||
@@ -1177,7 +1185,7 @@ struct rpc_request *dcerpc_ndr_request_send(struct dcerpc_pipe *p,
|
||||
dump_data(10, request.data, request.length);
|
||||
|
||||
/* make the actual dcerpc request */
|
||||
req = dcerpc_request_send(p, opnum, mem_ctx, &request);
|
||||
req = dcerpc_request_send(p, object, opnum, mem_ctx, &request);
|
||||
|
||||
if (req != NULL) {
|
||||
req->ndr.ndr_push = ndr_push;
|
||||
@@ -1264,6 +1272,7 @@ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req)
|
||||
standard format
|
||||
*/
|
||||
NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
|
||||
struct GUID *object,
|
||||
uint32_t opnum,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
NTSTATUS (*ndr_push)(struct ndr_push *, int, void *),
|
||||
@@ -1273,7 +1282,7 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
|
||||
{
|
||||
struct rpc_request *req;
|
||||
|
||||
req = dcerpc_ndr_request_send(p, opnum, mem_ctx, ndr_push, ndr_pull, struct_ptr, struct_size);
|
||||
req = dcerpc_ndr_request_send(p, object, opnum, mem_ctx, ndr_push, ndr_pull, struct_ptr, struct_size);
|
||||
if (req == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
51
source/rpc_server/dcom/dcom.h
Normal file
51
source/rpc_server/dcom/dcom.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
DCOM standard objects
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef _DCOM_H /* _DCOM_H */
|
||||
#define _DCOM_H
|
||||
|
||||
struct dcom_class
|
||||
{
|
||||
const char *name;
|
||||
struct GUID CLSID;
|
||||
|
||||
/* List of IID's implemented */
|
||||
uint32 cIIDs;
|
||||
struct GUID *IID;
|
||||
|
||||
/* Pointers to functions this class implements */
|
||||
};
|
||||
|
||||
struct dcom_object
|
||||
{
|
||||
struct dcom_class *class;
|
||||
struct GUID oid;
|
||||
HYPER_T OXID;
|
||||
struct dcom_interface_pointer *interfaces;
|
||||
void *private_data;
|
||||
};
|
||||
|
||||
struct dcom_interface_pointer
|
||||
{
|
||||
struct dcom_object *object;
|
||||
struct GUID ipid;
|
||||
};
|
||||
|
||||
#endif /* _DCOM_H */
|
||||
@@ -46,8 +46,7 @@ struct PingSet
|
||||
/*
|
||||
ResolveOxid
|
||||
*/
|
||||
static WERROR ResolveOxid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct ResolveOxid *r)
|
||||
static WERROR ResolveOxid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ResolveOxid *r)
|
||||
{
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
@@ -56,8 +55,7 @@ static WERROR ResolveOxid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ct
|
||||
/*
|
||||
SimplePing
|
||||
*/
|
||||
static WERROR SimplePing(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct SimplePing *r)
|
||||
static WERROR SimplePing(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct SimplePing *r)
|
||||
{
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
@@ -65,8 +63,7 @@ static WERROR SimplePing(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx
|
||||
/*
|
||||
ComplexPing
|
||||
*/
|
||||
static WERROR ComplexPing(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct ComplexPing *r)
|
||||
static WERROR ComplexPing(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ComplexPing *r)
|
||||
{
|
||||
/* struct PingSet *ps; */
|
||||
|
||||
@@ -81,8 +78,7 @@ static WERROR ComplexPing(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ct
|
||||
/*
|
||||
ServerAlive
|
||||
*/
|
||||
static WERROR ServerAlive(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct ServerAlive *r)
|
||||
static WERROR ServerAlive(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ServerAlive *r)
|
||||
{
|
||||
return WERR_OK;
|
||||
}
|
||||
@@ -91,8 +87,7 @@ static WERROR ServerAlive(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ct
|
||||
/*
|
||||
ResolveOxid2
|
||||
*/
|
||||
static WERROR ResolveOxid2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct ResolveOxid2 *r)
|
||||
static WERROR ResolveOxid2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ResolveOxid2 *r)
|
||||
{
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
@@ -101,8 +96,7 @@ static WERROR ResolveOxid2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_c
|
||||
/*
|
||||
ServerAlive2
|
||||
*/
|
||||
static WERROR ServerAlive2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct ServerAlive2 *r)
|
||||
static WERROR ServerAlive2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ServerAlive2 *r)
|
||||
{
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
@@ -24,16 +24,40 @@
|
||||
#include "rpc_server/dcerpc_server.h"
|
||||
#include "rpc_server/common/common.h"
|
||||
#include "librpc/gen_ndr/ndr_remact.h"
|
||||
#include "rpc_server/dcom/dcom.h"
|
||||
|
||||
static void register_dcom_class(void *_c)
|
||||
{
|
||||
struct dcom_class *class = _c;
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
struct dcom_object *dcom_object_by_oid(struct GUID *oid)
|
||||
{
|
||||
/* FIXME */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct dcom_class *dcom_class_by_clsid(struct GUID *clsid)
|
||||
{
|
||||
/* FIXME */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct dcom_interface_pointer *dcom_interface_pointer_by_ipid(struct GUID *ipid)
|
||||
{
|
||||
/* FIXME */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
RemoteActivation
|
||||
*/
|
||||
static WERROR RemoteActivation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||
struct RemoteActivation *r)
|
||||
static WERROR RemoteActivation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct RemoteActivation *r)
|
||||
{
|
||||
/* FIXME: CoGetClassObject() */
|
||||
/* FIXME: IClassFactory::CreateInstance() */
|
||||
/* FIXME: IClassFactory::ReleaseInstance() */
|
||||
/* FIXME: IClassFactory::Release() */
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CT
|
||||
ndr_print_function_debug(ndr_print_fn, name, NDR_IN | NDR_SET_VALUES, r);
|
||||
}
|
||||
|
||||
status = dcerpc_ndr_request(private->c_pipe, opnum, mem_ctx,
|
||||
status = dcerpc_ndr_request(private->c_pipe, NULL, opnum, mem_ctx,
|
||||
(ndr_push_flags_fn_t) ndr_push_fn,
|
||||
(ndr_pull_flags_fn_t) ndr_pull_fn,
|
||||
r, struct_size);
|
||||
|
||||
@@ -4,6 +4,8 @@ SMB_SUBSYSTEM_MK(TORTURE_BASIC,torture/config.mk)
|
||||
|
||||
SMB_SUBSYSTEM_MK(TORTURE_RAW,torture/config.mk)
|
||||
|
||||
SMB_SUBSYSTEM_MK(TORTURE_DCOM,torture/config.mk)
|
||||
|
||||
SMB_SUBSYSTEM_MK(TORTURE_RPC,torture/config.mk)
|
||||
|
||||
SMB_SUBSYSTEM_MK(TORTURE_RAP,torture/config.mk)
|
||||
|
||||
@@ -49,6 +49,16 @@ REQUIRED_SUBSYSTEMS = \
|
||||
# End SUBSYSTEM TORTURE_RAW
|
||||
#################################
|
||||
|
||||
#################################
|
||||
# Start SUBSYSTEM TORTURE_DCOM
|
||||
[SUBSYSTEM::TORTURE_DCOM]
|
||||
ADD_OBJ_FILES = \
|
||||
torture/dcom/simple.o
|
||||
REQUIRED_SUBSYSTEMS = \
|
||||
LIBDCOM
|
||||
# End SUBSYSTEM TORTURE_DCOM
|
||||
#################################
|
||||
|
||||
#################################
|
||||
# Start SUBSYSTEM TORTURE_RPC
|
||||
[SUBSYSTEM::TORTURE_RPC]
|
||||
@@ -147,6 +157,7 @@ REQUIRED_SUBSYSTEMS = \
|
||||
TORTURE_BASIC \
|
||||
TORTURE_RAW \
|
||||
TORTURE_RPC \
|
||||
TORTURE_DCOM \
|
||||
TORTURE_RAP \
|
||||
TORTURE_AUTH \
|
||||
TORTURE_LOCAL \
|
||||
|
||||
75
source/torture/dcom/simple.c
Normal file
75
source/torture/dcom/simple.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
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
|
||||
|
||||
BOOL torture_dcom_simple(void)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct dcerpc_pipe *p;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
BOOL ret = True;
|
||||
struct GUID IID[2];
|
||||
struct GUID clsid;
|
||||
WERROR error;
|
||||
char pv[DEFAULT_TRANS];
|
||||
struct dcom_interface *interfaces;
|
||||
struct IStream_Read r_read;
|
||||
struct IStream_Write r_write;
|
||||
|
||||
mem_ctx = talloc_init("torture_dcom_simple");
|
||||
|
||||
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(mem_ctx, &clsid, "192.168.4.28", 2, IID, &interfaces);
|
||||
|
||||
if (!W_ERROR_IS_OK(error)) {
|
||||
printf("dcom_create_object failed - %s\n", win_errstr(error));
|
||||
return False;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(r_read);
|
||||
status = dcerpc_IStream_Read(interfaces[0].pipe, &interfaces[0].ipid, mem_ctx, &r_read);
|
||||
if (NT_STATUS_IS_ERR(error)) {
|
||||
printf("IStream::Read() failed - %s\n", win_errstr(error));
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
status = dcerpc_IStream_Write(interfaces[0].pipe, &interfaces[0].ipid, mem_ctx, &r_write);
|
||||
if (NT_STATUS_IS_ERR(error)) {
|
||||
printf("IStream::Write() failed - %s\n", win_errstr(error));
|
||||
return False;
|
||||
}
|
||||
|
||||
/*FIXME: dcerpc_IUnknown_Release();*/
|
||||
|
||||
talloc_destroy(mem_ctx);
|
||||
|
||||
torture_rpc_close(p);
|
||||
return ret;
|
||||
}
|
||||
@@ -127,7 +127,7 @@ static void try_expand(TALLOC_CTX *mem_ctx, const struct dcerpc_interface_table
|
||||
memcpy(stub_in.data, base_in->data, insert_ofs);
|
||||
memcpy(stub_in.data+insert_ofs+n, base_in->data+insert_ofs, base_in->length-insert_ofs);
|
||||
|
||||
status = dcerpc_request(p, opnum, mem_ctx, &stub_in, &stub_out);
|
||||
status = dcerpc_request(p, NULL, opnum, mem_ctx, &stub_in, &stub_out);
|
||||
|
||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
|
||||
print_depth(depth);
|
||||
@@ -168,7 +168,7 @@ static void test_ptr_scan(TALLOC_CTX *mem_ctx, const struct dcerpc_interface_tab
|
||||
/* work out which elements are pointers */
|
||||
for (ofs=min_ofs;ofs<=max_ofs-4;ofs+=4) {
|
||||
SIVAL(stub_in.data, ofs, 1);
|
||||
status = dcerpc_request(p, opnum, mem_ctx, &stub_in, &stub_out);
|
||||
status = dcerpc_request(p, NULL, opnum, mem_ctx, &stub_in, &stub_out);
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
|
||||
print_depth(depth);
|
||||
@@ -210,7 +210,7 @@ static void test_scan_call(TALLOC_CTX *mem_ctx, const struct dcerpc_interface_ta
|
||||
data_blob_clear(&stub_in);
|
||||
|
||||
|
||||
status = dcerpc_request(p, opnum, mem_ctx, &stub_in, &stub_out);
|
||||
status = dcerpc_request(p, NULL, opnum, mem_ctx, &stub_in, &stub_out);
|
||||
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
printf("opnum %d min_input %d - output %d\n",
|
||||
@@ -223,7 +223,7 @@ static void test_scan_call(TALLOC_CTX *mem_ctx, const struct dcerpc_interface_ta
|
||||
|
||||
fill_blob_handle(&stub_in, mem_ctx, &handle);
|
||||
|
||||
status = dcerpc_request(p, opnum, mem_ctx, &stub_in, &stub_out);
|
||||
status = dcerpc_request(p, NULL, opnum, mem_ctx, &stub_in, &stub_out);
|
||||
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
printf("opnum %d min_input %d - output %d (with handle)\n",
|
||||
|
||||
@@ -56,7 +56,7 @@ BOOL torture_rpc_countcalls(void)
|
||||
printf("\nScanning pipe '%s'\n", iface->name);
|
||||
|
||||
for (i=0;i<5000;i++) {
|
||||
status = dcerpc_request(p, i, p, &stub_in, &stub_out);
|
||||
status = dcerpc_request(p, NULL, i, p, &stub_in, &stub_out);
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT) &&
|
||||
p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) break;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ static BOOL test_ReadEventLog(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL test_CloseEventLog(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
static BOOL test_CloseEventLog(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
@@ -67,6 +67,7 @@ static int test_RemoteActivation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
GUID_from_string(DCERPC_ICLASSFACTORY_UUID, &iids[0]);
|
||||
r.in.Mode = MODE_GET_CLASS_OBJECT;
|
||||
|
||||
status = dcerpc_RemoteActivation(p, mem_ctx, &r);
|
||||
|
||||
@@ -53,7 +53,7 @@ static BOOL test_num_calls(const struct dcerpc_interface_table *iface,
|
||||
memset(stub_in.data, 0xFF, stub_in.length);
|
||||
|
||||
for (i=0;i<200;i++) {
|
||||
status = dcerpc_request(p, i, mem_ctx, &stub_in, &stub_out);
|
||||
status = dcerpc_request(p, NULL, i, mem_ctx, &stub_in, &stub_out);
|
||||
if (!NT_STATUS_IS_OK(status) &&
|
||||
p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
|
||||
break;
|
||||
|
||||
@@ -2506,6 +2506,9 @@ static struct {
|
||||
{"RPC-MULTIBIND", torture_multi_bind, 0},
|
||||
{"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
|
||||
|
||||
/* Distributed COM testers */
|
||||
{"DCOM-SIMPLE", torture_dcom_simple, 0},
|
||||
|
||||
/* local (no server) testers */
|
||||
{"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
|
||||
{"LOCAL-ICONV", torture_local_iconv, 0},
|
||||
|
||||
Reference in New Issue
Block a user