summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/librpc/rpc/dcerpc_util.c99
-rw-r--r--source4/torture/rpc/mgmt.c44
-rw-r--r--source4/torture/rpc/scanner.c43
3 files changed, 136 insertions, 50 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);
diff --git a/source4/torture/rpc/mgmt.c b/source4/torture/rpc/mgmt.c
index 3a50732c7e..b41e24976f 100644
--- a/source4/torture/rpc/mgmt.c
+++ b/source4/torture/rpc/mgmt.c
@@ -173,14 +173,29 @@ BOOL torture_rpc_mgmt(int dummy)
TALLOC_CTX *mem_ctx;
BOOL ret = True;
int i;
- char *host = lp_parm_string(-1, "torture", "host");
- uint32 port;
+ char *binding = lp_parm_string(-1, "torture", "binding");
+ struct dcerpc_binding b;
mem_ctx = talloc_init("torture_rpc_mgmt");
- for (i=0;dcerpc_pipes[i];i++) {
- char *transport = lp_parm_string(-1, "torture", "transport");
+ if (!binding) {
+ printf("You must supply a ncacn binding string\n");
+ return False;
+ }
+
+ status = dcerpc_parse_binding(mem_ctx, binding, &b);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("Failed to parse binding '%s'\n", binding);
+ return False;
+ }
+ b.options = talloc_array_p(mem_ctx, const char *, 2);
+ if (!b.options) {
+ return False;
+ }
+
+
+ for (i=0;dcerpc_pipes[i];i++) {
/* some interfaces are not mappable */
if (dcerpc_pipes[i]->num_calls == 0 ||
strcmp(dcerpc_pipes[i]->name, "mgmt") == 0) {
@@ -189,20 +204,23 @@ BOOL torture_rpc_mgmt(int dummy)
printf("\nTesting pipe '%s'\n", dcerpc_pipes[i]->name);
- /* on TCP we need to find the right endpoint */
- if (strcasecmp(transport, "ncacn_ip_tcp") == 0) {
- status = dcerpc_epm_map_tcp_port(host,
- dcerpc_pipes[i]->uuid,
- dcerpc_pipes[i]->if_version,
+ if (b.transport == NCACN_IP_TCP) {
+ uint32 port;
+ status = dcerpc_epm_map_tcp_port(b.host,
+ dcerpc_pipes[i]->uuid,
+ dcerpc_pipes[i]->if_version,
&port);
if (!NT_STATUS_IS_OK(status)) {
- ret = False;
+ printf("Failed to map port for uuid %s\n", dcerpc_pipes[i]->uuid);
continue;
}
-
- lp_set_cmdline("torture:share",
- talloc_asprintf(mem_ctx, "%u", port));
+ b.options[0] = talloc_asprintf(mem_ctx, "%u", port);
+ } else {
+ b.options[0] = dcerpc_pipes[i]->name;
}
+ b.options[1] = NULL;
+
+ lp_set_cmdline("torture:binding", dcerpc_binding_string(mem_ctx, &b));
status = torture_rpc_connection(&p,
dcerpc_pipes[i]->name,
diff --git a/source4/torture/rpc/scanner.c b/source4/torture/rpc/scanner.c
index 99c047bf2e..944bb4372d 100644
--- a/source4/torture/rpc/scanner.c
+++ b/source4/torture/rpc/scanner.c
@@ -134,14 +134,28 @@ BOOL torture_rpc_scanner(int dummy)
TALLOC_CTX *mem_ctx;
BOOL ret = True;
int i;
- char *host = lp_parm_string(-1, "torture", "host");
- uint32 port;
+ char *binding = lp_parm_string(-1, "torture", "binding");
+ struct dcerpc_binding b;
mem_ctx = talloc_init("torture_rpc_scanner");
- for (i=0;dcerpc_pipes[i];i++) {
- char *transport = lp_parm_string(-1, "torture", "transport");
+ if (!binding) {
+ printf("You must supply a ncacn binding string\n");
+ return False;
+ }
+
+ status = dcerpc_parse_binding(mem_ctx, binding, &b);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("Failed to parse binding '%s'\n", binding);
+ return False;
+ }
+ b.options = talloc_array_p(mem_ctx, const char *, 2);
+ if (!b.options) {
+ return False;
+ }
+
+ for (i=0;dcerpc_pipes[i];i++) {
/* some interfaces are not mappable */
if (dcerpc_pipes[i]->num_calls == 0 ||
strcmp(dcerpc_pipes[i]->name, "mgmt") == 0) {
@@ -150,20 +164,23 @@ BOOL torture_rpc_scanner(int dummy)
printf("\nTesting pipe '%s'\n", dcerpc_pipes[i]->name);
- /* on TCP we need to find the right endpoint */
- if (strcasecmp(transport, "ncacn_ip_tcp") == 0) {
- status = dcerpc_epm_map_tcp_port(host,
- dcerpc_pipes[i]->uuid,
- dcerpc_pipes[i]->if_version,
+ if (b.transport == NCACN_IP_TCP) {
+ uint32 port;
+ status = dcerpc_epm_map_tcp_port(b.host,
+ dcerpc_pipes[i]->uuid,
+ dcerpc_pipes[i]->if_version,
&port);
if (!NT_STATUS_IS_OK(status)) {
- ret = False;
+ printf("Failed to map port for uuid %s\n", dcerpc_pipes[i]->uuid);
continue;
}
-
- lp_set_cmdline("torture:share",
- talloc_asprintf(mem_ctx, "%u", port));
+ b.options[0] = talloc_asprintf(mem_ctx, "%u", port);
+ } else {
+ b.options[0] = dcerpc_pipes[i]->name;
}
+ b.options[1] = NULL;
+
+ lp_set_cmdline("torture:binding", dcerpc_binding_string(mem_ctx, &b));
status = torture_rpc_connection(&p,
dcerpc_pipes[i]->name,