summaryrefslogtreecommitdiff
path: root/source4/librpc
diff options
context:
space:
mode:
Diffstat (limited to 'source4/librpc')
-rw-r--r--source4/librpc/rpc/dcerpc_util.c99
1 files changed, 75 insertions, 24 deletions
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
index f1b719e64a..bc10f4e92d 100644
--- a/source4/librpc/rpc/dcerpc_util.c
+++ b/source4/librpc/rpc/dcerpc_util.c
@@ -262,6 +262,66 @@ NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
}
+static const struct {
+ const char *name;
+ enum dcerpc_transport_t transport;
+} ncacn_transports[] = {
+ {"ncacn_np", NCACN_NP},
+ {"ncacn_ip_tcp", NCACN_IP_TCP}
+};
+
+static const struct {
+ const char *name;
+ uint32 flag;
+} ncacn_options[] = {
+ {"sign", DCERPC_SIGN},
+ {"seal", DCERPC_SEAL},
+ {"validate", DCERPC_DEBUG_VALIDATE_BOTH},
+ {"bigendian", DCERPC_PUSH_BIGENDIAN}
+};
+
+/*
+ form a binding string from a binding structure
+*/
+const char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_binding *b)
+{
+ char *s = NULL;
+ int i;
+ const char *t_name=NULL;
+
+ for (i=0;i<ARRAY_SIZE(ncacn_transports);i++) {
+ if (ncacn_transports[i].transport == b->transport) {
+ t_name = ncacn_transports[i].name;
+ }
+ }
+ if (!t_name) {
+ return NULL;
+ }
+
+ s = talloc_asprintf(mem_ctx, "%s:%s:[", t_name, b->host);
+ if (!s) return NULL;
+
+ /* this is a *really* inefficent way of dealing with strings,
+ but this is rarely called and the strings are always short,
+ so I don't care */
+ for (i=0;b->options[i];i++) {
+ s = talloc_asprintf(mem_ctx, "%s%s,", s, b->options[i]);
+ if (!s) return NULL;
+ }
+ for (i=0;i<ARRAY_SIZE(ncacn_options);i++) {
+ if (b->flags & ncacn_options[i].flag) {
+ s = talloc_asprintf(mem_ctx, "%s%s,", s, ncacn_options[i].name);
+ if (!s) return NULL;
+ }
+ }
+ if (s[strlen(s)-1] == ',') {
+ s[strlen(s)-1] = 0;
+ }
+ s = talloc_asprintf(mem_ctx, "%s]", s);
+
+ return s;
+}
+
/*
parse a binding string into a dcerpc_binding structure
*/
@@ -270,22 +330,6 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_
char *part1, *part2, *part3;
char *p;
int i, j, comma_count;
- const struct {
- const char *name;
- enum dcerpc_transport_t transport;
- } transports[] = {
- {"ncacn_np", NCACN_NP},
- {"ncacn_ip_tcp", NCACN_IP_TCP}
- };
- const struct {
- const char *name;
- uint32 flag;
- } options[] = {
- {"sign", DCERPC_SIGN},
- {"seal", DCERPC_SEAL},
- {"validate", DCERPC_DEBUG_VALIDATE_BOTH},
- {"bigendian", DCERPC_PUSH_BIGENDIAN}
- };
p = strchr(s, ':');
if (!p) {
@@ -319,14 +363,14 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_
return NT_STATUS_NO_MEMORY;
}
- for (i=0;i<ARRAY_SIZE(transports);i++) {
- if (strcasecmp(part1, transports[i].name) == 0) {
- b->transport = transports[i].transport;
+ for (i=0;i<ARRAY_SIZE(ncacn_transports);i++) {
+ if (strcasecmp(part1, ncacn_transports[i].name) == 0) {
+ b->transport = ncacn_transports[i].transport;
break;
}
}
- if (i==ARRAY_SIZE(transports)) {
- DEBUG(1,("Unknown dcerpc transport '%s'\n", part1));
+ if (i==ARRAY_SIZE(ncacn_transports)) {
+ DEBUG(0,("Unknown dcerpc transport '%s'\n", part1));
return NT_STATUS_INVALID_PARAMETER;
}
@@ -362,10 +406,10 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_
/* some options are pre-parsed for convenience */
for (i=0;b->options[i];i++) {
- for (j=0;j<ARRAY_SIZE(options);j++) {
- if (strcasecmp(options[j].name, b->options[i]) == 0) {
+ for (j=0;j<ARRAY_SIZE(ncacn_options);j++) {
+ if (strcasecmp(ncacn_options[j].name, b->options[i]) == 0) {
int k;
- b->flags |= options[j].flag;
+ b->flags |= ncacn_options[j].flag;
for (k=i;b->options[k];k++) {
b->options[k] = b->options[k+1];
}
@@ -399,6 +443,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
DEBUG(0,("Unknown interface endpoint '%s'\n", pipe_uuid));
return NT_STATUS_INVALID_PARAMETER;
}
+ /* only try the first endpoint for now */
pipe_name = table->endpoints->names[0];
} else {
pipe_name = binding->options[0];
@@ -417,11 +462,13 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
username, username[0]?domain:"",
password, 0, &retry);
if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to connect to %s - %s\n", binding->host, nt_errstr(status)));
return status;
}
status = dcerpc_pipe_open_smb(p, cli->tree, pipe_name);
if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to open pipe %s - %s\n", pipe_name, nt_errstr(status)));
cli_tdis(cli);
cli_shutdown(cli);
return status;
@@ -439,6 +486,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
}
if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
dcerpc_pipe_close(*p);
return status;
}
@@ -498,6 +546,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p,
}
if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
dcerpc_pipe_close(*p);
return status;
}
@@ -557,6 +606,8 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **p,
return status;
}
+ DEBUG(3,("Using binding %s\n", dcerpc_binding_string(mem_ctx, &b)));
+
status = dcerpc_pipe_connect_b(p, &b, pipe_uuid, pipe_version, domain, username, password);
talloc_destroy(mem_ctx);