From 9f5a59eb536b3dcf98f90259877d55c58d8c7f9a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 23 Jan 2014 12:13:14 +0100 Subject: librpc/rpc: simplify dcerpc_parse_binding() We now make a copy of the given string, so that we can mark chunks inline. Then we call dcerpc_binding_set_string_option() in order to set the elements. Signed-off-by: Stefan Metzmacher Reviewed-by: Guenther Deschner --- librpc/rpc/binding.c | 192 +++++++++++++++++++++++---------------------------- 1 file changed, 88 insertions(+), 104 deletions(-) (limited to 'librpc/rpc') diff --git a/librpc/rpc/binding.c b/librpc/rpc/binding.c index 2d9014e524b..c2798e6c1ff 100644 --- a/librpc/rpc/binding.c +++ b/librpc/rpc/binding.c @@ -290,156 +290,140 @@ _PUBLIC_ char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_bi /* 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) +_PUBLIC_ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *_s, struct dcerpc_binding **b_out) { + char *_t; struct dcerpc_binding *b; - char *options; + char *s; + char *options = NULL; char *p; - int i, j, comma_count; + size_t i; + NTSTATUS status; b = talloc_zero(mem_ctx, struct dcerpc_binding); if (!b) { return NT_STATUS_NO_MEMORY; } + _t = talloc_strdup(b, _s); + if (_t == NULL) { + talloc_free(b); + return NT_STATUS_NO_MEMORY; + } + + s = _t; + + p = strchr(s, '['); + if (p) { + *p = '\0'; + options = p + 1; + if (options[strlen(options)-1] != ']') { + talloc_free(b); + return NT_STATUS_INVALID_PARAMETER_MIX; + } + options[strlen(options)-1] = 0; + } + p = strchr(s, '@'); if (p && PTR_DIFF(p, s) == 36) { /* 36 is the length of a UUID */ - NTSTATUS status; - DATA_BLOB blob = data_blob(s, 36); - status = GUID_from_data_blob(&blob, &b->object.uuid); + *p = '\0'; - if (NT_STATUS_IS_ERR(status)) { - DEBUG(0, ("Failed parsing UUID\n")); + status = dcerpc_binding_set_string_option(b, "object", s); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(b); 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; - } + *p = '\0'; - for (i=0;itransport = transports[i].transport; - break; - } - } - - if (i==ARRAY_SIZE(transports)) { - DEBUG(0,("Unknown dcerpc transport '%s'\n", type)); - return NT_STATUS_INVALID_PARAMETER; + status = dcerpc_binding_set_string_option(b, "transport", s); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(b); + return status; } - talloc_free(type); - - s = p+1; + 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; + if (strlen(s) > 0) { + status = dcerpc_binding_set_string_option(b, "host", s); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(b); + return status; } - 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; + b->target_hostname = talloc_strdup(b, b->host); + if (b->target_hostname == NULL) { + talloc_free(b); + return NT_STATUS_NO_MEMORY; + } } - 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; options != NULL; i++) { + const char *name = options; + const char *value = NULL; - for (i=0; (p = strchr(options, ',')); i++) { - b->options[i] = talloc_strndup(b->options, - options, - PTR_DIFF(p, options)); - if (!b->options[i]) { - return NT_STATUS_NO_MEMORY; + p = strchr(options, ','); + if (p != NULL) { + *p = '\0'; + options = p+1; + } else { + options = NULL; } - options = p+1; - } - b->options[i] = talloc_strdup(b->options, options); - if (!b->options[i]) { - return NT_STATUS_NO_MEMORY; - } - b->options[i+1] = NULL; - /* some options are pre-parsed for convenience */ - for (i=0;b->options[i];i++) { - for (j=0;joptions[i], opt_len) == 0) { - char *o = discard_const_p(char, b->options[i]); - int k; - char c = b->options[i][opt_len]; + p = strchr(name, '='); + if (p != NULL) { + *p = '\0'; + value = p + 1; + } - if (c != 0) { - continue; + if (value == NULL) { + /* + * If it's not a key=value pair + * it might be a ncacn_option + * or if it's the first option + * it's the endpoint. + */ + const struct ncacn_option *no = NULL; + + value = name; + + no = ncacn_option_by_name(name); + if (no == NULL) { + if (i > 0) { + /* + * we don't allow unknown options + */ + return NT_STATUS_INVALID_PARAMETER_MIX; } - b->flags |= ncacn_options[j].flag; - talloc_free(o); - for (k=i;b->options[k];k++) { - b->options[k] = b->options[k+1]; + /* + * This is the endpoint + */ + name = "endpoint"; + if (strlen(value) == 0) { + value = NULL; } - i--; - break; } } - } - if (b->options[0] && strchr(b->options[0], '=') == NULL) { - /* Endpoint is first option */ - b->endpoint = talloc_steal(b, b->options[0]); - if (strlen(b->endpoint) == 0) { - char *e = discard_const_p(char, b->endpoint); - talloc_free(e); - b->endpoint = NULL; - } - - for (i=0;b->options[i];i++) { - b->options[i] = b->options[i+1]; + status = dcerpc_binding_set_string_option(b, name, value); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(b); + return status; } } - if (b->options[0] == NULL) { - TALLOC_FREE(b->options); - } - + talloc_free(_t); *b_out = b; return NT_STATUS_OK; } -- cgit