From cc368fa69e6a205516c64712aee701fe0cf6d20b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 21 Nov 2004 17:47:09 +0000 Subject: r3898: Work towards local/server DCOM support, start working on Simple example server side implementation (This used to be commit 98afb504d95ccca4d6ec48273e10b52ccfa26ad0) --- source4/lib/dcom/common/main.c | 126 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 118 insertions(+), 8 deletions(-) (limited to 'source4/lib/dcom/common/main.c') diff --git a/source4/lib/dcom/common/main.c b/source4/lib/dcom/common/main.c index 60f866aede..3730137268 100644 --- a/source4/lib/dcom/common/main.c +++ b/source4/lib/dcom/common/main.c @@ -143,15 +143,15 @@ WERROR dcom_ping(struct dcom_context *ctx) 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) +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) { + uint16 protseq[] = DCOM_NEGOTIATED_PROTOCOLS; + struct dcerpc_pipe *p; + struct dcom_object_exporter *m; + NTSTATUS status; struct RemoteActivation r; struct DUALSTRINGARRAY dualstring; int i; - struct dcom_object_exporter *m; - struct dcerpc_pipe *p; - NTSTATUS status; - uint16 protseq[] = DCOM_NEGOTIATED_PROTOCOLS; status = dcom_connect_host(ctx, &p, server); if (NT_STATUS_IS_ERR(status)) { @@ -207,7 +207,60 @@ WERROR dcom_create_object(struct dcom_context *ctx, struct GUID *clsid, const ch 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) +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; + 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) { struct dcom_object_exporter *m; struct RemoteActivation r; @@ -258,6 +311,36 @@ WERROR dcom_get_class_object(struct dcom_context *ctx, struct GUID *clsid, const 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 **p) { struct dcerpc_binding binding; @@ -326,6 +409,12 @@ struct dcom_object *dcom_object_by_oid(struct dcom_object_exporter *ox, HYPER_T return o; } + +NTSTATUS dcom_OBJREF_from_ifacep(struct dcom_context *ctx, struct OBJREF *o, struct dcom_interface_p *_p) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + NTSTATUS dcom_ifacep_from_OBJREF(struct dcom_context *ctx, struct dcom_interface_p **_p, struct OBJREF *o) { struct dcom_interface_p *p = talloc_p(ctx, struct dcom_interface_p); @@ -363,7 +452,7 @@ NTSTATUS dcom_ifacep_from_OBJREF(struct dcom_context *ctx, struct dcom_interface p->ipid = o->u_objref.u_handler.std.ipid; p->object = dcom_object_by_oid(p->ox, o->u_objref.u_standard.std.oid); p->ox->resolver_address = o->u_objref.u_handler.saResAddr; - p->vtable = dcom_vtable_by_clsid(&o->u_objref.u_handler.clsid); +/*FIXME p->vtable = dcom_vtable_by_clsid(&o->u_objref.u_handler.clsid);*/ /* FIXME: Do the custom unmarshaling call */ *_p = p; @@ -371,7 +460,6 @@ NTSTATUS dcom_ifacep_from_OBJREF(struct dcom_context *ctx, struct dcom_interface case OBJREF_CUSTOM: { - const struct dcom_interface *imarshal = dcom_vtable_by_clsid(&o->u_objref.u_custom.clsid); p->vtable = NULL; /* FIXME: Do the actual custom unmarshaling call */ @@ -437,3 +525,25 @@ NTSTATUS dcom_ifacep_from_OBJREF(struct dcom_context *ctx, struct dcom_interface return NT_STATUS_NOT_SUPPORTED; } + +HYPER_T dcom_get_current_oxid(void) +{ + return getpid(); +} + +struct dcom_interface_p *dcom_new_local_ifacep(struct dcom_context *ctx, const struct dcom_interface *iface, void *vtable, struct dcom_object *object) +{ + struct dcom_interface_p *ip = talloc_p(ctx, struct dcom_interface_p); + + ip->ctx = ctx; + ip->interface = iface; + ip->vtable = vtable; + uuid_generate_random(&ip->ipid); + ip->object = object; + ip->objref_flags = 0; + ip->orpc_flags = 0; + ip->ox = NULL; + ip->private_references = 1; + + return ip; +} -- cgit