diff options
-rw-r--r-- | source4/build/pidl/client.pm | 58 | ||||
-rw-r--r-- | source4/build/pidl/header.pm | 10 | ||||
-rw-r--r-- | source4/include/includes.h | 2 | ||||
-rw-r--r-- | source4/lib/dcom/common/dcom.h | 14 | ||||
-rw-r--r-- | source4/lib/dcom/common/main.c | 207 | ||||
-rw-r--r-- | source4/librpc/config.mk | 2 | ||||
-rw-r--r-- | source4/librpc/idl/dcom.idl | 13 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc.c | 6 | ||||
-rw-r--r-- | source4/torture/dcom/simple.c | 30 | ||||
-rw-r--r-- | source4/torture/rpc/remact.c | 4 |
10 files changed, 274 insertions, 72 deletions
diff --git a/source4/build/pidl/client.pm b/source4/build/pidl/client.pm index 10ae81ec18..d9d2a0ca14 100644 --- a/source4/build/pidl/client.pm +++ b/source4/build/pidl/client.pm @@ -19,22 +19,35 @@ sub ParseFunction($) return if (util::has_property($fn, "local")); - my $objargdef = ""; - my $objarg = ", NULL"; + my $objarg; if (util::has_property($fn, "object")) { - $objargdef = ", struct GUID *object"; - $objarg = ", object"; + $objarg = "&d->objref->u_objref.u_standard.std.ipid"; + # FIXME: Support custom marshalling + + $res .= " +struct rpc_request *dcerpc_$name\_send(struct dcom_interface *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; } - $res .= -" -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) { +"; + } else { + $objarg = "NULL"; + $res .= " +struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r) +{"; + } + + $res.=" + if (p->flags & DCERPC_DEBUG_PRINT_IN) { NDR_PRINT_IN_DEBUG($name, r); } - return dcerpc_ndr_request_send(p$objarg, 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)); @@ -42,13 +55,32 @@ struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p$objargdef, TALLOC_C "; - $objarg = "" unless (util::has_property($fn, "object")); + if (util::has_property($fn, "object")) { $res .= " -NTSTATUS dcerpc_$name(struct dcerpc_pipe *p$objargdef, TALLOC_CTX *mem_ctx, struct $name *r) +NTSTATUS dcerpc_$name(struct dcom_interface *d, TALLOC_CTX *mem_ctx, struct $name *r) { - struct rpc_request *req = dcerpc_$name\_send(p$objarg, mem_ctx, r); + struct dcerpc_pipe *p; + NTSTATUS status = dcom_get_pipe(d, &p); + struct rpc_request *req; + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + "; + } else { + $res .= +" +NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r) +{ + struct rpc_request *req; NTSTATUS status; + "; + } + + $res .= " + req = dcerpc_$name\_send(p, mem_ctx, r); if (req == NULL) return NT_STATUS_NO_MEMORY; status = dcerpc_ndr_request_recv(req); diff --git a/source4/build/pidl/header.pm b/source4/build/pidl/header.pm index d1eb1d1630..0c4c5df425 100644 --- a/source4/build/pidl/header.pm +++ b/source4/build/pidl/header.pm @@ -303,16 +303,14 @@ sub HeaderFnProto($) my $fn = shift; my $name = $fn->{NAME}; - return if (util::has_property($fn, "call_as") ); - - my $objarg = ""; + my $firstarg = "dcerpc_pipe"; if (util::has_property($fn, "object")) { - $objarg = ", struct GUID *"; + $firstarg = "dcom_interface"; } $res .= "void ndr_print_$name(struct ndr_print *, const char *, int, 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 .= "struct rpc_request *dcerpc_$name\_send(struct $firstarg *, TALLOC_CTX *, struct $name *);\n"; + $res .= "NTSTATUS dcerpc_$name(struct $firstarg *, TALLOC_CTX *, struct $name *);\n"; $res .= "\n"; } diff --git a/source4/include/includes.h b/source4/include/includes.h index d815e8c424..c7cc1338f5 100644 --- a/source4/include/includes.h +++ b/source4/include/includes.h @@ -183,8 +183,8 @@ extern int errno; #include "librpc/gen_ndr/ndr_misc.h" #include "librpc/gen_ndr/ndr_dcerpc.h" #include "librpc/rpc/dcerpc.h" -#include "librpc/gen_ndr/ndr_dcom.h" #include "lib/dcom/common/dcom.h" +#include "librpc/gen_ndr/ndr_dcom.h" #include "smb_interfaces.h" #include "smbd/server.h" #include "smbd/service.h" diff --git a/source4/lib/dcom/common/dcom.h b/source4/lib/dcom/common/dcom.h index d97364a125..06407cf2f4 100644 --- a/source4/lib/dcom/common/dcom.h +++ b/source4/lib/dcom/common/dcom.h @@ -25,10 +25,22 @@ struct IUnknown_AddRef; struct IUnknown_Release; struct IUnknown_QueryInterface; +struct dcom_oxid_mapping; + +struct dcom_context +{ + struct dcom_oxid_mapping *oxids; + const char *domain; + const char *user; + const char *password; +}; + struct dcom_interface { + struct dcom_context *ctx; struct dcerpc_pipe *pipe; - struct OBJREF object; + struct OBJREF *objref; + uint32_t private_references; }; #endif /* _DCOM_H */ diff --git a/source4/lib/dcom/common/main.c b/source4/lib/dcom/common/main.c index 7a8def25c5..a2650e3446 100644 --- a/source4/lib/dcom/common/main.c +++ b/source4/lib/dcom/common/main.c @@ -19,12 +19,15 @@ */ #include "includes.h" +#include "dlinklist.h" #include "librpc/gen_ndr/ndr_epmapper.h" #include "librpc/gen_ndr/ndr_remact.h" +#include "librpc/gen_ndr/ndr_oxidresolver.h" +#include "librpc/gen_ndr/ndr_dcom.h" #define DCOM_NEGOTIATED_PROTOCOLS { EPM_PROTOCOL_TCP, EPM_PROTOCOL_SMB, EPM_PROTOCOL_NCALRPC } -static NTSTATUS dcom_connect(struct dcerpc_pipe **p, const char *server, const char *domain, const char *user, const char *pass) +static NTSTATUS dcom_connect_host(struct dcom_context *ctx, struct dcerpc_pipe **p, const char *server) { struct dcerpc_binding bd; enum dcerpc_transport_t available_transports[] = { NCACN_IP_TCP, NCACN_NP }; @@ -34,7 +37,7 @@ static NTSTATUS dcom_connect(struct dcerpc_pipe **p, const char *server, const c /* Allow server name to contain a binding string */ if (NT_STATUS_IS_OK(dcerpc_parse_binding(mem_ctx, server, &bd))) { - status = dcerpc_pipe_connect_b(p, &bd, DCERPC_IREMOTEACTIVATION_UUID, DCERPC_IREMOTEACTIVATION_VERSION, domain, user, pass); + status = dcerpc_pipe_connect_b(p, &bd, DCERPC_IREMOTEACTIVATION_UUID, DCERPC_IREMOTEACTIVATION_VERSION, ctx->domain, ctx->user, ctx->password); talloc_destroy(mem_ctx); return status; } @@ -45,14 +48,14 @@ static NTSTATUS dcom_connect(struct dcerpc_pipe **p, const char *server, const c if (server == NULL) { bd.transport = NCALRPC; - return dcerpc_pipe_connect_b(p, &bd, DCERPC_IREMOTEACTIVATION_UUID, DCERPC_IREMOTEACTIVATION_VERSION, domain, user, pass); + return dcerpc_pipe_connect_b(p, &bd, DCERPC_IREMOTEACTIVATION_UUID, DCERPC_IREMOTEACTIVATION_VERSION, ctx->domain, ctx->user, ctx->password); } for (i = 0; i < ARRAY_SIZE(available_transports); i++) { bd.transport = available_transports[i]; - status = dcerpc_pipe_connect_b(p, &bd, DCERPC_IREMOTEACTIVATION_UUID, DCERPC_IREMOTEACTIVATION_VERSION, domain, user, pass); + status = dcerpc_pipe_connect_b(p, &bd, DCERPC_IREMOTEACTIVATION_UUID, DCERPC_IREMOTEACTIVATION_VERSION, ctx->domain, ctx->user, ctx->password); if (NT_STATUS_IS_OK(status)) { return status; @@ -62,34 +65,73 @@ static NTSTATUS dcom_connect(struct dcerpc_pipe **p, const char *server, const c return status; } -#if 0 -static WERROR dcom_connect_oxid(TALLOC_CTX *mem_ctx, struct dcerpc_pipe **p, HYPER_T oxid) +static NTSTATUS dcom_connect_STRINGBINDINGARRAY(struct dcom_context *ctx, struct dcerpc_pipe **p, DATA_BLOB *stringbindingarray) { - /* FIXME */ - return WERR_NOT_SUPPORTED; + return NT_STATUS_NOT_SUPPORTED; } -#endif -NTSTATUS dcerpc_IUnknown_AddRef(struct dcerpc_pipe *p, struct GUID *o, TALLOC_CTX *mem_ctx, struct IUnknown_AddRef *r) +static NTSTATUS dcom_connect_DUALSTRINGBINDINGARRAY(struct dcom_context *ctx, struct dcerpc_pipe **p, struct DUALSTRINGARRAY *array) { - /* FIXME: Tell local server we're adding a reference to this interface on this object. Local server can then call RemAddRef() if necessary */ return NT_STATUS_NOT_SUPPORTED; } -NTSTATUS dcerpc_IUnknown_Release(struct dcerpc_pipe *p, struct GUID *o, TALLOC_CTX *mem_ctx, struct IUnknown_Release *r) +NTSTATUS dcerpc_IUnknown_AddRef(struct dcom_interface *p, TALLOC_CTX *mem_ctx, struct IUnknown_AddRef *rr) { - /* FIXME: Tell local server we're releasing a reference to this interface on this object. Local server can then call RemRelease() if necessary */ - return NT_STATUS_NOT_SUPPORTED; + struct RemAddRef r; + struct REMINTERFACEREF ref; + + /* This is rather inefficient, but we'll patch it up later */ + r.in.cInterfaceRefs = 1; + r.in.InterfaceRefs = &ref; + + return dcerpc_RemAddRef(p, mem_ctx, &r); +} + +NTSTATUS dcerpc_IUnknown_Release(struct dcom_interface *p, TALLOC_CTX *mem_ctx, struct IUnknown_Release *rr) +{ + struct RemRelease r; + struct REMINTERFACEREF ref; + + p->private_references--; + + /* Only do the remote version of this call when all local references have + * been released */ + if (p->private_references == 0) { + NTSTATUS status; + r.in.cInterfaceRefs = 1; + r.in.InterfaceRefs = &ref; + + status = dcerpc_RemRelease(p, mem_ctx, &r); + + if (NT_STATUS_IS_OK(status)) { + talloc_destroy(p); + } + + return status; + } + + return NT_STATUS_OK; } -NTSTATUS dcerpc_IUnknown_QueryInterface(struct dcerpc_pipe *p, struct GUID *o, TALLOC_CTX *mem_ctx, struct IUnknown_QueryInterface *r) +NTSTATUS dcerpc_IUnknown_QueryInterface(struct dcom_interface *o, TALLOC_CTX *mem_ctx, struct IUnknown_QueryInterface *rr) { /* FIXME: Ask local server for interface pointer. Local server can then * call RemQueryInterface if necessary */ return NT_STATUS_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, const char *domain, const char *user, const char *pass) +WERROR dcom_init(struct dcom_context **ctx, const char *domain, const char *user, const char *pass) +{ + *ctx = talloc_p(NULL, struct dcom_context); + (*ctx)->oxids = NULL; + (*ctx)->domain = talloc_strdup(*ctx, domain); + (*ctx)->user = talloc_strdup(*ctx, user); + (*ctx)->password = talloc_strdup(*ctx, pass); + + 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 **ip, WERROR *results) { struct RemoteActivation r; int i; @@ -97,7 +139,7 @@ WERROR dcom_create_object(TALLOC_CTX *mem_ctx, struct GUID *clsid, const char *s NTSTATUS status; uint16 protseq[] = DCOM_NEGOTIATED_PROTOCOLS; - status = dcom_connect(&p, server, domain, user, pass); + 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))); return ntstatus_to_werror(status); @@ -113,28 +155,35 @@ WERROR dcom_create_object(TALLOC_CTX *mem_ctx, struct GUID *clsid, const char *s r.in.protseq = protseq; r.in.Interfaces = num_ifaces; r.in.pIIDs = iid; - r.out.ifaces = talloc_array_p(mem_ctx, struct pMInterfacePointer, num_ifaces); + r.out.ifaces = talloc_array_p(ctx, struct pMInterfacePointer, num_ifaces); - status = dcerpc_RemoteActivation(p, mem_ctx, &r); + status = dcerpc_RemoteActivation(p, ctx, &r); if(NT_STATUS_IS_ERR(status)) { DEBUG(1, ("Error while running 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]; } + if(!W_ERROR_IS_OK(r.out.result)) { + return r.out.result; + } + + if(!W_ERROR_IS_OK(r.out.hr)) { + return r.out.hr; + } - *ip = talloc_array_p(mem_ctx, struct dcom_interface, num_ifaces); + *ip = talloc_array_p(ctx, struct dcom_interface, num_ifaces); for (i = 0; i < num_ifaces; i++) { - (*ip)[i].object = r.out.ifaces[i].p->obj; - (*ip)[i].pipe = NULL; /* FIXME */ + results[i] = r.out.results[i]; + (*ip)[i].private_references = 1; + (*ip)[i].objref = &r.out.ifaces[i].p->obj; + (*ip)[i].pipe = NULL; + (*ip)[i].ctx = ctx; } return WERR_OK; } -WERROR dcom_get_class_object(TALLOC_CTX *mem_ctx, struct GUID *clsid, const char *server, struct GUID *iid, struct dcom_interface *ip, const char *domain, const char *user, const char *pass) +WERROR dcom_get_class_object(struct dcom_context *ctx, struct GUID *clsid, const char *server, struct GUID *iid, struct dcom_interface *ip) { struct RemoteActivation r; struct dcerpc_pipe *p; @@ -142,7 +191,7 @@ WERROR dcom_get_class_object(TALLOC_CTX *mem_ctx, struct GUID *clsid, const char struct pMInterfacePointer pm; uint16 protseq[] = DCOM_NEGOTIATED_PROTOCOLS; - status = dcom_connect(&p, server, domain, user, pass); + 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))); return ntstatus_to_werror(status); @@ -161,7 +210,7 @@ WERROR dcom_get_class_object(TALLOC_CTX *mem_ctx, struct GUID *clsid, const char r.in.Mode = MODE_GET_CLASS_OBJECT; r.out.ifaces = ± - status = dcerpc_RemoteActivation(p, mem_ctx, &r); + status = dcerpc_RemoteActivation(p, ctx, &r); if(NT_STATUS_IS_ERR(status)) { DEBUG(1, ("Error while running RemoteActivation - %s\n", nt_errstr(status))); return ntstatus_to_werror(status); @@ -170,9 +219,105 @@ WERROR dcom_get_class_object(TALLOC_CTX *mem_ctx, struct GUID *clsid, const char 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]; } - - ip->pipe = NULL; /* FIXME */ - ip->object = pm.p->obj; + + ip->private_references = 1; + ip->pipe = NULL; + ip->objref = &pm.p->obj; + ip->ctx = ctx; return WERR_OK; } + +struct dcom_oxid_mapping { + struct dcom_oxid_mapping *prev, *next; + struct DUALSTRINGARRAY bindings; + HYPER_T oxid; + struct dcerpc_pipe *pipe; +}; + +static struct dcom_oxid_mapping *oxid_mapping_by_oxid (struct dcom_context *ctx, HYPER_T oxid) +{ + struct dcom_oxid_mapping *m; + + for (m = ctx->oxids;m;m = m->next) { + if (m->oxid == oxid) { + return m; + } + } + + return NULL; +} + +NTSTATUS dcom_get_pipe (struct dcom_interface *iface, struct dcerpc_pipe **p) +{ + struct dcom_oxid_mapping *m; + HYPER_T oxid; + NTSTATUS status; + + SMB_ASSERT(iface->objref->signature == OBJREF_SIGNATURE); + + if (iface->objref->flags & OBJREF_HANDLER) { + DEBUG(0, ("dcom_get_pipe: OBJREF_HANDLER not supported!\n")); + return NT_STATUS_NOT_SUPPORTED; + } + + if (iface->objref->flags & OBJREF_CUSTOM) { + DEBUG(0, ("dcom_get_pipe: OBJREF_CUSTOM not supported!\n")); + 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; + + m = oxid_mapping_by_oxid(iface->ctx, oxid); + + /* Add OXID mapping if none present yet */ + if (!m) { + struct dcerpc_pipe *po; + struct ResolveOxid r; + uint16 protseq[] = DCOM_NEGOTIATED_PROTOCOLS; + + DEBUG(3, ("No binding data present yet, resolving OXID %llu\n", oxid)); + + m = talloc_zero_p(iface->ctx, struct dcom_oxid_mapping); + m->oxid = oxid; + + status = dcom_connect_STRINGBINDINGARRAY(iface->ctx, &po, &iface->objref->u_objref.u_standard.saResAddr); + + if (NT_STATUS_IS_ERR(status)) { + DEBUG(1, ("Error while connecting to OXID Resolver : %s\n", nt_errstr(status))); + return status; + } + + r.in.pOxid = oxid; + r.in.cRequestedProtseqs = ARRAY_SIZE(protseq); + r.in.arRequestedProtseqs = protseq; + r.out.ppdsaOxidBindings = &m->bindings; + + status = dcerpc_ResolveOxid(po, iface->ctx, &r); + if (NT_STATUS_IS_ERR(status)) { + DEBUG(1, ("Error while resolving OXID: %s\n", nt_errstr(status))); + return status; + } + + dcerpc_pipe_close(po); + + DLIST_ADD(iface->ctx->oxids, m); + } + + if (m->pipe) { + *p = m->pipe; + /* FIXME: Switch to correct IID using an alter context call */ + return NT_STATUS_OK; + } + + status = dcom_connect_DUALSTRINGBINDINGARRAY(iface->ctx, &m->pipe, &m->bindings); + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + *p = m->pipe; + return NT_STATUS_OK; +} diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 09e2a278c4..b16c42b938 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -81,6 +81,6 @@ ADD_OBJ_FILES = \ ################################################ # Start SUBSYSTEM LIBRPC [SUBSYSTEM::LIBRPC] -REQUIRED_SUBSYSTEMS = LIBNDR_RAW LIBNDR_GEN LIBRPC_RAW +REQUIRED_SUBSYSTEMS = LIBNDR_RAW LIBNDR_GEN LIBRPC_RAW LIBDCOM # End SUBSYSTEM LIBRPC ################################################ diff --git a/source4/librpc/idl/dcom.idl b/source4/librpc/idl/dcom.idl index 615d812b47..41e2ccb73c 100644 --- a/source4/librpc/idl/dcom.idl +++ b/source4/librpc/idl/dcom.idl @@ -151,19 +151,19 @@ interface ObjectRpcBaseTypes /* DUALSTRINGARRAYS are the return type for arrays of network addresses, */ /* arrays of endpoints and arrays of both used in many ORPC interfaces */ - typedef struct + typedef [public] struct { uint16 wTowerId; /* Cannot be zero. */ - uint16 aNetworkAddr; /* Zero terminated. */ + nstring NetworkAddr; } STRINGBINDING; const uint16 COM_C_AUTHZ_NONE = 0xffff; - typedef struct + typedef [public] struct { uint16 wAuthnSvc; /* Cannot be zero. */ uint16 wAuthzSvc; /* Must not be zero. */ - uint16 aPrincName; /* Zero terminated. */ + nstring PrincName; } SECURITYBINDING; @@ -177,7 +177,6 @@ interface ObjectRpcBaseTypes [size_is(wNumEntries)] uint16 aStringArray[]; } DUALSTRINGARRAY; - /* signature value for OBJREF (object reference, actually the */ /* marshaled form of a COM interface). */ const uint32 OBJREF_SIGNATURE = 0x574f454d; /* 'MEOW' */ @@ -219,14 +218,14 @@ interface ObjectRpcBaseTypes typedef struct { STDOBJREF std; /* standard objref */ - DUALSTRINGARRAY saResAddr; /* resolver address */ + [flag(NDR_REMAINING)] DATA_BLOB saResAddr; /* resolver address */ } u_standard; typedef struct { STDOBJREF std; /* standard objref */ GUID clsid; /* Clsid of handler code */ - DUALSTRINGARRAY saResAddr; /* resolver address */ + [flag(NDR_REMAINING)] DATA_BLOB saResAddr; /* resolver address */ } u_handler; typedef struct diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 27292bc8c3..beccac78ca 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -974,7 +974,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, + struct OBJREF *object, uint16_t opnum, TALLOC_CTX *mem_ctx, DATA_BLOB *stub_data_in, @@ -1141,7 +1141,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, + struct OBJREF *object, uint32_t opnum, TALLOC_CTX *mem_ctx, NTSTATUS (*ndr_push)(struct ndr_push *, int, void *), @@ -1278,7 +1278,7 @@ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req) standard format */ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, - struct GUID *object, + struct OBJREF *object, uint32_t opnum, TALLOC_CTX *mem_ctx, NTSTATUS (*ndr_push)(struct ndr_push *, int, void *), diff --git a/source4/torture/dcom/simple.c b/source4/torture/dcom/simple.c index 112ebcacc6..d057bf9627 100644 --- a/source4/torture/dcom/simple.c +++ b/source4/torture/dcom/simple.c @@ -38,13 +38,23 @@ BOOL torture_dcom_simple(void) struct dcom_interface *interfaces; struct IStream_Read r_read; struct IStream_Write r_write; + WERROR results[2]; + struct dcom_context *ctx; mem_ctx = talloc_init("torture_dcom_simple"); + dcom_init(&ctx, lp_parm_string(-1, "torture", "userdomain"), + lp_parm_string(-1, "torture", "username"), + lp_parm_string(-1, "torture", "password")); + 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, lp_parm_string(-1, "torture", "binding"), 2, IID, &interfaces, lp_parm_string(-1, "torture", "userdomain"), lp_parm_string(-1, "torture", "username"), lp_parm_string(-1, "torture", "password")); + error = dcom_create_object(ctx, &clsid, + lp_parm_string(-1, "torture", "binding"), 2, IID, + &interfaces, + results); + if (!W_ERROR_IS_OK(error)) { printf("dcom_create_object failed - %s\n", win_errstr(error)); @@ -52,19 +62,23 @@ BOOL torture_dcom_simple(void) } ZERO_STRUCT(r_read); - status = dcerpc_IStream_Read(interfaces[0].pipe, NULL, mem_ctx, &r_read); - if (NT_STATUS_IS_ERR(error)) { - printf("IStream::Read() failed - %s\n", win_errstr(error)); + 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; } - status = dcerpc_IStream_Write(interfaces[0].pipe, NULL, mem_ctx, &r_write); - if (NT_STATUS_IS_ERR(error)) { - printf("IStream::Write() failed - %s\n", win_errstr(error)); + 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; } - /*FIXME: dcerpc_IUnknown_Release();*/ + status = dcerpc_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_destroy(mem_ctx); diff --git a/source4/torture/rpc/remact.c b/source4/torture/rpc/remact.c index 073b8177c6..2e09f84da6 100644 --- a/source4/torture/rpc/remact.c +++ b/source4/torture/rpc/remact.c @@ -42,8 +42,9 @@ static int test_RemoteActivation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) r.in.ClientImpLevel = RPC_C_IMP_LEVEL_IDENTIFY; r.in.num_protseqs = 3; r.in.protseq = protseq; - r.in.Interfaces = 1; + r.in.Interfaces = 2; GUID_from_string(DCERPC_IUNKNOWN_UUID, &iids[0]); + GUID_from_string(DCERPC_ISTREAM_UUID, &iids[1]); r.in.pIIDs = iids; status = dcerpc_RemoteActivation(p, mem_ctx, &r); @@ -68,6 +69,7 @@ static int test_RemoteActivation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) } GUID_from_string(DCERPC_ICLASSFACTORY_UUID, &iids[0]); + r.in.Interfaces = 1; r.in.Mode = MODE_GET_CLASS_OBJECT; status = dcerpc_RemoteActivation(p, mem_ctx, &r); |