2 Unix SMB/CIFS implementation.
6 Copyright (C) Andrew Tridgell 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "torture/torture.h"
25 #include "librpc/gen_ndr/ndr_mgmt_c.h"
26 #include "librpc/rpc/dcerpc_table.h"
27 #include "torture/rpc/rpc.h"
30 work out how many calls there are for an interface
32 static BOOL
test_num_calls(const struct dcerpc_interface_table
*iface
,
34 struct dcerpc_syntax_id
*id
)
36 struct dcerpc_pipe
*p
;
39 DATA_BLOB stub_in
, stub_out
;
41 struct dcerpc_interface_table tbl
;
43 /* FIXME: This should be fixed when torture_rpc_connection
44 * takes a dcerpc_syntax_id */
45 tbl
.name
= iface
->name
;
47 tbl
.if_version
= id
->if_version
;
49 status
= torture_rpc_connection(mem_ctx
, &p
, iface
);
50 if (!NT_STATUS_IS_OK(status
)) {
51 char *uuid_str
= GUID_string(mem_ctx
, &id
->uuid
);
52 printf("Failed to connect to '%s' on '%s' - %s\n",
53 uuid_str
, iface
->name
, nt_errstr(status
));
54 talloc_free(uuid_str
);
59 stub_in
= data_blob(NULL
, 1000);
60 memset(stub_in
.data
, 0xFF, stub_in
.length
);
63 status
= dcerpc_request(p
, NULL
, False
, i
, mem_ctx
, &stub_in
, &stub_out
);
64 if (!NT_STATUS_IS_OK(status
) &&
65 p
->last_fault_code
== DCERPC_FAULT_OP_RNG_ERROR
) {
69 if (!NT_STATUS_IS_OK(status
) && p
->last_fault_code
== 5) {
70 printf("\tpipe disconnected at %d\n", i
);
74 if (!NT_STATUS_IS_OK(status
) && p
->last_fault_code
== 0x80010111) {
75 printf("\terr 0x80010111 at %d\n", i
);
80 printf("\t%d calls available\n", i
);
81 idl_calls
= idl_num_calls(&id
->uuid
, id
->if_version
);
82 if (idl_calls
== -1) {
83 printf("\tinterface not known in local IDL\n");
84 } else if (i
!= idl_calls
) {
85 printf("\tWARNING: local IDL defines %u calls\n", idl_calls
);
87 printf("\tOK: matches num_calls in local IDL\n");
96 ask the server what interface IDs are available on this endpoint
98 static BOOL
test_inq_if_ids(struct dcerpc_pipe
*p
,
100 const struct dcerpc_interface_table
*iface
)
103 struct mgmt_inq_if_ids r
;
106 status
= dcerpc_mgmt_inq_if_ids(p
, mem_ctx
, &r
);
107 if (!NT_STATUS_IS_OK(status
)) {
108 printf("inq_if_ids failed - %s\n", nt_errstr(status
));
112 if (!W_ERROR_IS_OK(r
.out
.result
)) {
113 printf("inq_if_ids gave error code %s\n", win_errstr(r
.out
.result
));
117 if (!r
.out
.if_id_vector
) {
118 printf("inq_if_ids gave NULL if_id_vector\n");
122 for (i
=0;i
<r
.out
.if_id_vector
->count
;i
++) {
124 struct dcerpc_syntax_id
*id
= r
.out
.if_id_vector
->if_id
[i
].id
;
127 uuid
= GUID_string(mem_ctx
, &id
->uuid
),
129 printf("\n\tuuid %s version 0x%08x '%s'\n",
131 id
->if_version
, idl_pipe_name(&id
->uuid
, id
->if_version
));
133 test_num_calls(iface
, mem_ctx
, id
);
140 BOOL
torture_rpc_scanner(void)
143 struct dcerpc_pipe
*p
;
144 TALLOC_CTX
*mem_ctx
, *loop_ctx
;
146 const struct dcerpc_interface_list
*l
;
147 const char *binding
= lp_parm_string(-1, "torture", "binding");
148 struct dcerpc_binding
*b
;
150 mem_ctx
= talloc_init("torture_rpc_scanner");
153 talloc_free(mem_ctx
);
154 printf("You must supply a ncacn binding string\n");
158 status
= dcerpc_parse_binding(mem_ctx
, binding
, &b
);
159 if (!NT_STATUS_IS_OK(status
)) {
160 talloc_free(mem_ctx
);
161 printf("Failed to parse binding '%s'\n", binding
);
165 for (l
=librpc_dcerpc_pipes();l
;l
=l
->next
) {
166 loop_ctx
= talloc_named(mem_ctx
, 0, "torture_rpc_scanner loop context");
167 /* some interfaces are not mappable */
168 if (l
->table
->num_calls
== 0 ||
169 strcmp(l
->table
->name
, "mgmt") == 0) {
170 talloc_free(loop_ctx
);
174 printf("\nTesting pipe '%s'\n", l
->table
->name
);
176 if (b
->transport
== NCACN_IP_TCP
) {
177 status
= dcerpc_epm_map_binding(mem_ctx
, b
, l
->table
, NULL
);
178 if (!NT_STATUS_IS_OK(status
)) {
179 printf("Failed to map port for uuid %s\n",
180 GUID_string(loop_ctx
, &l
->table
->uuid
));
181 talloc_free(loop_ctx
);
185 b
->endpoint
= talloc_strdup(b
, l
->table
->name
);
188 lp_set_cmdline("torture:binding", dcerpc_binding_string(mem_ctx
, b
));
190 status
= torture_rpc_connection(loop_ctx
, &p
, &dcerpc_table_mgmt
);
191 if (!NT_STATUS_IS_OK(status
)) {
192 talloc_free(loop_ctx
);
197 if (!test_inq_if_ids(p
, mem_ctx
, l
->table
)) {