{
uint16 opnum = dce_call->pkt.u.request.opnum;
struct GUID ipid = dce_call->pkt.u.request.object.object;
- struct dcom_interface_p *iface = dcom_get_iface_p(&ipid);
+ struct dcom_interface_p *iface = dcom_get_local_iface_p(&ipid);
const struct dcom_$name\_vtable *vtable = iface->vtable;
dce_call->fault_code = 0;
--- /dev/null
+/*
+ Unix SMB/CIFS implementation.
+ Simple class
+ 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/dcom/common/dcom.h"
+
+static struct dcom_IClassFactory_vtable simple_classobject;
+
+NTSTATUS dcom_simple_init(void)
+{
+ struct GUID iid;
+ struct dcom_class simple_class = {
+ "Samba.Simple",
+ };
+
+ GUID_from_string(DCERPC_IUNKNOWN_UUID, &iid);
+
+ simple_class.class_object = dcom_new_local_ifacep(NULL, dcom_interface_by_iid(&iid), &simple_classobject, NULL);
+
+ GUID_from_string("5e9ddec7-5767-11cf-beab-00aa006c3606", &simple_class.clsid);
+ return dcom_register_class(&simple_class);
+}
struct IUnknown_AddRef;
struct IUnknown_Release;
struct IUnknown_QueryInterface;
+struct dcom_interface_p;
struct dcom_context
{
{
const char *prog_id;
struct GUID clsid;
- void (*get_class_object) (struct GUID *iid, void **vtable);
+
+ /* IUnknown */
+ struct dcom_interface_p *class_object;
};
struct dcom_interface
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)) {
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;
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;
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);
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;
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 */
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;
+}
#include "includes.h"
-
-struct dcom_interface_p *dcom_get_iface_p(struct GUID *ipid)
+struct dcom_interface_p *dcom_get_local_iface_p(struct GUID *ipid)
{
- /* FIXME */
+ /* 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;
}
return NULL;
}
-const void *dcom_vtable_by_clsid(const struct GUID *clsid)
+const struct dcom_class *dcom_class_by_clsid(const struct GUID *clsid)
{
struct class_list *c = classes;
while(c) {
- if (uuid_equal(clsid, &c->class.clsid))
+ if (uuid_equal(clsid, &c->class.clsid)) {
return &c->class;
+ }
c = c->next;
}
lib/dcom/common/rot.o
REQUIRED_SUBSYSTEMS = DCOM_PROXY_DCOM RPC_NDR_REMACT \
RPC_NDR_OXIDRESOLVER
+
+[MODULE::DCOM_SIMPLE]
+SUBSYSTEM = LIBDCOM
+INIT_FUNCTION = dcom_simple_init
+INIT_OBJ_FILES = \
+ lib/dcom/classes/simple.o
#
# End SUBSYSTEM LIBDCOM
################################################
#ifdef DEBUG_PASSWORD
DEBUG(100,("SMBencrypt: lm#, challenge, response\n"));
- dump_data(100, (char *)p21, 16);
- dump_data(100, (const char *)c8, 8);
- dump_data(100, (char *)p24, 24);
+ dump_data(100, p21, 16);
+ dump_data(100, c8, 8);
+ dump_data(100, p24, 24);
#endif
return ret;
#ifdef DEBUG_PASSWORD
DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
- dump_data(100, (char *)p21, 16);
- dump_data(100, (char *)c8, 8);
- dump_data(100, (char *)p24, 24);
+ dump_data(100, p21, 16);
+ dump_data(100, c8, 8);
+ dump_data(100, p24, 24);
#endif
}
INIT_OBJ_FILES = \
rpc_server/dcom/oxidresolver.o \
rpc_server/dcom/rot.o \
+ rpc_server/dcom/rodb.o \
rpc_server/dcom/remact.o \
librpc/gen_ndr/ndr_dcom_d.o
REQUIRED_SUBSYSTEMS = \
--- /dev/null
+/*
+ Unix SMB/CIFS implementation.
+
+ Running objects database
+
+ Copyright (C) Jelmer Vernooij 2004
+
+ 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 "rpc_server/dcerpc_server.h"
+#include "librpc/gen_ndr/ndr_rot.h"
+#include "rpc_server/common/common.h"
+
+struct tdb_wrap *openrodb(TALLOC_CTX *mem_ctx)
+{
+ struct tdb_wrap *wrap;
+ char *rodb_name = NULL;
+
+ asprintf(&rodb_name, "%s/rot.tdb", lp_lockdir());
+ wrap = tdb_wrap_open(mem_ctx, rodb_name, 0, 0, O_RDWR|O_CREAT, 0600);
+ SAFE_FREE(rodb_name);
+
+ return wrap;
+}
+
#include "librpc/gen_ndr/ndr_rot.h"
#include "rpc_server/common/common.h"
-
/*
rot_add
*/
static WERROR rot_add(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct rot_add *r)
{
+ struct tdb_wrap *db = openrodb(mem_ctx);
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ talloc_destroy(db);
}
static WERROR rot_remove(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct rot_remove *r)
{
+ struct tdb_wrap *db = openrodb(mem_ctx);
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ talloc_destroy(db);
}
static WERROR rot_is_listed(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct rot_is_listed *r)
{
+ struct tdb_wrap *db = openrodb(mem_ctx);
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ talloc_destroy(db);
}
static WERROR rot_get_interface_pointer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct rot_get_interface_pointer *r)
{
+ struct tdb_wrap *db = openrodb(mem_ctx);
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ talloc_destroy(db);
}
static WERROR rot_set_modification_time(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct rot_set_modification_time *r)
{
+ struct tdb_wrap *db = openrodb(mem_ctx);
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ talloc_destroy(db);
}
static WERROR rot_get_modification_time(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct rot_get_modification_time *r)
{
+ struct tdb_wrap *db = openrodb(mem_ctx);
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ talloc_destroy(db);
}
static WERROR rot_enum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct rot_enum *r)
{
+ struct tdb_wrap *db = openrodb(mem_ctx);
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ talloc_destroy(db);
}
mem_ctx = talloc_init("torture_dcom_simple");
- dcom_init(&ctx, lp_parm_string(-1, "torture", "userdomain"),
- lp_parm_string(-1, "torture", "username"),
- lp_parm_string(-1, "torture", "password"));
+ torture_dcom_init(&ctx);
GUID_from_string(DCERPC_ISTREAM_UUID, &IID[0]);
GUID_from_string(DCERPC_IUNKNOWN_UUID, &IID[1]);
GUID_from_string(CLSID_SIMPLE, &clsid);
error = dcom_create_object(ctx, &clsid,
- lp_parm_string(-1, "torture", "binding"), 2, IID,
+ lp_parm_string(-1, "torture", "dcomhost"), 2, IID,
&interfaces,
results);
return ret;
}
+/* initialise a DCOM context */
+NTSTATUS torture_dcom_init(struct dcom_context **ctx)
+{
+ dcom_init(ctx, lp_parm_string(-1, "torture", "userdomain"),
+ lp_parm_string(-1, "torture", "username"),
+ lp_parm_string(-1, "torture", "password"));
+
+ return NT_STATUS_OK;
+}
/* open a rpc connection to the chosen binding string */
NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p,