diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-10-21 14:51:13 +0200 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-10-21 14:51:13 +0200 |
commit | 5209a846a9157e649fcdcb561f7eaf19c8c0e465 (patch) | |
tree | b0a7e52b5646c8eec182dbc391e7934b6804488c /source4/librpc/rpc | |
parent | 625359b2e266105022309df8985720108ecd6f67 (diff) | |
parent | 2ee8d29d22bcb1c350ab59d71b0aee548489bc9c (diff) | |
download | samba-5209a846a9157e649fcdcb561f7eaf19c8c0e465.tar.gz samba-5209a846a9157e649fcdcb561f7eaf19c8c0e465.tar.bz2 samba-5209a846a9157e649fcdcb561f7eaf19c8c0e465.zip |
Merge branch 'master' of ssh://git.samba.org/data/git/samba into regsrv
Conflicts:
source4/lib/registry/ldb.c
source4/rpc_server/winreg/rpc_winreg.c
Diffstat (limited to 'source4/librpc/rpc')
-rw-r--r-- | source4/librpc/rpc/binding.c | 725 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc.c | 12 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc.h | 4 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc_connect.c | 3 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc_secondary.c | 7 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc_sock.c | 40 |
6 files changed, 42 insertions, 749 deletions
diff --git a/source4/librpc/rpc/binding.c b/source4/librpc/rpc/binding.c deleted file mode 100644 index bfe62c4054..0000000000 --- a/source4/librpc/rpc/binding.c +++ /dev/null @@ -1,725 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - dcerpc utility functions - - Copyright (C) Andrew Tridgell 2003 - Copyright (C) Jelmer Vernooij 2004 - Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005 - Copyright (C) Rafal Szczesniak 2006 - - 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/>. -*/ - -#include "includes.h" -#include "lib/events/events.h" -#include "librpc/gen_ndr/ndr_epmapper_c.h" -#include "librpc/gen_ndr/ndr_dcerpc.h" -#include "librpc/gen_ndr/ndr_misc.h" - -#define MAX_PROTSEQ 10 - -static const struct { - const char *name; - enum dcerpc_transport_t transport; - int num_protocols; - enum epm_protocol protseq[MAX_PROTSEQ]; -} transports[] = { - { "ncacn_np", NCACN_NP, 3, - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_SMB, EPM_PROTOCOL_NETBIOS }}, - { "ncacn_ip_tcp", NCACN_IP_TCP, 3, - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_TCP, EPM_PROTOCOL_IP } }, - { "ncacn_http", NCACN_HTTP, 3, - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_HTTP, EPM_PROTOCOL_IP } }, - { "ncadg_ip_udp", NCACN_IP_UDP, 3, - { EPM_PROTOCOL_NCADG, EPM_PROTOCOL_UDP, EPM_PROTOCOL_IP } }, - { "ncalrpc", NCALRPC, 2, - { EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_PIPE } }, - { "ncacn_unix_stream", NCACN_UNIX_STREAM, 2, - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_UNIX_DS } }, - { "ncadg_unix_dgram", NCADG_UNIX_DGRAM, 2, - { EPM_PROTOCOL_NCADG, EPM_PROTOCOL_UNIX_DS } }, - { "ncacn_at_dsp", NCACN_AT_DSP, 3, - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_APPLETALK, EPM_PROTOCOL_DSP } }, - { "ncadg_at_ddp", NCADG_AT_DDP, 3, - { EPM_PROTOCOL_NCADG, EPM_PROTOCOL_APPLETALK, EPM_PROTOCOL_DDP } }, - { "ncacn_vns_ssp", NCACN_VNS_SPP, 3, - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_STREETTALK, EPM_PROTOCOL_VINES_SPP } }, - { "ncacn_vns_ipc", NCACN_VNS_IPC, 3, - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_STREETTALK, EPM_PROTOCOL_VINES_IPC }, }, - { "ncadg_ipx", NCADG_IPX, 2, - { EPM_PROTOCOL_NCADG, EPM_PROTOCOL_IPX }, - }, - { "ncacn_spx", NCACN_SPX, 3, - /* I guess some MS programmer confused the identifier for - * EPM_PROTOCOL_UUID (0x0D or 13) with the one for - * EPM_PROTOCOL_SPX (0x13) here. -- jelmer*/ - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_UUID }, - }, -}; - -static const struct { - const char *name; - uint32_t flag; -} ncacn_options[] = { - {"sign", DCERPC_SIGN}, - {"seal", DCERPC_SEAL}, - {"connect", DCERPC_CONNECT}, - {"spnego", DCERPC_AUTH_SPNEGO}, - {"ntlm", DCERPC_AUTH_NTLM}, - {"krb5", DCERPC_AUTH_KRB5}, - {"validate", DCERPC_DEBUG_VALIDATE_BOTH}, - {"print", DCERPC_DEBUG_PRINT_BOTH}, - {"padcheck", DCERPC_DEBUG_PAD_CHECK}, - {"bigendian", DCERPC_PUSH_BIGENDIAN}, - {"smb2", DCERPC_SMB2}, - {"hdrsign", DCERPC_HEADER_SIGNING} -}; - -const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor) -{ - struct ndr_syntax_id syntax; - NTSTATUS status; - - switch(epm_floor->lhs.protocol) { - case EPM_PROTOCOL_UUID: - status = dcerpc_floor_get_lhs_data(epm_floor, &syntax); - if (NT_STATUS_IS_OK(status)) { - /* lhs is used: UUID */ - char *uuidstr; - - if (GUID_equal(&syntax.uuid, &ndr_transfer_syntax.uuid)) { - return "NDR"; - } - - if (GUID_equal(&syntax.uuid, &ndr64_transfer_syntax.uuid)) { - return "NDR64"; - } - - uuidstr = GUID_string(mem_ctx, &syntax.uuid); - - return talloc_asprintf(mem_ctx, " uuid %s/0x%02x", uuidstr, syntax.if_version); - } else { /* IPX */ - return talloc_asprintf(mem_ctx, "IPX:%s", - data_blob_hex_string(mem_ctx, &epm_floor->rhs.uuid.unknown)); - } - - case EPM_PROTOCOL_NCACN: - return "RPC-C"; - - case EPM_PROTOCOL_NCADG: - return "RPC"; - - case EPM_PROTOCOL_NCALRPC: - return "NCALRPC"; - - case EPM_PROTOCOL_DNET_NSP: - return "DNET/NSP"; - - case EPM_PROTOCOL_IP: - return talloc_asprintf(mem_ctx, "IP:%s", epm_floor->rhs.ip.ipaddr); - - case EPM_PROTOCOL_PIPE: - return talloc_asprintf(mem_ctx, "PIPE:%s", epm_floor->rhs.pipe.path); - - case EPM_PROTOCOL_SMB: - return talloc_asprintf(mem_ctx, "SMB:%s", epm_floor->rhs.smb.unc); - - case EPM_PROTOCOL_UNIX_DS: - return talloc_asprintf(mem_ctx, "Unix:%s", epm_floor->rhs.unix_ds.path); - - case EPM_PROTOCOL_NETBIOS: - return talloc_asprintf(mem_ctx, "NetBIOS:%s", epm_floor->rhs.netbios.name); - - case EPM_PROTOCOL_NETBEUI: - return "NETBeui"; - - case EPM_PROTOCOL_SPX: - return "SPX"; - - case EPM_PROTOCOL_NB_IPX: - return "NB_IPX"; - - case EPM_PROTOCOL_HTTP: - return talloc_asprintf(mem_ctx, "HTTP:%d", epm_floor->rhs.http.port); - - case EPM_PROTOCOL_TCP: - return talloc_asprintf(mem_ctx, "TCP:%d", epm_floor->rhs.tcp.port); - - case EPM_PROTOCOL_UDP: - return talloc_asprintf(mem_ctx, "UDP:%d", epm_floor->rhs.udp.port); - - default: - return talloc_asprintf(mem_ctx, "UNK(%02x):", epm_floor->lhs.protocol); - } -} - - -/* - form a binding string from a binding structure -*/ -_PUBLIC_ char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_binding *b) -{ - char *s = talloc_strdup(mem_ctx, ""); - int i; - const char *t_name = NULL; - - if (b->transport != NCA_UNKNOWN) { - for (i=0;i<ARRAY_SIZE(transports);i++) { - if (transports[i].transport == b->transport) { - t_name = transports[i].name; - } - } - if (!t_name) { - return NULL; - } - } - - if (!GUID_all_zero(&b->object.uuid)) { - s = talloc_asprintf(s, "%s@", - GUID_string(mem_ctx, &b->object.uuid)); - } - - if (t_name != NULL) { - s = talloc_asprintf_append_buffer(s, "%s:", t_name); - if (s == NULL) { - return NULL; - } - } - - if (b->host) { - s = talloc_asprintf_append_buffer(s, "%s", b->host); - } - - if (!b->endpoint && !b->options && !b->flags) { - return s; - } - - s = talloc_asprintf_append_buffer(s, "["); - - if (b->endpoint) { - s = talloc_asprintf_append_buffer(s, "%s", b->endpoint); - } - - /* this is a *really* inefficent way of dealing with strings, - but this is rarely called and the strings are always short, - so I don't care */ - for (i=0;b->options && b->options[i];i++) { - s = talloc_asprintf_append_buffer(s, ",%s", b->options[i]); - if (!s) return NULL; - } - - for (i=0;i<ARRAY_SIZE(ncacn_options);i++) { - if (b->flags & ncacn_options[i].flag) { - s = talloc_asprintf_append_buffer(s, ",%s", ncacn_options[i].name); - if (!s) return NULL; - } - } - - s = talloc_asprintf_append_buffer(s, "]"); - - return s; -} - -/* - parse a binding string into a dcerpc_binding structure -*/ -_PUBLIC_ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding **b_out) -{ - struct dcerpc_binding *b; - char *options; - char *p; - int i, j, comma_count; - - b = talloc(mem_ctx, struct dcerpc_binding); - if (!b) { - return NT_STATUS_NO_MEMORY; - } - - p = strchr(s, '@'); - - if (p && PTR_DIFF(p, s) == 36) { /* 36 is the length of a UUID */ - NTSTATUS status; - - status = GUID_from_string(s, &b->object.uuid); - - if (NT_STATUS_IS_ERR(status)) { - DEBUG(0, ("Failed parsing UUID\n")); - return status; - } - - s = p + 1; - } else { - ZERO_STRUCT(b->object); - } - - b->object.if_version = 0; - - p = strchr(s, ':'); - - if (p == NULL) { - b->transport = NCA_UNKNOWN; - } else { - char *type = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s)); - if (!type) { - return NT_STATUS_NO_MEMORY; - } - - for (i=0;i<ARRAY_SIZE(transports);i++) { - if (strcasecmp(type, transports[i].name) == 0) { - b->transport = transports[i].transport; - break; - } - } - - if (i==ARRAY_SIZE(transports)) { - DEBUG(0,("Unknown dcerpc transport '%s'\n", type)); - return NT_STATUS_INVALID_PARAMETER; - } - - talloc_free(type); - - s = p+1; - } - - p = strchr(s, '['); - if (p) { - b->host = talloc_strndup(b, s, PTR_DIFF(p, s)); - options = talloc_strdup(mem_ctx, p+1); - if (options[strlen(options)-1] != ']') { - return NT_STATUS_INVALID_PARAMETER; - } - options[strlen(options)-1] = 0; - } else { - b->host = talloc_strdup(b, s); - options = NULL; - } - if (!b->host) { - return NT_STATUS_NO_MEMORY; - } - - b->target_hostname = b->host; - - b->options = NULL; - b->flags = 0; - b->assoc_group_id = 0; - b->endpoint = NULL; - - if (!options) { - *b_out = b; - return NT_STATUS_OK; - } - - comma_count = count_chars(options, ','); - - b->options = talloc_array(b, const char *, comma_count+2); - if (!b->options) { - return NT_STATUS_NO_MEMORY; - } - - for (i=0; (p = strchr(options, ',')); i++) { - b->options[i] = talloc_strndup(b, options, PTR_DIFF(p, options)); - if (!b->options[i]) { - return NT_STATUS_NO_MEMORY; - } - options = p+1; - } - b->options[i] = options; - b->options[i+1] = NULL; - - /* some options are pre-parsed for convenience */ - for (i=0;b->options[i];i++) { - for (j=0;j<ARRAY_SIZE(ncacn_options);j++) { - if (strcasecmp(ncacn_options[j].name, b->options[i]) == 0) { - int k; - b->flags |= ncacn_options[j].flag; - for (k=i;b->options[k];k++) { - b->options[k] = b->options[k+1]; - } - i--; - break; - } - } - } - - if (b->options[0]) { - /* Endpoint is first option */ - b->endpoint = b->options[0]; - if (strlen(b->endpoint) == 0) b->endpoint = NULL; - - for (i=0;b->options[i];i++) { - b->options[i] = b->options[i+1]; - } - } - - if (b->options[0] == NULL) - b->options = NULL; - - *b_out = b; - return NT_STATUS_OK; -} - -_PUBLIC_ NTSTATUS dcerpc_floor_get_lhs_data(struct epm_floor *epm_floor, struct ndr_syntax_id *syntax) -{ - TALLOC_CTX *mem_ctx = talloc_init("floor_get_lhs_data"); - struct ndr_pull *ndr = ndr_pull_init_blob(&epm_floor->lhs.lhs_data, mem_ctx, NULL); - enum ndr_err_code ndr_err; - uint16_t if_version=0; - - ndr->flags |= LIBNDR_FLAG_NOALIGN; - - ndr_err = ndr_pull_GUID(ndr, NDR_SCALARS | NDR_BUFFERS, &syntax->uuid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(mem_ctx); - return ndr_map_error2ntstatus(ndr_err); - } - - ndr_err = ndr_pull_uint16(ndr, NDR_SCALARS, &if_version); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(mem_ctx); - return ndr_map_error2ntstatus(ndr_err); - } - - syntax->if_version = if_version; - - talloc_free(mem_ctx); - - return NT_STATUS_OK; -} - -static DATA_BLOB dcerpc_floor_pack_lhs_data(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *syntax) -{ - struct ndr_push *ndr = ndr_push_init_ctx(mem_ctx, NULL); - - ndr->flags |= LIBNDR_FLAG_NOALIGN; - - ndr_push_GUID(ndr, NDR_SCALARS | NDR_BUFFERS, &syntax->uuid); - ndr_push_uint16(ndr, NDR_SCALARS, syntax->if_version); - - return ndr_push_blob(ndr); -} - -const char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor) -{ - switch (epm_floor->lhs.protocol) { - case EPM_PROTOCOL_TCP: - if (epm_floor->rhs.tcp.port == 0) return NULL; - return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.tcp.port); - - case EPM_PROTOCOL_UDP: - if (epm_floor->rhs.udp.port == 0) return NULL; - return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.udp.port); - - case EPM_PROTOCOL_HTTP: - if (epm_floor->rhs.http.port == 0) return NULL; - return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.http.port); - - case EPM_PROTOCOL_IP: - return talloc_strdup(mem_ctx, epm_floor->rhs.ip.ipaddr); - - case EPM_PROTOCOL_NCACN: - return NULL; - - case EPM_PROTOCOL_NCADG: - return NULL; - - case EPM_PROTOCOL_SMB: - if (strlen(epm_floor->rhs.smb.unc) == 0) return NULL; - return talloc_strdup(mem_ctx, epm_floor->rhs.smb.unc); - - case EPM_PROTOCOL_PIPE: - if (strlen(epm_floor->rhs.pipe.path) == 0) return NULL; - return talloc_strdup(mem_ctx, epm_floor->rhs.pipe.path); - - case EPM_PROTOCOL_NETBIOS: - if (strlen(epm_floor->rhs.netbios.name) == 0) return NULL; - return talloc_strdup(mem_ctx, epm_floor->rhs.netbios.name); - - case EPM_PROTOCOL_NCALRPC: - return NULL; - - case EPM_PROTOCOL_VINES_SPP: - return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.vines_spp.port); - - case EPM_PROTOCOL_VINES_IPC: - return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.vines_ipc.port); - - case EPM_PROTOCOL_STREETTALK: - return talloc_strdup(mem_ctx, epm_floor->rhs.streettalk.streettalk); - - case EPM_PROTOCOL_UNIX_DS: - if (strlen(epm_floor->rhs.unix_ds.path) == 0) return NULL; - return talloc_strdup(mem_ctx, epm_floor->rhs.unix_ds.path); - - case EPM_PROTOCOL_NULL: - return NULL; - - default: - DEBUG(0,("Unsupported lhs protocol %d\n", epm_floor->lhs.protocol)); - break; - } - - return NULL; -} - -static NTSTATUS dcerpc_floor_set_rhs_data(TALLOC_CTX *mem_ctx, - struct epm_floor *epm_floor, - const char *data) -{ - switch (epm_floor->lhs.protocol) { - case EPM_PROTOCOL_TCP: - epm_floor->rhs.tcp.port = atoi(data); - return NT_STATUS_OK; - - case EPM_PROTOCOL_UDP: - epm_floor->rhs.udp.port = atoi(data); - return NT_STATUS_OK; - - case EPM_PROTOCOL_HTTP: - epm_floor->rhs.http.port = atoi(data); - return NT_STATUS_OK; - - case EPM_PROTOCOL_IP: - epm_floor->rhs.ip.ipaddr = talloc_strdup(mem_ctx, data); - NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.ip.ipaddr); - return NT_STATUS_OK; - - case EPM_PROTOCOL_NCACN: - epm_floor->rhs.ncacn.minor_version = 0; - return NT_STATUS_OK; - - case EPM_PROTOCOL_NCADG: - epm_floor->rhs.ncadg.minor_version = 0; - return NT_STATUS_OK; - - case EPM_PROTOCOL_SMB: - epm_floor->rhs.smb.unc = talloc_strdup(mem_ctx, data); - NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.smb.unc); - return NT_STATUS_OK; - - case EPM_PROTOCOL_PIPE: - epm_floor->rhs.pipe.path = talloc_strdup(mem_ctx, data); - NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.pipe.path); - return NT_STATUS_OK; - - case EPM_PROTOCOL_NETBIOS: - epm_floor->rhs.netbios.name = talloc_strdup(mem_ctx, data); - NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.netbios.name); - return NT_STATUS_OK; - - case EPM_PROTOCOL_NCALRPC: - return NT_STATUS_OK; - - case EPM_PROTOCOL_VINES_SPP: - epm_floor->rhs.vines_spp.port = atoi(data); - return NT_STATUS_OK; - - case EPM_PROTOCOL_VINES_IPC: - epm_floor->rhs.vines_ipc.port = atoi(data); - return NT_STATUS_OK; - - case EPM_PROTOCOL_STREETTALK: - epm_floor->rhs.streettalk.streettalk = talloc_strdup(mem_ctx, data); - NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.streettalk.streettalk); - return NT_STATUS_OK; - - case EPM_PROTOCOL_UNIX_DS: - epm_floor->rhs.unix_ds.path = talloc_strdup(mem_ctx, data); - NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.unix_ds.path); - return NT_STATUS_OK; - - case EPM_PROTOCOL_NULL: - return NT_STATUS_OK; - - default: - DEBUG(0,("Unsupported lhs protocol %d\n", epm_floor->lhs.protocol)); - break; - } - - return NT_STATUS_NOT_SUPPORTED; -} - -enum dcerpc_transport_t dcerpc_transport_by_endpoint_protocol(int prot) -{ - int i; - - /* Find a transport that has 'prot' as 4th protocol */ - for (i=0;i<ARRAY_SIZE(transports);i++) { - if (transports[i].num_protocols >= 2 && - transports[i].protseq[1] == prot) { - return transports[i].transport; - } - } - - /* Unknown transport */ - return (unsigned int)-1; -} - -_PUBLIC_ enum dcerpc_transport_t dcerpc_transport_by_tower(struct epm_tower *tower) -{ - int i; - - /* Find a transport that matches this tower */ - for (i=0;i<ARRAY_SIZE(transports);i++) { - int j; - if (transports[i].num_protocols != tower->num_floors - 2) { - continue; - } - - for (j = 0; j < transports[i].num_protocols; j++) { - if (transports[i].protseq[j] != tower->floors[j+2].lhs.protocol) { - break; - } - } - - if (j == transports[i].num_protocols) { - return transports[i].transport; - } - } - - /* Unknown transport */ - return (unsigned int)-1; -} - -_PUBLIC_ NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, - struct epm_tower *tower, - struct dcerpc_binding **b_out) -{ - NTSTATUS status; - struct dcerpc_binding *binding; - - binding = talloc(mem_ctx, struct dcerpc_binding); - NT_STATUS_HAVE_NO_MEMORY(binding); - - ZERO_STRUCT(binding->object); - binding->options = NULL; - binding->host = NULL; - binding->target_hostname = NULL; - binding->flags = 0; - binding->assoc_group_id = 0; - - binding->transport = dcerpc_transport_by_tower(tower); - - if (binding->transport == (unsigned int)-1) { - return NT_STATUS_NOT_SUPPORTED; - } - - if (tower->num_floors < 1) { - return NT_STATUS_OK; - } - - /* Set object uuid */ - status = dcerpc_floor_get_lhs_data(&tower->floors[0], &binding->object); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Error pulling object uuid and version: %s", nt_errstr(status))); - return status; - } - - /* Ignore floor 1, it contains the NDR version info */ - - binding->options = NULL; - - /* Set endpoint */ - if (tower->num_floors >= 4) { - binding->endpoint = dcerpc_floor_get_rhs_data(mem_ctx, &tower->floors[3]); - } else { - binding->endpoint = NULL; - } - - /* Set network address */ - if (tower->num_floors >= 5) { - binding->host = dcerpc_floor_get_rhs_data(mem_ctx, &tower->floors[4]); - NT_STATUS_HAVE_NO_MEMORY(binding->host); - binding->target_hostname = binding->host; - } - *b_out = binding; - return NT_STATUS_OK; -} - -_PUBLIC_ NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding *binding, struct epm_tower *tower) -{ - const enum epm_protocol *protseq = NULL; - int num_protocols = -1, i; - NTSTATUS status; - - /* Find transport */ - for (i=0;i<ARRAY_SIZE(transports);i++) { - if (transports[i].transport == binding->transport) { - protseq = transports[i].protseq; - num_protocols = transports[i].num_protocols; - break; - } - } - - if (num_protocols == -1) { - DEBUG(0, ("Unable to find transport with id '%d'\n", binding->transport)); - return NT_STATUS_UNSUCCESSFUL; - } - - tower->num_floors = 2 + num_protocols; - tower->floors = talloc_array(mem_ctx, struct epm_floor, tower->num_floors); - - /* Floor 0 */ - tower->floors[0].lhs.protocol = EPM_PROTOCOL_UUID; - - tower->floors[0].lhs.lhs_data = dcerpc_floor_pack_lhs_data(mem_ctx, &binding->object); - - tower->floors[0].rhs.uuid.unknown = data_blob_talloc_zero(mem_ctx, 2); - - /* Floor 1 */ - tower->floors[1].lhs.protocol = EPM_PROTOCOL_UUID; - - tower->floors[1].lhs.lhs_data = dcerpc_floor_pack_lhs_data(mem_ctx, - &ndr_transfer_syntax); - - tower->floors[1].rhs.uuid.unknown = data_blob_talloc_zero(mem_ctx, 2); - - /* Floor 2 to num_protocols */ - for (i = 0; i < num_protocols; i++) { - tower->floors[2 + i].lhs.protocol = protseq[i]; - tower->floors[2 + i].lhs.lhs_data = data_blob_talloc(mem_ctx, NULL, 0); - ZERO_STRUCT(tower->floors[2 + i].rhs); - dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[2 + i], ""); - } - - /* The 4th floor contains the endpoint */ - if (num_protocols >= 2 && binding->endpoint) { - status = dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[3], binding->endpoint); - if (NT_STATUS_IS_ERR(status)) { - return status; - } - } - - /* The 5th contains the network address */ - if (num_protocols >= 3 && binding->host) { - if (is_ipaddress(binding->host)) { - status = dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[4], - binding->host); - } else { - /* note that we don't attempt to resolve the - name here - when we get a hostname here we - are in the client code, and want to put in - a wildcard all-zeros IP for the server to - fill in */ - status = dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[4], - "0.0.0.0"); - } - if (NT_STATUS_IS_ERR(status)) { - return status; - } - } - - return NT_STATUS_OK; -} diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 5bbcc5e91c..bd8e60d4bd 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -21,7 +21,7 @@ */ #include "includes.h" -#include "lib/util/dlinklist.h" +#include "../lib/util/dlinklist.h" #include "lib/events/events.h" #include "librpc/rpc/dcerpc.h" #include "librpc/rpc/dcerpc_proto.h" @@ -33,9 +33,7 @@ _PUBLIC_ NTSTATUS dcerpc_init(void) { - gensec_init(global_loadparm); - - return NT_STATUS_OK; + return gensec_init(global_loadparm); } static void dcerpc_connection_dead(struct dcerpc_connection *conn, NTSTATUS status); @@ -334,6 +332,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, DATA_BLOB creds2; size_t payload_length; enum ndr_err_code ndr_err; + size_t hdr_size = DCERPC_REQUEST_LENGTH; /* non-signed packets are simpler */ if (sig_size == 0) { @@ -367,6 +366,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT; + hdr_size += 16; } ndr_err = ndr_push_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt); @@ -415,7 +415,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, case DCERPC_AUTH_LEVEL_PRIVACY: status = gensec_seal_packet(c->security_state.generic_state, mem_ctx, - blob->data + DCERPC_REQUEST_LENGTH, + blob->data + hdr_size, payload_length, blob->data, blob->length, @@ -428,7 +428,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, case DCERPC_AUTH_LEVEL_INTEGRITY: status = gensec_sign_packet(c->security_state.generic_state, mem_ctx, - blob->data + DCERPC_REQUEST_LENGTH, + blob->data + hdr_size, payload_length, blob->data, blob->length, diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 1fd56cb052..482e803a35 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -27,7 +27,7 @@ #ifndef __DCERPC_H__ #define __DCERPC_H__ -#include "lib/util/data_blob.h" +#include "../lib/util/data_blob.h" #include "librpc/gen_ndr/dcerpc.h" #include "librpc/ndr/libndr.h" @@ -375,4 +375,6 @@ NTSTATUS dcerpc_request(struct dcerpc_pipe *p, typedef NTSTATUS (*dcerpc_call_fn) (struct dcerpc_pipe *, TALLOC_CTX *, void *); +enum dcerpc_transport_t dcerpc_transport_by_endpoint_protocol(int prot); + #endif /* __DCERPC_H__ */ diff --git a/source4/librpc/rpc/dcerpc_connect.c b/source4/librpc/rpc/dcerpc_connect.c index 318b8fe36d..b117a98270 100644 --- a/source4/librpc/rpc/dcerpc_connect.c +++ b/source4/librpc/rpc/dcerpc_connect.c @@ -121,6 +121,7 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb_send(TALLOC_CT conn->in.workgroup = lp_workgroup(lp_ctx); lp_smbcli_options(lp_ctx, &conn->in.options); + lp_smbcli_session_options(lp_ctx, &conn->in.session_options); /* * provide proper credentials - user supplied, but allow a @@ -137,7 +138,7 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb_send(TALLOC_CT /* send smb connect request */ conn_req = smb_composite_connect_send(conn, s->io.pipe->conn, - lp_resolve_context(lp_ctx), + s->io.resolve_ctx, s->io.pipe->conn->event_ctx); if (composite_nomem(conn_req, c)) return c; diff --git a/source4/librpc/rpc/dcerpc_secondary.c b/source4/librpc/rpc/dcerpc_secondary.c index abc67ad38b..b4d5d05b61 100644 --- a/source4/librpc/rpc/dcerpc_secondary.c +++ b/source4/librpc/rpc/dcerpc_secondary.c @@ -95,13 +95,14 @@ _PUBLIC_ struct composite_context* dcerpc_secondary_connection_send(struct dcerp s->binding->host, s->binding->target_hostname, atoi(s->binding->endpoint), - lp_resolve_context(global_loadparm)); + dcerpc_resolve_ctx(s->pipe->conn)); composite_continue(c, pipe_tcp_req, continue_open_tcp, c); return c; case NCALRPC: - pipe_ncalrpc_req = dcerpc_pipe_open_pipe_send(s->pipe2->conn, lp_ncalrpc_dir(global_loadparm), - s->binding->endpoint); + case NCACN_UNIX_STREAM: + pipe_ncalrpc_req = dcerpc_pipe_open_unix_stream_send(s->pipe2->conn, + dcerpc_unix_socket_path(s->pipe->conn)); composite_continue(c, pipe_ncalrpc_req, continue_open_pipe, c); return c; diff --git a/source4/librpc/rpc/dcerpc_sock.c b/source4/librpc/rpc/dcerpc_sock.c index 7480beae33..1e2b4cde48 100644 --- a/source4/librpc/rpc/dcerpc_sock.c +++ b/source4/librpc/rpc/dcerpc_sock.c @@ -39,6 +39,9 @@ struct sock_private { struct packet_context *packet; uint32_t pending_reads; + + struct resolve_context *resolve_ctx; + const char *path; /* For ncacn_unix_sock and ncalrpc */ }; @@ -307,6 +310,7 @@ static struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ct struct resolve_context *resolve_context, struct socket_address *server, const char *target_hostname, + const char *full_path, enum dcerpc_transport_t transport) { struct composite_context *c; @@ -334,6 +338,9 @@ static struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ct talloc_steal(s->sock, s->socket_ctx); + s->sock->resolve_ctx = resolve_context; + s->sock->path = talloc_reference(s->sock, full_path); + conn_req = socket_connect_send(s->socket_ctx, NULL, s->server, 0, resolve_context, c->event_ctx); @@ -386,6 +393,7 @@ static void continue_ip_resolve_name(struct composite_context *ctx) sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn, s->resolve_ctx, s->srvaddr, s->target_hostname, + NULL, NCACN_IP_TCP); composite_continue(c, sock_ipv4_req, continue_ipv4_open_socket, c); } @@ -561,6 +569,7 @@ struct composite_context *dcerpc_pipe_open_unix_stream_send(struct dcerpc_connec sock_unix_req = dcerpc_pipe_open_socket_send(c, s->conn, NULL, s->srvaddr, NULL, + s->path, NCALRPC); composite_continue(c, sock_unix_req, continue_unix_open_socket, c); return c; @@ -579,13 +588,6 @@ NTSTATUS dcerpc_pipe_open_unix_stream_recv(struct composite_context *c) } -struct pipe_np_state { - char *full_path; - struct socket_address *srvaddr; - struct dcerpc_connection *conn; -}; - - /* Stage 2 of dcerpc_pipe_open_pipe_send: receive socket open request */ @@ -612,13 +614,13 @@ struct composite_context* dcerpc_pipe_open_pipe_send(struct dcerpc_connection *c struct composite_context *c; struct composite_context *sock_np_req; - struct pipe_np_state *s; + struct pipe_unix_state *s; /* composite context allocation and setup */ c = composite_create(conn, conn->event_ctx); if (c == NULL) return NULL; - s = talloc_zero(c, struct pipe_np_state); + s = talloc_zero(c, struct pipe_unix_state); if (composite_nomem(s, c)) return c; c->private_data = s; @@ -628,15 +630,15 @@ struct composite_context* dcerpc_pipe_open_pipe_send(struct dcerpc_connection *c s->conn = conn; string_replace(canon, '/', '\\'); - s->full_path = talloc_asprintf(canon, "%s/%s", ncalrpc_dir, canon); - if (composite_nomem(s->full_path, c)) return c; + s->path = talloc_asprintf(canon, "%s/%s", ncalrpc_dir, canon); + if (composite_nomem(s->path, c)) return c; /* prepare server address using path and transport name */ - s->srvaddr = socket_address_from_strings(conn, "unix", s->full_path, 0); + s->srvaddr = socket_address_from_strings(conn, "unix", s->path, 0); if (composite_nomem(s->srvaddr, c)) return c; /* send socket open request */ - sock_np_req = dcerpc_pipe_open_socket_send(c, s->conn, NULL, s->srvaddr, NULL, NCALRPC); + sock_np_req = dcerpc_pipe_open_socket_send(c, s->conn, NULL, s->srvaddr, NULL, s->path, NCALRPC); composite_continue(c, sock_np_req, continue_np_open_socket, c); return c; } @@ -662,3 +664,15 @@ NTSTATUS dcerpc_pipe_open_pipe(struct dcerpc_connection *conn, const char *ncalr struct composite_context *c = dcerpc_pipe_open_pipe_send(conn, ncalrpc_dir, identifier); return dcerpc_pipe_open_pipe_recv(c); } + +const char *dcerpc_unix_socket_path(struct dcerpc_connection *p) +{ + struct sock_private *sock = (struct sock_private *)p->transport.private_data; + return sock->path; +} + +struct resolve_context *dcerpc_resolve_ctx(struct dcerpc_connection *p) +{ + struct sock_private *sock = (struct sock_private *)p->transport.private_data; + return sock->resolve_ctx; +} |