summaryrefslogtreecommitdiffstats
path: root/librpc/rpc
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2014-01-23 12:13:14 +0100
committerGünther Deschner <gd@samba.org>2014-02-13 11:54:14 +0100
commit9f5a59eb536b3dcf98f90259877d55c58d8c7f9a (patch)
tree5e5a237c66b7b993d68a96456b784d309a0643bb /librpc/rpc
parented8adc292047112d41fc2de0e77f76fcbdc7daac (diff)
downloadsamba-9f5a59eb536b3dcf98f90259877d55c58d8c7f9a.tar.gz
samba-9f5a59eb536b3dcf98f90259877d55c58d8c7f9a.tar.xz
samba-9f5a59eb536b3dcf98f90259877d55c58d8c7f9a.zip
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 <metze@samba.org> Reviewed-by: Guenther Deschner <gd@samba.org>
Diffstat (limited to 'librpc/rpc')
-rw-r--r--librpc/rpc/binding.c192
1 files changed, 88 insertions, 104 deletions
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;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;
+ 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;j<ARRAY_SIZE(ncacn_options);j++) {
- size_t opt_len = strlen(ncacn_options[j].name);
- if (strncasecmp(ncacn_options[j].name, b->options[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;
}