From 656c04da48a3885d14ff4939d5225b8aa037f0d5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 18 Oct 2004 11:43:26 +0000 Subject: r3032: Somewhat stricter syntax for binding strings: [] is now mandatory : after the hostname is no longer allowed examples of allowed binding strings: ncacn_np:myhost[samr] ncacn_ip_tcp:10.0.0.1[1045] ncacn_ip_tcp:2001:7b8:37b:1:210:dcff:fecb:a9e3[1024,sign,seal] ncacn_np:myhost ncacn_ip_tcp:192.168.4.2 308FB580-1EB2-11CA-923B-08002B1075A7@ncacn_ip_tcp:192.168.4.2 308FB580-1EB2-11CA-923B-08002B1075A7@ncacn_ip_tcp:192.168.4.2[,print] Note that the last two lines are not recognized by smbtorture as a binding string yet. dcerpc_parse_binding() does accept them though. (This used to be commit c15862e778507287bddef7967383d4b5d22eaee9) --- source4/librpc/rpc/dcerpc.h | 1 + source4/librpc/rpc/dcerpc_util.c | 99 +++++++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 43 deletions(-) (limited to 'source4/librpc') diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 011d70ec0c..3dd8143511 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -142,6 +142,7 @@ struct dcerpc_interface_table { /* this describes a binding to a particular transport/pipe */ struct dcerpc_binding { enum dcerpc_transport_t transport; + struct GUID *object; const char *host; const char **options; uint32_t flags; diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index 5f3d911d15..747f8d1277 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -273,7 +273,11 @@ const char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_bindi return NULL; } - s = talloc_asprintf(mem_ctx, "%s:%s:[", t_name, b->host); + if (b->object) { + s = talloc_asprintf(mem_ctx, "%s@", GUID_string(mem_ctx, b->object)); + } + + s = talloc_asprintf_append(s, "%s:%s[", t_name, b->host); if (!s) return NULL; /* this is a *really* inefficent way of dealing with strings, @@ -302,81 +306,90 @@ const char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_bindi */ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding *b) { - char *part1, *part2, *part3; + char *options, *type; char *p; int i, j, comma_count; - p = strchr(s, ':'); - if (!p) { - return NT_STATUS_INVALID_PARAMETER; - } - part1 = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s)); - if (!part1) { - return NT_STATUS_NO_MEMORY; + p = strchr(s, '@'); + + if (p && PTR_DIFF(p, s) == 36) { /* 36 is the length of a UUID */ + NTSTATUS status; + + b->object = talloc_p(mem_ctx, struct GUID); + + status = GUID_from_string(s, b->object); + + if (NT_STATUS_IS_ERR(status)) { + DEBUG(0, ("Failed parsing UUID\n")); + return status; + } + + s = p + 1; + } else { + b->object = NULL; } - s = p+1; p = strchr(s, ':'); if (!p) { - p = strchr(s, '['); - if (p) { - part2 = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s)); - part3 = talloc_strdup(mem_ctx, p+1); - if (part3[strlen(part3)-1] != ']') { - return NT_STATUS_INVALID_PARAMETER; - } - part3[strlen(part3)-1] = 0; - } else { - part2 = talloc_strdup(mem_ctx, s); - part3 = NULL; - } - } else { - part2 = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s)); - part3 = talloc_strdup(mem_ctx, p+1); + return NT_STATUS_INVALID_PARAMETER; } - if (!part2) { + + type = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s)); + if (!type) { return NT_STATUS_NO_MEMORY; } for (i=0;itransport = ncacn_transports[i].transport; break; } } if (i==ARRAY_SIZE(ncacn_transports)) { - DEBUG(0,("Unknown dcerpc transport '%s'\n", part1)); + DEBUG(0,("Unknown dcerpc transport '%s'\n", type)); return NT_STATUS_INVALID_PARAMETER; } + + s = p+1; + + p = strchr(s, '['); + if (p) { + b->host = talloc_strndup(mem_ctx, 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(mem_ctx, s); + options = NULL; + } + + if (!b->host) { + return NT_STATUS_NO_MEMORY; + } - b->host = part2; b->options = NULL; b->flags = 0; - if (!part3) { + if (!options) { return NT_STATUS_OK; } - /* the [] brackets are optional */ - if (*part3 == '[' && part3[strlen(part3)-1] == ']') { - part3++; - part3[strlen(part3)-1] = 0; - } - - comma_count = count_chars(part3, ','); + comma_count = count_chars(options, ','); b->options = talloc_array_p(mem_ctx, const char *, comma_count+2); if (!b->options) { return NT_STATUS_NO_MEMORY; } - for (i=0; (p = strchr(part3, ',')); i++) { - b->options[i] = talloc_strndup(mem_ctx, part3, PTR_DIFF(p, part3)); + for (i=0; (p = strchr(options, ',')); i++) { + b->options[i] = talloc_strndup(mem_ctx, options, PTR_DIFF(p, options)); if (!b->options[i]) { return NT_STATUS_NO_MEMORY; } - part3 = p+1; + options = p+1; } - b->options[i] = part3; + b->options[i] = options; b->options[i+1] = NULL; /* some options are pre-parsed for convenience */ @@ -413,7 +426,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p, struct smbcli_state *cli; const char *pipe_name; - if (!binding->options || !binding->options[0]) { + if (!binding->options || !binding->options[0] || !strlen(binding->options[0])) { const struct dcerpc_interface_table *table = idl_iface_by_uuid(pipe_uuid); if (!table) { DEBUG(0,("Unknown interface endpoint '%s'\n", pipe_uuid)); @@ -501,7 +514,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p, NTSTATUS status; uint32_t port = 0; - if (binding->options && binding->options[0]) { + if (binding->options && binding->options[0] && strlen(binding->options[0])) { port = atoi(binding->options[0]); } -- cgit