diff options
-rwxr-xr-x | source4/script/tests/test_rpc.sh | 6 | ||||
-rw-r--r-- | source4/torture/rpc/countcalls.c | 106 |
2 files changed, 81 insertions, 31 deletions
diff --git a/source4/script/tests/test_rpc.sh b/source4/script/tests/test_rpc.sh index 0de741a515..5eb223c62a 100755 --- a/source4/script/tests/test_rpc.sh +++ b/source4/script/tests/test_rpc.sh @@ -5,9 +5,9 @@ ncacn_np_tests="RPC-SPOOLSS RPC-SRVSVC RPC-UNIXINFO RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-ECHO RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-MGMT RPC-HANDLES" ncalrpc_tests="RPC-MGMT RPC-UNIXINFO RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-ECHO RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON" ncacn_ip_tcp_tests="RPC-UNIXINFO RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-ECHO RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-MGMT RPC-HANDLES" -slow_ncacn_np_tests="RPC-SAMLOGON RPC-SAMR RPC-SAMR-USERS RPC-SAMR-PASSWORDS" -slow_ncalrpc_tests="RPC-SAMLOGON RPC-SAMR RPC-SAMR-USERS RPC-SAMR-PASSWORDS" -slow_ncacn_ip_tcp_tests="RPC-SAMLOGON RPC-SAMR RPC-SAMR-USERS RPC-SAMR-PASSWORDS" +slow_ncacn_np_tests="RPC-SAMLOGON RPC-SAMR RPC-SAMR-USERS RPC-SAMR-PASSWORDS RPC-COUNTCALLS" +slow_ncalrpc_tests="RPC-SAMLOGON RPC-SAMR RPC-SAMR-USERS RPC-SAMR-PASSWORDS RPC-COUNTCALLS" +slow_ncacn_ip_tcp_tests="RPC-SAMLOGON RPC-SAMR RPC-SAMR-USERS RPC-SAMR-PASSWORDS RPC-COUNTCALLS" if [ $# -lt 4 ]; then cat <<EOF diff --git a/source4/torture/rpc/countcalls.c b/source4/torture/rpc/countcalls.c index f197e80954..80fdfd04c4 100644 --- a/source4/torture/rpc/countcalls.c +++ b/source4/torture/rpc/countcalls.c @@ -4,6 +4,7 @@ count number of calls on an interface Copyright (C) Andrew Tridgell 2003 + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,55 +28,104 @@ #include "torture/rpc/rpc.h" -BOOL torture_rpc_countcalls(struct torture_context *torture) + +BOOL count_calls(TALLOC_CTX *mem_ctx, + const struct dcerpc_interface_table *iface, + BOOL all) { - const struct dcerpc_interface_table *iface; - NTSTATUS status; struct dcerpc_pipe *p; - int i; - const char *iface_name; DATA_BLOB stub_in, stub_out; - - iface_name = lp_parm_string(-1, "countcalls", "interface"); - if (iface_name == NULL) { - printf("You must specify an interface name with countcalls:interface\n"); - return False; - } - - iface = idl_iface_by_name(iface_name); - if (!iface) { - printf("Unknown interface '%s'\n", iface_name); - return False; - } - - status = torture_rpc_connection(NULL, &p, iface); - if (!NT_STATUS_IS_OK(status)) { - printf("Failed to open '%s' - %s\n", iface->name, nt_errstr(status)); + int i; + NTSTATUS status = torture_rpc_connection(mem_ctx, &p, iface); + if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status) + || NT_STATUS_EQUAL(NT_STATUS_NET_WRITE_FAULT, status) + || NT_STATUS_EQUAL(NT_STATUS_PORT_UNREACHABLE, status) + || NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) { + if (all) { + /* Not fatal if looking for all pipes */ + return True; + } else { + printf("Failed to open '%s' to count calls - %s\n", iface->name, nt_errstr(status)); + return False; + } + } else if (!NT_STATUS_IS_OK(status)) { + printf("Failed to open '%s' to count calls - %s\n", iface->name, nt_errstr(status)); return False; } - stub_in = data_blob_talloc(p, NULL, 0); + stub_in = data_blob_talloc(p, mem_ctx, 0); printf("\nScanning pipe '%s'\n", iface->name); - for (i=0;i<5000;i++) { - status = dcerpc_request(p, NULL, i, False, p, &stub_in, &stub_out); + for (i=0;i<500;i++) { + status = dcerpc_request(p, mem_ctx, i, False, p, &stub_in, &stub_out); + if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT) && + p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) { + i--; + break; + } if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT) && - p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) break; + p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) { + i--; + break; + } if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) { + i--; + break; + } + if (NT_STATUS_EQUAL(status, NT_STATUS_PIPE_DISCONNECTED)) { + i--; + break; + } + if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + i--; + break; + } + if (NT_STATUS_EQUAL(status, NT_STATUS_LOGON_FAILURE)) { + i--; break; } } - if (i==5000) { + if (i==500) { talloc_free(p); - printf("no limit on calls!?\n"); + printf("no limit on calls: %s!?\n", nt_errstr(status)); return False; } printf("Found %d calls\n", i); talloc_free(p); - + return True; + +} + +BOOL torture_rpc_countcalls(struct torture_context *torture) +{ + const struct dcerpc_interface_table *iface; + const char *iface_name; + BOOL ret = True; + const struct dcerpc_interface_list *l; + TALLOC_CTX *mem_ctx = talloc_named(torture, 0, "torture_rpc_countcalls context"); + if (!mem_ctx) { + return False; + } + iface_name = lp_parm_string(-1, "countcalls", "interface"); + if (iface_name != NULL) { + iface = idl_iface_by_name(iface_name); + if (!iface) { + printf("Unknown interface '%s'\n", iface_name); + return False; + } + return count_calls(mem_ctx, iface, False); + } + + for (l=librpc_dcerpc_pipes();l;l=l->next) { + TALLOC_CTX *loop_ctx; + loop_ctx = talloc_named(mem_ctx, 0, "torture_rpc_councalls loop context"); + ret &= count_calls(loop_ctx, l->table, True); + talloc_free(loop_ctx); + } + return ret; } |