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