summaryrefslogtreecommitdiff
path: root/source4/lib/dcom/common
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/dcom/common')
-rw-r--r--source4/lib/dcom/common/dcom.h4
-rw-r--r--source4/lib/dcom/common/main.c120
2 files changed, 97 insertions, 27 deletions
diff --git a/source4/lib/dcom/common/dcom.h b/source4/lib/dcom/common/dcom.h
index 871bead376..091200d4c1 100644
--- a/source4/lib/dcom/common/dcom.h
+++ b/source4/lib/dcom/common/dcom.h
@@ -21,6 +21,10 @@
#ifndef _DCOM_H /* _DCOM_H */
#define _DCOM_H
+struct IUnknown_AddRef;
+struct IUnknown_Release;
+struct IUnknown_QueryInterface;
+
struct dcom_interface
{
struct dcerpc_pipe *pipe;
diff --git a/source4/lib/dcom/common/main.c b/source4/lib/dcom/common/main.c
index f567b639e5..3c95caebe0 100644
--- a/source4/lib/dcom/common/main.c
+++ b/source4/lib/dcom/common/main.c
@@ -22,54 +22,121 @@
#include "librpc/gen_ndr/ndr_epmapper.h"
#include "librpc/gen_ndr/ndr_remact.h"
-static WERROR dcom_binding_from_oxid(TALLOC_CTX *mem_ctx, HYPER_T oxid, struct dcerpc_binding *bd)
-{
- /* FIXME */
- return WERR_NOT_SUPPORTED;
-}
+#define DCOM_NEGOTIATED_PROTOCOLS { EPM_PROTOCOL_TCP, EPM_PROTOCOL_SMB, EPM_PROTOCOL_NCALRPC }
-static WERROR dcom_tower_from_oxid(TALLOC_CTX *mem_ctx, HYPER_T oxid, struct epm_tower *bd)
+static NTSTATUS dcom_connect(struct dcerpc_pipe **p, const char *server, const char *domain, const char *user, const char *pass)
{
- /* FIXME */
- return WERR_NOT_SUPPORTED;
+ struct dcerpc_binding bd;
+ enum dcerpc_transport_t available_transports[] = { NCACN_IP_TCP, NCACN_NP };
+ int i;
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx = talloc_init("dcom_connect");
+
+ /* Allow server name to contain a binding string */
+ if (NT_STATUS_IS_OK(dcerpc_parse_binding(mem_ctx, server, &bd))) {
+ status = dcerpc_pipe_connect_b(p, &bd, DCERPC_IREMOTEACTIVATION_UUID, DCERPC_IREMOTEACTIVATION_VERSION, domain, user, pass);
+ talloc_destroy(mem_ctx);
+ return status;
+ }
+ talloc_destroy(mem_ctx);
+
+ ZERO_STRUCT(bd);
+ bd.host = server;
+
+ if (server == NULL) {
+ bd.transport = NCALRPC;
+ return dcerpc_pipe_connect_b(p, &bd, DCERPC_IREMOTEACTIVATION_UUID, DCERPC_IREMOTEACTIVATION_VERSION, domain, user, pass);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(available_transports); i++)
+ {
+ bd.transport = available_transports[i];
+
+ status = dcerpc_pipe_connect_b(p, &bd, DCERPC_IREMOTEACTIVATION_UUID, DCERPC_IREMOTEACTIVATION_VERSION, domain, user, pass);
+
+ if (NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ }
+
+ return status;
}
-static WERROR dcom_create_instance (struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct GUID clsid)
+static WERROR dcom_connect_oxid(TALLOC_CTX *mem_ctx, struct dcerpc_pipe **p, HYPER_T oxid)
{
+ /* FIXME */
return WERR_NOT_SUPPORTED;
}
-static uint32 IUnknown_AddRef(void)
+NTSTATUS dcerpc_IUnknown_AddRef(struct dcerpc_pipe *p, struct GUID *o, TALLOC_CTX *mem_ctx, struct IUnknown_AddRef *r)
{
/* FIXME: Tell local server we're adding a reference to this interface on this object. Local server can then call RemAddRef() if necessary */
- return 0;
+ return NT_STATUS_NOT_SUPPORTED;
}
-static uint32 IUnknown_Release(void)
+NTSTATUS dcerpc_IUnknown_Release(struct dcerpc_pipe *p, struct GUID *o, TALLOC_CTX *mem_ctx, struct IUnknown_Release *r)
{
/* FIXME: Tell local server we're releasing a reference to this interface on this object. Local server can then call RemRelease() if necessary */
- return 0;
+ return NT_STATUS_NOT_SUPPORTED;
}
-static WERROR IUnknown_QueryInterface(struct GUID *riid, void **data)
+NTSTATUS dcerpc_IUnknown_QueryInterface(struct dcerpc_pipe *p, struct GUID *o, TALLOC_CTX *mem_ctx, struct IUnknown_QueryInterface *r)
{
/* FIXME: Ask local server for interface pointer. Local server can then
* call RemQueryInterface if necessary */
- return WERR_NOT_SUPPORTED;
+ return NT_STATUS_NOT_SUPPORTED;
}
-WERROR dcom_create_object(TALLOC_CTX *mem_ctx, struct GUID *clsid, const char *server, int num_ifaces, struct GUID *iid, struct dcom_interface **ip)
+WERROR dcom_create_object(TALLOC_CTX *mem_ctx, struct GUID *clsid, const char *server, int num_ifaces, struct GUID *iid, struct dcom_interface **ip, const char *domain, const char *user, const char *pass)
{
- return WERR_NOT_SUPPORTED;
+ struct RemoteActivation r;
+ struct dcerpc_pipe *p;
+ NTSTATUS status;
+ uint16 protseq[] = DCOM_NEGOTIATED_PROTOCOLS;
+
+ status = dcom_connect(&p, server, domain, user, pass);
+ if (NT_STATUS_IS_ERR(status)) {
+ DEBUG(1, ("Unable to connect to %s - %s\n", server, nt_errstr(status)));
+ return ntstatus_to_werror(status);
+ }
+
+ ZERO_STRUCT(r.in);
+ r.in.this.version.MajorVersion = 5;
+ r.in.this.version.MinorVersion = 1;
+ uuid_generate_random(&r.in.this.cid);
+ 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;
+
+ status = dcerpc_RemoteActivation(p, mem_ctx, &r);
+ if(NT_STATUS_IS_ERR(status)) {
+ DEBUG(1, ("Error while running RemoteActivation %s\n", nt_errstr(status)));
+ return ntstatus_to_werror(status);
+ }
+
+ if(!W_ERROR_IS_OK(r.out.result)) { return r.out.result; }
+ if(!W_ERROR_IS_OK(r.out.hr)) { return r.out.hr; }
+ if(!W_ERROR_IS_OK(r.out.results[0])) { return r.out.results[0]; }
+
+ /* FIXME: Fill ip */
+ return WERR_OK;
}
-WERROR dcom_get_class_object(TALLOC_CTX *mem_ctx, struct GUID *clsid, const char *server, struct GUID *iid, struct dcom_interface **ip)
+WERROR dcom_get_class_object(TALLOC_CTX *mem_ctx, struct GUID *clsid, const char *server, struct GUID *iid, struct dcom_interface **ip, const char *domain, const char *user, const char *pass)
{
struct RemoteActivation r;
- struct dcerpc_pipe *p = NULL; /* FIXME */
+ struct dcerpc_pipe *p;
NTSTATUS status;
- struct GUID iids[2];
- uint16 protseq[3] = { EPM_PROTOCOL_TCP, EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_UUID };
+ uint16 protseq[] = DCOM_NEGOTIATED_PROTOCOLS;
+
+ status = dcom_connect(&p, server, domain, user, pass);
+ if (NT_STATUS_IS_ERR(status)) {
+ DEBUG(1, ("Unable to connect to %s - %s\n", server, nt_errstr(status)));
+ return ntstatus_to_werror(status);
+ }
ZERO_STRUCT(r.in);
r.in.this.version.MajorVersion = 5;
@@ -77,16 +144,15 @@ WERROR dcom_get_class_object(TALLOC_CTX *mem_ctx, struct GUID *clsid, const char
uuid_generate_random(&r.in.this.cid);
r.in.Clsid = *clsid;
r.in.ClientImpLevel = RPC_C_IMP_LEVEL_IDENTIFY;
- r.in.num_protseqs = 3;
+ r.in.num_protseqs = ARRAY_SIZE(protseq);
r.in.protseq = protseq;
r.in.Interfaces = 1;
- GUID_from_string(DCERPC_IUNKNOWN_UUID, &iids[0]);
- r.in.pIIDs = iids;
+ r.in.pIIDs = iid;
r.in.Mode = MODE_GET_CLASS_OBJECT;
status = dcerpc_RemoteActivation(p, mem_ctx, &r);
if(NT_STATUS_IS_ERR(status)) {
- fprintf(stderr, "RemoteActivation: %s\n", nt_errstr(status));
+ DEBUG(1, ("Error while running RemoteActivation - %s\n", nt_errstr(status)));
return ntstatus_to_werror(status);
}
@@ -94,6 +160,6 @@ WERROR dcom_get_class_object(TALLOC_CTX *mem_ctx, struct GUID *clsid, const char
if(!W_ERROR_IS_OK(r.out.hr)) { return r.out.hr; }
if(!W_ERROR_IS_OK(r.out.results[0])) { return r.out.results[0]; }
-
- return WERR_NOT_SUPPORTED;
+ /* FIXME: Fill ip */
+ return WERR_OK;
}