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