r3898: Work towards local/server DCOM support, start working
authorJelmer Vernooij <jelmer@samba.org>
Sun, 21 Nov 2004 17:47:09 +0000 (17:47 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:06:02 +0000 (13:06 -0500)
on Simple example server side implementation
(This used to be commit 98afb504d95ccca4d6ec48273e10b52ccfa26ad0)

13 files changed:
source4/build/pidl/stub.pm
source4/lib/dcom/classes/simple.c [new file with mode: 0644]
source4/lib/dcom/common/dcom.h
source4/lib/dcom/common/main.c
source4/lib/dcom/common/rot.c
source4/lib/dcom/common/tables.c
source4/lib/dcom/config.mk
source4/libcli/util/smbencrypt.c
source4/rpc_server/config.mk
source4/rpc_server/dcom/rodb.c [new file with mode: 0644]
source4/rpc_server/dcom/rot.c
source4/torture/dcom/simple.c
source4/torture/torture.c

index 2bcece841682bd3a10abae00703cb4b7aa1d8aa8..a9843e106e4d1581142d16a91f776ede6f0ba4db 100644 (file)
@@ -90,7 +90,7 @@ static NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_C
 {
        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;
diff --git a/source4/lib/dcom/classes/simple.c b/source4/lib/dcom/classes/simple.c
new file mode 100644 (file)
index 0000000..e8b8730
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+   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);
+}
index 9c09cc17d9a49bc822aca9ca89d65e8400e0274c..d8e3797c73f99941575790623848463079fc8034 100644 (file)
@@ -26,6 +26,7 @@
 struct IUnknown_AddRef;
 struct IUnknown_Release;
 struct IUnknown_QueryInterface;
+struct dcom_interface_p;
 
 struct dcom_context 
 {
@@ -53,7 +54,9 @@ struct dcom_class
 {
        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
index 60f866aede325163d656045a721d13c1482c0c53..373013726860927aca08d9d8936834f5bb9669ef 100644 (file)
@@ -143,15 +143,15 @@ WERROR dcom_ping(struct dcom_context *ctx)
        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)) {
@@ -207,7 +207,60 @@ WERROR dcom_create_object(struct dcom_context *ctx, struct GUID *clsid, const ch
        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;
@@ -258,6 +311,36 @@ WERROR dcom_get_class_object(struct dcom_context *ctx, struct GUID *clsid, const
        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;
@@ -326,6 +409,12 @@ struct dcom_object *dcom_object_by_oid(struct dcom_object_exporter *ox, HYPER_T
        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);
@@ -363,7 +452,7 @@ NTSTATUS dcom_ifacep_from_OBJREF(struct dcom_context *ctx, struct dcom_interface
                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;
@@ -371,7 +460,6 @@ NTSTATUS dcom_ifacep_from_OBJREF(struct dcom_context *ctx, struct dcom_interface
                
        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 */
@@ -437,3 +525,25 @@ NTSTATUS dcom_ifacep_from_OBJREF(struct dcom_context *ctx, struct dcom_interface
 
        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;
+}
index 95f83d000c77fe00fe3b35ce73c765b083754cab..7acdbe066e0844cd34a571ee03198f3f181ea34f 100644 (file)
 
 #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; 
 }
index f9f1c49380c1f2575529be25bbe86f9ebcb72366..f615662b47344021a8557e2a0bd9b2182975b17c 100644 (file)
@@ -46,14 +46,15 @@ const struct dcom_interface *dcom_interface_by_iid(const struct GUID *iid)
        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;
        }
index 9fda924881837f96260bbbfb91795d6242e6ceea..d599231525af3852da4165b5352d80b1040352cf 100644 (file)
@@ -7,6 +7,12 @@ INIT_OBJ_FILES = \
                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
 ################################################
index dac8674f035b43f74ab4cd762c8d7a485fc1a24d..1218de1fe7693b1625b224c5b5db5e0170cb143d 100644 (file)
@@ -46,9 +46,9 @@ BOOL SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24])
 
 #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;
@@ -196,9 +196,9 @@ void SMBNTencrypt(const char *passwd, uint8_t *c8, uint8_t *p24)
 
 #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
 }
 
index 58f842add0a1d1f4cb02d8fbbf3a7e366a8637a7..466d86a0c46077a02ba6611d6035feca6f6994d8 100644 (file)
@@ -19,6 +19,7 @@ SUBSYSTEM = DCERPC
 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 = \
diff --git a/source4/rpc_server/dcom/rodb.c b/source4/rpc_server/dcom/rodb.c
new file mode 100644 (file)
index 0000000..56d51c7
--- /dev/null
@@ -0,0 +1,39 @@
+/* 
+   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;
+}
+
index 1a588332045089513f65cd476acb7ea87a55b095..04fb7c73a56aef77cdcc6798ca19bf6b2e5669fc 100644 (file)
 #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);
 }
 
 
@@ -42,7 +43,9 @@ static WERROR rot_add(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
 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);
 }
 
 
@@ -52,7 +55,9 @@ static WERROR rot_remove(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx
 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);
 }
 
 
@@ -62,7 +67,9 @@ static WERROR rot_is_listed(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_
 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);
 }
 
 
@@ -72,7 +79,9 @@ static WERROR rot_get_interface_pointer(struct dcesrv_call_state *dce_call, TALL
 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);
 }
 
 
@@ -82,7 +91,9 @@ static WERROR rot_set_modification_time(struct dcesrv_call_state *dce_call, TALL
 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);
 }
 
 
@@ -92,7 +103,9 @@ static WERROR rot_get_modification_time(struct dcesrv_call_state *dce_call, TALL
 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);
 }
 
 
index fe44a78cf5d4dc63caea7e1b30eefb69826116d3..68bf9be813f8859377342a015f2f28bb378088b8 100644 (file)
@@ -47,15 +47,13 @@ BOOL torture_dcom_simple(void)
 
        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);
                                                          
index 7d309f3741b40e08d898dc92f4b35c19d99b78e3..b0a4f6ab8ae048ca124011595cd2fca9ce90adea 100644 (file)
@@ -141,6 +141,15 @@ BOOL torture_close_connection(struct smbcli_state *c)
        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,