From 73c1f61350a01c0cc5825ae0a08bb4c03121eda4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 8 Nov 2004 20:54:00 +0000 Subject: r3625: Couple of minor DCOM bugfixes (This used to be commit 6f5bf44ade8bad10c6cf08a7d6e3528ec6b4ec8a) --- source4/lib/dcom/common/dcom.h | 9 +++-- source4/lib/dcom/common/local.c | 72 +++++++++++++++++++++++++++++++++++++ source4/lib/dcom/common/main.c | 79 +++++++++++------------------------------ source4/lib/dcom/config.mk | 3 +- 4 files changed, 100 insertions(+), 63 deletions(-) create mode 100644 source4/lib/dcom/common/local.c (limited to 'source4') diff --git a/source4/lib/dcom/common/dcom.h b/source4/lib/dcom/common/dcom.h index 526340c384..23db4c355f 100644 --- a/source4/lib/dcom/common/dcom.h +++ b/source4/lib/dcom/common/dcom.h @@ -27,11 +27,14 @@ struct IUnknown_AddRef; struct IUnknown_Release; struct IUnknown_QueryInterface; -struct dcom_oxid_mapping; - struct dcom_context { - struct dcom_oxid_mapping *oxids; + struct dcom_oxid_mapping { + struct dcom_oxid_mapping *prev, *next; + struct DUALSTRINGARRAY bindings; + HYPER_T oxid; + struct dcerpc_pipe *pipe; + } *oxids; const char *domain; const char *user; const char *password; diff --git a/source4/lib/dcom/common/local.c b/source4/lib/dcom/common/local.c new file mode 100644 index 0000000000..3c5405e9dc --- /dev/null +++ b/source4/lib/dcom/common/local.c @@ -0,0 +1,72 @@ +/* + Unix SMB/CIFS implementation. + Implementation of some of the local COM calls. Interfaces: + - IUnknown + + Copyright (C) 2004 Jelmer Vernooij + + 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 "librpc/gen_ndr/ndr_dcom.h" + +NTSTATUS dcerpc_IUnknown_AddRef(struct dcom_interface *p, TALLOC_CTX *mem_ctx, struct IUnknown_AddRef *rr) +{ + 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; + + return NT_STATUS_NOT_SUPPORTED; + + 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 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; +} diff --git a/source4/lib/dcom/common/main.c b/source4/lib/dcom/common/main.c index 8b947ba8ef..c276b5e61a 100644 --- a/source4/lib/dcom/common/main.c +++ b/source4/lib/dcom/common/main.c @@ -27,13 +27,6 @@ #define DCOM_NEGOTIATED_PROTOCOLS { EPM_PROTOCOL_TCP, EPM_PROTOCOL_SMB, EPM_PROTOCOL_NCALRPC } -struct dcom_oxid_mapping { - struct dcom_oxid_mapping *prev, *next; - struct DUALSTRINGARRAY bindings; - HYPER_T oxid; - struct dcerpc_pipe *pipe; -}; - static NTSTATUS dcerpc_binding_from_STRINGBINDING(TALLOC_CTX *mem_ctx, struct dcerpc_binding *b, struct STRINGBINDING *bd) { char *host, *endpoint; @@ -111,53 +104,6 @@ static NTSTATUS dcom_connect_host(struct dcom_context *ctx, struct dcerpc_pipe * return status; } -NTSTATUS dcerpc_IUnknown_AddRef(struct dcom_interface *p, TALLOC_CTX *mem_ctx, struct IUnknown_AddRef *rr) -{ - 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; - - return NT_STATUS_NOT_SUPPORTED; - - 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 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_init(struct dcom_context **ctx, const char *domain, const char *user, const char *pass) { *ctx = talloc_p(NULL, struct dcom_context); @@ -303,6 +249,9 @@ NTSTATUS dcom_get_pipe (struct dcom_interface *iface, struct dcerpc_pipe **p) struct GUID iid; HYPER_T oxid; NTSTATUS status; + int i; + + *p = NULL; SMB_ASSERT(iface->objref->signature == OBJREF_SIGNATURE); @@ -332,8 +281,11 @@ NTSTATUS dcom_get_pipe (struct dcom_interface *iface, struct dcerpc_pipe **p) m = talloc_zero_p(iface->ctx, struct dcom_oxid_mapping); m->oxid = oxid; - /* FIXME: Check other string bindings as well, not just 0 */ - status = dcerpc_binding_from_STRINGBINDING(iface->ctx, &binding, iface->objref->u_objref.u_standard.saResAddr.stringbindings[0]); + i = 0; + do { + status = dcerpc_binding_from_STRINGBINDING(iface->ctx, &binding, iface->objref->u_objref.u_standard.saResAddr.stringbindings[i]); + i++; + } while (!NT_STATUS_IS_OK(status) && iface->objref->u_objref.u_standard.saResAddr.stringbindings[i]); if (NT_STATUS_IS_ERR(status)) { DEBUG(1, ("Error parsing string binding")); @@ -364,13 +316,22 @@ NTSTATUS dcom_get_pipe (struct dcom_interface *iface, struct dcerpc_pipe **p) } if (m->pipe) { + if (!uuid_equal(&m->pipe->syntax.uuid, &iid)) { + m->pipe->syntax.uuid = iid; + status = dcerpc_alter(m->pipe, iface->ctx); + if (NT_STATUS_IS_ERR(status)) { + return status; + } + } *p = m->pipe; - /* FIXME: Switch to correct IID using an alter context call */ return NT_STATUS_OK; } - /* FIXME: Check other string bindings as well, not just 0 */ - status = dcerpc_binding_from_STRINGBINDING(iface->ctx, &binding, m->bindings.stringbindings[0]); + i = 0; + do { + status = dcerpc_binding_from_STRINGBINDING(iface->ctx, &binding, m->bindings.stringbindings[i]); + i++; + } while (NT_STATUS_IS_ERR(status) && m->bindings.stringbindings[i]); if (NT_STATUS_IS_ERR(status)) { DEBUG(1, ("Error parsing string binding")); diff --git a/source4/lib/dcom/config.mk b/source4/lib/dcom/config.mk index 98b7031407..39424e6b25 100644 --- a/source4/lib/dcom/config.mk +++ b/source4/lib/dcom/config.mk @@ -2,7 +2,8 @@ # Start SUBSYSTEM LIBDCOM [SUBSYSTEM::LIBDCOM] INIT_OBJ_FILES = \ - lib/dcom/common/main.o + lib/dcom/common/main.o \ + lib/dcom/common/local.o # # End SUBSYSTEM LIBDCOM ################################################ -- cgit