s4-torture: Comment out the test_InqObject.
[metze/samba/wip.git] / source4 / torture / rpc / epmapper.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for epmapper rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    
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.
11    
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.
16    
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/>.
19 */
20
21 #include "includes.h"
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"
26
27
28 /*
29   display any protocol tower
30  */
31 static void display_tower(struct torture_context *tctx, struct epm_tower *twr)
32 {
33         int i;
34
35         for (i = 0; i < twr->num_floors; i++) {
36                 torture_comment(tctx,
37                                 " %s",
38                                 epm_floor_string(tctx, &twr->floors[i]));
39         }
40         torture_comment(tctx, "\n");
41 }
42
43 static bool test_Map(struct dcerpc_binding_handle *b,
44                      struct torture_context *tctx,
45                      struct epm_twr_t *twr)
46 {
47         NTSTATUS status;
48         struct epm_Map r;
49         struct GUID uuid;
50         struct policy_handle handle;
51         struct ndr_syntax_id syntax;
52         uint32_t num_towers;
53         uint32_t i;
54
55         ZERO_STRUCT(uuid);
56         ZERO_STRUCT(handle);
57
58         r.in.object = &uuid;
59         r.in.map_tower = twr;
60         r.in.entry_handle = &handle;
61         r.out.entry_handle = &handle;
62         r.in.max_towers = 10;
63         r.out.num_towers = &num_towers;
64
65         dcerpc_floor_get_lhs_data(&twr->tower.floors[0], &syntax);
66
67         torture_comment(tctx,
68                         "epm_Map results for '%s':\n",
69                         ndr_interface_name(&syntax.uuid, syntax.if_version));
70
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;
75
76         /* Port address */
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;
80
81         /* Transport */
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";
85
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);
91                         }
92                 }
93         }
94
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;
98
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);
104                         }
105                 }
106         }
107
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;
111
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);
117                         }
118                 }
119         }
120
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 = "";
124
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 = "";
128
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);
134                         }
135                 }
136         }
137
138         /* FIXME: Extend to do other protocols as well (ncacn_unix_stream, ncalrpc) */
139
140         return true;
141 }
142
143 static bool test_Map_simple(struct torture_context *tctx,
144                             struct dcerpc_pipe *p)
145 {
146         NTSTATUS status;
147         struct epm_Lookup r;
148         struct policy_handle entry_handle;
149         uint32_t num_ents = 0;
150         struct dcerpc_binding_handle *h = p->binding_handle;
151
152         ZERO_STRUCT(entry_handle);
153
154         torture_comment(tctx, "Testing epm_Map\n");
155
156         /* get all elements */
157         r.in.inquiry_type = RPC_C_EP_ALL_ELTS;
158         r.in.object = NULL;
159         r.in.interface_id = NULL;
160         r.in.vers_option = RPC_C_VERS_ALL;
161
162         r.in.entry_handle = &entry_handle;
163         r.in.max_ents = 10;
164
165         r.out.entry_handle = &entry_handle;
166         r.out.num_ents = &num_ents;
167
168         do {
169                 int i;
170
171                 status = dcerpc_epm_Lookup_r(h, tctx, &r);
172                 if (!NT_STATUS_IS_OK(status) ||
173                     r.out.result != EPMAPPER_STATUS_OK) {
174                         break;
175                 }
176
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);
180                         }
181                 }
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));
186
187         torture_assert_ntstatus_ok(tctx, status, "epm_Map_simple failed");
188
189         torture_assert(tctx,
190                        policy_handle_empty(&entry_handle),
191                        "epm_Map_simple failed - The policy handle should be emtpy.");
192
193         return true;
194 }
195
196 static bool test_LookupHandleFree(struct torture_context *tctx,
197                                   struct dcerpc_binding_handle *h,
198                                   struct policy_handle *entry_handle) {
199         NTSTATUS status;
200         struct epm_LookupHandleFree r;
201
202         if (torture_setting_bool(tctx, "samba4", false)) {
203                 torture_skip(tctx, "Skip Insert test against Samba4");
204         }
205
206         if (policy_handle_empty(entry_handle)) {
207                 torture_comment(tctx,
208                                 "epm_LookupHandleFree failed - empty policy_handle\n");
209                 return false;
210         }
211
212         r.in.entry_handle = entry_handle;
213         r.out.entry_handle = entry_handle;
214
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",
219                                 nt_errstr(status));
220                 return false;
221         }
222
223         if (r.out.result != EPMAPPER_STATUS_OK) {
224                 torture_comment(tctx,
225                                 "epm_LookupHandleFree failed - internal error: "
226                                 "0x%.4x\n",
227                                 r.out.result);
228                 return false;
229         }
230
231         return true;
232 }
233
234 static bool test_Lookup_simple(struct torture_context *tctx,
235                                struct dcerpc_pipe *p)
236 {
237         NTSTATUS status;
238         struct epm_Lookup r;
239         struct policy_handle entry_handle;
240         uint32_t num_ents = 0;
241         struct dcerpc_binding_handle *h = p->binding_handle;
242
243         ZERO_STRUCT(entry_handle);
244
245         torture_comment(tctx, "Testing epm_Lookup\n");
246
247         /* get all elements */
248         r.in.inquiry_type = RPC_C_EP_ALL_ELTS;
249         r.in.object = NULL;
250         r.in.interface_id = NULL;
251         r.in.vers_option = RPC_C_VERS_ALL;
252
253         r.in.entry_handle = &entry_handle;
254         r.in.max_ents = 10;
255
256         r.out.entry_handle = &entry_handle;
257         r.out.num_ents = &num_ents;
258
259         do {
260                 int i;
261
262                 status = dcerpc_epm_Lookup_r(h, tctx, &r);
263                 if (!NT_STATUS_IS_OK(status) ||
264                     r.out.result != EPMAPPER_STATUS_OK) {
265                         break;
266                 }
267
268                 torture_comment(tctx,
269                                 "epm_Lookup returned %d events, entry_handle: %s\n",
270                                 *r.out.num_ents,
271                                 GUID_string(tctx, &entry_handle.uuid));
272
273                 for (i = 0; i < *r.out.num_ents; i++) {
274                         torture_comment(tctx,
275                                         "\n  Found '%s'\n",
276                                         r.out.entries[i].annotation);
277
278                         display_tower(tctx, &r.out.entries[i].tower->tower);
279                 }
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));
284
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");
287
288         torture_assert(tctx,
289                        policy_handle_empty(&entry_handle),
290                        "epm_Lookup failed - The policy handle should be emtpy.");
291
292         return true;
293 }
294
295 /*
296  * This test starts a epm_Lookup request, but doesn't finish the
297  * call terminates the search. So it will call epm_LookupHandleFree.
298  */
299 static bool test_Lookup_terminate_search(struct torture_context *tctx,
300                                          struct dcerpc_pipe *p)
301 {
302         bool ok;
303         NTSTATUS status;
304         struct epm_Lookup r;
305         struct policy_handle entry_handle;
306         uint32_t i, num_ents = 0;
307         struct dcerpc_binding_handle *h = p->binding_handle;
308
309         ZERO_STRUCT(entry_handle);
310
311         torture_comment(tctx, "Testing epm_Lookup and epm_LookupHandleFree\n");
312
313         /* get all elements */
314         r.in.inquiry_type = RPC_C_EP_ALL_ELTS;
315         r.in.object = NULL;
316         r.in.interface_id = NULL;
317         r.in.vers_option = RPC_C_VERS_ALL;
318
319         r.in.entry_handle = &entry_handle;
320         r.in.max_ents = 2;
321
322         r.out.entry_handle = &entry_handle;
323         r.out.num_ents = &num_ents;
324
325         status = dcerpc_epm_Lookup_r(h, tctx, &r);
326
327         torture_assert_ntstatus_ok(tctx, status, "epm_Lookup failed");
328         torture_assert(tctx, r.out.result == EPMAPPER_STATUS_OK, "epm_Lookup failed");
329
330         torture_comment(tctx,
331                         "epm_Lookup returned %d events, entry_handle: %s\n",
332                         *r.out.num_ents,
333                         GUID_string(tctx, &entry_handle.uuid));
334
335         for (i = 0; i < *r.out.num_ents; i++) {
336                 torture_comment(tctx,
337                                 "\n  Found '%s'\n",
338                                 r.out.entries[i].annotation);
339         }
340
341         ok = test_LookupHandleFree(tctx,
342                                    h,
343                                    &entry_handle);
344         if (!ok) {
345                 return false;
346         }
347
348         return true;
349 }
350
351 static bool test_Delete(struct torture_context *tctx,
352                         struct dcerpc_binding_handle *h,
353                         struct epm_entry_t *entries)
354 {
355         NTSTATUS status;
356         struct epm_Delete r;
357
358         r.in.num_ents = 1;
359         r.in.entries = entries;
360
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",
365                                 nt_errstr(status));
366                 return false;
367         }
368
369         if (r.out.result != EPMAPPER_STATUS_OK) {
370                 torture_comment(tctx,
371                                 "epm_Delete failed - internal error: 0x%.4x\n",
372                                 r.out.result);
373                 return false;
374         }
375
376         return true;
377 }
378
379 static bool test_Insert_noreplace(struct torture_context *tctx,
380                                   struct dcerpc_pipe *p)
381 {
382         bool ok;
383         NTSTATUS status;
384         struct epm_Insert r;
385         struct dcerpc_binding *b;
386         struct dcerpc_binding_handle *h = p->binding_handle;
387
388         torture_comment(tctx, "Testing epm_Insert(noreplace) and epm_Delete\n");
389
390         if (torture_setting_bool(tctx, "samba4", false)) {
391                 torture_skip(tctx, "Skip Insert test against Samba4");
392         }
393
394         r.in.num_ents = 1;
395         r.in.entries = talloc_array(tctx, struct epm_entry_t, 1);
396
397         ZERO_STRUCT(r.in.entries[0].object);
398         r.in.entries[0].annotation = "smbtorture endpoint";
399
400         status = dcerpc_parse_binding(tctx, "ncalrpc:[SMBTORTURE]", &b);
401         torture_assert_ntstatus_ok(tctx,
402                                    status,
403                                    "Unable to generate dcerpc_binding struct");
404
405         r.in.entries[0].tower = talloc(tctx, struct epm_twr_t);
406
407         status = dcerpc_binding_build_tower(tctx,
408                                             b,
409                                             &r.in.entries[0].tower->tower);
410         torture_assert_ntstatus_ok(tctx,
411                                    status,
412                                    "Unable to build tower from binding struct");
413         r.in.replace = 0;
414
415         status = dcerpc_epm_Insert_r(h, tctx, &r);
416         torture_assert_ntstatus_ok(tctx, status, "epm_Insert failed");
417
418         torture_assert(tctx, r.out.result == 0, "epm_Insert failed");
419
420         ok = test_Delete(tctx, h, r.in.entries);
421         if (!ok) {
422                 return false;
423         }
424
425         return true;
426 }
427
428 #if 0
429 /*
430  * The MS-RPCE documentation states that this function isn't implemented and
431  * SHOULD NOT be called by a client.
432  */
433 static bool test_InqObject(struct torture_context *tctx, struct dcerpc_pipe *p)
434 {
435         NTSTATUS status;
436         struct epm_InqObject r;
437         struct dcerpc_binding_handle *b = p->binding_handle;
438
439         r.in.epm_object = talloc(tctx, struct GUID);
440         *r.in.epm_object = ndr_table_epmapper.syntax_id.uuid;
441
442         status = dcerpc_epm_InqObject_r(b, tctx, &r);
443         torture_assert_ntstatus_ok(tctx, status, "InqObject failed");
444
445         return true;
446 }
447 #endif
448
449 struct torture_suite *torture_rpc_epmapper(TALLOC_CTX *mem_ctx)
450 {
451         struct torture_suite *suite = torture_suite_create(mem_ctx, "epmapper");
452         struct torture_rpc_tcase *tcase;
453
454         tcase = torture_suite_add_rpc_iface_tcase(suite,
455                                                   "epmapper",
456                                                   &ndr_table_epmapper);
457
458         torture_rpc_tcase_add_test(tcase,
459                                    "Insert_noreplace",
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,
465                                    "Lookup_simple",
466                                    test_Lookup_simple);
467         torture_rpc_tcase_add_test(tcase,
468                                    "Map_simple",
469                                    test_Map_simple);
470
471
472         return suite;
473 }
474
475 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */