diff options
Diffstat (limited to 'source4/lib')
-rw-r--r-- | source4/lib/dcom/common/dcom.h | 4 | ||||
-rw-r--r-- | source4/lib/dcom/common/main.c | 120 |
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; } |