summaryrefslogtreecommitdiff
path: root/source4/lib/dcom
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2004-11-08 20:54:00 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:05:40 -0500
commit73c1f61350a01c0cc5825ae0a08bb4c03121eda4 (patch)
treef121c0e4f240db6f37062d8d9ba09f4d2c326b35 /source4/lib/dcom
parentc077300a22806bab94d11a87c8ef96b6b541ada5 (diff)
downloadsamba-73c1f61350a01c0cc5825ae0a08bb4c03121eda4.tar.gz
samba-73c1f61350a01c0cc5825ae0a08bb4c03121eda4.tar.bz2
samba-73c1f61350a01c0cc5825ae0a08bb4c03121eda4.zip
r3625: Couple of minor DCOM bugfixes
(This used to be commit 6f5bf44ade8bad10c6cf08a7d6e3528ec6b4ec8a)
Diffstat (limited to 'source4/lib/dcom')
-rw-r--r--source4/lib/dcom/common/dcom.h9
-rw-r--r--source4/lib/dcom/common/local.c72
-rw-r--r--source4/lib/dcom/common/main.c79
-rw-r--r--source4/lib/dcom/config.mk3
4 files changed, 100 insertions, 63 deletions
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 <jelmer@samba.org>
+
+ 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
################################################