s4-torture: use torture_comment in torture_rpc_connection()
[metze/samba/wip.git] / source4 / torture / rpc / rpc.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-2003
5    Copyright (C) Jelmer Vernooij 2006
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 "lib/cmdline/popt_common.h"
23 #include "torture/rpc/torture_rpc.h"
24 #include "torture/smbtorture.h"
25 #include "librpc/ndr/ndr_table.h"
26 #include "../lib/util/dlinklist.h"
27
28 static bool torture_rpc_teardown (struct torture_context *tcase, 
29                                           void *data)
30 {
31         struct torture_rpc_tcase_data *tcase_data = 
32                 (struct torture_rpc_tcase_data *)data;
33         if (tcase_data->join_ctx != NULL)
34             torture_leave_domain(tcase, tcase_data->join_ctx);
35         talloc_free(tcase_data);
36         return true;
37 }
38
39 /**
40  * Obtain the DCE/RPC binding context associated with a torture context.
41  *
42  * @param tctx Torture context
43  * @param binding Pointer to store DCE/RPC binding
44  */
45 NTSTATUS torture_rpc_binding(struct torture_context *tctx,
46                              struct dcerpc_binding **binding)
47 {
48         NTSTATUS status;
49         const char *binding_string = torture_setting_string(tctx, "binding", 
50                                                             NULL);
51
52         if (binding_string == NULL) {
53                 torture_comment(tctx, 
54                                 "You must specify a DCE/RPC binding string\n");
55                 return NT_STATUS_INVALID_PARAMETER;
56         }
57
58         status = dcerpc_parse_binding(tctx, binding_string, binding);
59         if (NT_STATUS_IS_ERR(status)) {
60                 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", 
61                          binding_string));
62                 return status;
63         }
64
65         return NT_STATUS_OK;    
66 }
67
68 /**
69  * open a rpc connection to the chosen binding string
70  */
71 _PUBLIC_ NTSTATUS torture_rpc_connection(struct torture_context *tctx,
72                                 struct dcerpc_pipe **p, 
73                                 const struct ndr_interface_table *table)
74 {
75         NTSTATUS status;
76         struct dcerpc_binding *binding;
77
78         dcerpc_init();
79
80         status = torture_rpc_binding(tctx, &binding);
81         if (NT_STATUS_IS_ERR(status))
82                 return status;
83
84         status = dcerpc_pipe_connect_b(tctx, 
85                                      p, binding, table,
86                                      cmdline_credentials, tctx->ev, tctx->lp_ctx);
87  
88         if (NT_STATUS_IS_ERR(status)) {
89                 torture_warning(tctx, "Failed to connect to remote server: %s %s\n",
90                            dcerpc_binding_string(tctx, binding), nt_errstr(status));
91         }
92
93         return status;
94 }
95
96 /**
97  * open a rpc connection to a specific transport
98  */
99 NTSTATUS torture_rpc_connection_transport(struct torture_context *tctx, 
100                                           struct dcerpc_pipe **p, 
101                                           const struct ndr_interface_table *table,
102                                           enum dcerpc_transport_t transport,
103                                           uint32_t assoc_group_id)
104 {
105         NTSTATUS status;
106         struct dcerpc_binding *binding;
107
108         *p = NULL;
109
110         status = torture_rpc_binding(tctx, &binding);
111         if (!NT_STATUS_IS_OK(status)) {
112                 return status;
113         }
114
115         status = dcerpc_binding_set_transport(binding, transport);
116         if (!NT_STATUS_IS_OK(status)) {
117                 return status;
118         }
119
120         status = dcerpc_binding_set_assoc_group_id(binding, assoc_group_id);
121         if (!NT_STATUS_IS_OK(status)) {
122                 return status;
123         }
124
125         status = dcerpc_pipe_connect_b(tctx, p, binding, table,
126                                        cmdline_credentials,
127                                        tctx->ev, tctx->lp_ctx);
128         if (!NT_STATUS_IS_OK(status)) {
129                 *p = NULL;
130                 return status;
131         }
132
133         return NT_STATUS_OK;
134 }
135
136 static bool torture_rpc_setup_machine_workstation(struct torture_context *tctx,
137                                                   void **data)
138 {
139         NTSTATUS status;
140         struct dcerpc_binding *binding;
141         struct torture_rpc_tcase *tcase = talloc_get_type(tctx->active_tcase,
142                                                 struct torture_rpc_tcase);
143         struct torture_rpc_tcase_data *tcase_data;
144
145         status = torture_rpc_binding(tctx, &binding);
146         if (NT_STATUS_IS_ERR(status))
147                 return false;
148
149         *data = tcase_data = talloc_zero(tctx, struct torture_rpc_tcase_data);
150         tcase_data->credentials = cmdline_credentials;
151         tcase_data->join_ctx = torture_join_domain(tctx, tcase->machine_name,
152                                                    ACB_WSTRUST,
153                                                    &tcase_data->credentials);
154         if (tcase_data->join_ctx == NULL)
155             torture_fail(tctx, "Failed to join as WORKSTATION");
156
157         status = dcerpc_pipe_connect_b(tctx,
158                                 &(tcase_data->pipe),
159                                 binding,
160                                 tcase->table,
161                                 tcase_data->credentials, tctx->ev, tctx->lp_ctx);
162
163         torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
164
165         return NT_STATUS_IS_OK(status);
166 }
167
168 static bool torture_rpc_setup_machine_bdc(struct torture_context *tctx,
169                                           void **data)
170 {
171         NTSTATUS status;
172         struct dcerpc_binding *binding;
173         struct torture_rpc_tcase *tcase = talloc_get_type(tctx->active_tcase, 
174                                                 struct torture_rpc_tcase);
175         struct torture_rpc_tcase_data *tcase_data;
176
177         status = torture_rpc_binding(tctx, &binding);
178         if (NT_STATUS_IS_ERR(status))
179                 return false;
180
181         *data = tcase_data = talloc_zero(tctx, struct torture_rpc_tcase_data);
182         tcase_data->credentials = cmdline_credentials;
183         tcase_data->join_ctx = torture_join_domain(tctx, tcase->machine_name,
184                                                    ACB_SVRTRUST, 
185                                                    &tcase_data->credentials);
186         if (tcase_data->join_ctx == NULL)
187             torture_fail(tctx, "Failed to join as BDC");
188
189         status = dcerpc_pipe_connect_b(tctx, 
190                                 &(tcase_data->pipe),
191                                 binding,
192                                 tcase->table,
193                                 tcase_data->credentials, tctx->ev, tctx->lp_ctx);
194
195         torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
196
197         return NT_STATUS_IS_OK(status);
198 }
199
200 _PUBLIC_ struct torture_rpc_tcase *torture_suite_add_machine_workstation_rpc_iface_tcase(
201                                 struct torture_suite *suite,
202                                 const char *name,
203                                 const struct ndr_interface_table *table,
204                                 const char *machine_name)
205 {
206         struct torture_rpc_tcase *tcase = talloc(suite,
207                                                  struct torture_rpc_tcase);
208
209         torture_suite_init_rpc_tcase(suite, tcase, name, table);
210
211         tcase->machine_name = talloc_strdup(tcase, machine_name);
212         tcase->tcase.setup = torture_rpc_setup_machine_workstation;
213         tcase->tcase.teardown = torture_rpc_teardown;
214
215         return tcase;
216 }
217
218 _PUBLIC_ struct torture_rpc_tcase *torture_suite_add_machine_bdc_rpc_iface_tcase(
219                                 struct torture_suite *suite, 
220                                 const char *name,
221                                 const struct ndr_interface_table *table,
222                                 const char *machine_name)
223 {
224         struct torture_rpc_tcase *tcase = talloc(suite, 
225                                                  struct torture_rpc_tcase);
226
227         torture_suite_init_rpc_tcase(suite, tcase, name, table);
228
229         tcase->machine_name = talloc_strdup(tcase, machine_name);
230         tcase->tcase.setup = torture_rpc_setup_machine_bdc;
231         tcase->tcase.teardown = torture_rpc_teardown;
232
233         return tcase;
234 }
235
236 _PUBLIC_ bool torture_suite_init_rpc_tcase(struct torture_suite *suite, 
237                                            struct torture_rpc_tcase *tcase, 
238                                            const char *name,
239                                            const struct ndr_interface_table *table)
240 {
241         if (!torture_suite_init_tcase(suite, (struct torture_tcase *)tcase, name))
242                 return false;
243
244         tcase->table = table;
245
246         return true;
247 }
248
249 static bool torture_rpc_setup_anonymous(struct torture_context *tctx, 
250                                         void **data)
251 {
252         NTSTATUS status;
253         struct dcerpc_binding *binding;
254         struct torture_rpc_tcase_data *tcase_data;
255         struct torture_rpc_tcase *tcase = talloc_get_type(tctx->active_tcase, 
256                                                           struct torture_rpc_tcase);
257
258         status = torture_rpc_binding(tctx, &binding);
259         if (NT_STATUS_IS_ERR(status))
260                 return false;
261
262         *data = tcase_data = talloc_zero(tctx, struct torture_rpc_tcase_data);
263         tcase_data->credentials = cli_credentials_init_anon(tctx);
264
265         status = dcerpc_pipe_connect_b(tctx, 
266                                 &(tcase_data->pipe),
267                                 binding,
268                                 tcase->table,
269                                 tcase_data->credentials, tctx->ev, tctx->lp_ctx);
270
271         torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
272
273         return NT_STATUS_IS_OK(status);
274 }
275
276 static bool torture_rpc_setup (struct torture_context *tctx, void **data)
277 {
278         NTSTATUS status;
279         struct torture_rpc_tcase *tcase = talloc_get_type(
280                                                 tctx->active_tcase, struct torture_rpc_tcase);
281         struct torture_rpc_tcase_data *tcase_data;
282
283         *data = tcase_data = talloc_zero(tctx, struct torture_rpc_tcase_data);
284         tcase_data->credentials = cmdline_credentials;
285         
286         status = torture_rpc_connection(tctx, 
287                                 &(tcase_data->pipe),
288                                 tcase->table);
289
290         torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
291
292         return NT_STATUS_IS_OK(status);
293 }
294
295
296
297 _PUBLIC_ struct torture_rpc_tcase *torture_suite_add_anon_rpc_iface_tcase(struct torture_suite *suite, 
298                                                                 const char *name,
299                                                                 const struct ndr_interface_table *table)
300 {
301         struct torture_rpc_tcase *tcase = talloc(suite, struct torture_rpc_tcase);
302
303         torture_suite_init_rpc_tcase(suite, tcase, name, table);
304
305         tcase->tcase.setup = torture_rpc_setup_anonymous;
306         tcase->tcase.teardown = torture_rpc_teardown;
307
308         return tcase;
309 }
310
311
312 _PUBLIC_ struct torture_rpc_tcase *torture_suite_add_rpc_iface_tcase(struct torture_suite *suite, 
313                                                                 const char *name,
314                                                                 const struct ndr_interface_table *table)
315 {
316         struct torture_rpc_tcase *tcase = talloc(suite, struct torture_rpc_tcase);
317
318         torture_suite_init_rpc_tcase(suite, tcase, name, table);
319
320         tcase->tcase.setup = torture_rpc_setup;
321         tcase->tcase.teardown = torture_rpc_teardown;
322
323         return tcase;
324 }
325
326 static bool torture_rpc_wrap_test(struct torture_context *tctx, 
327                                                                   struct torture_tcase *tcase,
328                                                                   struct torture_test *test)
329 {
330         bool (*fn) (struct torture_context *, struct dcerpc_pipe *);
331         struct torture_rpc_tcase_data *tcase_data = 
332                 (struct torture_rpc_tcase_data *)tcase->data;
333
334         fn = test->fn;
335
336         return fn(tctx, tcase_data->pipe);
337 }
338
339 static bool torture_rpc_wrap_test_ex(struct torture_context *tctx, 
340                                                                   struct torture_tcase *tcase,
341                                                                   struct torture_test *test)
342 {
343         bool (*fn) (struct torture_context *, struct dcerpc_pipe *, const void *);
344         struct torture_rpc_tcase_data *tcase_data = 
345                 (struct torture_rpc_tcase_data *)tcase->data;
346
347         fn = test->fn;
348
349         return fn(tctx, tcase_data->pipe, test->data);
350 }
351
352
353 static bool torture_rpc_wrap_test_creds(struct torture_context *tctx, 
354                                                                   struct torture_tcase *tcase,
355                                                                   struct torture_test *test)
356 {
357         bool (*fn) (struct torture_context *, struct dcerpc_pipe *, struct cli_credentials *);
358         struct torture_rpc_tcase_data *tcase_data = 
359                 (struct torture_rpc_tcase_data *)tcase->data;
360
361         fn = test->fn;
362
363         return fn(tctx, tcase_data->pipe, tcase_data->credentials);
364 }
365
366 static bool torture_rpc_wrap_test_join(struct torture_context *tctx,
367                                        struct torture_tcase *tcase,
368                                        struct torture_test *test)
369 {
370         bool (*fn) (struct torture_context *, struct dcerpc_pipe *, struct cli_credentials *, struct test_join *);
371         struct torture_rpc_tcase_data *tcase_data =
372                 (struct torture_rpc_tcase_data *)tcase->data;
373
374         fn = test->fn;
375
376         return fn(tctx, tcase_data->pipe, tcase_data->credentials, tcase_data->join_ctx);
377 }
378
379 _PUBLIC_ struct torture_test *torture_rpc_tcase_add_test(
380                                         struct torture_rpc_tcase *tcase, 
381                                         const char *name, 
382                                         bool (*fn) (struct torture_context *, struct dcerpc_pipe *))
383 {
384         struct torture_test *test;
385
386         test = talloc(tcase, struct torture_test);
387
388         test->name = talloc_strdup(test, name);
389         test->description = NULL;
390         test->run = torture_rpc_wrap_test;
391         test->dangerous = false;
392         test->data = NULL;
393         test->fn = fn;
394
395         DLIST_ADD(tcase->tcase.tests, test);
396
397         return test;
398 }
399
400 _PUBLIC_ struct torture_test *torture_rpc_tcase_add_test_creds(
401                                         struct torture_rpc_tcase *tcase, 
402                                         const char *name, 
403                                         bool (*fn) (struct torture_context *, struct dcerpc_pipe *, struct cli_credentials *))
404 {
405         struct torture_test *test;
406
407         test = talloc(tcase, struct torture_test);
408
409         test->name = talloc_strdup(test, name);
410         test->description = NULL;
411         test->run = torture_rpc_wrap_test_creds;
412         test->dangerous = false;
413         test->data = NULL;
414         test->fn = fn;
415
416         DLIST_ADD(tcase->tcase.tests, test);
417
418         return test;
419 }
420
421 _PUBLIC_ struct torture_test *torture_rpc_tcase_add_test_join(
422                                         struct torture_rpc_tcase *tcase,
423                                         const char *name,
424                                         bool (*fn) (struct torture_context *, struct dcerpc_pipe *,
425                                                     struct cli_credentials *, struct test_join *))
426 {
427         struct torture_test *test;
428
429         test = talloc(tcase, struct torture_test);
430
431         test->name = talloc_strdup(test, name);
432         test->description = NULL;
433         test->run = torture_rpc_wrap_test_join;
434         test->dangerous = false;
435         test->data = NULL;
436         test->fn = fn;
437
438         DLIST_ADD(tcase->tcase.tests, test);
439
440         return test;
441 }
442
443 _PUBLIC_ struct torture_test *torture_rpc_tcase_add_test_ex(
444                                         struct torture_rpc_tcase *tcase, 
445                                         const char *name, 
446                                         bool (*fn) (struct torture_context *, struct dcerpc_pipe *,
447                                                                 void *),
448                                         void *userdata)
449 {
450         struct torture_test *test;
451
452         test = talloc(tcase, struct torture_test);
453
454         test->name = talloc_strdup(test, name);
455         test->description = NULL;
456         test->run = torture_rpc_wrap_test_ex;
457         test->dangerous = false;
458         test->data = userdata;
459         test->fn = fn;
460
461         DLIST_ADD(tcase->tcase.tests, test);
462
463         return test;
464 }
465
466 NTSTATUS torture_rpc_init(void)
467 {
468         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "rpc");
469
470         ndr_table_init();
471
472         torture_suite_add_simple_test(suite, "lsa", torture_rpc_lsa);
473         torture_suite_add_simple_test(suite, "lsalookup", torture_rpc_lsa_lookup);
474         torture_suite_add_simple_test(suite, "lsa-getuser", torture_rpc_lsa_get_user);
475         torture_suite_add_suite(suite, torture_rpc_lsa_lookup_sids(suite));
476         torture_suite_add_suite(suite, torture_rpc_lsa_lookup_names(suite));
477         torture_suite_add_suite(suite, torture_rpc_lsa_secrets(suite));
478         torture_suite_add_suite(suite, torture_rpc_lsa_trusted_domains(suite));
479         torture_suite_add_suite(suite, torture_rpc_lsa_forest_trust(suite));
480         torture_suite_add_suite(suite, torture_rpc_lsa_privileges(suite));
481         torture_suite_add_suite(suite, torture_rpc_echo(suite));
482         torture_suite_add_suite(suite, torture_rpc_dfs(suite));
483         torture_suite_add_suite(suite, torture_rpc_frsapi(suite));
484         torture_suite_add_suite(suite, torture_rpc_unixinfo(suite));
485         torture_suite_add_suite(suite, torture_rpc_eventlog(suite));
486         torture_suite_add_suite(suite, torture_rpc_atsvc(suite));
487         torture_suite_add_suite(suite, torture_rpc_wkssvc(suite));
488         torture_suite_add_suite(suite, torture_rpc_handles(suite));
489         torture_suite_add_suite(suite, torture_rpc_object_uuid(suite));
490         torture_suite_add_suite(suite, torture_rpc_winreg(suite));
491         torture_suite_add_suite(suite, torture_rpc_spoolss(suite));
492 #ifdef WITH_NTVFS_FILESERVER
493         torture_suite_add_suite(suite, torture_rpc_spoolss_notify(suite));
494 #endif
495         torture_suite_add_suite(suite, torture_rpc_spoolss_win(suite));
496         torture_suite_add_suite(suite, torture_rpc_spoolss_driver(suite));
497         torture_suite_add_suite(suite, torture_rpc_spoolss_access(suite));
498         torture_suite_add_simple_test(suite, "samr", torture_rpc_samr);
499         torture_suite_add_simple_test(suite, "samr.users", torture_rpc_samr_users);
500         torture_suite_add_simple_test(suite, "samr.passwords", torture_rpc_samr_passwords);
501         torture_suite_add_suite(suite, torture_rpc_netlogon(suite));
502         torture_suite_add_suite(suite, torture_rpc_netlogon_s3(suite));
503         torture_suite_add_suite(suite, torture_rpc_netlogon_admin(suite));
504         torture_suite_add_suite(suite, torture_rpc_remote_pac(suite));
505         torture_suite_add_simple_test(suite, "samlogon", torture_rpc_samlogon);
506         torture_suite_add_simple_test(suite, "samsync", torture_rpc_samsync);
507         torture_suite_add_simple_test(suite, "schannel", torture_rpc_schannel);
508         torture_suite_add_simple_test(suite, "schannel2", torture_rpc_schannel2);
509         torture_suite_add_simple_test(suite, "bench-schannel1", torture_rpc_schannel_bench1);
510         torture_suite_add_simple_test(suite, "schannel_anon_setpw", torture_rpc_schannel_anon_setpw);
511         torture_suite_add_suite(suite, torture_rpc_srvsvc(suite));
512         torture_suite_add_suite(suite, torture_rpc_svcctl(suite));
513         torture_suite_add_suite(suite, torture_rpc_samr_accessmask(suite));
514         torture_suite_add_suite(suite, torture_rpc_samr_workstation_auth(suite));
515         torture_suite_add_suite(suite, torture_rpc_samr_passwords_pwdlastset(suite));
516         torture_suite_add_suite(suite, torture_rpc_samr_passwords_badpwdcount(suite));
517         torture_suite_add_suite(suite, torture_rpc_samr_passwords_lockout(suite));
518         torture_suite_add_suite(suite, torture_rpc_samr_passwords_validate(suite));
519         torture_suite_add_suite(suite, torture_rpc_samr_user_privileges(suite));
520         torture_suite_add_suite(suite, torture_rpc_samr_large_dc(suite));
521         torture_suite_add_suite(suite, torture_rpc_samr_priv(suite));
522         torture_suite_add_suite(suite, torture_rpc_epmapper(suite));
523         torture_suite_add_suite(suite, torture_rpc_initshutdown(suite));
524         torture_suite_add_suite(suite, torture_rpc_oxidresolve(suite));
525         torture_suite_add_suite(suite, torture_rpc_remact(suite));
526         torture_suite_add_simple_test(suite, "mgmt", torture_rpc_mgmt);
527         torture_suite_add_simple_test(suite, "scanner", torture_rpc_scanner);
528         torture_suite_add_simple_test(suite, "autoidl", torture_rpc_autoidl);
529         torture_suite_add_simple_test(suite, "countcalls", torture_rpc_countcalls);
530         torture_suite_add_simple_test(suite, "authcontext", torture_bind_authcontext);
531         torture_suite_add_suite(suite, torture_rpc_samba3(suite));
532         torture_rpc_drsuapi_tcase(suite);
533         torture_rpc_drsuapi_w2k8_tcase(suite);
534         torture_rpc_drsuapi_cracknames_tcase(suite);
535         torture_suite_add_suite(suite, torture_rpc_dssetup(suite));
536         torture_suite_add_suite(suite, torture_rpc_browser(suite));
537         torture_suite_add_simple_test(suite, "altercontext", torture_rpc_alter_context);
538         torture_suite_add_simple_test(suite, "join", torture_rpc_join);
539         torture_drs_rpc_dsgetinfo_tcase(suite);
540         torture_suite_add_simple_test(suite, "bench-rpc", torture_bench_rpc);
541         torture_suite_add_simple_test(suite, "asyncbind", torture_async_bind);
542         torture_suite_add_suite(suite, torture_rpc_ntsvcs(suite));
543         torture_suite_add_suite(suite, torture_rpc_bind(suite));
544 #ifdef AD_DC_BUILD_IS_ENABLED
545         torture_suite_add_suite(suite, torture_rpc_backupkey(suite));
546 #endif
547         torture_suite_add_suite(suite, torture_rpc_fsrvp(suite));
548         torture_suite_add_suite(suite, torture_rpc_clusapi(suite));
549         torture_suite_add_suite(suite, torture_rpc_witness(suite));
550
551         suite->description = talloc_strdup(suite, "DCE/RPC protocol and interface tests");
552
553         torture_register_suite(suite);
554
555         return NT_STATUS_OK;
556 }