mirror of
https://github.com/samba-team/samba.git
synced 2025-01-03 01:18:10 +03:00
s4: remove unused lib/com/*
Maybe the following IDL files are now unused: librpc/idl/oxidresolver.idl librpc/idl/remact.idl librpc/idl/dcom.idl Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
d128d401f0
commit
f2416493c0
@ -1,9 +0,0 @@
|
||||
This directory contains Samba's very simple COM implementation.
|
||||
It is by no means finished yet.
|
||||
|
||||
The main aim of this implementation is for use by our DCOM implementation,
|
||||
which lives in the dcom subdirectory. The local version is used mostly for
|
||||
testing.
|
||||
|
||||
More information on this effort can be found in the DCOM whitepaper in
|
||||
the lorikeet repository.
|
@ -1,137 +0,0 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Simple class
|
||||
Copyright (C) 2004-2005 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 "lib/com/com.h"
|
||||
#include "librpc/gen_ndr/com_dcom.h"
|
||||
|
||||
NTSTATUS com_simple_init(TALLOC_CTX *);
|
||||
|
||||
static struct IClassFactory_vtable simple_classobject_vtable;
|
||||
static struct IStream_vtable simple_IStream_vtable;
|
||||
|
||||
static WERROR simple_IUnknown_QueryInterface (struct IUnknown *d, TALLOC_CTX *mem_ctx, struct GUID *iid, struct IUnknown **iun)
|
||||
{
|
||||
*iun = d;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static uint32_t simple_IUnknown_AddRef (struct IUnknown *d, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint32_t simple_IUnknown_Release (struct IUnknown *d, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static WERROR simple_IStream_Read(struct IStream *d,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
uint8_t *pv,
|
||||
uint32_t num_requested,
|
||||
uint32_t *num_readx,
|
||||
uint32_t *num_read)
|
||||
{
|
||||
printf("%d bytes are being read\n", *num_read);
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static WERROR simple_IStream_Write(struct IStream *d,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
uint8_t *data,
|
||||
uint32_t num_requested,
|
||||
uint32_t *num_written)
|
||||
{
|
||||
printf("%d bytes are being written\n", num_requested);
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static WERROR simpleclass_IUnknown_QueryInterface (struct IUnknown *d, TALLOC_CTX *mem_ctx, struct GUID *iid, struct IUnknown **iun)
|
||||
{
|
||||
/* FIXME: Return WERR_IFACE_NOT_SUPPORTED if IID != IID_IUNKNOWN and IID != IID_CLASSFACTORY */
|
||||
*iun = d;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static WERROR simpleclass_IClassFactory_CreateInstance(struct IClassFactory *d,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct MInterfacePointer *pUnknown,
|
||||
struct GUID *iid,
|
||||
struct MInterfacePointer **ppv)
|
||||
{
|
||||
struct IStream *ret;
|
||||
/* FIXME: Check whether IID == ISTREAM_IID */
|
||||
ret = talloc(mem_ctx, struct IStream);
|
||||
ret->ctx = NULL;
|
||||
ret->vtable = &simple_IStream_vtable;
|
||||
ret->object_data = NULL;
|
||||
|
||||
*ppv = (struct MInterfacePointer *)ret;
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static uint32_t simpleclass_IUnknown_AddRef (struct IUnknown *d, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint32_t simpleclass_IUnknown_Release (struct IUnknown *d, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Everything below this line should be autogenerated later on */
|
||||
static struct IClassFactory_vtable simple_classobject_vtable = {
|
||||
{ 0, 0, 0, { 0, 0 }, { 0, 0, 0, 0, 0, 0 } },
|
||||
simpleclass_IUnknown_QueryInterface,
|
||||
simpleclass_IUnknown_AddRef,
|
||||
simpleclass_IUnknown_Release,
|
||||
simpleclass_IClassFactory_CreateInstance,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct IStream_vtable simple_IStream_vtable = {
|
||||
{ 0, 0, 0, { 0, 0 }, { 0, 0, 0, 0, 0, 0 } },
|
||||
simple_IUnknown_QueryInterface,
|
||||
simple_IUnknown_AddRef,
|
||||
simple_IUnknown_Release,
|
||||
simple_IStream_Read,
|
||||
simple_IStream_Write
|
||||
};
|
||||
|
||||
NTSTATUS com_simple_init(TALLOC_CTX *ctx)
|
||||
{
|
||||
struct GUID clsid;
|
||||
struct IUnknown *class_object = talloc(ctx, struct IUnknown);
|
||||
|
||||
class_object->ctx = NULL;
|
||||
class_object->object_data = NULL;
|
||||
class_object->vtable = (struct IUnknown_vtable *)&simple_classobject_vtable;
|
||||
|
||||
GUID_from_string(CLSID_SIMPLE, &clsid);
|
||||
GUID_from_string(COM_ICLASSFACTORY_UUID, &simple_classobject_vtable.iid);
|
||||
GUID_from_string(COM_ISTREAM_UUID, &simple_IStream_vtable.iid);
|
||||
|
||||
return com_register_running_class(ctx, &clsid, PROGID_SIMPLE, class_object);
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Utility functions for Samba
|
||||
Copyright (C) Jelmer Vernooij 2008
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __SAMBA_COM_H__
|
||||
#define __SAMBA_COM_H__
|
||||
|
||||
#include <talloc.h>
|
||||
#include "librpc/gen_ndr/misc.h"
|
||||
|
||||
struct com_context;
|
||||
struct tevent_context;
|
||||
|
||||
struct com_context
|
||||
{
|
||||
struct dcom_client_context *dcom;
|
||||
struct tevent_context *event_ctx;
|
||||
struct com_extension {
|
||||
uint32_t id;
|
||||
void *data;
|
||||
struct com_extension *prev, *next;
|
||||
} *extensions;
|
||||
struct loadparm_context *lp_ctx;
|
||||
};
|
||||
|
||||
struct IUnknown *com_class_by_clsid(struct com_context *ctx, const struct GUID *clsid);
|
||||
NTSTATUS com_register_running_class(TALLOC_CTX *ctx, struct GUID *clsid, const char *progid, struct IUnknown *p);
|
||||
|
||||
struct dcom_interface_p *dcom_get_local_iface_p(struct GUID *ipid);
|
||||
|
||||
WERROR com_init_ctx(struct com_context **ctx, struct tevent_context *event_ctx);
|
||||
WERROR com_create_object(struct com_context *ctx, struct GUID *clsid, int num_ifaces, struct GUID *iid, struct IUnknown **ip, WERROR *results);
|
||||
WERROR com_get_class_object(struct com_context *ctx, struct GUID *clsid, struct GUID *iid, struct IUnknown **ip);
|
||||
NTSTATUS com_init(void);
|
||||
|
||||
typedef struct IUnknown *(*get_class_object_function) (const struct GUID *clsid);
|
||||
|
||||
#endif /* __SAMBA_COM_H__ */
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
COM standard objects
|
||||
Copyright (C) Jelmer Vernooij 2004-2005.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef _DCOM_H /* _DCOM_H */
|
||||
#define _DCOM_H
|
||||
|
||||
struct cli_credentials;
|
||||
struct dcerpc_pipe;
|
||||
|
||||
#include "lib/com/com.h"
|
||||
#include "librpc/gen_ndr/orpc.h"
|
||||
|
||||
struct dcom_client_context {
|
||||
struct dcom_server_credentials {
|
||||
const char *server;
|
||||
struct cli_credentials *credentials;
|
||||
struct dcom_server_credentials *prev, *next;
|
||||
} *credentials;
|
||||
struct dcom_object_exporter {
|
||||
uint64_t oxid;
|
||||
char *host;
|
||||
struct IRemUnknown *rem_unknown;
|
||||
struct DUALSTRINGARRAY *bindings;
|
||||
struct dcerpc_pipe *pipe;
|
||||
struct dcom_object_exporter *prev, *next;
|
||||
} *object_exporters;
|
||||
};
|
||||
|
||||
typedef enum ndr_err_code (*marshal_fn)(TALLOC_CTX *mem_ctx, struct IUnknown *pv, struct OBJREF *o);
|
||||
typedef enum ndr_err_code (*unmarshal_fn)(TALLOC_CTX *mem_ctx, struct OBJREF *o, struct IUnknown **pv);
|
||||
|
||||
|
||||
struct dcom_client_context *dcom_client_init(struct com_context *ctx, struct cli_credentials *credentials);
|
||||
struct dcom_object_exporter *object_exporter_by_oxid(struct com_context *ctx, uint64_t oxid);
|
||||
struct dcom_object_exporter *object_exporter_by_ip(struct com_context *ctx, struct IUnknown *ip);
|
||||
WERROR dcom_create_object(struct com_context *ctx, struct GUID *clsid, const char *server, int num_ifaces, struct GUID *iid, struct IUnknown ***ip, HRESULT *results);
|
||||
WERROR dcom_get_class_object(struct com_context *ctx, struct GUID *clsid, const char *server, struct GUID *iid, struct IUnknown **ip);
|
||||
NTSTATUS dcom_get_pipe(struct IUnknown *iface, struct dcerpc_pipe **pp);
|
||||
NTSTATUS dcom_OBJREF_from_IUnknown(struct OBJREF *o, struct IUnknown *p);
|
||||
NTSTATUS dcom_IUnknown_from_OBJREF(TALLOC_CTX *mem_ctx, struct com_context *ctx, struct IUnknown **_p, struct OBJREF *o);
|
||||
uint64_t dcom_get_current_oxid(void);
|
||||
void dcom_add_server_credentials(struct com_context *ctx, const char *server, struct cli_credentials *credentials);
|
||||
WERROR dcom_query_interface(struct IUnknown *d, uint32_t cRefs, uint16_t cIids, struct GUID *iids, struct IUnknown **ip, WERROR *results);
|
||||
|
||||
#include "librpc/gen_ndr/com_dcom.h"
|
||||
|
||||
NTSTATUS dcom_register_proxy(struct IUnknown_vtable *proxy_vtable);
|
||||
struct IUnknown_vtable *dcom_proxy_vtable_by_iid(struct GUID *iid);
|
||||
NTSTATUS dcom_register_marshal(struct GUID *clsid, marshal_fn marshal, unmarshal_fn unmarshal);
|
||||
|
||||
#include "libcli/composite/composite.h"
|
||||
void dcom_release_continue(struct composite_context *cr);
|
||||
#define IUnknown_ipid(d) ((d)->obj.u_objref.u_standard.std.ipid)
|
||||
struct composite_context *dcom_release_send(struct IUnknown *d, TALLOC_CTX *mem_ctx);
|
||||
marshal_fn dcom_marshal_by_clsid(struct GUID *clsid);
|
||||
unmarshal_fn dcom_unmarshal_by_clsid(struct GUID *clsid);
|
||||
|
||||
struct dcom_proxy_async_call_state {
|
||||
struct IUnknown *d;
|
||||
const struct ndr_interface_table *table;
|
||||
uint32_t opnum;
|
||||
void (*continuation)(struct rpc_request *);
|
||||
TALLOC_CTX *mem_ctx;
|
||||
void *r;
|
||||
};
|
||||
|
||||
|
||||
#endif /* _DCOM_H */
|
@ -1,706 +0,0 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Main DCOM functionality
|
||||
Copyright (C) 2004 Jelmer Vernooij <jelmer@samba.org>
|
||||
Copyright (C) 2006 Andrzej Hajda <andrzej.hajda@wp.pl>
|
||||
|
||||
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 "system/filesys.h"
|
||||
#include "librpc/gen_ndr/epmapper.h"
|
||||
#include "librpc/gen_ndr/ndr_remact_c.h"
|
||||
#include "librpc/gen_ndr/com_dcom.h"
|
||||
#include "librpc/gen_ndr/dcom.h"
|
||||
#include "librpc/rpc/dcerpc.h"
|
||||
#include "lib/com/dcom/dcom.h"
|
||||
#include "librpc/ndr/ndr_table.h"
|
||||
#include "../lib/util/dlinklist.h"
|
||||
#include "auth/credentials/credentials.h"
|
||||
#include "libcli/composite/composite.h"
|
||||
|
||||
#undef strncasecmp
|
||||
|
||||
#define DCOM_NEGOTIATED_PROTOCOLS { EPM_PROTOCOL_TCP, EPM_PROTOCOL_SMB, EPM_PROTOCOL_NCALRPC }
|
||||
|
||||
static NTSTATUS dcerpc_binding_from_STRINGBINDING(TALLOC_CTX *mem_ctx, struct dcerpc_binding **b_out, struct STRINGBINDING *bd)
|
||||
{
|
||||
char *tstr;
|
||||
char *bstr;
|
||||
enum dcerpc_transport_t transport;
|
||||
struct dcerpc_binding *b;
|
||||
|
||||
transport = dcerpc_transport_by_endpoint_protocol(bd->wTowerId);
|
||||
if (transport == NCA_UNKNOWN) {
|
||||
DEBUG(1, ("Can't find transport match endpoint protocol %d\n", bd->wTowerId));
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
tstr = derpc_transport_string_by_transport(transport);
|
||||
bstr = talloc_asprintf(mem_ctx, "%s:%s", tstr, bd->NetworkAddr);
|
||||
if (bstr == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
status = dcerpc_parse_binding(mem_ctx, bstr, &b);
|
||||
TALLOC_FREE(bstr);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
*b_out = b;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
struct cli_credentials *dcom_get_server_credentials(struct com_context *ctx, const char *server)
|
||||
{
|
||||
struct dcom_server_credentials *c;
|
||||
struct cli_credentials *d;
|
||||
|
||||
d = NULL;
|
||||
for (c = ctx->dcom->credentials; c; c = c->next) {
|
||||
if (c->server == NULL) {
|
||||
d = c->credentials;
|
||||
continue;
|
||||
}
|
||||
if (server && !strcmp(c->server, server)) return c->credentials;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register credentials for a specific server.
|
||||
*
|
||||
* @param ctx COM context
|
||||
* @param server Name of server, can be NULL
|
||||
* @param credentials Credentials object
|
||||
*/
|
||||
void dcom_add_server_credentials(struct com_context *ctx, const char *server,
|
||||
struct cli_credentials *credentials)
|
||||
{
|
||||
struct dcom_server_credentials *c;
|
||||
|
||||
/* FIXME: Don't use talloc_find_parent_bytype */
|
||||
for (c = ctx->dcom->credentials; c; c = c->next) {
|
||||
if ((server == NULL && c->server == NULL) ||
|
||||
(server != NULL && c->server != NULL &&
|
||||
!strcmp(c->server, server))) {
|
||||
if (c->credentials && c->credentials != credentials) {
|
||||
talloc_unlink(c, c->credentials);
|
||||
c->credentials = credentials;
|
||||
if (talloc_find_parent_bytype(c->credentials, struct dcom_server_credentials))
|
||||
(void)talloc_reference(c, c->credentials);
|
||||
else
|
||||
talloc_steal(c, c->credentials);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
c = talloc(ctx->event_ctx, struct dcom_server_credentials);
|
||||
c->server = talloc_strdup(c, server);
|
||||
c->credentials = credentials;
|
||||
if (talloc_find_parent_bytype(c->credentials, struct dcom_server_credentials))
|
||||
(void)talloc_reference(c, c->credentials);
|
||||
else
|
||||
talloc_steal(c, c->credentials);
|
||||
|
||||
DLIST_ADD(ctx->dcom->credentials, c);
|
||||
}
|
||||
|
||||
void dcom_update_credentials_for_aliases(struct com_context *ctx,
|
||||
const char *server,
|
||||
struct DUALSTRINGARRAY *pds)
|
||||
{
|
||||
struct cli_credentials *cc;
|
||||
struct dcerpc_binding *b;
|
||||
uint32_t i;
|
||||
NTSTATUS status;
|
||||
|
||||
cc = dcom_get_server_credentials(ctx, server);
|
||||
for (i = 0; pds->stringbindings[i]; ++i) {
|
||||
if (pds->stringbindings[i]->wTowerId != EPM_PROTOCOL_TCP)
|
||||
continue;
|
||||
status = dcerpc_binding_from_STRINGBINDING(ctx, &b, pds->stringbindings[i]);
|
||||
if (!NT_STATUS_IS_OK(status))
|
||||
continue;
|
||||
dcom_add_server_credentials(ctx, b->host, cc);
|
||||
talloc_free(b);
|
||||
}
|
||||
}
|
||||
|
||||
struct dcom_client_context *dcom_client_init(struct com_context *ctx, struct cli_credentials *credentials)
|
||||
{
|
||||
ctx->dcom = talloc_zero(ctx, struct dcom_client_context);
|
||||
if (!credentials) {
|
||||
credentials = cli_credentials_init(ctx);
|
||||
cli_credentials_set_conf(credentials, ctx->lp_ctx);
|
||||
cli_credentials_parse_string(credentials, "%", CRED_SPECIFIED);
|
||||
}
|
||||
dcom_add_server_credentials(ctx, NULL, credentials);
|
||||
return ctx->dcom;
|
||||
}
|
||||
|
||||
static NTSTATUS dcom_connect_host(struct com_context *ctx,
|
||||
struct dcerpc_pipe **p, const char *server)
|
||||
{
|
||||
struct dcerpc_binding *bd;
|
||||
const char * available_transports[] = { "ncacn_ip_tcp", "ncacn_np" };
|
||||
int i;
|
||||
NTSTATUS status;
|
||||
TALLOC_CTX *loc_ctx;
|
||||
|
||||
if (server == NULL) {
|
||||
return dcerpc_pipe_connect(ctx->event_ctx, p, "ncalrpc",
|
||||
&ndr_table_IRemoteActivation,
|
||||
dcom_get_server_credentials(ctx, NULL), ctx->event_ctx, ctx->lp_ctx);
|
||||
}
|
||||
loc_ctx = talloc_new(ctx);
|
||||
|
||||
/* Allow server name to contain a binding string */
|
||||
if (strchr(server, ':') &&
|
||||
NT_STATUS_IS_OK(dcerpc_parse_binding(loc_ctx, server, &bd))) {
|
||||
if (DEBUGLVL(11))
|
||||
bd->flags |= DCERPC_DEBUG_PRINT_BOTH;
|
||||
status = dcerpc_pipe_connect_b(ctx->event_ctx, p, bd,
|
||||
&ndr_table_IRemoteActivation,
|
||||
dcom_get_server_credentials(ctx, bd->host), ctx->event_ctx, ctx->lp_ctx);
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(available_transports); i++)
|
||||
{
|
||||
char *binding = talloc_asprintf(loc_ctx, "%s:%s", available_transports[i], server);
|
||||
if (!binding) {
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
goto end;
|
||||
}
|
||||
status = dcerpc_pipe_connect(ctx->event_ctx, p, binding,
|
||||
&ndr_table_IRemoteActivation,
|
||||
dcom_get_server_credentials(ctx, server),
|
||||
ctx->event_ctx, ctx->lp_ctx);
|
||||
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
if (DEBUGLVL(11))
|
||||
(*p)->conn->flags |= DCERPC_DEBUG_PRINT_BOTH;
|
||||
goto end;
|
||||
} else {
|
||||
DEBUG(1,(__location__": dcom_connect_host : %s\n", get_friendly_nt_error_msg(status)));
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
talloc_free(loc_ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
struct dcom_object_exporter *object_exporter_by_oxid(struct com_context *ctx,
|
||||
uint64_t oxid)
|
||||
{
|
||||
struct dcom_object_exporter *ox;
|
||||
for (ox = ctx->dcom->object_exporters; ox; ox = ox->next) {
|
||||
if (ox->oxid == oxid) {
|
||||
return ox;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct dcom_object_exporter *object_exporter_update_oxid(struct com_context *ctx, uint64_t oxid, struct DUALSTRINGARRAY *bindings)
|
||||
{
|
||||
struct dcom_object_exporter *ox;
|
||||
ox = object_exporter_by_oxid(ctx, oxid);
|
||||
if (!ox) {
|
||||
ox = talloc_zero(ctx, struct dcom_object_exporter);
|
||||
DLIST_ADD(ctx->dcom->object_exporters, ox);
|
||||
ox->oxid = oxid;
|
||||
} else {
|
||||
talloc_free(ox->bindings);
|
||||
}
|
||||
ox->bindings = bindings;
|
||||
talloc_steal(ox, bindings);
|
||||
return ox;
|
||||
}
|
||||
|
||||
struct dcom_object_exporter *object_exporter_by_ip(struct com_context *ctx, struct IUnknown *ip)
|
||||
{
|
||||
return object_exporter_by_oxid(ctx, ip->obj.u_objref.u_standard.std.oxid);
|
||||
}
|
||||
|
||||
WERROR dcom_create_object(struct com_context *ctx, struct GUID *clsid, const char *server, int num_ifaces, struct GUID *iid, struct IUnknown ***ip, HRESULT *results)
|
||||
{
|
||||
uint16_t protseq[] = DCOM_NEGOTIATED_PROTOCOLS;
|
||||
struct dcerpc_pipe *p;
|
||||
struct dcom_object_exporter *m;
|
||||
NTSTATUS status;
|
||||
struct RemoteActivation r;
|
||||
struct DUALSTRINGARRAY *pds;
|
||||
int i;
|
||||
HRESULT hr;
|
||||
uint64_t oxid;
|
||||
struct GUID ipidRemUnknown;
|
||||
struct IUnknown *ru_template;
|
||||
struct ORPCTHAT that;
|
||||
uint32_t AuthnHint;
|
||||
struct COMVERSION ServerVersion;
|
||||
struct MInterfacePointer **ifaces;
|
||||
TALLOC_CTX *loc_ctx;
|
||||
|
||||
status = dcom_connect_host(ctx, &p, server);
|
||||
if (NT_STATUS_IS_ERR(status)) {
|
||||
DEBUG(1, ("Unable to connect to %s - %s\n", server, get_friendly_nt_error_msg(status)));
|
||||
return ntstatus_to_werror(status);
|
||||
}
|
||||
loc_ctx = talloc_new(ctx);
|
||||
|
||||
ifaces = talloc_array(loc_ctx, struct MInterfacePointer *, num_ifaces);
|
||||
|
||||
ZERO_STRUCT(r.in);
|
||||
r.in.this.version.MajorVersion = COM_MAJOR_VERSION;
|
||||
r.in.this.version.MinorVersion = COM_MINOR_VERSION;
|
||||
r.in.this.cid = GUID_random();
|
||||
r.in.Clsid = *clsid;
|
||||
r.in.ClientImpLevel = RPC_C_IMP_LEVEL_IDENTIFY;
|
||||
r.in.num_protseqs = ARRAY_SIZE(protseq);
|
||||
r.in.protseq = protseq;
|
||||
r.in.Interfaces = num_ifaces;
|
||||
r.in.pIIDs = iid;
|
||||
r.out.that = &that;
|
||||
r.out.pOxid = &oxid;
|
||||
r.out.pdsaOxidBindings = &pds;
|
||||
r.out.ipidRemUnknown = &ipidRemUnknown;
|
||||
r.out.AuthnHint = &AuthnHint;
|
||||
r.out.ServerVersion = &ServerVersion;
|
||||
r.out.hr = &hr;
|
||||
r.out.ifaces = ifaces;
|
||||
r.out.results = results;
|
||||
|
||||
status = dcerpc_RemoteActivation(p, loc_ctx, &r);
|
||||
talloc_free(p);
|
||||
|
||||
if(NT_STATUS_IS_ERR(status)) {
|
||||
DEBUG(1, ("Error while running RemoteActivation %s\n", nt_errstr(status)));
|
||||
hr = ntstatus_to_werror(status);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(!W_ERROR_IS_OK(r.out.result)) {
|
||||
hr = r.out.result;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if(!HRES_IS_OK(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
m = object_exporter_update_oxid(ctx, oxid, pds);
|
||||
|
||||
ru_template = NULL;
|
||||
*ip = talloc_array(ctx, struct IUnknown *, num_ifaces);
|
||||
for (i = 0; i < num_ifaces; i++) {
|
||||
(*ip)[i] = NULL;
|
||||
if (W_ERROR_IS_OK(results[i])) {
|
||||
status = dcom_IUnknown_from_OBJREF(ctx, &(*ip)[i], &r.out.ifaces[i]->obj);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
results[i] = ntstatus_to_werror(status);
|
||||
} else if (!ru_template)
|
||||
ru_template = (*ip)[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO:avg check when exactly oxid should be updated,its lifetime etc */
|
||||
if (m->rem_unknown && memcmp(&m->rem_unknown->obj.u_objref.u_standard.std.ipid, &ipidRemUnknown, sizeof(ipidRemUnknown))) {
|
||||
talloc_free(m->rem_unknown);
|
||||
m->rem_unknown = NULL;
|
||||
}
|
||||
if (!m->rem_unknown) {
|
||||
if (!ru_template) {
|
||||
DEBUG(1,("dcom_create_object: Cannot Create IRemUnknown - template interface not available\n"));
|
||||
hr = WERR_GEN_FAILURE;
|
||||
}
|
||||
m->rem_unknown = talloc_zero(m, struct IRemUnknown);
|
||||
memcpy(m->rem_unknown, ru_template, sizeof(struct IUnknown));
|
||||
GUID_from_string(COM_IREMUNKNOWN_UUID, &m->rem_unknown->obj.iid);
|
||||
m->rem_unknown->obj.u_objref.u_standard.std.ipid = ipidRemUnknown;
|
||||
m->rem_unknown->vtable = (struct IRemUnknown_vtable *)dcom_proxy_vtable_by_iid(&m->rem_unknown->obj.iid);
|
||||
/* TODO:avg copy stringbindigs?? */
|
||||
}
|
||||
|
||||
dcom_update_credentials_for_aliases(ctx, server, pds);
|
||||
{
|
||||
char *c;
|
||||
c = strchr(server, '[');
|
||||
if (m->host) talloc_free(m->host);
|
||||
m->host = c ? talloc_strndup(m, server, c - server) : talloc_strdup(m, server);
|
||||
}
|
||||
hr = WERR_OK;
|
||||
end:
|
||||
talloc_free(loc_ctx);
|
||||
return hr;
|
||||
}
|
||||
|
||||
int find_similar_binding(struct STRINGBINDING **sb, const char *host)
|
||||
{
|
||||
int i, l;
|
||||
l = strlen(host);
|
||||
for (i = 0; sb[i]; ++i) {
|
||||
if ((sb[i]->wTowerId == EPM_PROTOCOL_TCP) && !strncasecmp(host, sb[i]->NetworkAddr, l) && (sb[i]->NetworkAddr[l] == '['))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
WERROR dcom_query_interface(struct IUnknown *d, uint32_t cRefs, uint16_t cIids, struct GUID *iids, struct IUnknown **ip, WERROR *results)
|
||||
{
|
||||
struct dcom_object_exporter *ox;
|
||||
struct REMQIRESULT *rqir;
|
||||
WERROR result;
|
||||
NTSTATUS status;
|
||||
int i;
|
||||
TALLOC_CTX *loc_ctx;
|
||||
struct IUnknown ru;
|
||||
|
||||
loc_ctx = talloc_new(d);
|
||||
ox = object_exporter_by_ip(d->ctx, d);
|
||||
|
||||
result = IRemUnknown_RemQueryInterface(ox->rem_unknown, loc_ctx, &IUnknown_ipid(d), cRefs, cIids, iids, &rqir);
|
||||
if (!W_ERROR_IS_OK(result)) {
|
||||
DEBUG(1, ("dcom_query_interface failed: %08X\n", W_ERROR_V(result)));
|
||||
talloc_free(loc_ctx);
|
||||
return result;
|
||||
}
|
||||
ru = *(struct IUnknown *)ox->rem_unknown;
|
||||
for (i = 0; i < cIids; ++i) {
|
||||
ip[i] = NULL;
|
||||
results[i] = rqir[i].hResult;
|
||||
if (W_ERROR_IS_OK(results[i])) {
|
||||
ru.obj.iid = iids[i];
|
||||
ru.obj.u_objref.u_standard.std = rqir[i].std;
|
||||
status = dcom_IUnknown_from_OBJREF(d->ctx, &ip[i], &ru.obj);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
results[i] = ntstatus_to_werror(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
talloc_free(loc_ctx);
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
int is_ip_binding(const char* s)
|
||||
{
|
||||
while (*s && (*s != '[')) {
|
||||
if (((*s >= '0') && (*s <= '9')) || *s == '.')
|
||||
++s;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
NTSTATUS dcom_get_pipe(struct IUnknown *iface, struct dcerpc_pipe **pp)
|
||||
{
|
||||
struct dcerpc_binding *binding;
|
||||
struct GUID iid;
|
||||
uint64_t oxid;
|
||||
NTSTATUS status;
|
||||
int i, j, isimilar;
|
||||
struct dcerpc_pipe *p;
|
||||
struct dcom_object_exporter *ox;
|
||||
const struct ndr_interface_table *table;
|
||||
|
||||
ox = object_exporter_by_oxid(iface->ctx, iface->obj.u_objref.u_standard.std.oxid);
|
||||
if (!ox) {
|
||||
DEBUG(0, ("dcom_get_pipe: OXID not found\n"));
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
p = ox->pipe;
|
||||
|
||||
iid = iface->vtable->iid;
|
||||
table = ndr_table_by_uuid(&iid);
|
||||
if (table == NULL) {
|
||||
char *guid_str;
|
||||
guid_str = GUID_string(NULL, &iid);
|
||||
DEBUG(0,(__location__": dcom_get_pipe - unrecognized interface{%s}\n", guid_str));
|
||||
talloc_free(guid_str);
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (p && p->last_fault_code) {
|
||||
talloc_free(p);
|
||||
ox->pipe = p = NULL;
|
||||
}
|
||||
|
||||
if (p) {
|
||||
if (!GUID_equal(&p->syntax.uuid, &iid)) {
|
||||
ox->pipe->syntax.uuid = iid;
|
||||
|
||||
/* interface will always be present, so
|
||||
* idl_iface_by_uuid can't return NULL */
|
||||
/* status = dcerpc_secondary_context(p, &p2, idl_iface_by_uuid(&iid)); */
|
||||
status = dcerpc_alter_context(p, p, &ndr_table_by_uuid(&iid)->syntax_id, &p->transfer_syntax);
|
||||
} else
|
||||
status = NT_STATUS_OK;
|
||||
*pp = p;
|
||||
return status;
|
||||
}
|
||||
|
||||
status = NT_STATUS_NO_MORE_ENTRIES;
|
||||
|
||||
/* To avoid delays whe connecting nonroutable bindings we 1st check binding starting with hostname */
|
||||
/* FIX:low create concurrent connections to all bindings, fastest wins - Win2k and newer does this way???? */
|
||||
isimilar = find_similar_binding(ox->bindings->stringbindings, ox->host);
|
||||
DEBUG(1, (__location__": dcom_get_pipe: host=%s, similar=%s\n", ox->host, ox->bindings->stringbindings[isimilar] ? ox->bindings->stringbindings[isimilar]->NetworkAddr : "None"));
|
||||
j = isimilar - 1;
|
||||
for (i = 0; ox->bindings->stringbindings[i]; ++i) {
|
||||
if (!ox->bindings->stringbindings[++j]) j = 0;
|
||||
/* FIXME:LOW Use also other transports if possible */
|
||||
if ((j != isimilar) && (ox->bindings->stringbindings[j]->wTowerId != EPM_PROTOCOL_TCP || !is_ip_binding(ox->bindings->stringbindings[j]->NetworkAddr))) {
|
||||
DEBUG(9, ("dcom_get_pipe: Skipping stringbinding %24.24s\n", ox->bindings->stringbindings[j]->NetworkAddr));
|
||||
continue;
|
||||
}
|
||||
DEBUG(9, ("dcom_get_pipe: Trying stringbinding %s\n", ox->bindings->stringbindings[j]->NetworkAddr));
|
||||
status = dcerpc_binding_from_STRINGBINDING(iface->ctx, &binding,
|
||||
ox->bindings->stringbindings[j]);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(1, ("Error parsing string binding"));
|
||||
} else {
|
||||
/* FIXME:LOW Make flags more flexible */
|
||||
binding->flags |= DCERPC_AUTH_NTLM | DCERPC_SIGN;
|
||||
if (DEBUGLVL(11))
|
||||
binding->flags |= DCERPC_DEBUG_PRINT_BOTH;
|
||||
status = dcerpc_pipe_connect_b(iface->ctx->event_ctx, &p, binding,
|
||||
ndr_table_by_uuid(&iid),
|
||||
dcom_get_server_credentials(iface->ctx, binding->host),
|
||||
iface->ctx->event_ctx, iface->ctx->lp_ctx);
|
||||
talloc_unlink(iface->ctx, binding);
|
||||
}
|
||||
if (NT_STATUS_IS_OK(status)) break;
|
||||
}
|
||||
|
||||
if (NT_STATUS_IS_ERR(status)) {
|
||||
DEBUG(0, ("Unable to connect to remote host - %s\n", nt_errstr(status)));
|
||||
return status;
|
||||
}
|
||||
|
||||
DEBUG(2, ("Successfully connected to OXID %llx\n", (long long)oxid));
|
||||
|
||||
ox->pipe = *pp = p;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
NTSTATUS dcom_OBJREF_from_IUnknown(TALLLOC_CTX *mem_ctx, struct OBJREF *o, struct IUnknown *p)
|
||||
{
|
||||
/* FIXME: Cache generated objref objects? */
|
||||
ZERO_STRUCTP(o);
|
||||
|
||||
if (!p) {
|
||||
o->signature = OBJREF_SIGNATURE;
|
||||
o->flags = OBJREF_NULL;
|
||||
} else {
|
||||
*o = p->obj;
|
||||
switch(o->flags) {
|
||||
case OBJREF_CUSTOM: {
|
||||
marshal_fn marshal;
|
||||
|
||||
marshal = dcom_marshal_by_clsid(&o->u_objref.u_custom.clsid);
|
||||
if (marshal) {
|
||||
return marshal(mem_ctx, p, o);
|
||||
} else {
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
enum ndr_err_code dcom_IUnknown_from_OBJREF(struct com_context *ctx, struct IUnknown **_p, struct OBJREF *o)
|
||||
{
|
||||
struct IUnknown *p;
|
||||
struct dcom_object_exporter *ox;
|
||||
unmarshal_fn unmarshal;
|
||||
|
||||
switch(o->flags) {
|
||||
case OBJREF_NULL:
|
||||
*_p = NULL;
|
||||
return NDR_ERR_SUCCESS;
|
||||
|
||||
case OBJREF_STANDARD:
|
||||
p = talloc_zero(ctx, struct IUnknown);
|
||||
p->ctx = ctx;
|
||||
p->obj = *o;
|
||||
p->vtable = dcom_proxy_vtable_by_iid(&o->iid);
|
||||
|
||||
if (!p->vtable) {
|
||||
DEBUG(0, ("Unable to find proxy class for interface with IID %s\n", GUID_string(ctx, &o->iid)));
|
||||
return NDR_ERR_INVALID_POINTER;
|
||||
}
|
||||
|
||||
p->vtable->Release_send = dcom_release_send;
|
||||
|
||||
ox = object_exporter_by_oxid(ctx, o->u_objref.u_standard.std.oxid);
|
||||
/* FIXME: Add object to list of objects to ping */
|
||||
*_p = p;
|
||||
return NDR_ERR_SUCCESS;
|
||||
|
||||
case OBJREF_HANDLER:
|
||||
p = talloc_zero(ctx, struct IUnknown);
|
||||
p->ctx = ctx;
|
||||
p->obj = *o;
|
||||
ox = object_exporter_by_oxid(ctx, o->u_objref.u_handler.std.oxid );
|
||||
/* FIXME: Add object to list of objects to ping */
|
||||
/*FIXME p->vtable = dcom_vtable_by_clsid(&o->u_objref.u_handler.clsid);*/
|
||||
/* FIXME: Do the custom unmarshaling call */
|
||||
|
||||
*_p = p;
|
||||
return NDR_ERR_BAD_SWITCH;
|
||||
|
||||
case OBJREF_CUSTOM:
|
||||
p = talloc_zero(ctx, struct IUnknown);
|
||||
p->ctx = ctx;
|
||||
p->vtable = NULL;
|
||||
p->obj = *o;
|
||||
unmarshal = dcom_unmarshal_by_clsid(&o->u_objref.u_custom.clsid);
|
||||
*_p = p;
|
||||
if (unmarshal) {
|
||||
return unmarshal(ctx, o, _p);
|
||||
} else {
|
||||
return NDR_ERR_BAD_SWITCH;
|
||||
}
|
||||
}
|
||||
|
||||
return NDR_ERR_BAD_SWITCH;
|
||||
}
|
||||
|
||||
uint64_t dcom_get_current_oxid(void)
|
||||
{
|
||||
return getpid();
|
||||
}
|
||||
|
||||
/* FIXME:Fake async dcom_get_pipe_* */
|
||||
struct composite_context *dcom_get_pipe_send(struct IUnknown *d, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
struct composite_context *c;
|
||||
|
||||
c = composite_create(0, d->ctx->event_ctx);
|
||||
if (c == NULL) return NULL;
|
||||
c->private_data = d;
|
||||
/* composite_done(c); bugged - callback is triggered twice by composite_continue and composite_done */
|
||||
c->state = COMPOSITE_STATE_DONE; /* this is workaround */
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
NTSTATUS dcom_get_pipe_recv(struct composite_context *c, struct dcerpc_pipe **pp)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
status = dcom_get_pipe((struct IUnknown *)c->private_data, pp);
|
||||
talloc_free(c);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* FIXME:avg put IUnknown_Release_out into header */
|
||||
struct IUnknown_Release_out {
|
||||
uint32_t result;
|
||||
};
|
||||
|
||||
void dcom_release_continue(struct composite_context *cr)
|
||||
{
|
||||
struct composite_context *c;
|
||||
struct IUnknown *d;
|
||||
struct IUnknown_Release_out *out;
|
||||
WERROR r;
|
||||
|
||||
c = talloc_get_type(cr->async.private_data, struct composite_context);
|
||||
d = c->private_data;
|
||||
r = IRemUnknown_RemRelease_recv(cr);
|
||||
talloc_free(d);
|
||||
out = talloc_zero(c, struct IUnknown_Release_out);
|
||||
out->result = W_ERROR_V(r);
|
||||
c->private_data = out;
|
||||
composite_done(c);
|
||||
}
|
||||
|
||||
struct composite_context *dcom_release_send(struct IUnknown *d, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
struct composite_context *c, *cr;
|
||||
struct REMINTERFACEREF iref;
|
||||
struct dcom_object_exporter *ox;
|
||||
|
||||
c = composite_create(d->ctx, d->ctx->event_ctx);
|
||||
if (c == NULL) return NULL;
|
||||
c->private_data = d;
|
||||
|
||||
ox = object_exporter_by_ip(d->ctx, d);
|
||||
iref.ipid = IUnknown_ipid(d);
|
||||
iref.cPublicRefs = 5;
|
||||
iref.cPrivateRefs = 0;
|
||||
cr = IRemUnknown_RemRelease_send(ox->rem_unknown, mem_ctx, 1, &iref);
|
||||
|
||||
composite_continue(c, cr, dcom_release_continue, c);
|
||||
return c;
|
||||
}
|
||||
|
||||
uint32_t dcom_release_recv(struct composite_context *c)
|
||||
{
|
||||
NTSTATUS status;
|
||||
WERROR r;
|
||||
|
||||
status = composite_wait(c);
|
||||
if (!NT_STATUS_IS_OK(status))
|
||||
r = ntstatus_to_werror(status);
|
||||
else
|
||||
W_ERROR_V(r) = ((struct IUnknown_Release_out *)c->private_data)->result;
|
||||
talloc_free(c);
|
||||
return W_ERROR_IS_OK(r) ? 0 : W_ERROR_V(r);
|
||||
}
|
||||
|
||||
uint32_t dcom_release(void *interface, TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
struct composite_context *c;
|
||||
|
||||
c = dcom_release_send(interface, mem_ctx);
|
||||
return dcom_release_recv(c);
|
||||
}
|
||||
|
||||
void dcom_proxy_async_call_recv_pipe_send_rpc(struct composite_context *c_pipe)
|
||||
{
|
||||
struct composite_context *c;
|
||||
struct dcom_proxy_async_call_state *s;
|
||||
struct dcerpc_pipe *p;
|
||||
struct rpc_request *req;
|
||||
NTSTATUS status;
|
||||
|
||||
c = c_pipe->async.private_data;
|
||||
s = talloc_get_type(c->private_data, struct dcom_proxy_async_call_state);
|
||||
|
||||
status = dcom_get_pipe_recv(c_pipe, &p);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
composite_error(c, NT_STATUS_RPC_NT_CALL_FAILED);
|
||||
return;
|
||||
}
|
||||
/*TODO: FIXME - for now this unused anyway */
|
||||
req = dcerpc_ndr_request_send(p, &s->d->obj.u_objref.u_standard.std.ipid, s->table, s->opnum, s, s->r);
|
||||
composite_continue_rpc(c, req, s->continuation, c);
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
DCOM proxy tables functionality
|
||||
Copyright (C) 2005 Jelmer Vernooij <jelmer@samba.org>
|
||||
Copyright (C) 2006 Andrzej Hajda <andrzej.hajda@wp.pl>
|
||||
|
||||
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 "../lib/util/dlinklist.h"
|
||||
#include "librpc/gen_ndr/com_dcom.h"
|
||||
#include "lib/com/dcom/dcom.h"
|
||||
|
||||
static struct dcom_proxy {
|
||||
struct IUnknown_vtable *vtable;
|
||||
struct dcom_proxy *prev, *next;
|
||||
} *proxies = NULL;
|
||||
|
||||
NTSTATUS dcom_register_proxy(TALLOC_CTX *ctx,
|
||||
struct IUnknown_vtable *proxy_vtable)
|
||||
{
|
||||
struct dcom_proxy *proxy = talloc(ctx, struct dcom_proxy);
|
||||
|
||||
proxy->vtable = proxy_vtable;
|
||||
DLIST_ADD(proxies, proxy);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
struct IUnknown_vtable *dcom_proxy_vtable_by_iid(struct GUID *iid)
|
||||
{
|
||||
struct dcom_proxy *p;
|
||||
for (p = proxies; p; p = p->next) {
|
||||
if (GUID_equal(&p->vtable->iid, iid)) {
|
||||
return p->vtable;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct dcom_marshal {
|
||||
struct GUID clsid;
|
||||
marshal_fn marshal;
|
||||
unmarshal_fn unmarshal;
|
||||
struct dcom_marshal *prev, *next;
|
||||
} *marshals = NULL;
|
||||
|
||||
NTSTATUS dcom_register_marshal(TALLOC_CTX *ctx,
|
||||
struct GUID *clsid, marshal_fn marshal, unmarshal_fn unmarshal)
|
||||
{
|
||||
struct dcom_marshal *p = talloc(ctx, struct dcom_marshal);
|
||||
|
||||
p->clsid = *clsid;
|
||||
p->marshal = marshal;
|
||||
p->unmarshal = unmarshal;
|
||||
DLIST_ADD(marshals, p);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
_PUBLIC_ marshal_fn dcom_marshal_by_clsid(struct GUID *clsid)
|
||||
{
|
||||
struct dcom_marshal *p;
|
||||
for (p = marshals; p; p = p->next) {
|
||||
if (GUID_equal(&p->clsid, clsid)) {
|
||||
return p->marshal;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_PUBLIC_ unmarshal_fn dcom_unmarshal_by_clsid(struct GUID *clsid)
|
||||
{
|
||||
struct dcom_marshal *p;
|
||||
for (p = marshals; p; p = p->next) {
|
||||
if (GUID_equal(&p->clsid, clsid)) {
|
||||
return p->unmarshal;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Main COM functionality
|
||||
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 "../lib/util/dlinklist.h"
|
||||
#include "lib/com/com.h"
|
||||
#include "lib/events/events.h"
|
||||
#include "librpc/gen_ndr/com_dcom.h"
|
||||
|
||||
WERROR com_init_ctx(struct com_context **ctx, struct tevent_context *event_ctx)
|
||||
{
|
||||
*ctx = talloc(NULL, struct com_context);
|
||||
if (event_ctx == NULL) {
|
||||
event_ctx = samba_tevent_context_init(*ctx);
|
||||
}
|
||||
(*ctx)->event_ctx = event_ctx;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
WERROR com_create_object(struct com_context *ctx, struct GUID *clsid, int num_ifaces, struct GUID *iid, struct IUnknown **ip, WERROR *results)
|
||||
{
|
||||
struct IUnknown *iunk = NULL;
|
||||
struct IClassFactory *factory;
|
||||
WERROR error;
|
||||
int i;
|
||||
struct GUID classfact_iid;
|
||||
|
||||
GUID_from_string(NDR_ICLASSFACTORY_UUID, &classfact_iid);
|
||||
|
||||
/* Obtain class object */
|
||||
error = com_get_class_object(ctx, clsid, &classfact_iid, (struct IUnknown **)&factory);
|
||||
if (!W_ERROR_IS_OK(error)) {
|
||||
DEBUG(3, ("Unable to obtain class object for %s\n", GUID_string(NULL, clsid)));
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Run IClassFactory::CreateInstance() */
|
||||
error = IClassFactory_CreateInstance(factory, ctx, NULL, &classfact_iid, (struct MInterfacePointer **)&iunk);
|
||||
if (!W_ERROR_IS_OK(error)) {
|
||||
DEBUG(3, ("Error while calling IClassFactory::CreateInstance : %s\n", win_errstr(error)));
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!iunk) {
|
||||
DEBUG(0, ("IClassFactory_CreateInstance returned success but result pointer is still NULL!\n"));
|
||||
return WERR_GEN_FAILURE;
|
||||
}
|
||||
|
||||
/* Release class object */
|
||||
IUnknown_Release((struct IUnknown *)factory, ctx);
|
||||
|
||||
error = WERR_OK;
|
||||
|
||||
/* Do one or more QueryInterface calls */
|
||||
for (i = 0; i < num_ifaces; i++) {
|
||||
results[i] = IUnknown_QueryInterface(iunk, ctx, &iid[i], &ip[i]);
|
||||
if (!W_ERROR_IS_OK(results[i])) error = results[i];
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
WERROR com_get_class_object(struct com_context *ctx, struct GUID *clsid, struct GUID *iid, struct IUnknown **ip)
|
||||
{
|
||||
struct IUnknown *iu;
|
||||
|
||||
iu = com_class_by_clsid(ctx, clsid);
|
||||
if (!iu) {
|
||||
return W_ERROR(HRES_ERROR_V(HRES_REGDB_E_CLASSNOTREG));
|
||||
}
|
||||
|
||||
return IUnknown_QueryInterface(iu, ctx, iid, ip);
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
Running object table functions
|
||||
|
||||
Copyright (C) Jelmer Vernooij 2004-2005
|
||||
|
||||
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 "lib/com/com.h"
|
||||
|
||||
struct dcom_interface_p *dcom_get_local_iface_p(struct GUID *ipid)
|
||||
{
|
||||
/* FIXME: Call the local ROT and do a
|
||||
* rot_get_interface_pointer call */
|
||||
|
||||
/* FIXME: Perhaps have a local (thread-local) table with
|
||||
* local DCOM objects so that not every DCOM call requires a lookup
|
||||
* to the ROT? */
|
||||
return NULL;
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
COM class tables
|
||||
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 "../lib/util/dlinklist.h"
|
||||
#include "lib/com/com.h"
|
||||
#include "librpc/gen_ndr/ndr_misc.h"
|
||||
|
||||
/* Specific implementation of one or more interfaces */
|
||||
struct com_class
|
||||
{
|
||||
const char *progid;
|
||||
struct GUID clsid;
|
||||
|
||||
struct IUnknown *class_object;
|
||||
struct com_class *prev, *next;
|
||||
} * running_classes = NULL;
|
||||
|
||||
static struct IUnknown *get_com_class_running(const struct GUID *clsid)
|
||||
{
|
||||
struct com_class *c = running_classes;
|
||||
|
||||
while(c) {
|
||||
|
||||
if (GUID_equal(clsid, &c->clsid)) {
|
||||
return c->class_object;
|
||||
}
|
||||
|
||||
c = c->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct IUnknown *get_com_class_so(TALLOC_CTX *mem_ctx, const struct GUID *clsid)
|
||||
{
|
||||
char *module_name;
|
||||
char *clsid_str;
|
||||
void *mod;
|
||||
get_class_object_function f;
|
||||
|
||||
clsid_str = GUID_string(mem_ctx, clsid);
|
||||
module_name = talloc_asprintf(mem_ctx, "%s.so", clsid_str);
|
||||
talloc_free(clsid_str);
|
||||
|
||||
mod = dlopen(module_name, 0);
|
||||
|
||||
if (!mod) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f = dlsym(mod, "get_class_object");
|
||||
|
||||
if (!f) {
|
||||
dlclose(mod);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return f(clsid);
|
||||
}
|
||||
|
||||
struct IUnknown *com_class_by_clsid(struct com_context *ctx, const struct GUID *clsid)
|
||||
{
|
||||
struct IUnknown *c;
|
||||
|
||||
/* Check list of running COM classes first */
|
||||
c = get_com_class_running(clsid);
|
||||
|
||||
if (c != NULL) {
|
||||
return c;
|
||||
}
|
||||
|
||||
c = get_com_class_so(ctx, clsid);
|
||||
|
||||
if (c != NULL) {
|
||||
return c;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTSTATUS com_register_running_class(TALLOC_CTX *ctx,
|
||||
struct GUID *clsid, const char *progid, struct IUnknown *p)
|
||||
{
|
||||
struct com_class *l = talloc_zero(running_classes?
|
||||
running_classes : ctx, struct com_class);
|
||||
|
||||
l->clsid = *clsid;
|
||||
l->progid = talloc_strdup(l, progid);
|
||||
l->class_object = p;
|
||||
|
||||
DLIST_ADD(running_classes, l);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
bld.SAMBA_SUBSYSTEM('COM',
|
||||
source='tables.c rot.c main.c',
|
||||
allow_warnings=True,
|
||||
deps='samba-util samba-hostconfig events ndr NDR_DCOM'
|
||||
)
|
||||
|
||||
|
||||
bld.SAMBA_SUBSYSTEM('DCOM',
|
||||
source='dcom/main.c dcom/tables.c',
|
||||
public_deps='COM DCOM_PROXY_DCOM RPC_NDR_REMACT RPC_NDR_OXIDRESOLVER',
|
||||
# ORPCTHIS maps to this.*, which hits the "No C++ keywords" define
|
||||
# unless we force off developer mode
|
||||
cflags_end = '-UDEVELOPER',
|
||||
# even with the above hack this still doesn't compile - disable it for now
|
||||
enabled=False
|
||||
)
|
||||
|
||||
|
||||
bld.SAMBA_MODULE('com_simple',
|
||||
source='classes/simple.c',
|
||||
allow_warnings=True,
|
||||
deps='talloc',
|
||||
subsystem='COM',
|
||||
init_function='com_simple_init'
|
||||
)
|
||||
|
@ -86,7 +86,6 @@ bld.RECURSE('lib/tsocket')
|
||||
bld.RECURSE('lib/crypto')
|
||||
bld.RECURSE('lib/torture')
|
||||
bld.RECURSE('libgpo')
|
||||
bld.RECURSE('source4/lib/com')
|
||||
bld.RECURSE('source4/dns_server')
|
||||
bld.RECURSE('source4/echo_server')
|
||||
bld.RECURSE('source4/smb_server')
|
||||
|
Loading…
Reference in New Issue
Block a user