summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsource4/script/tests/test_rpc.sh6
-rw-r--r--source4/torture/rpc/countcalls.c106
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;
}