diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/librpc/rpc/dcerpc_util.c | 99 | ||||
-rw-r--r-- | source4/torture/rpc/mgmt.c | 44 | ||||
-rw-r--r-- | source4/torture/rpc/scanner.c | 43 |
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, |