mirror of
https://github.com/samba-team/samba.git
synced 2025-01-25 06:04:04 +03:00
r3625: Couple of minor DCOM bugfixes
(This used to be commit 6f5bf44ade8bad10c6cf08a7d6e3528ec6b4ec8a)
This commit is contained in:
parent
c077300a22
commit
73c1f61350
@ -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;
|
||||
|
72
source4/lib/dcom/common/local.c
Normal file
72
source4/lib/dcom/common/local.c
Normal file
@ -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;
|
||||
}
|
@ -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"));
|
||||
|
@ -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
|
||||
################################################
|
||||
|
Loading…
x
Reference in New Issue
Block a user