summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/librpc/rpc/dcerpc_util.c136
-rw-r--r--source4/torture/local/binding_string.c76
2 files changed, 193 insertions, 19 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 */
diff --git a/source4/torture/local/binding_string.c b/source4/torture/local/binding_string.c
index 26fe67dd5c..7ec9a30d24 100644
--- a/source4/torture/local/binding_string.c
+++ b/source4/torture/local/binding_string.c
@@ -22,11 +22,10 @@
#include "includes.h"
-static BOOL test_BindingString(const char *binding)
+static BOOL test_BindingString(TALLOC_CTX *mem_ctx, const char *binding)
{
- TALLOC_CTX *mem_ctx = talloc_init("test_BindingString");
- struct dcerpc_binding b;
- const char *s;
+ struct dcerpc_binding b, b2;
+ const char *s, *s2;
struct epm_tower *tower;
NTSTATUS status;
@@ -55,27 +54,70 @@ static BOOL test_BindingString(const char *binding)
return False;
}
- /* FIXME: Convert back to binding and then back to string and compare */
+ /* Convert back to binding and then back to string and compare */
+
+ status = dcerpc_binding_from_tower(mem_ctx, tower, &b2);
+ if (NT_STATUS_IS_ERR(status)) {
+ DEBUG(0, ("Error generating binding from tower for original binding '%s': %s\n", binding, nt_errstr(status)));
+ return False;
+ }
+
+ /* Compare to a stripped down version of the binding string because
+ * the protocol tower doesn't contain the extra option data */
+ if (b.options && b.options[0]) {
+ b.options[1] = NULL;
+ }
+
+ b.flags = 0;
+
+ s = dcerpc_binding_string(mem_ctx, &b);
+ if (!s) {
+ DEBUG(0, ("Error converting binding back to string for (stripped down) '%s'\n", binding));
+ return False;
+ }
+
+
+ s2 = dcerpc_binding_string(mem_ctx, &b2);
+ if (!s) {
+ DEBUG(0, ("Error converting binding back to string for '%s'\n", binding));
+ return False;
+ }
+
+ if (strcasecmp(s, s2) != 0) {
+ DEBUG(0, ("Mismatch while comparing original and from protocol tower generated binding strings: '%s' <> '%s'\n", s, s2));
+ return False;
+ }
return True;
}
+static const char *test_strings[] = {
+ "ncacn_np:",
+ "ncalrpc:",
+ "ncalrpc:[Security=Sane]",
+ "ncacn_np:[rpcecho]",
+ "ncacn_np:127.0.0.1[rpcecho]",
+ "ncacn_ip_tcp:127.0.0.1",
+ "ncacn_np:localhost[rpcecho]",
+ "ncacn_np:[/pipe/rpcecho]",
+ "ncacn_np:localhost[/pipe/rpcecho,sign,seal]",
+ "ncacn_np:[,sign]",
+ "ncadg_ip_udp:",
+ "308FB580-1EB2-11CA-923B-08002B1075A7@ncacn_np:localhost",
+ "308FB580-1EB2-11CA-923B-08002B1075A7@ncacn_ip_tcp:127.0.0.1",
+};
+
BOOL torture_local_binding_string(int dummy)
{
BOOL ret = True;
+ TALLOC_CTX *mem_ctx = talloc_init("test_BindingString");
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(test_strings); i++) {
+ ret &= test_BindingString(mem_ctx, test_strings[i]);
+ }
- ret &= test_BindingString("ncacn_np:");
- ret &= test_BindingString("ncalrpc:");
- ret &= test_BindingString("ncalrpc:");
- ret &= test_BindingString("ncacn_np:[rpcecho]");
- ret &= test_BindingString("ncacn_np:127.0.0.1[rpcecho]");
- ret &= test_BindingString("ncacn_np:localhost[rpcecho]");
- ret &= test_BindingString("ncacn_np:[/pipe/rpcecho]");
- ret &= test_BindingString("ncacn_np:localhost[/pipe/rpcecho,sign,seal]");
- ret &= test_BindingString("ncacn_np:[,sign]");
- ret &= test_BindingString("ncadg_ip_udp:");
- ret &= test_BindingString("308FB580-1EB2-11CA-923B-08002B1075A7@ncacn_np:localhost");
- ret &= test_BindingString("308FB580-1EB2-11CA-923B-08002B1075A7@ncacn_ip_tcp:localhost");
+ talloc_destroy(mem_ctx);
return ret;
}