s4:torture: add a rpc.samba3.smb2-reauth2 test
[kai/samba.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 #include "lib/util/util_net.h"
27 #include "librpc/rpc/rpc_common.h"
28
29 /*
30   display any protocol tower
31  */
32 static void display_tower(struct torture_context *tctx, struct epm_tower *twr)
33 {
34         int i;
35
36         for (i = 0; i < twr->num_floors; i++) {
37                 torture_comment(tctx,
38                                 " %s",
39                                 epm_floor_string(tctx, &twr->floors[i]));
40         }
41         torture_comment(tctx, "\n");
42 }
43
44 static bool test_Insert(struct torture_context *tctx,
45                         struct dcerpc_binding_handle *h,
46                         struct ndr_syntax_id object,
47                         const char *annotation,
48                         struct dcerpc_binding *b)
49 {
50         struct epm_Insert r;
51         NTSTATUS status;
52
53         r.in.num_ents = 1;
54         r.in.entries = talloc_array(tctx, struct epm_entry_t, 1);
55
56         if (torture_setting_bool(tctx, "samba4", false)) {
57                 torture_skip(tctx, "Skip Insert test against Samba4");
58         }
59
60         /* FIXME zero */
61         ZERO_STRUCT(r.in.entries[0].object);
62         r.in.entries[0].annotation = annotation;
63
64         r.in.entries[0].tower = talloc(tctx, struct epm_twr_t);
65
66         status = dcerpc_binding_build_tower(tctx,
67                                             b,
68                                             &r.in.entries[0].tower->tower);
69
70         torture_assert_ntstatus_ok(tctx,
71                                    status,
72                                    "Unable to build tower from binding struct");
73         r.in.replace = 0;
74
75         /* shoot! */
76         status = dcerpc_epm_Insert_r(h, tctx, &r);
77
78         if (NT_STATUS_IS_ERR(status)) {
79                 torture_comment(tctx,
80                                 "epm_Insert failed - %s\n",
81                                 nt_errstr(status));
82                 return false;
83         }
84
85         if (r.out.result != EPMAPPER_STATUS_OK) {
86                 torture_comment(tctx,
87                                 "epm_Insert failed - internal error: 0x%.4x\n",
88                                 r.out.result);
89                 return false;
90         }
91
92         return true;
93 }
94
95 static bool test_Delete(struct torture_context *tctx,
96                         struct dcerpc_binding_handle *h,
97                         const char *annotation,
98                         struct dcerpc_binding *b)
99 {
100         NTSTATUS status;
101         struct epm_Delete r;
102
103         r.in.num_ents = 1;
104         r.in.entries = talloc_array(tctx, struct epm_entry_t, 1);
105
106         ZERO_STRUCT(r.in.entries[0].object);
107         r.in.entries[0].annotation = annotation;
108
109         r.in.entries[0].tower = talloc(tctx, struct epm_twr_t);
110
111         status = dcerpc_binding_build_tower(tctx,
112                                             b,
113                                             &r.in.entries[0].tower->tower);
114
115         torture_assert_ntstatus_ok(tctx,
116                                    status,
117                                    "Unable to build tower from binding struct");
118         r.in.num_ents = 1;
119
120         status = dcerpc_epm_Delete_r(h, tctx, &r);
121         if (NT_STATUS_IS_ERR(status)) {
122                 torture_comment(tctx,
123                                 "epm_Delete failed - %s\n",
124                                 nt_errstr(status));
125                 return false;
126         }
127
128         if (r.out.result != EPMAPPER_STATUS_OK) {
129                 torture_comment(tctx,
130                                 "epm_Delete failed - internal error: 0x%.4x\n",
131                                 r.out.result);
132                 return false;
133         }
134
135         return true;
136 }
137
138 static bool test_Map_tcpip(struct torture_context *tctx,
139                            struct dcerpc_binding_handle *h,
140                            struct ndr_syntax_id map_syntax)
141 {
142         struct epm_Map r;
143         struct GUID uuid;
144         struct policy_handle entry_handle;
145         struct ndr_syntax_id syntax;
146         struct dcerpc_binding map_binding;
147         struct epm_twr_t map_tower;
148         struct epm_twr_p_t towers[20];
149         struct epm_tower t;
150         uint32_t num_towers;
151         uint32_t port;
152         uint32_t i;
153         long int p;
154         const char *tmp;
155         const char *ip;
156         char *ptr;
157         NTSTATUS status;
158
159         torture_comment(tctx, "Testing epm_Map\n");
160
161         ZERO_STRUCT(uuid);
162         ZERO_STRUCT(entry_handle);
163
164         r.in.object = &uuid;
165         r.in.map_tower = &map_tower;
166         r.in.entry_handle = &entry_handle;
167         r.out.entry_handle = &entry_handle;
168         r.in.max_towers = 10;
169         r.out.towers = towers;
170         r.out.num_towers = &num_towers;
171
172         /* Create map tower */
173         map_binding.transport = NCACN_IP_TCP;
174         map_binding.object = map_syntax;
175         map_binding.host = "0.0.0.0";
176         map_binding.endpoint = "135";
177
178         status = dcerpc_binding_build_tower(tctx, &map_binding,
179                                             &map_tower.tower);
180         torture_assert_ntstatus_ok(tctx, status,
181                                    "epm_Map_tcpip failed: can't create map_tower");
182
183         torture_comment(tctx,
184                         "epm_Map request for '%s':\n",
185                         ndr_interface_name(&map_syntax.uuid, map_syntax.if_version));
186         display_tower(tctx, &r.in.map_tower->tower);
187
188         status = dcerpc_epm_Map_r(h, tctx, &r);
189
190         torture_assert_ntstatus_ok(tctx, status, "epm_Map_simple failed");
191         torture_assert(tctx, r.out.result == EPMAPPER_STATUS_OK,
192                        "epm_Map_tcpip failed: result is not EPMAPPER_STATUS_OK");
193
194         /* Check the result */
195         t = r.out.towers[0].twr->tower;
196
197         /* Check if we got the correct RPC interface identifier */
198         dcerpc_floor_get_lhs_data(&t.floors[0], &syntax);
199         torture_assert(tctx, ndr_syntax_id_equal(&syntax, &map_syntax),
200                        "epm_Map_tcpip failed: Interface identifier mismatch");
201
202         torture_comment(tctx,
203                         "epm_Map_tcpip response for '%s':\n",
204                         ndr_interface_name(&syntax.uuid, syntax.if_version));
205
206         dcerpc_floor_get_lhs_data(&t.floors[1], &syntax);
207         torture_assert(tctx, ndr_syntax_id_equal(&syntax, &ndr_transfer_syntax_ndr),
208                        "epm_Map_tcpip failed: floor 2 is not NDR encoded");
209
210         torture_assert(tctx, t.floors[2].lhs.protocol == EPM_PROTOCOL_NCACN,
211                        "epm_Map_tcpip failed: floor 3 is not NCACN_IP_TCP");
212
213         tmp = dcerpc_floor_get_rhs_data(tctx, &t.floors[3]);
214         p = strtol(tmp, &ptr, 10);
215         port = p & 0xffff;
216         torture_assert(tctx, port > 1024 && port < 65535, "epm_Map_tcpip failed");
217
218         ip = dcerpc_floor_get_rhs_data(tctx, &t.floors[4]);
219         torture_assert(tctx, is_ipaddress(ip), "epm_Map_tcpip failed");
220
221         for (i = 0; i < *r.out.num_towers; i++) {
222                 if (r.out.towers[i].twr) {
223                         display_tower(tctx, &t);
224                 }
225         }
226
227         return true;
228 }
229
230 static bool test_Map_full(struct torture_context *tctx,
231                            struct dcerpc_pipe *p)
232 {
233         const struct ndr_syntax_id obj = {
234                 { 0x8a885d04, 0x1ceb, 0x11c9, {0x9f, 0xe8}, {0x08,0x00,0x2b,0x10,0x48,0x60} },
235                 2
236         };
237         struct dcerpc_binding_handle *h = p->binding_handle;
238         const char *annotation = "SMBTORTURE";
239         struct dcerpc_binding *b;
240         NTSTATUS status;
241         bool ok;
242
243         status = dcerpc_parse_binding(tctx, "ncacn_ip_tcp:216.83.154.106[41768]", &b);
244         torture_assert_ntstatus_ok(tctx,
245                                    status,
246                                    "Unable to generate dcerpc_binding struct");
247         b->object = obj;
248
249         ok = test_Insert(tctx, h, obj, annotation, b);
250         if (!ok) {
251                 return false;
252         }
253
254         ok = test_Map_tcpip(tctx, h, obj);
255         if (!ok) {
256                 return false;
257         }
258
259         ok = test_Delete(tctx, h, annotation, b);
260         if (!ok) {
261                 return false;
262         }
263
264         return true;
265 }
266
267 static bool test_Map_display(struct dcerpc_binding_handle *b,
268                              struct torture_context *tctx,
269                              struct epm_twr_t *twr)
270 {
271         NTSTATUS status;
272         struct epm_Map r;
273         struct GUID uuid;
274         struct policy_handle handle;
275         struct ndr_syntax_id syntax;
276         uint32_t num_towers;
277         uint32_t i;
278
279         ZERO_STRUCT(uuid);
280         ZERO_STRUCT(handle);
281
282         r.in.object = &uuid;
283         r.in.map_tower = twr;
284         r.in.entry_handle = &handle;
285         r.out.entry_handle = &handle;
286         r.in.max_towers = 10;
287         r.out.num_towers = &num_towers;
288
289         dcerpc_floor_get_lhs_data(&twr->tower.floors[0], &syntax);
290
291         torture_comment(tctx,
292                         "epm_Map results for '%s':\n",
293                         ndr_interface_name(&syntax.uuid, syntax.if_version));
294
295         /* RPC protocol identifier */
296         twr->tower.floors[2].lhs.protocol = EPM_PROTOCOL_NCACN;
297         twr->tower.floors[2].lhs.lhs_data = data_blob(NULL, 0);
298         twr->tower.floors[2].rhs.ncacn.minor_version = 0;
299
300         /* Port address */
301         twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_TCP;
302         twr->tower.floors[3].lhs.lhs_data = data_blob(NULL, 0);
303         twr->tower.floors[3].rhs.tcp.port = 0;
304
305         /* Transport */
306         twr->tower.floors[4].lhs.protocol = EPM_PROTOCOL_IP;
307         twr->tower.floors[4].lhs.lhs_data = data_blob(NULL, 0);
308         twr->tower.floors[4].rhs.ip.ipaddr = "0.0.0.0";
309
310         status = dcerpc_epm_Map_r(b, tctx, &r);
311         if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
312                 for (i=0;i<*r.out.num_towers;i++) {
313                         if (r.out.towers[i].twr) {
314                                 display_tower(tctx, &r.out.towers[i].twr->tower);
315                         }
316                 }
317         }
318
319         twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_HTTP;
320         twr->tower.floors[3].lhs.lhs_data = data_blob(NULL, 0);
321         twr->tower.floors[3].rhs.http.port = 0;
322
323         status = dcerpc_epm_Map_r(b, tctx, &r);
324         if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
325                 for (i=0;i<*r.out.num_towers;i++) {
326                         if (r.out.towers[i].twr) {
327                                 display_tower(tctx, &r.out.towers[i].twr->tower);
328                         }
329                 }
330         }
331
332         twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_UDP;
333         twr->tower.floors[3].lhs.lhs_data = data_blob(NULL, 0);
334         twr->tower.floors[3].rhs.http.port = 0;
335
336         status = dcerpc_epm_Map_r(b, tctx, &r);
337         if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
338                 for (i=0;i<*r.out.num_towers;i++) {
339                         if (r.out.towers[i].twr) {
340                                 display_tower(tctx, &r.out.towers[i].twr->tower);
341                         }
342                 }
343         }
344
345         twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_SMB;
346         twr->tower.floors[3].lhs.lhs_data = data_blob(NULL, 0);
347         twr->tower.floors[3].rhs.smb.unc = "";
348
349         twr->tower.floors[4].lhs.protocol = EPM_PROTOCOL_NETBIOS;
350         twr->tower.floors[4].lhs.lhs_data = data_blob(NULL, 0);
351         twr->tower.floors[4].rhs.netbios.name = "";
352
353         status = dcerpc_epm_Map_r(b, tctx, &r);
354         if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
355                 for (i = 0; i < *r.out.num_towers; i++) {
356                         if (r.out.towers[i].twr) {
357                                 display_tower(tctx, &r.out.towers[i].twr->tower);
358                         }
359                 }
360         }
361
362         /* FIXME: Extend to do other protocols as well (ncacn_unix_stream, ncalrpc) */
363
364         return true;
365 }
366
367 static bool test_Map_simple(struct torture_context *tctx,
368                             struct dcerpc_pipe *p)
369 {
370         NTSTATUS status;
371         struct epm_Lookup r;
372         struct policy_handle entry_handle;
373         uint32_t num_ents = 0;
374         struct dcerpc_binding_handle *h = p->binding_handle;
375
376         ZERO_STRUCT(entry_handle);
377
378         torture_comment(tctx, "Testing epm_Map\n");
379
380         /* get all elements */
381         r.in.inquiry_type = RPC_C_EP_ALL_ELTS;
382         r.in.object = NULL;
383         r.in.interface_id = NULL;
384         r.in.vers_option = RPC_C_VERS_ALL;
385
386         r.in.entry_handle = &entry_handle;
387         r.in.max_ents = 10;
388
389         r.out.entry_handle = &entry_handle;
390         r.out.num_ents = &num_ents;
391
392         do {
393                 int i;
394
395                 status = dcerpc_epm_Lookup_r(h, tctx, &r);
396                 if (!NT_STATUS_IS_OK(status) ||
397                     r.out.result != EPMAPPER_STATUS_OK) {
398                         break;
399                 }
400
401                 for (i = 0; i < *r.out.num_ents; i++) {
402                         if (r.out.entries[i].tower->tower.num_floors == 5) {
403                                 test_Map_display(h, tctx, r.out.entries[i].tower);
404                         }
405                 }
406         } while (NT_STATUS_IS_OK(status) &&
407                  r.out.result == EPMAPPER_STATUS_OK &&
408                  *r.out.num_ents == r.in.max_ents &&
409                  !ndr_policy_handle_empty(&entry_handle));
410
411         torture_assert_ntstatus_ok(tctx, status, "epm_Map_simple failed");
412
413         torture_assert(tctx,
414                        ndr_policy_handle_empty(&entry_handle),
415                        "epm_Map_simple failed - The policy handle should be emtpy.");
416
417         return true;
418 }
419
420 static bool test_LookupHandleFree(struct torture_context *tctx,
421                                   struct dcerpc_binding_handle *h,
422                                   struct policy_handle *entry_handle) {
423         NTSTATUS status;
424         struct epm_LookupHandleFree r;
425
426         if (torture_setting_bool(tctx, "samba4", false)) {
427                 torture_skip(tctx, "Skip Insert test against Samba4");
428         }
429
430         if (ndr_policy_handle_empty(entry_handle)) {
431                 torture_comment(tctx,
432                                 "epm_LookupHandleFree failed - empty policy_handle\n");
433                 return false;
434         }
435
436         r.in.entry_handle = entry_handle;
437         r.out.entry_handle = entry_handle;
438
439         status = dcerpc_epm_LookupHandleFree_r(h, tctx, &r);
440         if (NT_STATUS_IS_ERR(status)) {
441                 torture_comment(tctx,
442                                 "epm_LookupHandleFree failed - %s\n",
443                                 nt_errstr(status));
444                 return false;
445         }
446
447         if (r.out.result != EPMAPPER_STATUS_OK) {
448                 torture_comment(tctx,
449                                 "epm_LookupHandleFree failed - internal error: "
450                                 "0x%.4x\n",
451                                 r.out.result);
452                 return false;
453         }
454
455         return true;
456 }
457
458 static bool test_Lookup_simple(struct torture_context *tctx,
459                                struct dcerpc_pipe *p)
460 {
461         NTSTATUS status;
462         struct epm_Lookup r;
463         struct policy_handle entry_handle;
464         uint32_t num_ents = 0;
465         struct dcerpc_binding_handle *h = p->binding_handle;
466
467         ZERO_STRUCT(entry_handle);
468
469         torture_comment(tctx, "Testing epm_Lookup\n");
470
471         /* get all elements */
472         r.in.inquiry_type = RPC_C_EP_ALL_ELTS;
473         r.in.object = NULL;
474         r.in.interface_id = NULL;
475         r.in.vers_option = RPC_C_VERS_ALL;
476
477         r.in.entry_handle = &entry_handle;
478         r.in.max_ents = 10;
479
480         r.out.entry_handle = &entry_handle;
481         r.out.num_ents = &num_ents;
482
483         do {
484                 int i;
485
486                 status = dcerpc_epm_Lookup_r(h, tctx, &r);
487                 if (!NT_STATUS_IS_OK(status) ||
488                     r.out.result != EPMAPPER_STATUS_OK) {
489                         break;
490                 }
491
492                 torture_comment(tctx,
493                                 "epm_Lookup returned %d events, entry_handle: %s\n",
494                                 *r.out.num_ents,
495                                 GUID_string(tctx, &entry_handle.uuid));
496
497                 for (i = 0; i < *r.out.num_ents; i++) {
498                         torture_comment(tctx,
499                                         "\n  Found '%s'\n",
500                                         r.out.entries[i].annotation);
501
502                         display_tower(tctx, &r.out.entries[i].tower->tower);
503                 }
504         } while (NT_STATUS_IS_OK(status) &&
505                  r.out.result == EPMAPPER_STATUS_OK &&
506                  *r.out.num_ents == r.in.max_ents &&
507                  !ndr_policy_handle_empty(&entry_handle));
508
509         torture_assert_ntstatus_ok(tctx, status, "epm_Lookup failed");
510         torture_assert(tctx, r.out.result == EPMAPPER_STATUS_NO_MORE_ENTRIES, "epm_Lookup failed");
511
512         torture_assert(tctx,
513                        ndr_policy_handle_empty(&entry_handle),
514                        "epm_Lookup failed - The policy handle should be emtpy.");
515
516         return true;
517 }
518
519 /*
520  * This test starts a epm_Lookup request, but doesn't finish the
521  * call terminates the search. So it will call epm_LookupHandleFree.
522  */
523 static bool test_Lookup_terminate_search(struct torture_context *tctx,
524                                          struct dcerpc_pipe *p)
525 {
526         bool ok;
527         NTSTATUS status;
528         struct epm_Lookup r;
529         struct policy_handle entry_handle;
530         uint32_t i, num_ents = 0;
531         struct dcerpc_binding_handle *h = p->binding_handle;
532
533         ZERO_STRUCT(entry_handle);
534
535         torture_comment(tctx, "Testing epm_Lookup and epm_LookupHandleFree\n");
536
537         /* get all elements */
538         r.in.inquiry_type = RPC_C_EP_ALL_ELTS;
539         r.in.object = NULL;
540         r.in.interface_id = NULL;
541         r.in.vers_option = RPC_C_VERS_ALL;
542
543         r.in.entry_handle = &entry_handle;
544         r.in.max_ents = 2;
545
546         r.out.entry_handle = &entry_handle;
547         r.out.num_ents = &num_ents;
548
549         status = dcerpc_epm_Lookup_r(h, tctx, &r);
550
551         torture_assert_ntstatus_ok(tctx, status, "epm_Lookup failed");
552         torture_assert(tctx, r.out.result == EPMAPPER_STATUS_OK, "epm_Lookup failed");
553
554         torture_comment(tctx,
555                         "epm_Lookup returned %d events, entry_handle: %s\n",
556                         *r.out.num_ents,
557                         GUID_string(tctx, &entry_handle.uuid));
558
559         for (i = 0; i < *r.out.num_ents; i++) {
560                 torture_comment(tctx,
561                                 "\n  Found '%s'\n",
562                                 r.out.entries[i].annotation);
563         }
564
565         ok = test_LookupHandleFree(tctx,
566                                    h,
567                                    &entry_handle);
568         if (!ok) {
569                 return false;
570         }
571
572         return true;
573 }
574
575 static bool test_Insert_noreplace(struct torture_context *tctx,
576                                   struct dcerpc_pipe *p)
577 {
578         bool ok;
579         NTSTATUS status;
580         struct epm_Insert r;
581         struct dcerpc_binding *b;
582         struct dcerpc_binding_handle *h = p->binding_handle;
583
584         torture_comment(tctx, "Testing epm_Insert(noreplace) and epm_Delete\n");
585
586         if (torture_setting_bool(tctx, "samba4", false)) {
587                 torture_skip(tctx, "Skip Insert test against Samba4");
588         }
589
590         r.in.num_ents = 1;
591         r.in.entries = talloc_array(tctx, struct epm_entry_t, 1);
592
593         ZERO_STRUCT(r.in.entries[0].object);
594         r.in.entries[0].annotation = "smbtorture endpoint";
595
596         status = dcerpc_parse_binding(tctx, "ncalrpc:[SMBTORTURE]", &b);
597         torture_assert_ntstatus_ok(tctx,
598                                    status,
599                                    "Unable to generate dcerpc_binding struct");
600
601         r.in.entries[0].tower = talloc(tctx, struct epm_twr_t);
602
603         status = dcerpc_binding_build_tower(tctx,
604                                             b,
605                                             &r.in.entries[0].tower->tower);
606         torture_assert_ntstatus_ok(tctx,
607                                    status,
608                                    "Unable to build tower from binding struct");
609         r.in.replace = 0;
610
611         status = dcerpc_epm_Insert_r(h, tctx, &r);
612         torture_assert_ntstatus_ok(tctx, status, "epm_Insert failed");
613
614         torture_assert(tctx, r.out.result == 0, "epm_Insert failed");
615
616         ok = test_Delete(tctx, h, "smbtorture", b);
617         if (!ok) {
618                 return false;
619         }
620
621         return true;
622 }
623
624 #if 0
625 /*
626  * The MS-RPCE documentation states that this function isn't implemented and
627  * SHOULD NOT be called by a client.
628  */
629 static bool test_InqObject(struct torture_context *tctx, struct dcerpc_pipe *p)
630 {
631         NTSTATUS status;
632         struct epm_InqObject r;
633         struct dcerpc_binding_handle *b = p->binding_handle;
634
635         r.in.epm_object = talloc(tctx, struct GUID);
636         *r.in.epm_object = ndr_table_epmapper.syntax_id.uuid;
637
638         status = dcerpc_epm_InqObject_r(b, tctx, &r);
639         torture_assert_ntstatus_ok(tctx, status, "InqObject failed");
640
641         return true;
642 }
643 #endif
644
645 struct torture_suite *torture_rpc_epmapper(TALLOC_CTX *mem_ctx)
646 {
647         struct torture_suite *suite = torture_suite_create(mem_ctx, "epmapper");
648         struct torture_rpc_tcase *tcase;
649
650         tcase = torture_suite_add_rpc_iface_tcase(suite,
651                                                   "epmapper",
652                                                   &ndr_table_epmapper);
653
654         /* This is a stack */
655         torture_rpc_tcase_add_test(tcase,
656                                    "Map_simple",
657                                    test_Map_simple);
658         torture_rpc_tcase_add_test(tcase,
659                                    "Map_full",
660                                    test_Map_full);
661         torture_rpc_tcase_add_test(tcase,
662                                    "Lookup_simple",
663                                    test_Lookup_simple);
664         torture_rpc_tcase_add_test(tcase,
665                                    "Lookup_terminate_search",
666                                    test_Lookup_terminate_search);
667         torture_rpc_tcase_add_test(tcase,
668                                    "Insert_noreplace",
669                                    test_Insert_noreplace);
670
671         return suite;
672 }
673
674 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */