2 Unix SMB/CIFS implementation.
3 test suite for epmapper rpc operations
5 Copyright (C) Andrew Tridgell 2003
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "librpc/gen_ndr/ndr_epmapper_c.h"
23 #include "librpc/ndr/ndr_table.h"
24 #include "librpc/rpc/dcerpc_proto.h"
25 #include "torture/rpc/torture_rpc.h"
29 display any protocol tower
31 static void display_tower(struct torture_context *tctx, struct epm_tower *twr)
35 for (i = 0; i < twr->num_floors; i++) {
38 epm_floor_string(tctx, &twr->floors[i]));
40 torture_comment(tctx, "\n");
43 static bool test_Map(struct dcerpc_binding_handle *b,
44 struct torture_context *tctx,
45 struct epm_twr_t *twr)
50 struct policy_handle handle;
51 struct ndr_syntax_id syntax;
60 r.in.entry_handle = &handle;
61 r.out.entry_handle = &handle;
63 r.out.num_towers = &num_towers;
65 dcerpc_floor_get_lhs_data(&twr->tower.floors[0], &syntax);
68 "epm_Map results for '%s':\n",
69 ndr_interface_name(&syntax.uuid, syntax.if_version));
71 /* RPC protocol identifier */
72 twr->tower.floors[2].lhs.protocol = EPM_PROTOCOL_NCACN;
73 twr->tower.floors[2].lhs.lhs_data = data_blob(NULL, 0);
74 twr->tower.floors[2].rhs.ncacn.minor_version = 0;
77 twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_TCP;
78 twr->tower.floors[3].lhs.lhs_data = data_blob(NULL, 0);
79 twr->tower.floors[3].rhs.tcp.port = 0;
82 twr->tower.floors[4].lhs.protocol = EPM_PROTOCOL_IP;
83 twr->tower.floors[4].lhs.lhs_data = data_blob(NULL, 0);
84 twr->tower.floors[4].rhs.ip.ipaddr = "0.0.0.0";
86 status = dcerpc_epm_Map_r(b, tctx, &r);
87 if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
88 for (i=0;i<*r.out.num_towers;i++) {
89 if (r.out.towers[i].twr) {
90 display_tower(tctx, &r.out.towers[i].twr->tower);
95 twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_HTTP;
96 twr->tower.floors[3].lhs.lhs_data = data_blob(NULL, 0);
97 twr->tower.floors[3].rhs.http.port = 0;
99 status = dcerpc_epm_Map_r(b, tctx, &r);
100 if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
101 for (i=0;i<*r.out.num_towers;i++) {
102 if (r.out.towers[i].twr) {
103 display_tower(tctx, &r.out.towers[i].twr->tower);
108 twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_UDP;
109 twr->tower.floors[3].lhs.lhs_data = data_blob(NULL, 0);
110 twr->tower.floors[3].rhs.http.port = 0;
112 status = dcerpc_epm_Map_r(b, tctx, &r);
113 if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
114 for (i=0;i<*r.out.num_towers;i++) {
115 if (r.out.towers[i].twr) {
116 display_tower(tctx, &r.out.towers[i].twr->tower);
121 twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_SMB;
122 twr->tower.floors[3].lhs.lhs_data = data_blob(NULL, 0);
123 twr->tower.floors[3].rhs.smb.unc = "";
125 twr->tower.floors[4].lhs.protocol = EPM_PROTOCOL_NETBIOS;
126 twr->tower.floors[4].lhs.lhs_data = data_blob(NULL, 0);
127 twr->tower.floors[4].rhs.netbios.name = "";
129 status = dcerpc_epm_Map_r(b, tctx, &r);
130 if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
131 for (i = 0; i < *r.out.num_towers; i++) {
132 if (r.out.towers[i].twr) {
133 display_tower(tctx, &r.out.towers[i].twr->tower);
138 /* FIXME: Extend to do other protocols as well (ncacn_unix_stream, ncalrpc) */
143 static bool test_Map_simple(struct torture_context *tctx,
144 struct dcerpc_pipe *p)
148 struct policy_handle entry_handle;
149 uint32_t num_ents = 0;
150 struct dcerpc_binding_handle *h = p->binding_handle;
152 ZERO_STRUCT(entry_handle);
154 torture_comment(tctx, "Testing epm_Map\n");
156 /* get all elements */
157 r.in.inquiry_type = RPC_C_EP_ALL_ELTS;
159 r.in.interface_id = NULL;
160 r.in.vers_option = RPC_C_VERS_ALL;
162 r.in.entry_handle = &entry_handle;
165 r.out.entry_handle = &entry_handle;
166 r.out.num_ents = &num_ents;
171 status = dcerpc_epm_Lookup_r(h, tctx, &r);
172 if (!NT_STATUS_IS_OK(status) ||
173 r.out.result != EPMAPPER_STATUS_OK) {
177 for (i = 0; i < *r.out.num_ents; i++) {
178 if (r.out.entries[i].tower->tower.num_floors == 5) {
179 test_Map(h, tctx, r.out.entries[i].tower);
182 } while (NT_STATUS_IS_OK(status) &&
183 r.out.result == EPMAPPER_STATUS_OK &&
184 *r.out.num_ents == r.in.max_ents &&
185 !policy_handle_empty(&entry_handle));
187 torture_assert_ntstatus_ok(tctx, status, "epm_Map_simple failed");
190 policy_handle_empty(&entry_handle),
191 "epm_Map_simple failed - The policy handle should be emtpy.");
196 static bool test_LookupHandleFree(struct torture_context *tctx,
197 struct dcerpc_binding_handle *h,
198 struct policy_handle *entry_handle) {
200 struct epm_LookupHandleFree r;
202 if (torture_setting_bool(tctx, "samba4", false)) {
203 torture_skip(tctx, "Skip Insert test against Samba4");
206 if (policy_handle_empty(entry_handle)) {
207 torture_comment(tctx,
208 "epm_LookupHandleFree failed - empty policy_handle\n");
212 r.in.entry_handle = entry_handle;
213 r.out.entry_handle = entry_handle;
215 status = dcerpc_epm_LookupHandleFree_r(h, tctx, &r);
216 if (NT_STATUS_IS_ERR(status)) {
217 torture_comment(tctx,
218 "epm_LookupHandleFree failed - %s\n",
223 if (r.out.result != EPMAPPER_STATUS_OK) {
224 torture_comment(tctx,
225 "epm_LookupHandleFree failed - internal error: "
234 static bool test_Lookup_simple(struct torture_context *tctx,
235 struct dcerpc_pipe *p)
239 struct policy_handle entry_handle;
240 uint32_t num_ents = 0;
241 struct dcerpc_binding_handle *h = p->binding_handle;
243 ZERO_STRUCT(entry_handle);
245 torture_comment(tctx, "Testing epm_Lookup\n");
247 /* get all elements */
248 r.in.inquiry_type = RPC_C_EP_ALL_ELTS;
250 r.in.interface_id = NULL;
251 r.in.vers_option = RPC_C_VERS_ALL;
253 r.in.entry_handle = &entry_handle;
256 r.out.entry_handle = &entry_handle;
257 r.out.num_ents = &num_ents;
262 status = dcerpc_epm_Lookup_r(h, tctx, &r);
263 if (!NT_STATUS_IS_OK(status) ||
264 r.out.result != EPMAPPER_STATUS_OK) {
268 torture_comment(tctx,
269 "epm_Lookup returned %d events, entry_handle: %s\n",
271 GUID_string(tctx, &entry_handle.uuid));
273 for (i = 0; i < *r.out.num_ents; i++) {
274 torture_comment(tctx,
276 r.out.entries[i].annotation);
278 display_tower(tctx, &r.out.entries[i].tower->tower);
280 } while (NT_STATUS_IS_OK(status) &&
281 r.out.result == EPMAPPER_STATUS_OK &&
282 *r.out.num_ents == r.in.max_ents &&
283 !policy_handle_empty(&entry_handle));
285 torture_assert_ntstatus_ok(tctx, status, "epm_Lookup failed");
286 torture_assert(tctx, r.out.result == EPMAPPER_STATUS_NO_MORE_ENTRIES, "epm_Lookup failed");
289 policy_handle_empty(&entry_handle),
290 "epm_Lookup failed - The policy handle should be emtpy.");
296 * This test starts a epm_Lookup request, but doesn't finish the
297 * call terminates the search. So it will call epm_LookupHandleFree.
299 static bool test_Lookup_terminate_search(struct torture_context *tctx,
300 struct dcerpc_pipe *p)
305 struct policy_handle entry_handle;
306 uint32_t i, num_ents = 0;
307 struct dcerpc_binding_handle *h = p->binding_handle;
309 ZERO_STRUCT(entry_handle);
311 torture_comment(tctx, "Testing epm_Lookup and epm_LookupHandleFree\n");
313 /* get all elements */
314 r.in.inquiry_type = RPC_C_EP_ALL_ELTS;
316 r.in.interface_id = NULL;
317 r.in.vers_option = RPC_C_VERS_ALL;
319 r.in.entry_handle = &entry_handle;
322 r.out.entry_handle = &entry_handle;
323 r.out.num_ents = &num_ents;
325 status = dcerpc_epm_Lookup_r(h, tctx, &r);
327 torture_assert_ntstatus_ok(tctx, status, "epm_Lookup failed");
328 torture_assert(tctx, r.out.result == EPMAPPER_STATUS_OK, "epm_Lookup failed");
330 torture_comment(tctx,
331 "epm_Lookup returned %d events, entry_handle: %s\n",
333 GUID_string(tctx, &entry_handle.uuid));
335 for (i = 0; i < *r.out.num_ents; i++) {
336 torture_comment(tctx,
338 r.out.entries[i].annotation);
341 ok = test_LookupHandleFree(tctx,
351 static bool test_Delete(struct torture_context *tctx,
352 struct dcerpc_binding_handle *h,
353 struct epm_entry_t *entries)
359 r.in.entries = entries;
361 status = dcerpc_epm_Delete_r(h, tctx, &r);
362 if (NT_STATUS_IS_ERR(status)) {
363 torture_comment(tctx,
364 "epm_Delete failed - %s\n",
369 if (r.out.result != EPMAPPER_STATUS_OK) {
370 torture_comment(tctx,
371 "epm_Delete failed - internal error: 0x%.4x\n",
379 static bool test_Insert_noreplace(struct torture_context *tctx,
380 struct dcerpc_pipe *p)
385 struct dcerpc_binding *b;
386 struct dcerpc_binding_handle *h = p->binding_handle;
388 torture_comment(tctx, "Testing epm_Insert(noreplace) and epm_Delete\n");
390 if (torture_setting_bool(tctx, "samba4", false)) {
391 torture_skip(tctx, "Skip Insert test against Samba4");
395 r.in.entries = talloc_array(tctx, struct epm_entry_t, 1);
397 ZERO_STRUCT(r.in.entries[0].object);
398 r.in.entries[0].annotation = "smbtorture endpoint";
400 status = dcerpc_parse_binding(tctx, "ncalrpc:[SMBTORTURE]", &b);
401 torture_assert_ntstatus_ok(tctx,
403 "Unable to generate dcerpc_binding struct");
405 r.in.entries[0].tower = talloc(tctx, struct epm_twr_t);
407 status = dcerpc_binding_build_tower(tctx,
409 &r.in.entries[0].tower->tower);
410 torture_assert_ntstatus_ok(tctx,
412 "Unable to build tower from binding struct");
415 status = dcerpc_epm_Insert_r(h, tctx, &r);
416 torture_assert_ntstatus_ok(tctx, status, "epm_Insert failed");
418 torture_assert(tctx, r.out.result == 0, "epm_Insert failed");
420 ok = test_Delete(tctx, h, r.in.entries);
430 * The MS-RPCE documentation states that this function isn't implemented and
431 * SHOULD NOT be called by a client.
433 static bool test_InqObject(struct torture_context *tctx, struct dcerpc_pipe *p)
436 struct epm_InqObject r;
437 struct dcerpc_binding_handle *b = p->binding_handle;
439 r.in.epm_object = talloc(tctx, struct GUID);
440 *r.in.epm_object = ndr_table_epmapper.syntax_id.uuid;
442 status = dcerpc_epm_InqObject_r(b, tctx, &r);
443 torture_assert_ntstatus_ok(tctx, status, "InqObject failed");
449 struct torture_suite *torture_rpc_epmapper(TALLOC_CTX *mem_ctx)
451 struct torture_suite *suite = torture_suite_create(mem_ctx, "epmapper");
452 struct torture_rpc_tcase *tcase;
454 tcase = torture_suite_add_rpc_iface_tcase(suite,
456 &ndr_table_epmapper);
458 torture_rpc_tcase_add_test(tcase,
460 test_Insert_noreplace);
461 torture_rpc_tcase_add_test(tcase,
462 "Lookup_terminate_search",
463 test_Lookup_terminate_search);
464 torture_rpc_tcase_add_test(tcase,
467 torture_rpc_tcase_add_test(tcase,
475 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */