s4-smbtorture: add RPC-SAMR-MACHINE-AUTH test.
[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 "auth/credentials/credentials.h"
23 #include "lib/cmdline/popt_common.h"
24 #include "librpc/rpc/dcerpc.h"
25 #include "torture/rpc/rpc.h"
26 #include "torture/smbtorture.h"
27 #include "librpc/ndr/ndr_table.h"
28 #include "../lib/util/dlinklist.h"
29
30 static bool torture_rpc_teardown (struct torture_context *tcase, 
31                                           void *data)
32 {
33         struct torture_rpc_tcase_data *tcase_data = 
34                 (struct torture_rpc_tcase_data *)data;
35         if (tcase_data->join_ctx != NULL)
36             torture_leave_domain(tcase, tcase_data->join_ctx);
37         talloc_free(tcase_data);
38         return true;
39 }
40
41 /**
42  * Obtain the DCE/RPC binding context associated with a torture context.
43  *
44  * @param tctx Torture context
45  * @param binding Pointer to store DCE/RPC binding
46  */
47 NTSTATUS torture_rpc_binding(struct torture_context *tctx,
48                              struct dcerpc_binding **binding)
49 {
50         NTSTATUS status;
51         const char *binding_string = torture_setting_string(tctx, "binding", 
52                                                             NULL);
53
54         if (binding_string == NULL) {
55                 torture_comment(tctx, 
56                                 "You must specify a DCE/RPC binding string\n");
57                 return NT_STATUS_INVALID_PARAMETER;
58         }
59
60         status = dcerpc_parse_binding(tctx, binding_string, binding);
61         if (NT_STATUS_IS_ERR(status)) {
62                 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", 
63                          binding_string));
64                 return status;
65         }
66
67         return NT_STATUS_OK;    
68 }
69
70 /**
71  * open a rpc connection to the chosen binding string
72  */
73 _PUBLIC_ NTSTATUS torture_rpc_connection(struct torture_context *tctx,
74                                 struct dcerpc_pipe **p, 
75                                 const struct ndr_interface_table *table)
76 {
77         NTSTATUS status;
78         struct dcerpc_binding *binding;
79
80         dcerpc_init(tctx->lp_ctx);
81
82         status = torture_rpc_binding(tctx, &binding);
83         if (NT_STATUS_IS_ERR(status))
84                 return status;
85
86         status = dcerpc_pipe_connect_b(tctx, 
87                                      p, binding, table,
88                                      cmdline_credentials, tctx->ev, tctx->lp_ctx);
89  
90         if (NT_STATUS_IS_ERR(status)) {
91                 printf("Failed to connect to remote server: %s %s\n", 
92                            dcerpc_binding_string(tctx, binding), nt_errstr(status));
93         }
94
95         return status;
96 }
97
98 /**
99  * open a rpc connection to a specific transport
100  */
101 NTSTATUS torture_rpc_connection_transport(struct torture_context *tctx, 
102                                           struct dcerpc_pipe **p, 
103                                           const struct ndr_interface_table *table,
104                                           enum dcerpc_transport_t transport,
105                                           uint32_t assoc_group_id)
106 {
107         NTSTATUS status;
108         struct dcerpc_binding *binding;
109
110         status = torture_rpc_binding(tctx, &binding);
111         if (NT_STATUS_IS_ERR(status))
112                 return status;
113
114         binding->transport = transport;
115         binding->assoc_group_id = assoc_group_id;
116
117         status = dcerpc_pipe_connect_b(tctx, p, binding, table,
118                                        cmdline_credentials, tctx->ev, tctx->lp_ctx);
119                                            
120         if (NT_STATUS_IS_ERR(status)) {
121                 *p = NULL;
122         }
123
124         return status;
125 }
126
127 static bool torture_rpc_setup_machine_workstation(struct torture_context *tctx,
128                                                   void **data)
129 {
130         NTSTATUS status;
131         struct dcerpc_binding *binding;
132         struct torture_rpc_tcase *tcase = talloc_get_type(tctx->active_tcase,
133                                                 struct torture_rpc_tcase);
134         struct torture_rpc_tcase_data *tcase_data;
135
136         status = torture_rpc_binding(tctx, &binding);
137         if (NT_STATUS_IS_ERR(status))
138                 return false;
139
140         *data = tcase_data = talloc_zero(tctx, struct torture_rpc_tcase_data);
141         tcase_data->credentials = cmdline_credentials;
142         tcase_data->join_ctx = torture_join_domain(tctx, tcase->machine_name,
143                                                    ACB_WSTRUST,
144                                                    &tcase_data->credentials);
145         if (tcase_data->join_ctx == NULL)
146             torture_fail(tctx, "Failed to join as WORKSTATION");
147
148         status = dcerpc_pipe_connect_b(tctx,
149                                 &(tcase_data->pipe),
150                                 binding,
151                                 tcase->table,
152                                 tcase_data->credentials, tctx->ev, tctx->lp_ctx);
153
154         torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
155
156         return true;
157 }
158
159 static bool torture_rpc_setup_machine_bdc(struct torture_context *tctx,
160                                           void **data)
161 {
162         NTSTATUS status;
163         struct dcerpc_binding *binding;
164         struct torture_rpc_tcase *tcase = talloc_get_type(tctx->active_tcase, 
165                                                 struct torture_rpc_tcase);
166         struct torture_rpc_tcase_data *tcase_data;
167
168         status = torture_rpc_binding(tctx, &binding);
169         if (NT_STATUS_IS_ERR(status))
170                 return false;
171
172         *data = tcase_data = talloc_zero(tctx, struct torture_rpc_tcase_data);
173         tcase_data->credentials = cmdline_credentials;
174         tcase_data->join_ctx = torture_join_domain(tctx, tcase->machine_name,
175                                                    ACB_SVRTRUST, 
176                                                    &tcase_data->credentials);
177         if (tcase_data->join_ctx == NULL)
178             torture_fail(tctx, "Failed to join as BDC");
179
180         status = dcerpc_pipe_connect_b(tctx, 
181                                 &(tcase_data->pipe),
182                                 binding,
183                                 tcase->table,
184                                 tcase_data->credentials, tctx->ev, tctx->lp_ctx);
185
186         torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
187
188         return true;
189 }
190
191 _PUBLIC_ struct torture_rpc_tcase *torture_suite_add_machine_workstation_rpc_iface_tcase(
192                                 struct torture_suite *suite,
193                                 const char *name,
194                                 const struct ndr_interface_table *table,
195                                 const char *machine_name)
196 {
197         struct torture_rpc_tcase *tcase = talloc(suite,
198                                                  struct torture_rpc_tcase);
199
200         torture_suite_init_rpc_tcase(suite, tcase, name, table);
201
202         tcase->machine_name = talloc_strdup(tcase, machine_name);
203         tcase->tcase.setup = torture_rpc_setup_machine_workstation;
204         tcase->tcase.teardown = torture_rpc_teardown;
205
206         return tcase;
207 }
208
209 _PUBLIC_ struct torture_rpc_tcase *torture_suite_add_machine_bdc_rpc_iface_tcase(
210                                 struct torture_suite *suite, 
211                                 const char *name,
212                                 const struct ndr_interface_table *table,
213                                 const char *machine_name)
214 {
215         struct torture_rpc_tcase *tcase = talloc(suite, 
216                                                  struct torture_rpc_tcase);
217
218         torture_suite_init_rpc_tcase(suite, tcase, name, table);
219
220         tcase->machine_name = talloc_strdup(tcase, machine_name);
221         tcase->tcase.setup = torture_rpc_setup_machine_bdc;
222         tcase->tcase.teardown = torture_rpc_teardown;
223
224         return tcase;
225 }
226
227 _PUBLIC_ bool torture_suite_init_rpc_tcase(struct torture_suite *suite, 
228                                            struct torture_rpc_tcase *tcase, 
229                                            const char *name,
230                                            const struct ndr_interface_table *table)
231 {
232         if (!torture_suite_init_tcase(suite, (struct torture_tcase *)tcase, name))
233                 return false;
234
235         tcase->table = table;
236
237         return true;
238 }
239
240 static bool torture_rpc_setup_anonymous(struct torture_context *tctx, 
241                                         void **data)
242 {
243         NTSTATUS status;
244         struct dcerpc_binding *binding;
245         struct torture_rpc_tcase_data *tcase_data;
246         struct torture_rpc_tcase *tcase = talloc_get_type(tctx->active_tcase, 
247                                                           struct torture_rpc_tcase);
248
249         status = torture_rpc_binding(tctx, &binding);
250         if (NT_STATUS_IS_ERR(status))
251                 return false;
252
253         *data = tcase_data = talloc_zero(tctx, struct torture_rpc_tcase_data);
254         tcase_data->credentials = cli_credentials_init_anon(tctx);
255
256         status = dcerpc_pipe_connect_b(tctx, 
257                                 &(tcase_data->pipe),
258                                 binding,
259                                 tcase->table,
260                                 tcase_data->credentials, tctx->ev, tctx->lp_ctx);
261
262         torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
263
264         return true;
265 }
266
267 static bool torture_rpc_setup (struct torture_context *tctx, void **data)
268 {
269         NTSTATUS status;
270         struct torture_rpc_tcase *tcase = talloc_get_type(
271                                                 tctx->active_tcase, struct torture_rpc_tcase);
272         struct torture_rpc_tcase_data *tcase_data;
273
274         *data = tcase_data = talloc_zero(tctx, struct torture_rpc_tcase_data);
275         tcase_data->credentials = cmdline_credentials;
276         
277         status = torture_rpc_connection(tctx, 
278                                 &(tcase_data->pipe),
279                                 tcase->table);
280
281         torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
282
283         return true;
284 }
285
286
287
288 _PUBLIC_ struct torture_rpc_tcase *torture_suite_add_anon_rpc_iface_tcase(struct torture_suite *suite, 
289                                                                 const char *name,
290                                                                 const struct ndr_interface_table *table)
291 {
292         struct torture_rpc_tcase *tcase = talloc(suite, struct torture_rpc_tcase);
293
294         torture_suite_init_rpc_tcase(suite, tcase, name, table);
295
296         tcase->tcase.setup = torture_rpc_setup_anonymous;
297         tcase->tcase.teardown = torture_rpc_teardown;
298
299         return tcase;
300 }
301
302
303 _PUBLIC_ struct torture_rpc_tcase *torture_suite_add_rpc_iface_tcase(struct torture_suite *suite, 
304                                                                 const char *name,
305                                                                 const struct ndr_interface_table *table)
306 {
307         struct torture_rpc_tcase *tcase = talloc(suite, struct torture_rpc_tcase);
308
309         torture_suite_init_rpc_tcase(suite, tcase, name, table);
310
311         tcase->tcase.setup = torture_rpc_setup;
312         tcase->tcase.teardown = torture_rpc_teardown;
313
314         return tcase;
315 }
316
317 static bool torture_rpc_wrap_test(struct torture_context *tctx, 
318                                                                   struct torture_tcase *tcase,
319                                                                   struct torture_test *test)
320 {
321         bool (*fn) (struct torture_context *, struct dcerpc_pipe *);
322         struct torture_rpc_tcase_data *tcase_data = 
323                 (struct torture_rpc_tcase_data *)tcase->data;
324
325         fn = test->fn;
326
327         return fn(tctx, tcase_data->pipe);
328 }
329
330 static bool torture_rpc_wrap_test_ex(struct torture_context *tctx, 
331                                                                   struct torture_tcase *tcase,
332                                                                   struct torture_test *test)
333 {
334         bool (*fn) (struct torture_context *, struct dcerpc_pipe *, const void *);
335         struct torture_rpc_tcase_data *tcase_data = 
336                 (struct torture_rpc_tcase_data *)tcase->data;
337
338         fn = test->fn;
339
340         return fn(tctx, tcase_data->pipe, test->data);
341 }
342
343
344 static bool torture_rpc_wrap_test_creds(struct torture_context *tctx, 
345                                                                   struct torture_tcase *tcase,
346                                                                   struct torture_test *test)
347 {
348         bool (*fn) (struct torture_context *, struct dcerpc_pipe *, struct cli_credentials *);
349         struct torture_rpc_tcase_data *tcase_data = 
350                 (struct torture_rpc_tcase_data *)tcase->data;
351
352         fn = test->fn;
353
354         return fn(tctx, tcase_data->pipe, tcase_data->credentials);
355 }
356
357 _PUBLIC_ struct torture_test *torture_rpc_tcase_add_test(
358                                         struct torture_rpc_tcase *tcase, 
359                                         const char *name, 
360                                         bool (*fn) (struct torture_context *, struct dcerpc_pipe *))
361 {
362         struct torture_test *test;
363
364         test = talloc(tcase, struct torture_test);
365
366         test->name = talloc_strdup(test, name);
367         test->description = NULL;
368         test->run = torture_rpc_wrap_test;
369         test->dangerous = false;
370         test->data = NULL;
371         test->fn = fn;
372
373         DLIST_ADD(tcase->tcase.tests, test);
374
375         return test;
376 }
377
378 _PUBLIC_ struct torture_test *torture_rpc_tcase_add_test_creds(
379                                         struct torture_rpc_tcase *tcase, 
380                                         const char *name, 
381                                         bool (*fn) (struct torture_context *, struct dcerpc_pipe *, struct cli_credentials *))
382 {
383         struct torture_test *test;
384
385         test = talloc(tcase, struct torture_test);
386
387         test->name = talloc_strdup(test, name);
388         test->description = NULL;
389         test->run = torture_rpc_wrap_test_creds;
390         test->dangerous = false;
391         test->data = NULL;
392         test->fn = fn;
393
394         DLIST_ADD(tcase->tcase.tests, test);
395
396         return test;
397 }
398
399 _PUBLIC_ struct torture_test *torture_rpc_tcase_add_test_ex(
400                                         struct torture_rpc_tcase *tcase, 
401                                         const char *name, 
402                                         bool (*fn) (struct torture_context *, struct dcerpc_pipe *,
403                                                                 void *),
404                                         void *userdata)
405 {
406         struct torture_test *test;
407
408         test = talloc(tcase, struct torture_test);
409
410         test->name = talloc_strdup(test, name);
411         test->description = NULL;
412         test->run = torture_rpc_wrap_test_ex;
413         test->dangerous = false;
414         test->data = userdata;
415         test->fn = fn;
416
417         DLIST_ADD(tcase->tcase.tests, test);
418
419         return test;
420 }
421
422 NTSTATUS torture_rpc_init(void)
423 {
424         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "RPC");
425
426         ndr_table_init();
427
428         torture_suite_add_simple_test(suite, "LSA", torture_rpc_lsa);
429         torture_suite_add_simple_test(suite, "LSALOOKUP", torture_rpc_lsa_lookup);
430         torture_suite_add_simple_test(suite, "LSA-GETUSER", torture_rpc_lsa_get_user);
431         torture_suite_add_suite(suite, torture_rpc_lsa_lookup_sids(suite));
432         torture_suite_add_suite(suite, torture_rpc_lsa_lookup_names(suite));
433         torture_suite_add_suite(suite, torture_rpc_lsa_secrets(suite));
434         torture_suite_add_suite(suite, torture_rpc_echo(suite));
435         torture_suite_add_simple_test(suite, "DFS", torture_rpc_dfs);
436         torture_suite_add_suite(suite, torture_rpc_frsapi(suite));
437         torture_suite_add_suite(suite, torture_rpc_unixinfo(suite));
438         torture_suite_add_suite(suite, torture_rpc_eventlog(suite));
439         torture_suite_add_suite(suite, torture_rpc_atsvc(suite));
440         torture_suite_add_suite(suite, torture_rpc_wkssvc(suite));
441         torture_suite_add_suite(suite, torture_rpc_handles(suite));
442         torture_suite_add_suite(suite, torture_rpc_object_uuid(suite));
443         torture_suite_add_suite(suite, torture_rpc_winreg(suite));
444         torture_suite_add_simple_test(suite, "SPOOLSS", torture_rpc_spoolss);
445         torture_suite_add_suite(suite, torture_rpc_spoolss_notify(suite));
446         torture_suite_add_suite(suite, torture_rpc_spoolss_win(suite));
447         torture_suite_add_simple_test(suite, "SAMR", torture_rpc_samr);
448         torture_suite_add_simple_test(suite, "SAMR-USERS", torture_rpc_samr_users);
449         torture_suite_add_simple_test(suite, "SAMR-PASSWORDS", torture_rpc_samr_passwords);
450         torture_suite_add_suite(suite, torture_rpc_netlogon(suite));
451         torture_suite_add_suite(suite, torture_rpc_remote_pac(suite));
452         torture_suite_add_simple_test(suite, "SAMLOGON", torture_rpc_samlogon);
453         torture_suite_add_simple_test(suite, "SAMSYNC", torture_rpc_samsync);
454         torture_suite_add_simple_test(suite, "SCHANNEL", torture_rpc_schannel);
455         torture_suite_add_simple_test(suite, "SCHANNEL2", torture_rpc_schannel2);
456         torture_suite_add_simple_test(suite, "BENCH-SCHANNEL1", torture_rpc_schannel_bench1);
457         torture_suite_add_suite(suite, torture_rpc_srvsvc(suite));
458         torture_suite_add_suite(suite, torture_rpc_svcctl(suite));
459         torture_suite_add_suite(suite, torture_rpc_samr_accessmask(suite));
460         torture_suite_add_suite(suite, torture_rpc_samr_workstation_auth(suite));
461         torture_suite_add_suite(suite, torture_rpc_samr_passwords_pwdlastset(suite));
462         torture_suite_add_suite(suite, torture_rpc_samr_user_privileges(suite));
463         torture_suite_add_suite(suite, torture_rpc_samr_large_dc(suite));
464         torture_suite_add_suite(suite, torture_rpc_epmapper(suite));
465         torture_suite_add_suite(suite, torture_rpc_initshutdown(suite));
466         torture_suite_add_suite(suite, torture_rpc_oxidresolve(suite));
467         torture_suite_add_suite(suite, torture_rpc_remact(suite));
468         torture_suite_add_simple_test(suite, "MGMT", torture_rpc_mgmt);
469         torture_suite_add_simple_test(suite, "SCANNER", torture_rpc_scanner);
470         torture_suite_add_simple_test(suite, "AUTOIDL", torture_rpc_autoidl);
471         torture_suite_add_simple_test(suite, "COUNTCALLS", torture_rpc_countcalls);
472         torture_suite_add_simple_test(suite, "MULTIBIND", torture_multi_bind);
473         torture_suite_add_simple_test(suite, "AUTHCONTEXT", torture_bind_authcontext);
474         torture_suite_add_simple_test(suite, "BINDSAMBA3", torture_bind_samba3);
475         torture_suite_add_simple_test(suite, "NETLOGSAMBA3", torture_netlogon_samba3);
476         torture_suite_add_simple_test(suite, "SAMBA3SESSIONKEY", torture_samba3_sessionkey);
477         torture_suite_add_simple_test(suite, "SAMBA3-SRVSVC", torture_samba3_rpc_srvsvc);
478         torture_suite_add_simple_test(suite, "SAMBA3-SHARESEC",
479                             torture_samba3_rpc_sharesec);
480         torture_suite_add_simple_test(suite, "SAMBA3-GETUSERNAME",
481                             torture_samba3_rpc_getusername);
482         torture_suite_add_simple_test(suite, "SAMBA3-RANDOMAUTH2",
483                                       torture_samba3_rpc_randomauth2);
484         torture_suite_add_simple_test(suite, "SAMBA3-LSA", torture_samba3_rpc_lsa);
485         torture_suite_add_simple_test(suite, "SAMBA3-SPOOLSS", torture_samba3_rpc_spoolss);
486         torture_suite_add_simple_test(suite, "SAMBA3-WKSSVC", torture_samba3_rpc_wkssvc);
487         torture_suite_add_simple_test(suite, "SAMBA3-WINREG", torture_samba3_rpc_winreg);
488         torture_suite_add_simple_test(suite, "DRSUAPI", torture_rpc_drsuapi);
489         torture_suite_add_simple_test(suite, "CRACKNAMES", torture_rpc_drsuapi_cracknames);
490         torture_suite_add_suite(suite, torture_rpc_dssetup(suite));
491         torture_suite_add_suite(suite, torture_rpc_browser(suite));
492         torture_suite_add_simple_test(suite, "SAMBA3-REGCONFIG", torture_samba3_regconfig);
493         torture_suite_add_simple_test(suite, "ALTERCONTEXT", torture_rpc_alter_context);
494         torture_suite_add_simple_test(suite, "JOIN", torture_rpc_join);
495         torture_suite_add_simple_test(suite, "DSSYNC", torture_rpc_dssync);
496         torture_suite_add_simple_test(suite, "BENCH-RPC", torture_bench_rpc);
497         torture_suite_add_simple_test(suite, "ASYNCBIND", torture_async_bind);
498         torture_suite_add_suite(suite, torture_rpc_ntsvcs(suite));
499
500         suite->description = talloc_strdup(suite, "DCE/RPC protocol and interface tests");
501
502         torture_register_suite(suite);
503
504         return NT_STATUS_OK;
505 }