summaryrefslogtreecommitdiffstats
path: root/librpc
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
commit017338a180c87e938af5215720bf59610f4ddbb1 (patch)
treebb26b97f92077f6e1bd32cb2077c22754155b3df /librpc
parent05b54f5a3376735a84cc1c6f1427e3045aa8024d (diff)
downloadsamba-017338a180c87e938af5215720bf59610f4ddbb1.tar.gz
samba-017338a180c87e938af5215720bf59610f4ddbb1.tar.xz
samba-017338a180c87e938af5215720bf59610f4ddbb1.zip
librpc/rpc: set more things via dcerpc_binding_set_string_option()
Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Guenther Deschner <gd@samba.org>
Diffstat (limited to 'librpc')
-rw-r--r--librpc/rpc/binding.c121
-rw-r--r--librpc/rpc/rpc_common.h1
2 files changed, 122 insertions, 0 deletions
diff --git a/librpc/rpc/binding.c b/librpc/rpc/binding.c
index 15c1bca3f28..8c17b226a1e 100644
--- a/librpc/rpc/binding.c
+++ b/librpc/rpc/binding.c
@@ -447,9 +447,35 @@ _PUBLIC_ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struc
_PUBLIC_ const char *dcerpc_binding_get_string_option(const struct dcerpc_binding *b,
const char *name)
{
+ struct {
+ const char *name;
+ const char *value;
+#define _SPECIAL(x) { .name = #x, .value = b->x, }
+ } specials[] = {
+ { .name = "object", .value = b->object_string, },
+ _SPECIAL(host),
+ _SPECIAL(endpoint),
+ _SPECIAL(target_hostname),
+ _SPECIAL(target_principal),
+#undef _SPECIAL
+ };
size_t i;
int ret;
+ ret = strcmp(name, "transport");
+ if (ret == 0) {
+ return derpc_transport_string_by_transport(b->transport);
+ }
+
+ for (i=0; i < ARRAY_SIZE(specials); i++) {
+ ret = strcmp(specials[i].name, name);
+ if (ret != 0) {
+ continue;
+ }
+
+ return specials[i].value;
+ }
+
if (b->options == NULL) {
return NULL;
}
@@ -501,6 +527,17 @@ _PUBLIC_ NTSTATUS dcerpc_binding_set_string_option(struct dcerpc_binding *b,
const char *name,
const char *value)
{
+ struct {
+ const char *name;
+ const char **ptr;
+#define _SPECIAL(x) { .name = #x, .ptr = &b->x, }
+ } specials[] = {
+ _SPECIAL(host),
+ _SPECIAL(endpoint),
+ _SPECIAL(target_hostname),
+ _SPECIAL(target_principal),
+#undef _SPECIAL
+ };
const char *opt = NULL;
char *tmp;
size_t name_len = strlen(name);
@@ -512,6 +549,83 @@ _PUBLIC_ NTSTATUS dcerpc_binding_set_string_option(struct dcerpc_binding *b,
* value != NULL means add or reset.
*/
+ ret = strcmp(name, "transport");
+ if (ret == 0) {
+ enum dcerpc_transport_t t = dcerpc_transport_by_name(value);
+
+ if (t == NCA_UNKNOWN && value != NULL) {
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+ }
+
+ b->transport = t;
+ return NT_STATUS_OK;
+ }
+
+ ret = strcmp(name, "object");
+ if (ret == 0) {
+ DATA_BLOB blob;
+ NTSTATUS status;
+ struct GUID uuid;
+
+ tmp = discard_const_p(char, b->object_string);
+
+ if (value == NULL) {
+ talloc_free(tmp);
+ b->object_string = NULL;
+ ZERO_STRUCT(b->object);
+ return NT_STATUS_OK;
+ }
+
+ blob = data_blob_string_const(value);
+ if (blob.length != 36) {
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+ }
+
+ status = GUID_from_data_blob(&blob, &uuid);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ b->object_string = GUID_string(b, &uuid);
+ if (b->object_string == NULL) {
+ b->object_string = tmp;
+ return NT_STATUS_NO_MEMORY;
+ }
+ talloc_free(tmp);
+
+ ZERO_STRUCT(b->object);
+ b->object.uuid = uuid;
+ return NT_STATUS_OK;
+ }
+
+ for (i=0; i < ARRAY_SIZE(specials); i++) {
+ ret = strcmp(specials[i].name, name);
+ if (ret != 0) {
+ continue;
+ }
+
+ tmp = discard_const_p(char, *specials[i].ptr);
+
+ if (value == NULL) {
+ talloc_free(tmp);
+ *specials[i].ptr = NULL;
+ return NT_STATUS_OK;
+ }
+
+ if (value[0] == '\0') {
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+ }
+
+ *specials[i].ptr = talloc_strdup(b, value);
+ if (*specials[i].ptr == NULL) {
+ *specials[i].ptr = tmp;
+ return NT_STATUS_NO_MEMORY;
+ }
+ talloc_free(tmp);
+
+ return NT_STATUS_OK;
+ }
+
for (i=0; b->options && b->options[i]; i++) {
const char *o = b->options[i];
@@ -959,6 +1073,13 @@ _PUBLIC_ struct dcerpc_binding *dcerpc_binding_dup(TALLOC_CTX *mem_ctx,
n->flags = b->flags;
n->assoc_group_id = b->assoc_group_id;
+ if (b->object_string != NULL) {
+ n->object_string = talloc_strdup(n, b->object_string);
+ if (n->object_string == NULL) {
+ talloc_free(n);
+ return NULL;
+ }
+ }
if (b->host != NULL) {
n->host = talloc_strdup(n, b->host);
if (n->host == NULL) {
diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h
index 0fd9933d230..a7a081c1b1c 100644
--- a/librpc/rpc/rpc_common.h
+++ b/librpc/rpc/rpc_common.h
@@ -43,6 +43,7 @@ enum dcerpc_transport_t {
struct dcerpc_binding {
enum dcerpc_transport_t transport;
struct ndr_syntax_id object;
+ const char *object_string;
const char *host;
const char *target_hostname;
const char *target_principal;