diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2004-10-21 21:02:51 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:02:23 -0500 |
commit | 77b691e670b6372f74451f1cf87ccf8a6d7804e2 (patch) | |
tree | 08ae4f607367091ee9335a64481210667d6110b1 /source4/librpc/rpc | |
parent | a8d4d3c9f6e9a6726c9df5794646b2528eab703e (diff) | |
download | samba-77b691e670b6372f74451f1cf87ccf8a6d7804e2.tar.gz samba-77b691e670b6372f74451f1cf87ccf8a6d7804e2.tar.bz2 samba-77b691e670b6372f74451f1cf87ccf8a6d7804e2.zip |
r3124: Add dcerpc_binding_from_tower()
Add tests for dcerpc_binding_from_tower()
(This used to be commit 88c6d34bba1a409127b26f86bd963bfab30a804c)
Diffstat (limited to 'source4/librpc/rpc')
-rw-r--r-- | source4/librpc/rpc/dcerpc_util.c | 136 |
1 files changed, 134 insertions, 2 deletions
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index 3b4f7a7efb..f1b120894e 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -300,9 +300,13 @@ const char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_bindi s = talloc_asprintf(mem_ctx, "%s@", GUID_string(mem_ctx, b->object)); } - s = talloc_asprintf_append(s, "%s:%s", t_name, b->host); + s = talloc_asprintf_append(s, "%s:", t_name); if (!s) return NULL; + if (b->host) { + s = talloc_asprintf_append(s, "%s", b->host); + } + if ((!b->options || !b->options[0]) && !b->flags) { return s; } @@ -438,6 +442,69 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_ return NT_STATUS_OK; } +static const char *floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *floor) +{ + switch (floor->lhs.protocol) { + case EPM_PROTOCOL_TCP: + if (floor->rhs.tcp.port == 0) return NULL; + return talloc_asprintf(mem_ctx, "%d", floor->rhs.tcp.port); + + case EPM_PROTOCOL_UDP: + if (floor->rhs.udp.port == 0) return NULL; + return talloc_asprintf(mem_ctx, "%d", floor->rhs.udp.port); + + case EPM_PROTOCOL_HTTP: + if (floor->rhs.http.port == 0) return NULL; + return talloc_asprintf(mem_ctx, "%d", floor->rhs.http.port); + + case EPM_PROTOCOL_IP: + if (floor->rhs.ip.address == 0) { + return NULL; + } + + { + struct in_addr in; + in.s_addr = htonl(floor->rhs.ip.address); + return talloc_strdup(mem_ctx, inet_ntoa(in)); + } + + case EPM_PROTOCOL_NCACN: + return NULL; + + case EPM_PROTOCOL_NCADG: + return NULL; + + case EPM_PROTOCOL_SMB: + return talloc_strdup(mem_ctx, floor->rhs.smb.unc); + + case EPM_PROTOCOL_PIPE: + return talloc_strdup(mem_ctx, floor->rhs.pipe.path); + + case EPM_PROTOCOL_NETBIOS: + return talloc_strdup(mem_ctx, floor->rhs.netbios.name); + + case EPM_PROTOCOL_NCALRPC: + return NULL; + + case EPM_PROTOCOL_VINES_SPP: + return talloc_asprintf(mem_ctx, "%d", floor->rhs.vines_spp.port); + + case EPM_PROTOCOL_VINES_IPC: + return talloc_asprintf(mem_ctx, "%d", floor->rhs.vines_ipc.port); + + case EPM_PROTOCOL_STREETTALK: + return talloc_strdup(mem_ctx, floor->rhs.streettalk.streettalk); + + case EPM_PROTOCOL_UNIX_DS: + return talloc_strdup(mem_ctx, floor->rhs.unix_ds.path); + + case EPM_PROTOCOL_NULL: + return NULL; + } + + return NULL; +} + static NTSTATUS floor_set_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *floor, const char *data) { switch (floor->lhs.protocol) { @@ -464,12 +531,13 @@ static NTSTATUS floor_set_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *floor, memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; + hints.ai_protocol = PF_INET; if (getaddrinfo(data, NULL, &hints, &res) < 0) { return NT_STATUS_BAD_NETWORK_NAME; } - floor->rhs.ip.address = ntohl(((struct in_addr *)res->ai_addr)->s_addr); + floor->rhs.ip.address = ntohl(((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr); freeaddrinfo(res); } @@ -536,6 +604,67 @@ static NTSTATUS floor_set_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *floor, return NT_STATUS_NOT_SUPPORTED; } +NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower, struct dcerpc_binding *binding) +{ + int i; + + binding->transport = -1; + binding->object = NULL; + binding->options = NULL; + binding->host = NULL; + binding->flags = 0; + + /* 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) { + binding->transport = transports[i].transport; + break; + } + } + + if (binding->transport == -1) { + return NT_STATUS_NOT_SUPPORTED; + } + + if (tower->num_floors < 1) { + return NT_STATUS_OK; + } + + /* Set object uuid */ + if (!uuid_all_zero(&tower->floors[0].lhs.info.uuid.uuid)) { + binding->object = talloc_p(mem_ctx, struct GUID); + *binding->object = tower->floors[0].lhs.info.uuid.uuid; + } + + /* Ignore floor 1, it contains the NDR version info */ + + binding->options = talloc_array_p(mem_ctx, const char *, 2); + + /* Set endpoint */ + if (tower->num_floors >= 3) { + binding->options[0] = floor_get_rhs_data(mem_ctx, &tower->floors[tower->num_floors-1]); + } else { + binding->options[0] = NULL; + } + binding->options[1] = NULL; + + /* Set network address */ + if (tower->num_floors >= 4) { + binding->host = floor_get_rhs_data(mem_ctx, &tower->floors[tower->num_floors-2]); + } + return NT_STATUS_OK; +} NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding *binding, struct epm_tower **tower) { @@ -570,6 +699,8 @@ NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding * (*tower)->floors[0].lhs.protocol = EPM_PROTOCOL_UUID; if (binding->object) { (*tower)->floors[0].lhs.info.uuid.uuid = *binding->object; + } else { + ZERO_STRUCT((*tower)->floors[0].lhs.info.uuid.uuid); } (*tower)->floors[0].lhs.info.uuid.version = 0; @@ -584,6 +715,7 @@ NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding * /* Floor 2 to num_protocols */ for (i = 0; i < num_protocols; i++) { (*tower)->floors[2 + i].lhs.protocol = protseq[i]; + ZERO_STRUCT((*tower)->floors[2 + i].rhs); } /* The top floor contains the endpoint */ |