summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2004-11-08 02:12:15 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:05:39 -0500
commit8c2e179d477c99ab9c52e6b9af19a86d553d10b5 (patch)
tree386d8be6564c95686da8bf3eafb16de211dd28bc /source4
parent009892846fb25e6698c8e38c46cae3512abb7ec6 (diff)
downloadsamba-8c2e179d477c99ab9c52e6b9af19a86d553d10b5.tar.gz
samba-8c2e179d477c99ab9c52e6b9af19a86d553d10b5.tar.bz2
samba-8c2e179d477c99ab9c52e6b9af19a86d553d10b5.zip
r3611: DCOM client support works!!
The torture test DCOM-SIMPLE now successfully does an IStream_Read and a IStream_Write call. This test can now be run successfully against the "Simple DCOM" Visual Studio example. (You have to quote out line 337 in pidl. pidl complains if the variable that contains the array size follows the array. I still need to fix this properly) Next goals: - Clean up code - Server side support - Support custom marshalling - Support DCOM interfaces in files other then dcom.idl (This used to be commit 8693344772a9b700533179f4bacfe27ec27dfcfe)
Diffstat (limited to 'source4')
-rw-r--r--source4/build/pidl/client.pm4
-rw-r--r--source4/build/pidl/header.pm1
-rw-r--r--source4/build/pidl/idl.pm2
-rw-r--r--source4/build/pidl/idl.yp2
-rw-r--r--source4/lib/dcom/common/main.c4
-rw-r--r--source4/librpc/idl/dcerpc.idl17
-rw-r--r--source4/librpc/idl/dcom.idl20
-rw-r--r--source4/librpc/ndr/libndr.h2
-rw-r--r--source4/librpc/rpc/dcerpc.c9
-rw-r--r--source4/librpc/rpc/dcerpc_util.c4
-rw-r--r--source4/torture/dcom/simple.c18
11 files changed, 61 insertions, 22 deletions
diff --git a/source4/build/pidl/client.pm b/source4/build/pidl/client.pm
index 9502c68e1a..1c0baa16f8 100644
--- a/source4/build/pidl/client.pm
+++ b/source4/build/pidl/client.pm
@@ -34,6 +34,10 @@ struct rpc_request *dcerpc_$name\_send(struct dcom_interface *d, TALLOC_CTX *mem
return NULL;
}
+ ZERO_STRUCT(r->in.ORPCthis);
+ r->in.ORPCthis.version.MajorVersion = 5;
+ r->in.ORPCthis.version.MinorVersion = 1;
+
";
} else {
$objarg = "NULL";
diff --git a/source4/build/pidl/header.pm b/source4/build/pidl/header.pm
index 0c4c5df425..cc9b804387 100644
--- a/source4/build/pidl/header.pm
+++ b/source4/build/pidl/header.pm
@@ -350,6 +350,7 @@ sub HeaderInterface($)
$res .= "NTSTATUS dcerpc_server_$interface->{NAME}_init(void);\n\n";
}
+ $count = $interface->{INHERITED_FUNCTIONS};
foreach my $d (@{$data}) {
if ($d->{TYPE} eq "FUNCTION") {
my $u_name = uc $d->{NAME};
diff --git a/source4/build/pidl/idl.pm b/source4/build/pidl/idl.pm
index 19525e42f3..a3e2e2ca8c 100644
--- a/source4/build/pidl/idl.pm
+++ b/source4/build/pidl/idl.pm
@@ -2080,8 +2080,10 @@ sub parse_idl($$)
die("No such parent interface " . $x->{BASE});
}
+ $x->{INHERITED_FUNCTIONS} = scalar @{$parent->{INHERITED_DATA}};
@{$x->{INHERITED_DATA}} = (@{$parent->{INHERITED_DATA}}, @{$x->{DATA}});
} else {
+ $x->{INHERITED_FUNCTIONS} = 0;
$x->{INHERITED_DATA} = $x->{DATA};
}
}
diff --git a/source4/build/pidl/idl.yp b/source4/build/pidl/idl.yp
index 24f88dd531..e571645c4b 100644
--- a/source4/build/pidl/idl.yp
+++ b/source4/build/pidl/idl.yp
@@ -368,8 +368,10 @@ sub parse_idl($$)
die("No such parent interface " . $x->{BASE});
}
+ $x->{INHERITED_FUNCTIONS} = scalar @{$parent->{INHERITED_DATA}};
@{$x->{INHERITED_DATA}} = (@{$parent->{INHERITED_DATA}}, @{$x->{DATA}});
} else {
+ $x->{INHERITED_FUNCTIONS} = 0;
$x->{INHERITED_DATA} = $x->{DATA};
}
}
diff --git a/source4/lib/dcom/common/main.c b/source4/lib/dcom/common/main.c
index a4fcb7ec0d..8b947ba8ef 100644
--- a/source4/lib/dcom/common/main.c
+++ b/source4/lib/dcom/common/main.c
@@ -128,6 +128,8 @@ NTSTATUS dcerpc_IUnknown_Release(struct dcom_interface *p, TALLOC_CTX *mem_ctx,
struct RemRelease r;
struct REMINTERFACEREF ref;
+ return NT_STATUS_NOT_SUPPORTED;
+
p->private_references--;
/* Only do the remote version of this call when all local references have
@@ -314,8 +316,6 @@ NTSTATUS dcom_get_pipe (struct dcom_interface *iface, struct dcerpc_pipe **p)
return NT_STATUS_NOT_SUPPORTED;
}
- DEBUG(1, ("DCOM: Connecting to %s\n", GUID_string(NULL, &iface->objref->iid)));
-
oxid = iface->objref->u_objref.u_standard.std.oxid;
iid = iface->objref->iid;
diff --git a/source4/librpc/idl/dcerpc.idl b/source4/librpc/idl/dcerpc.idl
index cd87539589..1b8add3e79 100644
--- a/source4/librpc/idl/dcerpc.idl
+++ b/source4/librpc/idl/dcerpc.idl
@@ -37,9 +37,18 @@ interface dcerpc
const uint8 DCERPC_MAX_SIGN_SIZE = 32;
typedef struct {
+ } dcerpc_empty;
+
+ typedef [nodiscriminant] union {
+ [default] dcerpc_empty empty;
+ [case(LIBNDR_FLAG_OBJECT_PRESENT)] GUID object;
+ } dcerpc_object;
+
+ typedef struct {
uint32 alloc_hint;
uint16 context_id;
uint16 opnum;
+ [switch_is(ndr->flags & LIBNDR_FLAG_OBJECT_PRESENT)] dcerpc_object object;
[flag(NDR_ALIGN8)] DATA_BLOB _pad;
[flag(NDR_REMAINING)] DATA_BLOB stub_and_verifier;
} dcerpc_request;
@@ -170,13 +179,6 @@ 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;
@@ -201,7 +203,6 @@ 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;
}
diff --git a/source4/librpc/idl/dcom.idl b/source4/librpc/idl/dcom.idl
index 912902a29a..10e63772dd 100644
--- a/source4/librpc/idl/dcom.idl
+++ b/source4/librpc/idl/dcom.idl
@@ -200,7 +200,7 @@ interface ObjectRpcBaseTypes
uint32 cPublicRefs; /* count of references passed */
OXID oxid; /* oxid of server with this oid */
OID oid; /* oid of object with this ipid */
- IPID ipid; /* ipid of Interface */
+ IPID ipid; /* ipid of interface pointer to this object */
} STDOBJREF;
typedef struct
@@ -249,7 +249,7 @@ interface ObjectRpcBaseTypes
typedef [public] struct
{
uint32 size;
- [subcontext(4),align(4)] OBJREF obj;
+ [subcontext(4)] OBJREF obj;
} MInterfacePointer;
}
@@ -501,11 +501,15 @@ uuid(DB7C21F8-FE33-4C11-AEA5-CEB56F076FBB),
]
interface IStream : IUnknown
{
- WERROR IStream_Read([in] uint32 num_requested,
- [out,size_is(*num_read)] uint8 *data,
- [out] uint32 *num_read);
-
- WERROR IStream_Write([in,size_is(num_requested)] uint8 *data,
+ WERROR IStream_Read(
+ [out, size_is(num_requested), length_is(num_read)] uint8 pv[],
+ [in] uint32 num_requested,
+ [in] uint32 *num_readx,
+ [out] uint32 num_read
+ );
+
+ WERROR IStream_Write(
+ [in,size_is(num_requested)] uint8 *data,
[in] uint32 num_requested,
- [out] uint32 *num_written);
+ [out] uint32 num_written);
}
diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h
index 86312b0906..044b7129f8 100644
--- a/source4/librpc/ndr/libndr.h
+++ b/source4/librpc/ndr/libndr.h
@@ -124,6 +124,8 @@ struct ndr_print {
offset, not base) */
#define LIBNDR_FLAG_RELATIVE_CURRENT (1<<29)
+/* set if an object uuid will be present */
+#define LIBNDR_FLAG_OBJECT_PRESENT (1<<30)
/* useful macro for debugging */
#define NDR_PRINT_DEBUG(type, p) ndr_print_debug((ndr_print_fn_t)ndr_print_ ##type, #p, p)
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
index dcbbe3ac7d..f4b10f6b52 100644
--- a/source4/librpc/rpc/dcerpc.c
+++ b/source4/librpc/rpc/dcerpc.c
@@ -321,6 +321,10 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
}
+ if (pkt->pfc_flags & DCERPC_PFC_FLAG_ORPC) {
+ ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT;
+ }
+
status = ndr_push_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
if (!NT_STATUS_IS_OK(status)) {
return status;
@@ -883,10 +887,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.u.request.object.object = *object;
pkt.pfc_flags |= DCERPC_PFC_FLAG_ORPC;
- printf("OBJECT: %s\n", GUID_string(NULL, object));
+ chunk_size -= ndr_size_GUID(0,object,0);
}
DLIST_ADD(p->pending, req);
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
index 69dae46aef..c31cf2791b 100644
--- a/source4/librpc/rpc/dcerpc_util.c
+++ b/source4/librpc/rpc/dcerpc_util.c
@@ -106,6 +106,10 @@ NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
}
+ if (pkt->pfc_flags & DCERPC_PFC_FLAG_ORPC) {
+ ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT;
+ }
+
if (auth_info) {
pkt->auth_length = auth_info->credentials.length;
} else {
diff --git a/source4/torture/dcom/simple.c b/source4/torture/dcom/simple.c
index d057bf9627..287e35142e 100644
--- a/source4/torture/dcom/simple.c
+++ b/source4/torture/dcom/simple.c
@@ -40,6 +40,8 @@ BOOL torture_dcom_simple(void)
struct IStream_Write r_write;
WERROR results[2];
struct dcom_context *ctx;
+ char test_data[5];
+ int i;
mem_ctx = talloc_init("torture_dcom_simple");
@@ -62,16 +64,28 @@ BOOL torture_dcom_simple(void)
}
ZERO_STRUCT(r_read);
+ r_read.in.num_requested = 20; /* Give me 20 0xFF bytes... */
status = dcerpc_IStream_Read(&interfaces[0], mem_ctx, &r_read);
if (NT_STATUS_IS_ERR(status)) {
printf("IStream::Read() failed - %s\n", nt_errstr(status));
- return False;
+ 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 = dcerpc_IStream_Write(&interfaces[0], mem_ctx, &r_write);
if (NT_STATUS_IS_ERR(status)) {
printf("IStream::Write() failed - %s\n", nt_errstr(status));
- return False;
+ 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 = dcerpc_IUnknown_Release(&interfaces[1], mem_ctx, NULL);