#define MAX_PROTSEQ 10
-struct dcerpc_binding_pointer_ref;
-
-struct dcerpc_binding_pointer {
- struct dcerpc_binding *b;
- struct dcerpc_binding_pointer_ref *r;
- const char *name;
- const char *type;
- const void *pointer;
-};
-
-struct dcerpc_binding_pointer_ref {
- struct dcerpc_binding_pointer *p;
-};
-
struct dcerpc_binding {
enum dcerpc_transport_t transport;
struct GUID object;
uint32_t flags;
uint32_t assoc_group_id;
char assoc_group_string[11]; /* 0x3456789a + '\0' */
- uint8_t num_pointers;
- struct dcerpc_binding_pointer **pointers;
};
static const struct {
/*
form a binding string from a binding structure
- TODO
*/
-static char *dcerpc_binding_string_ex(TALLOC_CTX *mem_ctx,
- const struct dcerpc_binding *b,
- uint64_t flags)
+_PUBLIC_ char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_binding *b)
{
char *s = talloc_strdup(mem_ctx, "");
char *o = s;
option_section = true;
} else if (b->options) {
option_section = true;
- } else if (b->num_pointers != 0) {
- option_section = true;
} else if (b->flags) {
option_section = true;
}
}
}
- for (i=0; b->num_pointers; i++) {
- struct dcerpc_binding_pointer *p = b->pointers[i];
- char tsbuf[512];
-
- snprintf(tsbuf, sizeof(tsbuf),
- "pointer(%d:%p):%s=(%s *)%p",
- getpid(), p->pointer,
- p->name, p->type, p->pointer);
-
- o = s;
- s = talloc_asprintf_append_buffer(s, ",%s", tsbuf);
- if (s == NULL) {
- talloc_free(o);
- return NULL;
- }
- }
-
o = s;
s = talloc_asprintf_append_buffer(s, "]");
if (s == NULL) {
return s;
}
-/*
- form a binding string from a binding structure
-*/
-_PUBLIC_ char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_binding *b)
-{
- return dcerpc_binding_string_ex(mem_ctx, b, 0);
-}
-
/*
parse a binding string into a dcerpc_binding structure
*/
* value != NULL means add or reset.
*/
- ret = strncmp(name, "pointer(", 8);
- if (ret == 0) {
- return NT_STATUS_INVALID_PARAMETER_MIX;
- }
-
ret = strcmp(name, "transport");
if (ret == 0) {
enum dcerpc_transport_t t = dcerpc_transport_by_name(value);
return NT_STATUS_OK;
}
-static uint8_t dcerpc_binding_find_pointer_idx(const struct dcerpc_binding *b,
- const char *name,
- const char *type)
+_PUBLIC_ void *_dcerpc_binding_get_pointer_option(const struct dcerpc_binding *b,
+ const char *name, const char *type)
{
- uint8_t i;
-
- for (i = 0; i < b->num_pointers; i++) {
- struct dcerpc_binding_pointer *p = b->pointers[i];
- int ret;
-
- ret = strcmp(p->name, name);
- if (ret != 0) {
- continue;
- }
+ char tsbuf[256];
+ const char *vs;
+ char *end = NULL;
+ unsigned long long vl;
+ uintptr_t vp;
- ret = strcmp(p->type, type);
- if (ret != 0) {
- continue;
- }
-
- return i;
+ if (strlen(name) > 100) {
+ return NULL;
}
- return UINT8_MAX;
-}
-
-static int dcerpc_binding_pointer_destructor(struct dcerpc_binding_pointer *p)
-{
- struct dcerpc_binding *b = p->b;
- uint8_t i;
- uint8_t idx = UINT8_MAX;
-
- p->r->p = NULL;
- TALLOC_FREE(p->r);
+ if (strlen(type) > 100) {
+ return NULL;
+ }
- for (i = 0; i < b->num_pointers; i++) {
- if (p != b->pointers[i]) {
- continue;
- }
+ snprintf(tsbuf, sizeof(tsbuf), "%s:pointer:%d:%s", name, getpid(), type);
- idx = i;
- break;
+ vs = dcerpc_binding_get_string_option(b, tsbuf);
+ if (vs == NULL) {
+ return NULL;
}
- if (idx == UINT8_MAX) {
- return 0;
+ errno = 0;
+ vl = strtoull(vs, &end, 16);
+ if (errno != 0) {
+ return NULL;
}
-
- for (i = idx + 1; i < b->num_pointers; i++) {
- b->pointers[i - 1] = b->pointers[i];
+ if (end == NULL) {
+ return NULL;
}
-
- b->num_pointers -= 1;
- b->pointers = talloc_realloc(b, b->pointers,
- struct dcerpc_binding_pointer *,
- b->num_pointers);
-
- return 0;
-}
-
-static int dcerpc_binding_pointer_ref_destructor(struct dcerpc_binding_pointer_ref *r)
-{
- if (r->p == NULL) {
- return 0;
+ if (end[0] != '\0') {
+ return NULL;
}
- r->p->r = NULL;
- TALLOC_FREE(r->p);
- return 0;
-}
-
-_PUBLIC_ void *_dcerpc_binding_get_pointer_option(const struct dcerpc_binding *b,
- const char *name, const char *type)
-{
- struct dcerpc_binding_pointer *p;
- uint8_t idx;
-
- idx = dcerpc_binding_find_pointer_idx(b, name, type);
- if (idx == UINT8_MAX) {
+ vp = vl;
+ if (vp != vl) {
return NULL;
}
- p = b->pointers[idx];
-
- return discard_const(p->pointer);
-}
-
-_PUBLIC_ void dcerpc_binding_clear_pointer_options(struct dcerpc_binding *b,
- const char *name,
- const char *type)
-{
- uint8_t i;
-
- for (i = 0; i < b->num_pointers; ) {
- struct dcerpc_binding_pointer *p = b->pointers[i];
- int ret;
-
- if (name != NULL) {
- ret = strcmp(p->name, name);
- if (ret != 0) {
- i++;
- continue;
- }
- }
-
- if (type != NULL) {
- ret = strcmp(p->type, type);
- if (ret != 0) {
- i++;
- continue;
- }
- }
-
- /*
- * This removes the element at index 'i'
- */
- talloc_free(b->pointers[i]);
- }
+ return (void *)vp;
}
_PUBLIC_ NTSTATUS _dcerpc_binding_set_pointer_option(struct dcerpc_binding *b,
const char *name,
const char *type,
- const void *pointer)
+ const void *vp)
{
- struct dcerpc_binding_pointer *p = NULL;
- uint8_t idx;
+ char tsbuf[256];
+ char vsbuf[20];
+ const char *vs = NULL;
if (strlen(name) > 100) {
return NT_STATUS_INVALID_PARAMETER_MIX;
return NT_STATUS_INVALID_PARAMETER_MIX;
}
- if (pointer != NULL) {
- const void *pv = talloc_check_name(pointer, type);
-
- if (pv == NULL) {
- return NT_STATUS_INVALID_PARAMETER_MIX;
- }
- }
-
- if (b->num_pointers >= INT8_MAX) {
- return NT_STATUS_TOO_MANY_ADDRESSES;
- }
-
- idx = dcerpc_binding_find_pointer_idx(b, name, type);
- if (idx == UINT8_MAX) {
- struct dcerpc_binding_pointer **r = NULL;
-
- if (pointer == NULL) {
- return NT_STATUS_OK;
- }
-
- r = talloc_realloc(b, b->pointers,
- struct dcerpc_binding_pointer *,
- b->num_pointers + 1);
- if (r == NULL) {
- goto nomem;
- }
- b->pointers = r;
-
- idx = b->num_pointers;
- b->pointers[idx] = NULL;
- b->num_pointers += 1;
- }
-
- if (pointer == NULL) {
- talloc_free(b->pointers[idx]);
- return NT_STATUS_OK;
- }
-
- p = talloc_zero(b->pointers, struct dcerpc_binding_pointer);
- if (p == NULL) {
- goto nomem;
- }
- p->b = b;
- p->name = talloc_strdup(p, name);
- if (p->name == NULL) {
- goto nomem;
- }
- p->type = talloc_strdup(p, type);
- if (p->name == NULL) {
- goto nomem;
- }
- p->pointer = pointer;
+ snprintf(tsbuf, sizeof(tsbuf), "%s:pointer:%d:%s", name, getpid(), type);
- p->r = talloc_zero(pointer, struct dcerpc_binding_pointer_ref);
- if (p->r == NULL) {
- goto nomem;
+ if (vp != NULL) {
+ snprintf(vsbuf, sizeof(vsbuf), "%p", vp);
+ vs = vsbuf;
}
- p->r->p = p;
- talloc_set_destructor(p->r, dcerpc_binding_pointer_ref_destructor);
-
- TALLOC_FREE(b->pointers[idx]);
- b->pointers[idx] = p;
- talloc_set_destructor(p, dcerpc_binding_pointer_destructor);
- return NT_STATUS_OK;
-
- nomem:
- TALLOC_FREE(p);
- b->pointers = talloc_realloc(b, b->pointers,
- struct dcerpc_binding_pointer *,
- b->num_pointers);
- return NT_STATUS_NO_MEMORY;
+ return dcerpc_binding_set_string_option(b, tsbuf, vs);
}
_PUBLIC_ uint32_t dcerpc_binding_get_flags(const struct dcerpc_binding *b)
const struct dcerpc_binding *b)
{
struct dcerpc_binding *n;
- size_t i, count;
+ uint32_t count;
n = talloc_zero(mem_ctx, struct dcerpc_binding);
if (n == NULL) {
for (count = 0; b->options && b->options[count]; count++);
if (count > 0) {
+ uint32_t i;
+
n->options = talloc_array(n, const char *, count + 1);
if (n->options == NULL) {
talloc_free(n);
n->options[count] = NULL;
}
- for (i=0; i < b->num_pointers; i++) {
- struct dcerpc_binding_pointer *p = b->pointers[i];
- NTSTATUS status;
-
- status = _dcerpc_binding_set_pointer_option(n,
- p->name,
- p->type,
- p->pointer);
- if (!NT_STATUS_IS_OK(status)) {
- talloc_free(n);
- return NULL;
- }
- }
-
return n;
}