s4:torture: add a rpc.samba3.smb2-reauth2 test
[kai/samba.git] / source4 / torture / rpc / samba3rpc.c
1 /*f
2    Unix SMB/CIFS implementation.
3
4    dcerpc torture tests, designed to walk Samba3 code paths
5
6    Copyright (C) Volker Lendecke 2006
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/raw/raw_proto.h"
25 #include "torture/util.h"
26 #include "libcli/rap/rap.h"
27 #include "librpc/gen_ndr/ndr_lsa_c.h"
28 #include "librpc/gen_ndr/ndr_samr_c.h"
29 #include "librpc/gen_ndr/ndr_netlogon_c.h"
30 #include "librpc/gen_ndr/ndr_srvsvc_c.h"
31 #include "librpc/gen_ndr/ndr_spoolss_c.h"
32 #include "librpc/gen_ndr/ndr_winreg_c.h"
33 #include "librpc/gen_ndr/ndr_wkssvc_c.h"
34 #include "lib/cmdline/popt_common.h"
35 #include "torture/rpc/torture_rpc.h"
36 #include "libcli/libcli.h"
37 #include "libcli/smb_composite/smb_composite.h"
38 #include "libcli/auth/libcli_auth.h"
39 #include "../lib/crypto/crypto.h"
40 #include "libcli/security/security.h"
41 #include "param/param.h"
42 #include "lib/registry/registry.h"
43 #include "libcli/resolve/resolve.h"
44 #include "torture/ndr/ndr.h"
45 #include "libcli/smb2/smb2.h"
46 #include "libcli/smb2/smb2_calls.h"
47 #include "librpc/rpc/dcerpc.h"
48 #include "librpc/rpc/dcerpc_proto.h"
49
50 /*
51  * This tests a RPC call using an invalid vuid
52  */
53
54 bool torture_bind_authcontext(struct torture_context *torture)
55 {
56         TALLOC_CTX *mem_ctx;
57         NTSTATUS status;
58         bool ret = false;
59         struct lsa_ObjectAttribute objectattr;
60         struct lsa_OpenPolicy2 openpolicy;
61         struct policy_handle handle;
62         struct lsa_Close close_handle;
63         struct smbcli_session *tmp;
64         struct smbcli_session *session2;
65         struct smbcli_state *cli;
66         struct dcerpc_pipe *lsa_pipe;
67         struct dcerpc_binding_handle *lsa_handle;
68         struct cli_credentials *anon_creds;
69         struct smb_composite_sesssetup setup;
70         struct smbcli_options options;
71         struct smbcli_session_options session_options;
72
73         mem_ctx = talloc_init("torture_bind_authcontext");
74
75         if (mem_ctx == NULL) {
76                 torture_comment(torture, "talloc_init failed\n");
77                 return false;
78         }
79
80         lpcfg_smbcli_options(torture->lp_ctx, &options);
81         lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
82
83         status = smbcli_full_connection(mem_ctx, &cli,
84                                         torture_setting_string(torture, "host", NULL),
85                                         lpcfg_smb_ports(torture->lp_ctx),
86                                         "IPC$", NULL,
87                                         lpcfg_socket_options(torture->lp_ctx),
88                                         cmdline_credentials,
89                                         lpcfg_resolve_context(torture->lp_ctx),
90                                         torture->ev, &options, &session_options,
91                                         lpcfg_gensec_settings(torture, torture->lp_ctx));
92         if (!NT_STATUS_IS_OK(status)) {
93                 torture_comment(torture, "smbcli_full_connection failed: %s\n",
94                          nt_errstr(status));
95                 goto done;
96         }
97
98         lsa_pipe = dcerpc_pipe_init(mem_ctx, torture->ev);
99         if (lsa_pipe == NULL) {
100                 torture_comment(torture, "dcerpc_pipe_init failed\n");
101                 goto done;
102         }
103         lsa_handle = lsa_pipe->binding_handle;
104
105         status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
106         if (!NT_STATUS_IS_OK(status)) {
107                 torture_comment(torture, "dcerpc_pipe_open_smb failed: %s\n",
108                          nt_errstr(status));
109                 goto done;
110         }
111
112         status = dcerpc_bind_auth_none(lsa_pipe, &ndr_table_lsarpc);
113         if (!NT_STATUS_IS_OK(status)) {
114                 torture_comment(torture, "dcerpc_bind_auth_none failed: %s\n",
115                          nt_errstr(status));
116                 goto done;
117         }
118
119         openpolicy.in.system_name =talloc_asprintf(
120                 mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
121         ZERO_STRUCT(objectattr);
122         openpolicy.in.attr = &objectattr;
123         openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
124         openpolicy.out.handle = &handle;
125
126         status = dcerpc_lsa_OpenPolicy2_r(lsa_handle, mem_ctx, &openpolicy);
127
128         if (!NT_STATUS_IS_OK(status)) {
129                 torture_comment(torture, "dcerpc_lsa_OpenPolicy2 failed: %s\n",
130                          nt_errstr(status));
131                 goto done;
132         }
133         if (!NT_STATUS_IS_OK(openpolicy.out.result)) {
134                 torture_comment(torture, "dcerpc_lsa_OpenPolicy2 failed: %s\n",
135                          nt_errstr(openpolicy.out.result));
136                 goto done;
137         }
138
139         close_handle.in.handle = &handle;
140         close_handle.out.handle = &handle;
141
142         status = dcerpc_lsa_Close_r(lsa_handle, mem_ctx, &close_handle);
143         if (!NT_STATUS_IS_OK(status)) {
144                 torture_comment(torture, "dcerpc_lsa_Close failed: %s\n",
145                          nt_errstr(status));
146                 goto done;
147         }
148         if (!NT_STATUS_IS_OK(close_handle.out.result)) {
149                 torture_comment(torture, "dcerpc_lsa_Close failed: %s\n",
150                          nt_errstr(close_handle.out.result));
151                 goto done;
152         }
153
154         session2 = smbcli_session_init(cli->transport, mem_ctx, false, session_options);
155         if (session2 == NULL) {
156                 torture_comment(torture, "smbcli_session_init failed\n");
157                 goto done;
158         }
159
160         if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) {
161                 torture_comment(torture, "create_anon_creds failed\n");
162                 goto done;
163         }
164
165         setup.in.sesskey = cli->transport->negotiate.sesskey;
166         setup.in.capabilities = cli->transport->negotiate.capabilities;
167         setup.in.workgroup = "";
168         setup.in.credentials = anon_creds;
169         setup.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
170
171         status = smb_composite_sesssetup(session2, &setup);
172         if (!NT_STATUS_IS_OK(status)) {
173                 torture_comment(torture, "anon session setup failed: %s\n",
174                          nt_errstr(status));
175                 goto done;
176         }
177         session2->vuid = setup.out.vuid;
178
179         tmp = cli->tree->session;
180         cli->tree->session = session2;
181
182         status = dcerpc_lsa_OpenPolicy2_r(lsa_handle, mem_ctx, &openpolicy);
183
184         cli->tree->session = tmp;
185         talloc_free(lsa_pipe);
186         lsa_pipe = NULL;
187
188         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
189                 torture_comment(torture, "dcerpc_lsa_OpenPolicy2 with wrong vuid gave %s, "
190                          "expected NT_STATUS_INVALID_HANDLE\n",
191                          nt_errstr(status));
192                 goto done;
193         }
194
195         ret = true;
196  done:
197         talloc_free(mem_ctx);
198         return ret;
199 }
200
201 /*
202  * Bind to lsa using a specific auth method
203  */
204
205 static bool bindtest(struct torture_context *tctx,
206                      struct smbcli_state *cli,
207                      struct cli_credentials *credentials,
208                      uint8_t auth_type, uint8_t auth_level)
209 {
210         TALLOC_CTX *mem_ctx;
211         bool ret = false;
212         NTSTATUS status;
213
214         struct dcerpc_pipe *lsa_pipe;
215         struct dcerpc_binding_handle *lsa_handle;
216         struct lsa_ObjectAttribute objectattr;
217         struct lsa_OpenPolicy2 openpolicy;
218         struct lsa_QueryInfoPolicy query;
219         union lsa_PolicyInformation *info = NULL;
220         struct policy_handle handle;
221         struct lsa_Close close_handle;
222
223         if ((mem_ctx = talloc_init("bindtest")) == NULL) {
224                 torture_comment(tctx, "talloc_init failed\n");
225                 return false;
226         }
227
228         lsa_pipe = dcerpc_pipe_init(mem_ctx, tctx->ev);
229         if (lsa_pipe == NULL) {
230                 torture_comment(tctx, "dcerpc_pipe_init failed\n");
231                 goto done;
232         }
233         lsa_handle = lsa_pipe->binding_handle;
234
235         status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
236         if (!NT_STATUS_IS_OK(status)) {
237                 torture_comment(tctx, "dcerpc_pipe_open_smb failed: %s\n",
238                          nt_errstr(status));
239                 goto done;
240         }
241
242         status = dcerpc_bind_auth(lsa_pipe, &ndr_table_lsarpc,
243                                   credentials, lpcfg_gensec_settings(tctx->lp_ctx, tctx->lp_ctx), auth_type, auth_level,
244                                   NULL);
245         if (!NT_STATUS_IS_OK(status)) {
246                 torture_comment(tctx, "dcerpc_bind_auth failed: %s\n", nt_errstr(status));
247                 goto done;
248         }
249
250         openpolicy.in.system_name =talloc_asprintf(
251                 mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
252         ZERO_STRUCT(objectattr);
253         openpolicy.in.attr = &objectattr;
254         openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
255         openpolicy.out.handle = &handle;
256
257         status = dcerpc_lsa_OpenPolicy2_r(lsa_handle, mem_ctx, &openpolicy);
258
259         if (!NT_STATUS_IS_OK(status)) {
260                 torture_comment(tctx, "dcerpc_lsa_OpenPolicy2 failed: %s\n",
261                          nt_errstr(status));
262                 goto done;
263         }
264         if (!NT_STATUS_IS_OK(openpolicy.out.result)) {
265                 torture_comment(tctx, "dcerpc_lsa_OpenPolicy2 failed: %s\n",
266                          nt_errstr(openpolicy.out.result));
267                 goto done;
268         }
269
270         query.in.handle = &handle;
271         query.in.level = LSA_POLICY_INFO_DOMAIN;
272         query.out.info = &info;
273
274         status = dcerpc_lsa_QueryInfoPolicy_r(lsa_handle, mem_ctx, &query);
275         if (!NT_STATUS_IS_OK(status)) {
276                 torture_comment(tctx, "dcerpc_lsa_QueryInfoPolicy failed: %s\n",
277                          nt_errstr(status));
278                 goto done;
279         }
280         if (!NT_STATUS_IS_OK(query.out.result)) {
281                 torture_comment(tctx, "dcerpc_lsa_QueryInfoPolicy failed: %s\n",
282                          nt_errstr(query.out.result));
283                 goto done;
284         }
285
286         close_handle.in.handle = &handle;
287         close_handle.out.handle = &handle;
288
289         status = dcerpc_lsa_Close_r(lsa_handle, mem_ctx, &close_handle);
290         if (!NT_STATUS_IS_OK(status)) {
291                 torture_comment(tctx, "dcerpc_lsa_Close failed: %s\n",
292                          nt_errstr(status));
293                 goto done;
294         }
295         if (!NT_STATUS_IS_OK(close_handle.out.result)) {
296                 torture_comment(tctx, "dcerpc_lsa_Close failed: %s\n",
297                          nt_errstr(close_handle.out.result));
298                 goto done;
299         }
300
301
302         ret = true;
303  done:
304         talloc_free(mem_ctx);
305         return ret;
306 }
307
308 /*
309  * test authenticated RPC binds with the variants Samba3 does support
310  */
311
312 static bool torture_bind_samba3(struct torture_context *torture)
313 {
314         TALLOC_CTX *mem_ctx;
315         NTSTATUS status;
316         bool ret = false;
317         struct smbcli_state *cli;
318         struct smbcli_options options;
319         struct smbcli_session_options session_options;
320
321         mem_ctx = talloc_init("torture_bind_authcontext");
322
323         if (mem_ctx == NULL) {
324                 torture_comment(torture, "talloc_init failed\n");
325                 return false;
326         }
327
328         lpcfg_smbcli_options(torture->lp_ctx, &options);
329         lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
330
331         status = smbcli_full_connection(mem_ctx, &cli,
332                                         torture_setting_string(torture, "host", NULL),
333                                         lpcfg_smb_ports(torture->lp_ctx),
334                                         "IPC$", NULL,
335                                         lpcfg_socket_options(torture->lp_ctx),
336                                         cmdline_credentials,
337                                         lpcfg_resolve_context(torture->lp_ctx),
338                                         torture->ev, &options, &session_options,
339                                         lpcfg_gensec_settings(torture, torture->lp_ctx));
340         if (!NT_STATUS_IS_OK(status)) {
341                 torture_comment(torture, "smbcli_full_connection failed: %s\n",
342                          nt_errstr(status));
343                 goto done;
344         }
345
346         ret = true;
347
348         ret &= bindtest(torture, cli, cmdline_credentials, DCERPC_AUTH_TYPE_NTLMSSP,
349                         DCERPC_AUTH_LEVEL_INTEGRITY);
350         ret &= bindtest(torture, cli, cmdline_credentials, DCERPC_AUTH_TYPE_NTLMSSP,
351                         DCERPC_AUTH_LEVEL_PRIVACY);
352         ret &= bindtest(torture, cli, cmdline_credentials, DCERPC_AUTH_TYPE_SPNEGO,
353                         DCERPC_AUTH_LEVEL_INTEGRITY);
354         ret &= bindtest(torture, cli, cmdline_credentials, DCERPC_AUTH_TYPE_SPNEGO,
355                         DCERPC_AUTH_LEVEL_PRIVACY);
356
357  done:
358         talloc_free(mem_ctx);
359         return ret;
360 }
361
362 /*
363  * Lookup or create a user and return all necessary info
364  */
365
366 static bool get_usr_handle(struct torture_context *tctx,
367                            struct smbcli_state *cli,
368                            TALLOC_CTX *mem_ctx,
369                            struct cli_credentials *admin_creds,
370                            uint8_t auth_type,
371                            uint8_t auth_level,
372                            const char *username,
373                            char **domain,
374                            struct dcerpc_pipe **result_pipe,
375                            struct policy_handle **result_handle,
376                            struct dom_sid **sid_p)
377 {
378         struct dcerpc_pipe *samr_pipe;
379         struct dcerpc_binding_handle *samr_handle;
380         NTSTATUS status;
381         struct policy_handle conn_handle;
382         struct policy_handle domain_handle;
383         struct policy_handle *user_handle;
384         struct samr_Connect2 conn;
385         struct samr_EnumDomains enumdom;
386         uint32_t resume_handle = 0;
387         uint32_t num_entries = 0;
388         struct samr_SamArray *sam = NULL;
389         struct samr_LookupDomain l;
390         struct dom_sid2 *sid = NULL;
391         int dom_idx;
392         struct lsa_String domain_name;
393         struct lsa_String user_name;
394         struct samr_OpenDomain o;
395         struct samr_CreateUser2 c;
396         uint32_t user_rid,access_granted;
397
398         samr_pipe = dcerpc_pipe_init(mem_ctx, tctx->ev);
399         torture_assert(tctx, samr_pipe, "dcerpc_pipe_init failed");
400
401         samr_handle = samr_pipe->binding_handle;
402
403         torture_assert_ntstatus_ok(tctx,
404                 dcerpc_pipe_open_smb(samr_pipe, cli->tree, "\\samr"),
405                 "dcerpc_pipe_open_smb failed");
406
407         if (admin_creds != NULL) {
408                 torture_assert_ntstatus_ok(tctx,
409                         dcerpc_bind_auth(samr_pipe, &ndr_table_samr,
410                                           admin_creds, lpcfg_gensec_settings(tctx->lp_ctx, tctx->lp_ctx), auth_type, auth_level,
411                                           NULL),
412                         "dcerpc_bind_auth failed");
413         } else {
414                 /* We must have an authenticated SMB connection */
415                 torture_assert_ntstatus_ok(tctx,
416                         dcerpc_bind_auth_none(samr_pipe, &ndr_table_samr),
417                         "dcerpc_bind_auth_none failed");
418         }
419
420         conn.in.system_name = talloc_asprintf(
421                 mem_ctx, "\\\\%s", dcerpc_server_name(samr_pipe));
422         conn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
423         conn.out.connect_handle = &conn_handle;
424
425         torture_assert_ntstatus_ok(tctx,
426                 dcerpc_samr_Connect2_r(samr_handle, mem_ctx, &conn),
427                 "samr_Connect2 failed");
428         torture_assert_ntstatus_ok(tctx, conn.out.result,
429                 "samr_Connect2 failed");
430
431         enumdom.in.connect_handle = &conn_handle;
432         enumdom.in.resume_handle = &resume_handle;
433         enumdom.in.buf_size = (uint32_t)-1;
434         enumdom.out.resume_handle = &resume_handle;
435         enumdom.out.num_entries = &num_entries;
436         enumdom.out.sam = &sam;
437
438         torture_assert_ntstatus_ok(tctx,
439                 dcerpc_samr_EnumDomains_r(samr_handle, mem_ctx, &enumdom),
440                 "samr_EnumDomains failed");
441         torture_assert_ntstatus_ok(tctx, enumdom.out.result,
442                 "samr_EnumDomains failed");
443
444         torture_assert_int_equal(tctx, *enumdom.out.num_entries, 2,
445                 "samr_EnumDomains returned unexpected num_entries");
446
447         dom_idx = strequal(sam->entries[0].name.string,
448                            "builtin") ? 1:0;
449
450         l.in.connect_handle = &conn_handle;
451         domain_name.string = sam->entries[dom_idx].name.string;
452         *domain = talloc_strdup(mem_ctx, domain_name.string);
453         l.in.domain_name = &domain_name;
454         l.out.sid = &sid;
455
456         torture_assert_ntstatus_ok(tctx,
457                 dcerpc_samr_LookupDomain_r(samr_handle, mem_ctx, &l),
458                 "samr_LookupDomain failed");
459         torture_assert_ntstatus_ok(tctx, l.out.result,
460                 "samr_LookupDomain failed");
461
462         o.in.connect_handle = &conn_handle;
463         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
464         o.in.sid = *l.out.sid;
465         o.out.domain_handle = &domain_handle;
466
467         torture_assert_ntstatus_ok(tctx,
468                 dcerpc_samr_OpenDomain_r(samr_handle, mem_ctx, &o),
469                 "samr_OpenDomain failed");
470         torture_assert_ntstatus_ok(tctx, o.out.result,
471                 "samr_OpenDomain failed");
472
473         c.in.domain_handle = &domain_handle;
474         user_name.string = username;
475         c.in.account_name = &user_name;
476         c.in.acct_flags = ACB_NORMAL;
477         c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
478         user_handle = talloc(mem_ctx, struct policy_handle);
479         c.out.user_handle = user_handle;
480         c.out.access_granted = &access_granted;
481         c.out.rid = &user_rid;
482
483         torture_assert_ntstatus_ok(tctx,
484                 dcerpc_samr_CreateUser2_r(samr_handle, mem_ctx, &c),
485                 "samr_CreateUser2 failed");
486
487         if (NT_STATUS_EQUAL(c.out.result, NT_STATUS_USER_EXISTS)) {
488                 struct samr_LookupNames ln;
489                 struct samr_OpenUser ou;
490                 struct samr_Ids rids, types;
491
492                 ln.in.domain_handle = &domain_handle;
493                 ln.in.num_names = 1;
494                 ln.in.names = &user_name;
495                 ln.out.rids = &rids;
496                 ln.out.types = &types;
497
498                 torture_assert_ntstatus_ok(tctx,
499                         dcerpc_samr_LookupNames_r(samr_handle, mem_ctx, &ln),
500                         "samr_LookupNames failed");
501                 torture_assert_ntstatus_ok(tctx, ln.out.result,
502                         "samr_LookupNames failed");
503
504                 ou.in.domain_handle = &domain_handle;
505                 ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
506                 user_rid = ou.in.rid = ln.out.rids->ids[0];
507                 ou.out.user_handle = user_handle;
508
509                 torture_assert_ntstatus_ok(tctx,
510                         dcerpc_samr_OpenUser_r(samr_handle, mem_ctx, &ou),
511                         "samr_OpenUser failed");
512                 status = ou.out.result;
513         } else {
514                 status = c.out.result;
515         }
516
517         torture_assert_ntstatus_ok(tctx, status,
518                 "samr_CreateUser failed");
519
520         *result_pipe = samr_pipe;
521         *result_handle = user_handle;
522         if (sid_p != NULL) {
523                 *sid_p = dom_sid_add_rid(mem_ctx, *l.out.sid, user_rid);
524         }
525         return true;
526
527 }
528
529 /*
530  * Create a test user
531  */
532
533 static bool create_user(struct torture_context *tctx,
534                         TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
535                         struct cli_credentials *admin_creds,
536                         const char *username, const char *password,
537                         char **domain_name,
538                         struct dom_sid **user_sid)
539 {
540         TALLOC_CTX *tmp_ctx;
541         NTSTATUS status;
542         struct dcerpc_pipe *samr_pipe;
543         struct dcerpc_binding_handle *samr_handle;
544         struct policy_handle *wks_handle;
545         bool ret = false;
546
547         if (!(tmp_ctx = talloc_new(mem_ctx))) {
548                 torture_comment(tctx, "talloc_init failed\n");
549                 return false;
550         }
551
552         ret = get_usr_handle(tctx, cli, tmp_ctx, admin_creds,
553                              DCERPC_AUTH_TYPE_NTLMSSP,
554                              DCERPC_AUTH_LEVEL_INTEGRITY,
555                              username, domain_name, &samr_pipe, &wks_handle,
556                              user_sid);
557         if (ret == false) {
558                 torture_comment(tctx, "get_usr_handle failed\n");
559                 goto done;
560         }
561         samr_handle = samr_pipe->binding_handle;
562
563         {
564                 struct samr_SetUserInfo2 sui2;
565                 struct samr_SetUserInfo sui;
566                 struct samr_QueryUserInfo qui;
567                 union samr_UserInfo u_info;
568                 union samr_UserInfo *info;
569                 DATA_BLOB session_key;
570
571
572                 ZERO_STRUCT(u_info);
573                 encode_pw_buffer(u_info.info23.password.data, password,
574                                  STR_UNICODE);
575
576                 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
577                 if (!NT_STATUS_IS_OK(status)) {
578                         torture_comment(tctx, "dcerpc_fetch_session_key failed\n");
579                         goto done;
580                 }
581                 arcfour_crypt_blob(u_info.info23.password.data, 516,
582                                    &session_key);
583                 u_info.info23.info.password_expired = 0;
584                 u_info.info23.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
585                                                     SAMR_FIELD_LM_PASSWORD_PRESENT |
586                                                     SAMR_FIELD_EXPIRED_FLAG;
587                 sui2.in.user_handle = wks_handle;
588                 sui2.in.info = &u_info;
589                 sui2.in.level = 23;
590
591                 status = dcerpc_samr_SetUserInfo2_r(samr_handle, tmp_ctx, &sui2);
592                 if (!NT_STATUS_IS_OK(status)) {
593                         torture_comment(tctx, "samr_SetUserInfo(23) failed: %s\n",
594                                  nt_errstr(status));
595                         goto done;
596                 }
597                 if (!NT_STATUS_IS_OK(sui2.out.result)) {
598                         torture_comment(tctx, "samr_SetUserInfo(23) failed: %s\n",
599                                  nt_errstr(sui2.out.result));
600                         goto done;
601                 }
602
603                 u_info.info16.acct_flags = ACB_NORMAL;
604                 sui.in.user_handle = wks_handle;
605                 sui.in.info = &u_info;
606                 sui.in.level = 16;
607
608                 status = dcerpc_samr_SetUserInfo_r(samr_handle, tmp_ctx, &sui);
609                 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(sui.out.result)) {
610                         torture_comment(tctx, "samr_SetUserInfo(16) failed\n");
611                         goto done;
612                 }
613
614                 qui.in.user_handle = wks_handle;
615                 qui.in.level = 21;
616                 qui.out.info = &info;
617
618                 status = dcerpc_samr_QueryUserInfo_r(samr_handle, tmp_ctx, &qui);
619                 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(qui.out.result)) {
620                         torture_comment(tctx, "samr_QueryUserInfo(21) failed\n");
621                         goto done;
622                 }
623
624                 info->info21.allow_password_change = 0;
625                 info->info21.force_password_change = 0;
626                 info->info21.account_name.string = NULL;
627                 info->info21.rid = 0;
628                 info->info21.acct_expiry = 0;
629                 info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
630
631                 u_info.info21 = info->info21;
632                 sui.in.user_handle = wks_handle;
633                 sui.in.info = &u_info;
634                 sui.in.level = 21;
635
636                 status = dcerpc_samr_SetUserInfo_r(samr_handle, tmp_ctx, &sui);
637                 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(sui.out.result)) {
638                         torture_comment(tctx, "samr_SetUserInfo(21) failed\n");
639                         goto done;
640                 }
641         }
642
643         *domain_name= talloc_steal(mem_ctx, *domain_name);
644         *user_sid = talloc_steal(mem_ctx, *user_sid);
645         ret = true;
646  done:
647         talloc_free(tmp_ctx);
648         return ret;
649 }
650
651 /*
652  * Delete a test user
653  */
654
655 static bool delete_user(struct torture_context *tctx,
656                         struct smbcli_state *cli,
657                         struct cli_credentials *admin_creds,
658                         const char *username)
659 {
660         TALLOC_CTX *mem_ctx;
661         NTSTATUS status;
662         char *dom_name;
663         struct dcerpc_pipe *samr_pipe;
664         struct dcerpc_binding_handle *samr_handle;
665         struct policy_handle *user_handle;
666         bool ret = false;
667
668         if ((mem_ctx = talloc_init("leave")) == NULL) {
669                 torture_comment(tctx, "talloc_init failed\n");
670                 return false;
671         }
672
673         ret = get_usr_handle(tctx, cli, mem_ctx, admin_creds,
674                              DCERPC_AUTH_TYPE_NTLMSSP,
675                              DCERPC_AUTH_LEVEL_INTEGRITY,
676                              username, &dom_name, &samr_pipe,
677                              &user_handle, NULL);
678         if (ret == false) {
679                 torture_comment(tctx, "get_wks_handle failed\n");
680                 goto done;
681         }
682         samr_handle = samr_pipe->binding_handle;
683
684         {
685                 struct samr_DeleteUser d;
686
687                 d.in.user_handle = user_handle;
688                 d.out.user_handle = user_handle;
689
690                 status = dcerpc_samr_DeleteUser_r(samr_handle, mem_ctx, &d);
691                 if (!NT_STATUS_IS_OK(status)) {
692                         torture_comment(tctx, "samr_DeleteUser failed %s\n", nt_errstr(status));
693                         goto done;
694                 }
695                 if (!NT_STATUS_IS_OK(d.out.result)) {
696                         torture_comment(tctx, "samr_DeleteUser failed %s\n", nt_errstr(d.out.result));
697                         goto done;
698                 }
699
700         }
701
702         ret = true;
703
704  done:
705         talloc_free(mem_ctx);
706         return ret;
707 }
708
709 /*
710  * Do a Samba3-style join
711  */
712
713 static bool join3(struct torture_context *tctx,
714                   struct smbcli_state *cli,
715                   bool use_level25,
716                   struct cli_credentials *admin_creds,
717                   struct cli_credentials *wks_creds)
718 {
719         TALLOC_CTX *mem_ctx;
720         NTSTATUS status;
721         char *dom_name;
722         struct dcerpc_pipe *samr_pipe;
723         struct dcerpc_binding_handle *samr_handle;
724         struct policy_handle *wks_handle;
725         bool ret = false;
726         NTTIME last_password_change;
727
728         if ((mem_ctx = talloc_init("join3")) == NULL) {
729                 torture_comment(tctx, "talloc_init failed\n");
730                 return false;
731         }
732
733         ret = get_usr_handle(
734                 tctx, cli, mem_ctx, admin_creds,
735                 DCERPC_AUTH_TYPE_NTLMSSP,
736                 DCERPC_AUTH_LEVEL_PRIVACY,
737                 talloc_asprintf(mem_ctx, "%s$",
738                                 cli_credentials_get_workstation(wks_creds)),
739                 &dom_name, &samr_pipe, &wks_handle, NULL);
740         if (ret == false) {
741                 torture_comment(tctx, "get_wks_handle failed\n");
742                 goto done;
743         }
744         samr_handle = samr_pipe->binding_handle;
745
746         {
747                 struct samr_QueryUserInfo q;
748                 union samr_UserInfo *info;
749
750                 q.in.user_handle = wks_handle;
751                 q.in.level = 21;
752                 q.out.info = &info;
753
754                 status = dcerpc_samr_QueryUserInfo_r(samr_handle, mem_ctx, &q);
755                 if (!NT_STATUS_IS_OK(status)) {
756                         torture_warning(tctx, "QueryUserInfo failed: %s\n",
757                                   nt_errstr(status));
758                         goto done;
759                 }
760                 if (!NT_STATUS_IS_OK(q.out.result)) {
761                         torture_warning(tctx, "QueryUserInfo failed: %s\n",
762                                   nt_errstr(q.out.result));
763                         goto done;
764                 }
765
766
767                 last_password_change = info->info21.last_password_change;
768         }
769
770         cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);
771
772         if (use_level25) {
773                 struct samr_SetUserInfo2 sui2;
774                 union samr_UserInfo u_info;
775                 struct samr_UserInfo21 *i21 = &u_info.info25.info;
776                 DATA_BLOB session_key;
777                 DATA_BLOB confounded_session_key = data_blob_talloc(
778                         mem_ctx, NULL, 16);
779                 struct MD5Context ctx;
780                 uint8_t confounder[16];
781
782                 ZERO_STRUCT(u_info);
783
784                 i21->full_name.string = talloc_asprintf(
785                         mem_ctx, "%s$",
786                         cli_credentials_get_workstation(wks_creds));
787                 i21->acct_flags = ACB_WSTRUST;
788                 i21->fields_present = SAMR_FIELD_FULL_NAME |
789                         SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_NT_PASSWORD_PRESENT;
790                 /* this would break the test result expectations
791                 i21->fields_present |= SAMR_FIELD_EXPIRED_FLAG;
792                 i21->password_expired = 1;
793                 */
794
795                 encode_pw_buffer(u_info.info25.password.data,
796                                  cli_credentials_get_password(wks_creds),
797                                  STR_UNICODE);
798                 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
799                 if (!NT_STATUS_IS_OK(status)) {
800                         torture_comment(tctx, "dcerpc_fetch_session_key failed: %s\n",
801                                  nt_errstr(status));
802                         goto done;
803                 }
804                 generate_random_buffer((uint8_t *)confounder, 16);
805
806                 MD5Init(&ctx);
807                 MD5Update(&ctx, confounder, 16);
808                 MD5Update(&ctx, session_key.data, session_key.length);
809                 MD5Final(confounded_session_key.data, &ctx);
810
811                 arcfour_crypt_blob(u_info.info25.password.data, 516,
812                                    &confounded_session_key);
813                 memcpy(&u_info.info25.password.data[516], confounder, 16);
814
815                 sui2.in.user_handle = wks_handle;
816                 sui2.in.level = 25;
817                 sui2.in.info = &u_info;
818
819                 status = dcerpc_samr_SetUserInfo2_r(samr_handle, mem_ctx, &sui2);
820                 if (!NT_STATUS_IS_OK(status)) {
821                         torture_comment(tctx, "samr_SetUserInfo2(25) failed: %s\n",
822                                  nt_errstr(status));
823                         goto done;
824                 }
825                 if (!NT_STATUS_IS_OK(sui2.out.result)) {
826                         torture_comment(tctx, "samr_SetUserInfo2(25) failed: %s\n",
827                                  nt_errstr(sui2.out.result));
828                         goto done;
829                 }
830         } else {
831                 struct samr_SetUserInfo2 sui2;
832                 struct samr_SetUserInfo sui;
833                 union samr_UserInfo u_info;
834                 DATA_BLOB session_key;
835
836                 encode_pw_buffer(u_info.info24.password.data,
837                                  cli_credentials_get_password(wks_creds),
838                                  STR_UNICODE);
839                 /* just to make this test pass */
840                 u_info.info24.password_expired = 1;
841
842                 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
843                 if (!NT_STATUS_IS_OK(status)) {
844                         torture_comment(tctx, "dcerpc_fetch_session_key failed\n");
845                         goto done;
846                 }
847                 arcfour_crypt_blob(u_info.info24.password.data, 516,
848                                    &session_key);
849                 sui2.in.user_handle = wks_handle;
850                 sui2.in.info = &u_info;
851                 sui2.in.level = 24;
852
853                 status = dcerpc_samr_SetUserInfo2_r(samr_handle, mem_ctx, &sui2);
854                 if (!NT_STATUS_IS_OK(status)) {
855                         torture_comment(tctx, "samr_SetUserInfo(24) failed: %s\n",
856                                  nt_errstr(status));
857                         goto done;
858                 }
859                 if (!NT_STATUS_IS_OK(sui2.out.result)) {
860                         torture_comment(tctx, "samr_SetUserInfo(24) failed: %s\n",
861                                  nt_errstr(sui2.out.result));
862                         goto done;
863                 }
864
865                 u_info.info16.acct_flags = ACB_WSTRUST;
866                 sui.in.user_handle = wks_handle;
867                 sui.in.info = &u_info;
868                 sui.in.level = 16;
869
870                 status = dcerpc_samr_SetUserInfo_r(samr_handle, mem_ctx, &sui);
871                 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(sui.out.result)) {
872                         torture_comment(tctx, "samr_SetUserInfo(16) failed\n");
873                         goto done;
874                 }
875         }
876
877         {
878                 struct samr_QueryUserInfo q;
879                 union samr_UserInfo *info;
880
881                 q.in.user_handle = wks_handle;
882                 q.in.level = 21;
883                 q.out.info = &info;
884
885                 status = dcerpc_samr_QueryUserInfo_r(samr_handle, mem_ctx, &q);
886                 if (!NT_STATUS_IS_OK(status)) {
887                         torture_warning(tctx, "QueryUserInfo failed: %s\n",
888                                   nt_errstr(status));
889                         goto done;
890                 }
891                 if (!NT_STATUS_IS_OK(q.out.result)) {
892                         torture_warning(tctx, "QueryUserInfo failed: %s\n",
893                                   nt_errstr(q.out.result));
894                         goto done;
895                 }
896
897                 if (use_level25) {
898                         if (last_password_change
899                             == info->info21.last_password_change) {
900                                 torture_warning(tctx, "last_password_change unchanged "
901                                          "during join, level25 must change "
902                                          "it\n");
903                                 goto done;
904                         }
905                 }
906                 else {
907                         if (last_password_change
908                             != info->info21.last_password_change) {
909                                 torture_warning(tctx, "last_password_change changed "
910                                          "during join, level24 doesn't "
911                                          "change it\n");
912                                 goto done;
913                         }
914                 }
915         }
916
917         ret = true;
918
919  done:
920         talloc_free(mem_ctx);
921         return ret;
922 }
923
924 /*
925  * Do a ReqChallenge/Auth2 and get the wks creds
926  */
927
928 static bool auth2(struct torture_context *tctx,
929                   struct smbcli_state *cli,
930                   struct cli_credentials *wks_cred)
931 {
932         TALLOC_CTX *mem_ctx;
933         struct dcerpc_pipe *net_pipe;
934         struct dcerpc_binding_handle *net_handle;
935         bool result = false;
936         NTSTATUS status;
937         struct netr_ServerReqChallenge r;
938         struct netr_Credential netr_cli_creds;
939         struct netr_Credential netr_srv_creds;
940         uint32_t negotiate_flags;
941         struct netr_ServerAuthenticate2 a;
942         struct netlogon_creds_CredentialState *creds_state;
943         struct netr_Credential netr_cred;
944         struct samr_Password mach_pw;
945
946         mem_ctx = talloc_new(NULL);
947         if (mem_ctx == NULL) {
948                 torture_comment(tctx, "talloc_new failed\n");
949                 return false;
950         }
951
952         net_pipe = dcerpc_pipe_init(mem_ctx, tctx->ev);
953         if (net_pipe == NULL) {
954                 torture_comment(tctx, "dcerpc_pipe_init failed\n");
955                 goto done;
956         }
957         net_handle = net_pipe->binding_handle;
958
959         status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
960         if (!NT_STATUS_IS_OK(status)) {
961                 torture_comment(tctx, "dcerpc_pipe_open_smb failed: %s\n",
962                          nt_errstr(status));
963                 goto done;
964         }
965
966         status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon);
967         if (!NT_STATUS_IS_OK(status)) {
968                 torture_comment(tctx, "dcerpc_bind_auth_none failed: %s\n",
969                          nt_errstr(status));
970                 goto done;
971         }
972
973         r.in.computer_name = cli_credentials_get_workstation(wks_cred);
974         r.in.server_name = talloc_asprintf(
975                 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
976         if (r.in.server_name == NULL) {
977                 torture_comment(tctx, "talloc_asprintf failed\n");
978                 goto done;
979         }
980         generate_random_buffer(netr_cli_creds.data,
981                                sizeof(netr_cli_creds.data));
982         r.in.credentials = &netr_cli_creds;
983         r.out.return_credentials = &netr_srv_creds;
984
985         status = dcerpc_netr_ServerReqChallenge_r(net_handle, mem_ctx, &r);
986         if (!NT_STATUS_IS_OK(status)) {
987                 torture_comment(tctx, "netr_ServerReqChallenge failed: %s\n",
988                          nt_errstr(status));
989                 goto done;
990         }
991         if (!NT_STATUS_IS_OK(r.out.result)) {
992                 torture_comment(tctx, "netr_ServerReqChallenge failed: %s\n",
993                          nt_errstr(r.out.result));
994                 goto done;
995         }
996
997         negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
998         E_md4hash(cli_credentials_get_password(wks_cred), mach_pw.hash);
999
1000         a.in.server_name = talloc_asprintf(
1001                 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1002         a.in.account_name = talloc_asprintf(
1003                 mem_ctx, "%s$", cli_credentials_get_workstation(wks_cred));
1004         a.in.computer_name = cli_credentials_get_workstation(wks_cred);
1005         a.in.secure_channel_type = SEC_CHAN_WKSTA;
1006         a.in.negotiate_flags = &negotiate_flags;
1007         a.out.negotiate_flags = &negotiate_flags;
1008         a.in.credentials = &netr_cred;
1009         a.out.return_credentials = &netr_cred;
1010
1011         creds_state = netlogon_creds_client_init(mem_ctx,
1012                                                  a.in.account_name,
1013                                                  a.in.computer_name,
1014                                                  r.in.credentials,
1015                                                  r.out.return_credentials, &mach_pw,
1016                                                  &netr_cred, negotiate_flags);
1017
1018         status = dcerpc_netr_ServerAuthenticate2_r(net_handle, mem_ctx, &a);
1019         if (!NT_STATUS_IS_OK(status)) {
1020                 torture_comment(tctx, "netr_ServerServerAuthenticate2 failed: %s\n",
1021                          nt_errstr(status));
1022                 goto done;
1023         }
1024         if (!NT_STATUS_IS_OK(a.out.result)) {
1025                 torture_comment(tctx, "netr_ServerServerAuthenticate2 failed: %s\n",
1026                          nt_errstr(a.out.result));
1027                 goto done;
1028         }
1029
1030         if (!netlogon_creds_client_check(creds_state, a.out.return_credentials)) {
1031                 torture_comment(tctx, "creds_client_check failed\n");
1032                 goto done;
1033         }
1034
1035         cli_credentials_set_netlogon_creds(wks_cred, creds_state);
1036
1037         result = true;
1038
1039  done:
1040         talloc_free(mem_ctx);
1041         return result;
1042 }
1043
1044 /*
1045  * Do a couple of schannel protected Netlogon ops: Interactive and Network
1046  * login, and change the wks password
1047  */
1048
1049 static bool schan(struct torture_context *tctx,
1050                   struct smbcli_state *cli,
1051                   struct cli_credentials *wks_creds,
1052                   struct cli_credentials *user_creds)
1053 {
1054         TALLOC_CTX *mem_ctx;
1055         NTSTATUS status;
1056         bool ret = false;
1057         struct dcerpc_pipe *net_pipe;
1058         struct dcerpc_binding_handle *net_handle;
1059         int i;
1060
1061         mem_ctx = talloc_new(NULL);
1062         if (mem_ctx == NULL) {
1063                 torture_comment(tctx, "talloc_new failed\n");
1064                 return false;
1065         }
1066
1067         net_pipe = dcerpc_pipe_init(mem_ctx, tctx->ev);
1068         if (net_pipe == NULL) {
1069                 torture_comment(tctx, "dcerpc_pipe_init failed\n");
1070                 goto done;
1071         }
1072         net_handle = net_pipe->binding_handle;
1073
1074         status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
1075         if (!NT_STATUS_IS_OK(status)) {
1076                 torture_comment(tctx, "dcerpc_pipe_open_smb failed: %s\n",
1077                          nt_errstr(status));
1078                 goto done;
1079         }
1080
1081 #if 0
1082         net_pipe->conn->flags |= DCERPC_DEBUG_PRINT_IN |
1083                 DCERPC_DEBUG_PRINT_OUT;
1084 #endif
1085 #if 1
1086         net_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL);
1087         status = dcerpc_bind_auth(net_pipe, &ndr_table_netlogon,
1088                                   wks_creds, lpcfg_gensec_settings(tctx->lp_ctx, tctx->lp_ctx), DCERPC_AUTH_TYPE_SCHANNEL,
1089                                   DCERPC_AUTH_LEVEL_PRIVACY,
1090                                   NULL);
1091 #else
1092         status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon);
1093 #endif
1094         if (!NT_STATUS_IS_OK(status)) {
1095                 torture_comment(tctx, "schannel bind failed: %s\n", nt_errstr(status));
1096                 goto done;
1097         }
1098
1099
1100         for (i=2; i<4; i++) {
1101                 int flags;
1102                 DATA_BLOB chal, nt_resp, lm_resp, names_blob, session_key;
1103                 struct netlogon_creds_CredentialState *creds_state;
1104                 struct netr_Authenticator netr_auth, netr_auth2;
1105                 struct netr_NetworkInfo ninfo;
1106                 struct netr_PasswordInfo pinfo;
1107                 struct netr_LogonSamLogon r;
1108                 union netr_LogonLevel logon;
1109                 union netr_Validation validation;
1110                 uint8_t authoritative;
1111                 struct netr_Authenticator return_authenticator;
1112
1113                 flags = CLI_CRED_LANMAN_AUTH | CLI_CRED_NTLM_AUTH |
1114                         CLI_CRED_NTLMv2_AUTH;
1115
1116                 chal = data_blob_talloc(mem_ctx, NULL, 8);
1117                 if (chal.data == NULL) {
1118                         torture_comment(tctx, "data_blob_talloc failed\n");
1119                         goto done;
1120                 }
1121
1122                 generate_random_buffer(chal.data, chal.length);
1123                 names_blob = NTLMv2_generate_names_blob(
1124                         mem_ctx,
1125                         cli_credentials_get_workstation(user_creds),
1126                         cli_credentials_get_domain(user_creds));
1127                 status = cli_credentials_get_ntlm_response(
1128                         user_creds, mem_ctx, &flags, chal, names_blob,
1129                         &lm_resp, &nt_resp, NULL, NULL);
1130                 if (!NT_STATUS_IS_OK(status)) {
1131                         torture_comment(tctx, "cli_credentials_get_ntlm_response failed:"
1132                                  " %s\n", nt_errstr(status));
1133                         goto done;
1134                 }
1135
1136                 creds_state = cli_credentials_get_netlogon_creds(wks_creds);
1137                 netlogon_creds_client_authenticator(creds_state, &netr_auth);
1138
1139                 ninfo.identity_info.account_name.string =
1140                         cli_credentials_get_username(user_creds);
1141                 ninfo.identity_info.domain_name.string =
1142                         cli_credentials_get_domain(user_creds);
1143                 ninfo.identity_info.parameter_control = 0;
1144                 ninfo.identity_info.logon_id_low = 0;
1145                 ninfo.identity_info.logon_id_high = 0;
1146                 ninfo.identity_info.workstation.string =
1147                         cli_credentials_get_workstation(user_creds);
1148                 memcpy(ninfo.challenge, chal.data, sizeof(ninfo.challenge));
1149                 ninfo.nt.length = nt_resp.length;
1150                 ninfo.nt.data = nt_resp.data;
1151                 ninfo.lm.length = lm_resp.length;
1152                 ninfo.lm.data = lm_resp.data;
1153
1154                 logon.network = &ninfo;
1155
1156                 r.in.server_name = talloc_asprintf(
1157                         mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1158                 ZERO_STRUCT(netr_auth2);
1159                 r.in.computer_name =
1160                         cli_credentials_get_workstation(wks_creds);
1161                 r.in.credential = &netr_auth;
1162                 r.in.return_authenticator = &netr_auth2;
1163                 r.in.logon_level = 2;
1164                 r.in.validation_level = i;
1165                 r.in.logon = &logon;
1166                 r.out.validation = &validation;
1167                 r.out.authoritative = &authoritative;
1168                 r.out.return_authenticator = &return_authenticator;
1169
1170                 status = dcerpc_netr_LogonSamLogon_r(net_handle, mem_ctx, &r);
1171                 if (!NT_STATUS_IS_OK(status)) {
1172                         torture_comment(tctx, "netr_LogonSamLogon failed: %s\n",
1173                                  nt_errstr(status));
1174                         goto done;
1175                 }
1176                 if (!NT_STATUS_IS_OK(r.out.result)) {
1177                         torture_comment(tctx, "netr_LogonSamLogon failed: %s\n",
1178                                  nt_errstr(r.out.result));
1179                         goto done;
1180                 }
1181
1182                 if ((r.out.return_authenticator == NULL) ||
1183                     (!netlogon_creds_client_check(creds_state,
1184                                          &r.out.return_authenticator->cred))) {
1185                         torture_comment(tctx, "Credentials check failed!\n");
1186                         goto done;
1187                 }
1188
1189                 netlogon_creds_client_authenticator(creds_state, &netr_auth);
1190
1191                 pinfo.identity_info = ninfo.identity_info;
1192                 ZERO_STRUCT(pinfo.lmpassword.hash);
1193                 E_md4hash(cli_credentials_get_password(user_creds),
1194                           pinfo.ntpassword.hash);
1195                 session_key = data_blob_talloc(mem_ctx,
1196                                                creds_state->session_key, 16);
1197                 arcfour_crypt_blob(pinfo.ntpassword.hash,
1198                                    sizeof(pinfo.ntpassword.hash),
1199                                    &session_key);
1200
1201                 logon.password = &pinfo;
1202
1203                 r.in.logon_level = 1;
1204                 r.in.logon = &logon;
1205                 r.out.return_authenticator = &return_authenticator;
1206
1207                 status = dcerpc_netr_LogonSamLogon_r(net_handle, mem_ctx, &r);
1208                 if (!NT_STATUS_IS_OK(status)) {
1209                         torture_comment(tctx, "netr_LogonSamLogon failed: %s\n",
1210                                  nt_errstr(status));
1211                         goto done;
1212                 }
1213                 if (!NT_STATUS_IS_OK(r.out.result)) {
1214                         torture_comment(tctx, "netr_LogonSamLogon failed: %s\n",
1215                                  nt_errstr(r.out.result));
1216                         goto done;
1217                 }
1218
1219                 if ((r.out.return_authenticator == NULL) ||
1220                     (!netlogon_creds_client_check(creds_state,
1221                                          &r.out.return_authenticator->cred))) {
1222                         torture_comment(tctx, "Credentials check failed!\n");
1223                         goto done;
1224                 }
1225         }
1226
1227         {
1228                 struct netr_ServerPasswordSet s;
1229                 char *password = generate_random_password(wks_creds, 8, 255);
1230                 struct netlogon_creds_CredentialState *creds_state;
1231                 struct netr_Authenticator credential, return_authenticator;
1232                 struct samr_Password new_password;
1233
1234                 s.in.server_name = talloc_asprintf(
1235                         mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1236                 s.in.computer_name = cli_credentials_get_workstation(wks_creds);
1237                 s.in.account_name = talloc_asprintf(
1238                         mem_ctx, "%s$", s.in.computer_name);
1239                 s.in.secure_channel_type = SEC_CHAN_WKSTA;
1240                 s.in.credential = &credential;
1241                 s.in.new_password = &new_password;
1242                 s.out.return_authenticator = &return_authenticator;
1243
1244                 E_md4hash(password, new_password.hash);
1245
1246                 creds_state = cli_credentials_get_netlogon_creds(wks_creds);
1247                 netlogon_creds_des_encrypt(creds_state, &new_password);
1248                 netlogon_creds_client_authenticator(creds_state, &credential);
1249
1250                 status = dcerpc_netr_ServerPasswordSet_r(net_handle, mem_ctx, &s);
1251                 if (!NT_STATUS_IS_OK(status)) {
1252                         torture_comment(tctx, "ServerPasswordSet - %s\n", nt_errstr(status));
1253                         goto done;
1254                 }
1255                 if (!NT_STATUS_IS_OK(s.out.result)) {
1256                         torture_comment(tctx, "ServerPasswordSet - %s\n", nt_errstr(s.out.result));
1257                         goto done;
1258                 }
1259
1260                 if (!netlogon_creds_client_check(creds_state,
1261                                                  &s.out.return_authenticator->cred)) {
1262                         torture_comment(tctx, "Credential chaining failed\n");
1263                 }
1264
1265                 cli_credentials_set_password(wks_creds, password,
1266                                              CRED_SPECIFIED);
1267         }
1268
1269         ret = true;
1270  done:
1271         talloc_free(mem_ctx);
1272         return ret;
1273 }
1274
1275 /*
1276  * Delete the wks account again
1277  */
1278
1279 static bool leave(struct torture_context *tctx,
1280                   struct smbcli_state *cli,
1281                   struct cli_credentials *admin_creds,
1282                   struct cli_credentials *wks_creds)
1283 {
1284         char *wks_name = talloc_asprintf(
1285                 NULL, "%s$", cli_credentials_get_workstation(wks_creds));
1286         bool ret;
1287
1288         ret = delete_user(tctx, cli, admin_creds, wks_name);
1289         talloc_free(wks_name);
1290         return ret;
1291 }
1292
1293 /*
1294  * Test the Samba3 DC code a bit. Join, do some schan netlogon ops, leave
1295  */
1296
1297 static bool torture_netlogon_samba3(struct torture_context *torture)
1298 {
1299         NTSTATUS status;
1300         struct smbcli_state *cli;
1301         struct cli_credentials *anon_creds;
1302         struct cli_credentials *wks_creds;
1303         const char *wks_name;
1304         int i;
1305         struct smbcli_options options;
1306         struct smbcli_session_options session_options;
1307
1308         wks_name = torture_setting_string(torture, "wksname", NULL);
1309         if (wks_name == NULL) {
1310                 wks_name = get_myname(torture);
1311         }
1312
1313         if (!(anon_creds = cli_credentials_init_anon(torture))) {
1314                 torture_fail(torture, "create_anon_creds failed\n");
1315         }
1316
1317         lpcfg_smbcli_options(torture->lp_ctx, &options);
1318         lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
1319
1320         status = smbcli_full_connection(torture, &cli,
1321                                         torture_setting_string(torture, "host", NULL),
1322                                         lpcfg_smb_ports(torture->lp_ctx),
1323                                         "IPC$", NULL,
1324                                         lpcfg_socket_options(torture->lp_ctx),
1325                                         anon_creds,
1326                                         lpcfg_resolve_context(torture->lp_ctx),
1327                                         torture->ev, &options, &session_options,
1328                                         lpcfg_gensec_settings(torture, torture->lp_ctx));
1329         torture_assert_ntstatus_ok(torture, status, "smbcli_full_connection failed\n");
1330
1331         wks_creds = cli_credentials_init(torture);
1332         if (wks_creds == NULL) {
1333                 torture_fail(torture, "cli_credentials_init failed\n");
1334         }
1335
1336         cli_credentials_set_conf(wks_creds, torture->lp_ctx);
1337         cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1338         cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1339         cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1340         cli_credentials_set_password(wks_creds,
1341                                      generate_random_password(wks_creds, 8, 255),
1342                                      CRED_SPECIFIED);
1343
1344         torture_assert(torture,
1345                 join3(torture, cli, false, cmdline_credentials, wks_creds),
1346                 "join failed");
1347
1348         cli_credentials_set_domain(
1349                 cmdline_credentials, cli_credentials_get_domain(wks_creds),
1350                 CRED_SPECIFIED);
1351
1352         for (i=0; i<2; i++) {
1353
1354                 /* Do this more than once, the routine "schan" changes
1355                  * the workstation password using the netlogon
1356                  * password change routine */
1357
1358                 int j;
1359
1360                 torture_assert(torture,
1361                         auth2(torture, cli, wks_creds),
1362                         "auth2 failed");
1363
1364                 for (j=0; j<2; j++) {
1365                         torture_assert(torture,
1366                                 schan(torture, cli, wks_creds, cmdline_credentials),
1367                                 "schan failed");
1368                 }
1369         }
1370
1371         torture_assert(torture,
1372                 leave(torture, cli, cmdline_credentials, wks_creds),
1373                 "leave failed");
1374
1375         return true;
1376 }
1377
1378 /*
1379  * Do a simple join, testjoin and leave using specified smb and samr
1380  * credentials
1381  */
1382
1383 static bool test_join3(struct torture_context *tctx,
1384                        bool use_level25,
1385                        struct cli_credentials *smb_creds,
1386                        struct cli_credentials *samr_creds,
1387                        const char *wks_name)
1388 {
1389         NTSTATUS status;
1390         struct smbcli_state *cli;
1391         struct cli_credentials *wks_creds;
1392         struct smbcli_options options;
1393         struct smbcli_session_options session_options;
1394
1395         lpcfg_smbcli_options(tctx->lp_ctx, &options);
1396         lpcfg_smbcli_session_options(tctx->lp_ctx, &session_options);
1397
1398         status = smbcli_full_connection(tctx, &cli,
1399                                         torture_setting_string(tctx, "host", NULL),
1400                                         lpcfg_smb_ports(tctx->lp_ctx),
1401                                         "IPC$", NULL, lpcfg_socket_options(tctx->lp_ctx),
1402                                         smb_creds, lpcfg_resolve_context(tctx->lp_ctx),
1403                                         tctx->ev, &options, &session_options,
1404                                         lpcfg_gensec_settings(tctx, tctx->lp_ctx));
1405         torture_assert_ntstatus_ok(tctx, status,
1406                 "smbcli_full_connection failed");
1407
1408         wks_creds = cli_credentials_init(cli);
1409         torture_assert(tctx, wks_creds, "cli_credentials_init failed");
1410
1411         cli_credentials_set_conf(wks_creds, tctx->lp_ctx);
1412         cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1413         cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1414         cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1415         cli_credentials_set_password(wks_creds,
1416                                      generate_random_password(wks_creds, 8, 255),
1417                                      CRED_SPECIFIED);
1418
1419         torture_assert(tctx,
1420                 join3(tctx, cli, use_level25, samr_creds, wks_creds),
1421                 "join failed");
1422
1423         cli_credentials_set_domain(
1424                 cmdline_credentials, cli_credentials_get_domain(wks_creds),
1425                 CRED_SPECIFIED);
1426
1427         torture_assert(tctx,
1428                 auth2(tctx, cli, wks_creds),
1429                 "auth2 failed");
1430
1431         torture_assert(tctx,
1432                 leave(tctx, cli, samr_creds, wks_creds),
1433                 "leave failed");
1434
1435         talloc_free(cli);
1436
1437         return true;
1438 }
1439
1440 /*
1441  * Test the different session key variants. Do it by joining, this uses the
1442  * session key in the setpassword routine. Test the join by doing the auth2.
1443  */
1444
1445 static bool torture_samba3_sessionkey(struct torture_context *torture)
1446 {
1447         struct cli_credentials *anon_creds;
1448         const char *wks_name;
1449
1450         wks_name = torture_setting_string(torture, "wksname", get_myname(torture));
1451
1452         if (!(anon_creds = cli_credentials_init_anon(torture))) {
1453                 torture_fail(torture, "create_anon_creds failed\n");
1454         }
1455
1456         cli_credentials_set_workstation(anon_creds, wks_name, CRED_SPECIFIED);
1457
1458
1459         if (!torture_setting_bool(torture, "samba3", false)) {
1460
1461                 /* Samba3 in the build farm right now does this happily. Need
1462                  * to fix :-) */
1463
1464                 if (test_join3(torture, false, anon_creds, NULL, wks_name)) {
1465                         torture_fail(torture, "join using anonymous bind on an anonymous smb "
1466                                  "connection succeeded -- HUH??\n");
1467                 }
1468         }
1469
1470         torture_assert(torture,
1471                 test_join3(torture, false, anon_creds, cmdline_credentials, wks_name),
1472                 "join using ntlmssp bind on an anonymous smb connection failed");
1473
1474         torture_assert(torture,
1475                 test_join3(torture, false, cmdline_credentials, NULL, wks_name),
1476                 "join using anonymous bind on an authenticated smb connection failed");
1477
1478         torture_assert(torture,
1479                 test_join3(torture, false, cmdline_credentials, cmdline_credentials, wks_name),
1480                 "join using ntlmssp bind on an authenticated smb connection failed");
1481
1482         /*
1483          * The following two are tests for setuserinfolevel 25
1484          */
1485
1486         torture_assert(torture,
1487                 test_join3(torture, true, anon_creds, cmdline_credentials, wks_name),
1488                 "join using ntlmssp bind on an anonymous smb connection failed");
1489
1490         torture_assert(torture,
1491                 test_join3(torture, true, cmdline_credentials, NULL, wks_name),
1492                 "join using anonymous bind on an authenticated smb connection failed");
1493
1494         return true;
1495 }
1496
1497 /*
1498  * open pipe and bind, given an IPC$ context
1499  */
1500
1501 static NTSTATUS pipe_bind_smb(struct torture_context *tctx,
1502                               TALLOC_CTX *mem_ctx,
1503                               struct smbcli_tree *tree,
1504                               const char *pipe_name,
1505                               const struct ndr_interface_table *iface,
1506                               struct dcerpc_pipe **p)
1507 {
1508         struct dcerpc_pipe *result;
1509         NTSTATUS status;
1510
1511         if (!(result = dcerpc_pipe_init(mem_ctx, tctx->ev))) {
1512                 return NT_STATUS_NO_MEMORY;
1513         }
1514
1515         status = dcerpc_pipe_open_smb(result, tree, pipe_name);
1516         if (!NT_STATUS_IS_OK(status)) {
1517                 torture_comment(tctx, "dcerpc_pipe_open_smb failed: %s\n",
1518                          nt_errstr(status));
1519                 talloc_free(result);
1520                 return status;
1521         }
1522
1523         status = dcerpc_bind_auth_none(result, iface);
1524         if (!NT_STATUS_IS_OK(status)) {
1525                 torture_comment(tctx, "schannel bind failed: %s\n", nt_errstr(status));
1526                 talloc_free(result);
1527                 return status;
1528         }
1529
1530         *p = result;
1531         return NT_STATUS_OK;
1532 }
1533
1534 /*
1535  * Sane wrapper around lsa_LookupNames
1536  */
1537
1538 static struct dom_sid *name2sid(struct torture_context *tctx,
1539                                 TALLOC_CTX *mem_ctx,
1540                                 struct dcerpc_pipe *p,
1541                                 const char *name,
1542                                 const char *domain)
1543 {
1544         struct lsa_ObjectAttribute attr;
1545         struct lsa_QosInfo qos;
1546         struct lsa_OpenPolicy2 r;
1547         struct lsa_Close c;
1548         NTSTATUS status;
1549         struct policy_handle handle;
1550         struct lsa_LookupNames l;
1551         struct lsa_TransSidArray sids;
1552         struct lsa_RefDomainList *domains = NULL;
1553         struct lsa_String lsa_name;
1554         uint32_t count = 0;
1555         struct dom_sid *result;
1556         TALLOC_CTX *tmp_ctx;
1557         struct dcerpc_binding_handle *b = p->binding_handle;
1558
1559         if (!(tmp_ctx = talloc_new(mem_ctx))) {
1560                 return NULL;
1561         }
1562
1563         qos.len = 0;
1564         qos.impersonation_level = 2;
1565         qos.context_mode = 1;
1566         qos.effective_only = 0;
1567
1568         attr.len = 0;
1569         attr.root_dir = NULL;
1570         attr.object_name = NULL;
1571         attr.attributes = 0;
1572         attr.sec_desc = NULL;
1573         attr.sec_qos = &qos;
1574
1575         r.in.system_name = "\\";
1576         r.in.attr = &attr;
1577         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1578         r.out.handle = &handle;
1579
1580         status = dcerpc_lsa_OpenPolicy2_r(b, tmp_ctx, &r);
1581         if (!NT_STATUS_IS_OK(status)) {
1582                 torture_comment(tctx, "OpenPolicy2 failed - %s\n", nt_errstr(status));
1583                 talloc_free(tmp_ctx);
1584                 return NULL;
1585         }
1586         if (!NT_STATUS_IS_OK(r.out.result)) {
1587                 torture_comment(tctx, "OpenPolicy2 failed - %s\n", nt_errstr(r.out.result));
1588                 talloc_free(tmp_ctx);
1589                 return NULL;
1590         }
1591
1592         sids.count = 0;
1593         sids.sids = NULL;
1594
1595         lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, name);
1596
1597         l.in.handle = &handle;
1598         l.in.num_names = 1;
1599         l.in.names = &lsa_name;
1600         l.in.sids = &sids;
1601         l.in.level = 1;
1602         l.in.count = &count;
1603         l.out.count = &count;
1604         l.out.sids = &sids;
1605         l.out.domains = &domains;
1606
1607         status = dcerpc_lsa_LookupNames_r(b, tmp_ctx, &l);
1608         if (!NT_STATUS_IS_OK(status)) {
1609                 torture_comment(tctx, "LookupNames of %s failed - %s\n", lsa_name.string,
1610                        nt_errstr(status));
1611                 talloc_free(tmp_ctx);
1612                 return NULL;
1613         }
1614         if (!NT_STATUS_IS_OK(l.out.result)) {
1615                 torture_comment(tctx, "LookupNames of %s failed - %s\n", lsa_name.string,
1616                        nt_errstr(l.out.result));
1617                 talloc_free(tmp_ctx);
1618                 return NULL;
1619         }
1620
1621         result = dom_sid_add_rid(mem_ctx, domains->domains[0].sid,
1622                                  l.out.sids->sids[0].rid);
1623
1624         c.in.handle = &handle;
1625         c.out.handle = &handle;
1626
1627         status = dcerpc_lsa_Close_r(b, tmp_ctx, &c);
1628         if (!NT_STATUS_IS_OK(status)) {
1629                 torture_comment(tctx, "dcerpc_lsa_Close failed - %s\n", nt_errstr(status));
1630                 talloc_free(tmp_ctx);
1631                 return NULL;
1632         }
1633         if (!NT_STATUS_IS_OK(c.out.result)) {
1634                 torture_comment(tctx, "dcerpc_lsa_Close failed - %s\n", nt_errstr(c.out.result));
1635                 talloc_free(tmp_ctx);
1636                 return NULL;
1637         }
1638
1639         talloc_free(tmp_ctx);
1640         return result;
1641 }
1642
1643 /*
1644  * Find out the user SID on this connection
1645  */
1646
1647 static struct dom_sid *whoami(struct torture_context *tctx,
1648                               TALLOC_CTX *mem_ctx,
1649                               struct smbcli_tree *tree)
1650 {
1651         struct dcerpc_pipe *lsa;
1652         struct dcerpc_binding_handle *lsa_handle;
1653         struct lsa_GetUserName r;
1654         NTSTATUS status;
1655         struct lsa_String *authority_name_p = NULL;
1656         struct lsa_String *account_name_p = NULL;
1657         struct dom_sid *result;
1658
1659         status = pipe_bind_smb(tctx, mem_ctx, tree, "\\pipe\\lsarpc",
1660                                &ndr_table_lsarpc, &lsa);
1661         if (!NT_STATUS_IS_OK(status)) {
1662                 torture_warning(tctx, "Could not bind to LSA: %s\n",
1663                          nt_errstr(status));
1664                 return NULL;
1665         }
1666         lsa_handle = lsa->binding_handle;
1667
1668         r.in.system_name = "\\";
1669         r.in.account_name = &account_name_p;
1670         r.in.authority_name = &authority_name_p;
1671         r.out.account_name = &account_name_p;
1672
1673         status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
1674
1675         authority_name_p = *r.out.authority_name;
1676
1677         if (!NT_STATUS_IS_OK(status)) {
1678                 torture_warning(tctx, "GetUserName failed - %s\n",
1679                        nt_errstr(status));
1680                 talloc_free(lsa);
1681                 return NULL;
1682         }
1683         if (!NT_STATUS_IS_OK(r.out.result)) {
1684                 torture_warning(tctx, "GetUserName failed - %s\n",
1685                        nt_errstr(r.out.result));
1686                 talloc_free(lsa);
1687                 return NULL;
1688         }
1689
1690         result = name2sid(tctx, mem_ctx, lsa, account_name_p->string,
1691                           authority_name_p->string);
1692
1693         talloc_free(lsa);
1694         return result;
1695 }
1696
1697 static int destroy_tree(struct smbcli_tree *tree)
1698 {
1699         smb_tree_disconnect(tree);
1700         return 0;
1701 }
1702
1703 /*
1704  * Do a tcon, given a session
1705  */
1706
1707 static NTSTATUS secondary_tcon(struct torture_context *tctx,
1708                                TALLOC_CTX *mem_ctx,
1709                                struct smbcli_session *session,
1710                                const char *sharename,
1711                                struct smbcli_tree **res)
1712 {
1713         struct smbcli_tree *result;
1714         TALLOC_CTX *tmp_ctx;
1715         union smb_tcon tcon;
1716         NTSTATUS status;
1717
1718         if (!(tmp_ctx = talloc_new(mem_ctx))) {
1719                 return NT_STATUS_NO_MEMORY;
1720         }
1721
1722         if (!(result = smbcli_tree_init(session, mem_ctx, false))) {
1723                 talloc_free(tmp_ctx);
1724                 return NT_STATUS_NO_MEMORY;
1725         }
1726
1727         tcon.generic.level = RAW_TCON_TCONX;
1728         tcon.tconx.in.flags = 0;
1729         tcon.tconx.in.password = data_blob(NULL, 0);
1730         tcon.tconx.in.path = sharename;
1731         tcon.tconx.in.device = "?????";
1732
1733         status = smb_raw_tcon(result, tmp_ctx, &tcon);
1734         if (!NT_STATUS_IS_OK(status)) {
1735                 torture_warning(tctx, "smb_raw_tcon failed: %s\n",
1736                          nt_errstr(status));
1737                 talloc_free(tmp_ctx);
1738                 return status;
1739         }
1740
1741         result->tid = tcon.tconx.out.tid;
1742         result = talloc_steal(mem_ctx, result);
1743         talloc_set_destructor(result, destroy_tree);
1744         talloc_free(tmp_ctx);
1745         *res = result;
1746         return NT_STATUS_OK;
1747 }
1748
1749 /*
1750  * Test the getusername behaviour
1751  */
1752
1753 static bool torture_samba3_rpc_getusername(struct torture_context *torture)
1754 {
1755         NTSTATUS status;
1756         struct smbcli_state *cli;
1757         bool ret = true;
1758         struct dom_sid *user_sid;
1759         struct dom_sid *created_sid;
1760         struct cli_credentials *anon_creds;
1761         struct cli_credentials *user_creds;
1762         char *domain_name;
1763         struct smbcli_options options;
1764         struct smbcli_session_options session_options;
1765
1766         lpcfg_smbcli_options(torture->lp_ctx, &options);
1767         lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
1768
1769         status = smbcli_full_connection(
1770                 torture, &cli, torture_setting_string(torture, "host", NULL),
1771                 lpcfg_smb_ports(torture->lp_ctx),
1772                 "IPC$", NULL, lpcfg_socket_options(torture->lp_ctx), cmdline_credentials,
1773                 lpcfg_resolve_context(torture->lp_ctx), torture->ev, &options,
1774                 &session_options, lpcfg_gensec_settings(torture, torture->lp_ctx));
1775         torture_assert_ntstatus_ok(torture, status, "smbcli_full_connection failed\n");
1776
1777         if (!(user_sid = whoami(torture, torture, cli->tree))) {
1778                 torture_fail(torture, "whoami on auth'ed connection failed\n");
1779         }
1780
1781         talloc_free(cli);
1782
1783         if (!(anon_creds = cli_credentials_init_anon(torture))) {
1784                 torture_fail(torture, "create_anon_creds failed\n");
1785         }
1786
1787         status = smbcli_full_connection(
1788                 torture, &cli, torture_setting_string(torture, "host", NULL),
1789                 lpcfg_smb_ports(torture->lp_ctx), "IPC$", NULL,
1790                 lpcfg_socket_options(torture->lp_ctx), anon_creds,
1791                 lpcfg_resolve_context(torture->lp_ctx),
1792                 torture->ev, &options, &session_options,
1793                 lpcfg_gensec_settings(torture, torture->lp_ctx));
1794         torture_assert_ntstatus_ok(torture, status, "anon smbcli_full_connection failed\n");
1795
1796         if (!(user_sid = whoami(torture, torture, cli->tree))) {
1797                 torture_fail(torture, "whoami on anon connection failed\n");
1798         }
1799
1800         torture_assert_sid_equal(torture, user_sid, dom_sid_parse_talloc(torture, "s-1-5-7"),
1801                 "Anon lsa_GetUserName returned unexpected SID");
1802
1803         if (!(user_creds = cli_credentials_init(torture))) {
1804                 torture_fail(torture, "cli_credentials_init failed\n");
1805         }
1806
1807         cli_credentials_set_conf(user_creds, torture->lp_ctx);
1808         cli_credentials_set_username(user_creds, "torture_username",
1809                                      CRED_SPECIFIED);
1810         cli_credentials_set_password(user_creds,
1811                                      generate_random_password(user_creds, 8, 255),
1812                                      CRED_SPECIFIED);
1813
1814         if (!create_user(torture, torture, cli, cmdline_credentials,
1815                          cli_credentials_get_username(user_creds),
1816                          cli_credentials_get_password(user_creds),
1817                          &domain_name, &created_sid)) {
1818                 torture_fail(torture, "create_user failed\n");
1819         }
1820
1821         cli_credentials_set_domain(user_creds, domain_name,
1822                                    CRED_SPECIFIED);
1823
1824         {
1825                 struct smbcli_session *session2;
1826                 struct smb_composite_sesssetup setup;
1827                 struct smbcli_tree *tree;
1828
1829                 session2 = smbcli_session_init(cli->transport, torture, false, session_options);
1830                 if (session2 == NULL) {
1831                         torture_fail(torture, "smbcli_session_init failed\n");
1832                 }
1833
1834                 setup.in.sesskey = cli->transport->negotiate.sesskey;
1835                 setup.in.capabilities = cli->transport->negotiate.capabilities;
1836                 setup.in.workgroup = "";
1837                 setup.in.credentials = user_creds;
1838                 setup.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
1839
1840                 status = smb_composite_sesssetup(session2, &setup);
1841                 torture_assert_ntstatus_ok(torture, status, "session setup with new user failed");
1842
1843                 session2->vuid = setup.out.vuid;
1844
1845                 if (!NT_STATUS_IS_OK(secondary_tcon(torture, torture, session2,
1846                                                     "IPC$", &tree))) {
1847                         torture_fail(torture, "secondary_tcon failed\n");
1848                 }
1849
1850                 if (!(user_sid = whoami(torture, torture, tree))) {
1851                         torture_fail_goto(torture, del, "whoami on user connection failed\n");
1852                         ret = false;
1853                         goto del;
1854                 }
1855
1856                 talloc_free(tree);
1857         }
1858
1859         torture_comment(torture, "Created %s, found %s\n",
1860                  dom_sid_string(torture, created_sid),
1861                  dom_sid_string(torture, user_sid));
1862
1863         if (!dom_sid_equal(created_sid, user_sid)) {
1864                 ret = false;
1865         }
1866
1867  del:
1868         if (!delete_user(torture, cli,
1869                          cmdline_credentials,
1870                          cli_credentials_get_username(user_creds))) {
1871                 torture_fail(torture, "delete_user failed\n");
1872         }
1873
1874         return ret;
1875 }
1876
1877 static bool test_NetShareGetInfo(struct torture_context *tctx,
1878                                  struct dcerpc_pipe *p,
1879                                  const char *sharename)
1880 {
1881         NTSTATUS status;
1882         struct srvsvc_NetShareGetInfo r;
1883         union srvsvc_NetShareInfo info;
1884         uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007, 1501 };
1885         int i;
1886         bool ret = true;
1887         struct dcerpc_binding_handle *b = p->binding_handle;
1888
1889         r.in.server_unc = talloc_asprintf(tctx, "\\\\%s",
1890                                           dcerpc_server_name(p));
1891         r.in.share_name = sharename;
1892         r.out.info = &info;
1893
1894         for (i=0;i<ARRAY_SIZE(levels);i++) {
1895                 r.in.level = levels[i];
1896
1897                 torture_comment(tctx, "Testing NetShareGetInfo level %u on share '%s'\n",
1898                        r.in.level, r.in.share_name);
1899
1900                 status = dcerpc_srvsvc_NetShareGetInfo_r(b, tctx, &r);
1901                 if (!NT_STATUS_IS_OK(status)) {
1902                         torture_warning(tctx, "NetShareGetInfo level %u on share '%s' failed"
1903                                " - %s\n", r.in.level, r.in.share_name,
1904                                nt_errstr(status));
1905                         ret = false;
1906                         continue;
1907                 }
1908                 if (!W_ERROR_IS_OK(r.out.result)) {
1909                         torture_warning(tctx, "NetShareGetInfo level %u on share '%s' failed "
1910                                "- %s\n", r.in.level, r.in.share_name,
1911                                win_errstr(r.out.result));
1912                         ret = false;
1913                         continue;
1914                 }
1915         }
1916
1917         return ret;
1918 }
1919
1920 static bool test_NetShareEnum(struct torture_context *tctx,
1921                               struct dcerpc_pipe *p,
1922                               const char **one_sharename)
1923 {
1924         NTSTATUS status;
1925         struct srvsvc_NetShareEnum r;
1926         struct srvsvc_NetShareInfoCtr info_ctr;
1927         struct srvsvc_NetShareCtr0 c0;
1928         struct srvsvc_NetShareCtr1 c1;
1929         struct srvsvc_NetShareCtr2 c2;
1930         struct srvsvc_NetShareCtr501 c501;
1931         struct srvsvc_NetShareCtr502 c502;
1932         struct srvsvc_NetShareCtr1004 c1004;
1933         struct srvsvc_NetShareCtr1005 c1005;
1934         struct srvsvc_NetShareCtr1006 c1006;
1935         struct srvsvc_NetShareCtr1007 c1007;
1936         uint32_t totalentries = 0;
1937         uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007 };
1938         int i;
1939         bool ret = true;
1940         struct dcerpc_binding_handle *b = p->binding_handle;
1941
1942         ZERO_STRUCT(info_ctr);
1943
1944         r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p));
1945         r.in.info_ctr = &info_ctr;
1946         r.in.max_buffer = (uint32_t)-1;
1947         r.in.resume_handle = NULL;
1948         r.out.totalentries = &totalentries;
1949         r.out.info_ctr = &info_ctr;
1950
1951         for (i=0;i<ARRAY_SIZE(levels);i++) {
1952                 info_ctr.level = levels[i];
1953
1954                 switch (info_ctr.level) {
1955                 case 0:
1956                         ZERO_STRUCT(c0);
1957                         info_ctr.ctr.ctr0 = &c0;
1958                         break;
1959                 case 1:
1960                         ZERO_STRUCT(c1);
1961                         info_ctr.ctr.ctr1 = &c1;
1962                         break;
1963                 case 2:
1964                         ZERO_STRUCT(c2);
1965                         info_ctr.ctr.ctr2 = &c2;
1966                         break;
1967                 case 501:
1968                         ZERO_STRUCT(c501);
1969                         info_ctr.ctr.ctr501 = &c501;
1970                         break;
1971                 case 502:
1972                         ZERO_STRUCT(c502);
1973                         info_ctr.ctr.ctr502 = &c502;
1974                         break;
1975                 case 1004:
1976                         ZERO_STRUCT(c1004);
1977                         info_ctr.ctr.ctr1004 = &c1004;
1978                         break;
1979                 case 1005:
1980                         ZERO_STRUCT(c1005);
1981                         info_ctr.ctr.ctr1005 = &c1005;
1982                         break;
1983                 case 1006:
1984                         ZERO_STRUCT(c1006);
1985                         info_ctr.ctr.ctr1006 = &c1006;
1986                         break;
1987                 case 1007:
1988                         ZERO_STRUCT(c1007);
1989                         info_ctr.ctr.ctr1007 = &c1007;
1990                         break;
1991                 }
1992
1993                 torture_comment(tctx, "Testing NetShareEnum level %u\n", info_ctr.level);
1994
1995                 status = dcerpc_srvsvc_NetShareEnum_r(b, tctx, &r);
1996                 if (!NT_STATUS_IS_OK(status)) {
1997                         torture_warning(tctx, "NetShareEnum level %u failed - %s\n",
1998                                info_ctr.level, nt_errstr(status));
1999                         ret = false;
2000                         continue;
2001                 }
2002                 if (!W_ERROR_IS_OK(r.out.result)) {
2003                         torture_warning(tctx, "NetShareEnum level %u failed - %s\n",
2004                                info_ctr.level, win_errstr(r.out.result));
2005                         continue;
2006                 }
2007                 if (info_ctr.level == 0) {
2008                         struct srvsvc_NetShareCtr0 *ctr = r.out.info_ctr->ctr.ctr0;
2009                         if (ctr->count > 0) {
2010                                 *one_sharename = ctr->array[0].name;
2011                         }
2012                 }
2013         }
2014
2015         return ret;
2016 }
2017
2018 static bool torture_samba3_rpc_srvsvc(struct torture_context *torture)
2019 {
2020         struct dcerpc_pipe *p;
2021         const char *sharename = NULL;
2022         bool ret = true;
2023
2024         torture_assert_ntstatus_ok(torture,
2025                 torture_rpc_connection(torture, &p, &ndr_table_srvsvc),
2026                 "failed to open srvsvc");
2027
2028         ret &= test_NetShareEnum(torture, p, &sharename);
2029         if (sharename == NULL) {
2030                 torture_comment(torture, "did not get sharename\n");
2031         } else {
2032                 ret &= test_NetShareGetInfo(torture, p, sharename);
2033         }
2034
2035         return ret;
2036 }
2037
2038 /*
2039  * Do a ReqChallenge/Auth2 with a random wks name, make sure it returns
2040  * NT_STATUS_NO_SAM_ACCOUNT
2041  */
2042
2043 static bool torture_samba3_rpc_randomauth2(struct torture_context *torture)
2044 {
2045         TALLOC_CTX *mem_ctx;
2046         struct dcerpc_pipe *net_pipe;
2047         struct dcerpc_binding_handle *net_handle;
2048         char *wksname;
2049         bool result = false;
2050         NTSTATUS status;
2051         struct netr_ServerReqChallenge r;
2052         struct netr_Credential netr_cli_creds;
2053         struct netr_Credential netr_srv_creds;
2054         uint32_t negotiate_flags;
2055         struct netr_ServerAuthenticate2 a;
2056         struct netlogon_creds_CredentialState *creds_state;
2057         struct netr_Credential netr_cred;
2058         struct samr_Password mach_pw;
2059         struct smbcli_state *cli;
2060
2061         if (!(mem_ctx = talloc_new(torture))) {
2062                 torture_comment(torture, "talloc_new failed\n");
2063                 return false;
2064         }
2065
2066         if (!(wksname = generate_random_str_list(
2067                       mem_ctx, 14, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"))) {
2068                 torture_comment(torture, "generate_random_str_list failed\n");
2069                 goto done;
2070         }
2071
2072         if (!(torture_open_connection_share(
2073                       mem_ctx, &cli,
2074                       torture, torture_setting_string(torture, "host", NULL),
2075                       "IPC$", torture->ev))) {
2076                 torture_comment(torture, "IPC$ connection failed\n");
2077                 goto done;
2078         }
2079
2080         if (!(net_pipe = dcerpc_pipe_init(mem_ctx, torture->ev))) {
2081                 torture_comment(torture, "dcerpc_pipe_init failed\n");
2082                 goto done;
2083         }
2084         net_handle = net_pipe->binding_handle;
2085
2086         status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
2087         if (!NT_STATUS_IS_OK(status)) {
2088                 torture_comment(torture, "dcerpc_pipe_open_smb failed: %s\n",
2089                          nt_errstr(status));
2090                 goto done;
2091         }
2092
2093         status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon);
2094         if (!NT_STATUS_IS_OK(status)) {
2095                 torture_comment(torture, "dcerpc_bind_auth_none failed: %s\n",
2096                          nt_errstr(status));
2097                 goto done;
2098         }
2099
2100         r.in.computer_name = wksname;
2101         r.in.server_name = talloc_asprintf(
2102                 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
2103         if (r.in.server_name == NULL) {
2104                 torture_comment(torture, "talloc_asprintf failed\n");
2105                 goto done;
2106         }
2107         generate_random_buffer(netr_cli_creds.data,
2108                                sizeof(netr_cli_creds.data));
2109         r.in.credentials = &netr_cli_creds;
2110         r.out.return_credentials = &netr_srv_creds;
2111
2112         status = dcerpc_netr_ServerReqChallenge_r(net_handle, mem_ctx, &r);
2113         if (!NT_STATUS_IS_OK(status)) {
2114                 torture_comment(torture, "netr_ServerReqChallenge failed: %s\n",
2115                          nt_errstr(status));
2116                 goto done;
2117         }
2118         if (!NT_STATUS_IS_OK(r.out.result)) {
2119                 torture_comment(torture, "netr_ServerReqChallenge failed: %s\n",
2120                          nt_errstr(r.out.result));
2121                 goto done;
2122         }
2123
2124         negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
2125         E_md4hash("foobar", mach_pw.hash);
2126
2127         a.in.server_name = talloc_asprintf(
2128                 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
2129         a.in.account_name = talloc_asprintf(
2130                 mem_ctx, "%s$", wksname);
2131         a.in.computer_name = wksname;
2132         a.in.secure_channel_type = SEC_CHAN_WKSTA;
2133         a.in.negotiate_flags = &negotiate_flags;
2134         a.out.negotiate_flags = &negotiate_flags;
2135         a.in.credentials = &netr_cred;
2136         a.out.return_credentials = &netr_cred;
2137
2138         creds_state = netlogon_creds_client_init(mem_ctx,
2139                                                  a.in.account_name,
2140                                                  a.in.computer_name,
2141                                                  r.in.credentials,
2142                                                  r.out.return_credentials, &mach_pw,
2143                                                  &netr_cred, negotiate_flags);
2144
2145
2146         status = dcerpc_netr_ServerAuthenticate2_r(net_handle, mem_ctx, &a);
2147         if (!NT_STATUS_IS_OK(status)) {
2148                 goto done;
2149         }
2150         if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_NO_TRUST_SAM_ACCOUNT)) {
2151                 torture_comment(torture, "dcerpc_netr_ServerAuthenticate2 returned %s, "
2152                          "expected NT_STATUS_NO_TRUST_SAM_ACCOUNT\n",
2153                          nt_errstr(a.out.result));
2154                 goto done;
2155         }
2156
2157         result = true;
2158  done:
2159         talloc_free(mem_ctx);
2160         return result;
2161 }
2162
2163 static struct security_descriptor *get_sharesec(struct torture_context *tctx,
2164                                                 TALLOC_CTX *mem_ctx,
2165                                                 struct smbcli_session *sess,
2166                                                 const char *sharename)
2167 {
2168         struct smbcli_tree *tree;
2169         TALLOC_CTX *tmp_ctx;
2170         struct dcerpc_pipe *p;
2171         struct dcerpc_binding_handle *b;
2172         NTSTATUS status;
2173         struct srvsvc_NetShareGetInfo r;
2174         union srvsvc_NetShareInfo info;
2175         struct security_descriptor *result;
2176
2177         if (!(tmp_ctx = talloc_new(mem_ctx))) {
2178                 torture_comment(tctx, "talloc_new failed\n");
2179                 return NULL;
2180         }
2181
2182         if (!NT_STATUS_IS_OK(secondary_tcon(tctx, tmp_ctx, sess, "IPC$", &tree))) {
2183                 torture_comment(tctx, "secondary_tcon failed\n");
2184                 talloc_free(tmp_ctx);
2185                 return NULL;
2186         }
2187
2188         status = pipe_bind_smb(tctx, mem_ctx, tree, "\\pipe\\srvsvc",
2189                                &ndr_table_srvsvc, &p);
2190         if (!NT_STATUS_IS_OK(status)) {
2191                 torture_warning(tctx, "could not bind to srvsvc pipe: %s\n",
2192                          nt_errstr(status));
2193                 talloc_free(tmp_ctx);
2194                 return NULL;
2195         }
2196         b = p->binding_handle;
2197
2198 #if 0
2199         p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2200 #endif
2201
2202         r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
2203                                           dcerpc_server_name(p));
2204         r.in.share_name = sharename;
2205         r.in.level = 502;
2206         r.out.info = &info;
2207
2208         status = dcerpc_srvsvc_NetShareGetInfo_r(b, tmp_ctx, &r);
2209         if (!NT_STATUS_IS_OK(status)) {
2210                 torture_comment(tctx, "srvsvc_NetShareGetInfo failed: %s\n",
2211                          nt_errstr(status));
2212                 talloc_free(tmp_ctx);
2213                 return NULL;
2214         }
2215         if (!W_ERROR_IS_OK(r.out.result)) {
2216                 torture_comment(tctx, "srvsvc_NetShareGetInfo failed: %s\n",
2217                          win_errstr(r.out.result));
2218                 talloc_free(tmp_ctx);
2219                 return NULL;
2220         }
2221
2222         result = talloc_steal(mem_ctx, info.info502->sd_buf.sd);
2223         talloc_free(tmp_ctx);
2224         return result;
2225 }
2226
2227 static NTSTATUS set_sharesec(struct torture_context *tctx,
2228                              TALLOC_CTX *mem_ctx,
2229                              struct smbcli_session *sess,
2230                              const char *sharename,
2231                              struct security_descriptor *sd)
2232 {
2233         struct smbcli_tree *tree;
2234         TALLOC_CTX *tmp_ctx;
2235         struct dcerpc_pipe *p;
2236         struct dcerpc_binding_handle *b;
2237         NTSTATUS status;
2238         struct sec_desc_buf i;
2239         struct srvsvc_NetShareSetInfo r;
2240         union srvsvc_NetShareInfo info;
2241         uint32_t error = 0;
2242
2243         if (!(tmp_ctx = talloc_new(mem_ctx))) {
2244                 torture_comment(tctx, "talloc_new failed\n");
2245                 return NT_STATUS_NO_MEMORY;
2246         }
2247
2248         if (!NT_STATUS_IS_OK(secondary_tcon(tctx, tmp_ctx, sess, "IPC$", &tree))) {
2249                 torture_comment(tctx, "secondary_tcon failed\n");
2250                 talloc_free(tmp_ctx);
2251                 return NT_STATUS_UNSUCCESSFUL;
2252         }
2253
2254         status = pipe_bind_smb(tctx, mem_ctx, tree, "\\pipe\\srvsvc",
2255                                &ndr_table_srvsvc, &p);
2256         if (!NT_STATUS_IS_OK(status)) {
2257                 torture_warning(tctx, "could not bind to srvsvc pipe: %s\n",
2258                          nt_errstr(status));
2259                 talloc_free(tmp_ctx);
2260                 return NT_STATUS_UNSUCCESSFUL;
2261         }
2262         b = p->binding_handle;
2263
2264 #if 0
2265         p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2266 #endif
2267
2268         r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
2269                                           dcerpc_server_name(p));
2270         r.in.share_name = sharename;
2271         r.in.level = 1501;
2272         i.sd = sd;
2273         info.info1501 = &i;
2274         r.in.info = &info;
2275         r.in.parm_error = &error;
2276
2277         status = dcerpc_srvsvc_NetShareSetInfo_r(b, tmp_ctx, &r);
2278         if (!NT_STATUS_IS_OK(status)) {
2279                 torture_comment(tctx, "srvsvc_NetShareSetInfo failed: %s\n",
2280                          nt_errstr(status));
2281         }
2282         if (!W_ERROR_IS_OK(r.out.result)) {
2283                 torture_comment(tctx, "srvsvc_NetShareSetInfo failed: %s\n",
2284                         win_errstr(r.out.result));
2285                 status = werror_to_ntstatus(r.out.result);
2286         }
2287         talloc_free(tmp_ctx);
2288         return status;
2289 }
2290
2291 bool try_tcon(struct torture_context *tctx,
2292               TALLOC_CTX *mem_ctx,
2293               struct security_descriptor *orig_sd,
2294               struct smbcli_session *session,
2295               const char *sharename, const struct dom_sid *user_sid,
2296               unsigned int access_mask, NTSTATUS expected_tcon,
2297               NTSTATUS expected_mkdir)
2298 {
2299         TALLOC_CTX *tmp_ctx;
2300         struct smbcli_tree *rmdir_tree, *tree;
2301         struct dom_sid *domain_sid;
2302         uint32_t rid;
2303         struct security_descriptor *sd;
2304         NTSTATUS status;
2305         bool ret = true;
2306
2307         if (!(tmp_ctx = talloc_new(mem_ctx))) {
2308                 torture_comment(tctx, "talloc_new failed\n");
2309                 return false;
2310         }
2311
2312         status = secondary_tcon(tctx, tmp_ctx, session, sharename, &rmdir_tree);
2313         if (!NT_STATUS_IS_OK(status)) {
2314                 torture_comment(tctx, "first tcon to delete dir failed\n");
2315                 talloc_free(tmp_ctx);
2316                 return false;
2317         }
2318
2319         smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2320
2321         if (!NT_STATUS_IS_OK(dom_sid_split_rid(tmp_ctx, user_sid,
2322                                                &domain_sid, &rid))) {
2323                 torture_comment(tctx, "dom_sid_split_rid failed\n");
2324                 talloc_free(tmp_ctx);
2325                 return false;
2326         }
2327
2328         sd = security_descriptor_dacl_create(
2329                 tmp_ctx, 0, "S-1-5-32-544",
2330                 dom_sid_string(mem_ctx, dom_sid_add_rid(mem_ctx, domain_sid,
2331                                                         DOMAIN_RID_USERS)),
2332                 dom_sid_string(mem_ctx, user_sid),
2333                 SEC_ACE_TYPE_ACCESS_ALLOWED, access_mask, 0, NULL);
2334         if (sd == NULL) {
2335                 torture_comment(tctx, "security_descriptor_dacl_create failed\n");
2336                 talloc_free(tmp_ctx);
2337                 return false;
2338         }
2339
2340         status = set_sharesec(tctx, mem_ctx, session, sharename, sd);
2341         if (!NT_STATUS_IS_OK(status)) {
2342                 torture_comment(tctx, "custom set_sharesec failed: %s\n",
2343                          nt_errstr(status));
2344                 talloc_free(tmp_ctx);
2345                 return false;
2346         }
2347
2348         status = secondary_tcon(tctx, tmp_ctx, session, sharename, &tree);
2349         if (!NT_STATUS_EQUAL(status, expected_tcon)) {
2350                 torture_comment(tctx, "Expected %s, got %s\n", nt_errstr(expected_tcon),
2351                          nt_errstr(status));
2352                 ret = false;
2353                 goto done;
2354         }
2355
2356         if (!NT_STATUS_IS_OK(status)) {
2357                 /* An expected non-access, no point in trying to write */
2358                 goto done;
2359         }
2360
2361         status = smbcli_mkdir(tree, "sharesec_testdir");
2362         if (!NT_STATUS_EQUAL(status, expected_mkdir)) {
2363                 torture_warning(tctx, "Expected %s, got %s\n",
2364                          nt_errstr(expected_mkdir), nt_errstr(status));
2365                 ret = false;
2366         }
2367
2368  done:
2369         smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2370
2371         status = set_sharesec(tctx, mem_ctx, session, sharename, orig_sd);
2372         if (!NT_STATUS_IS_OK(status)) {
2373                 torture_comment(tctx, "custom set_sharesec failed: %s\n",
2374                          nt_errstr(status));
2375                 talloc_free(tmp_ctx);
2376                 return false;
2377         }
2378
2379         talloc_free(tmp_ctx);
2380         return ret;
2381 }
2382
2383 static bool torture_samba3_rpc_sharesec(struct torture_context *torture)
2384 {
2385         struct smbcli_state *cli;
2386         struct security_descriptor *sd;
2387         struct dom_sid *user_sid;
2388
2389         if (!(torture_open_connection_share(
2390                       torture, &cli, torture, torture_setting_string(torture, "host", NULL),
2391                       "IPC$", torture->ev))) {
2392                 torture_fail(torture, "IPC$ connection failed\n");
2393         }
2394
2395         if (!(user_sid = whoami(torture, torture, cli->tree))) {
2396                 torture_fail(torture, "whoami failed\n");
2397         }
2398
2399         sd = get_sharesec(torture, torture, cli->session,
2400                           torture_setting_string(torture, "share", NULL));
2401
2402         torture_assert(torture, try_tcon(
2403                         torture, torture, sd, cli->session,
2404                         torture_setting_string(torture, "share", NULL),
2405                         user_sid, 0, NT_STATUS_ACCESS_DENIED, NT_STATUS_OK),
2406                         "failed to test tcon with 0 access_mask");
2407
2408         torture_assert(torture, try_tcon(
2409                         torture, torture, sd, cli->session,
2410                         torture_setting_string(torture, "share", NULL),
2411                         user_sid, SEC_FILE_READ_DATA, NT_STATUS_OK,
2412                         NT_STATUS_MEDIA_WRITE_PROTECTED),
2413                         "failed to test tcon with SEC_FILE_READ_DATA access_mask");
2414
2415         torture_assert(torture, try_tcon(
2416                         torture, torture, sd, cli->session,
2417                         torture_setting_string(torture, "share", NULL),
2418                         user_sid, SEC_FILE_ALL, NT_STATUS_OK, NT_STATUS_OK),
2419                         "failed to test tcon with SEC_FILE_ALL access_mask")
2420
2421         return true;
2422 }
2423
2424 static bool torture_samba3_rpc_lsa(struct torture_context *torture)
2425 {
2426         struct dcerpc_pipe *p;
2427         struct dcerpc_binding_handle *b;
2428         struct policy_handle lsa_handle;
2429
2430         torture_assert_ntstatus_ok(torture,
2431                 torture_rpc_connection(torture, &p, &ndr_table_lsarpc),
2432                 "failed to setup lsarpc");
2433
2434         b = p->binding_handle;
2435
2436         {
2437                 struct lsa_ObjectAttribute attr;
2438                 struct lsa_OpenPolicy2 o;
2439                 o.in.system_name = talloc_asprintf(
2440                         torture, "\\\\%s", dcerpc_server_name(p));
2441                 ZERO_STRUCT(attr);
2442                 o.in.attr = &attr;
2443                 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2444                 o.out.handle = &lsa_handle;
2445
2446                 torture_assert_ntstatus_ok(torture,
2447                         dcerpc_lsa_OpenPolicy2_r(b, torture, &o),
2448                         "dcerpc_lsa_OpenPolicy2 failed");
2449                 torture_assert_ntstatus_ok(torture, o.out.result,
2450                         "dcerpc_lsa_OpenPolicy2 failed");
2451         }
2452
2453         {
2454                 int i;
2455                 int levels[] = { 2,3,5,6 };
2456
2457                 for (i=0; i<ARRAY_SIZE(levels); i++) {
2458                         struct lsa_QueryInfoPolicy r;
2459                         union lsa_PolicyInformation *info = NULL;
2460                         r.in.handle = &lsa_handle;
2461                         r.in.level = levels[i];
2462                         r.out.info = &info;
2463
2464                         torture_assert_ntstatus_ok(torture,
2465                                 dcerpc_lsa_QueryInfoPolicy_r(b, torture, &r),
2466                                 talloc_asprintf(torture, "dcerpc_lsa_QueryInfoPolicy level %d failed", levels[i]));
2467                         torture_assert_ntstatus_ok(torture, r.out.result,
2468                                 talloc_asprintf(torture, "dcerpc_lsa_QueryInfoPolicy level %d failed", levels[i]));
2469                 }
2470         }
2471
2472         return true;
2473 }
2474
2475 static NTSTATUS get_servername(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree,
2476                                char **name)
2477 {
2478         struct rap_WserverGetInfo r;
2479         NTSTATUS status;
2480         char servername[17];
2481         size_t converted_size;
2482
2483         r.in.level = 0;
2484         r.in.bufsize = 0xffff;
2485
2486         status = smbcli_rap_netservergetinfo(tree, mem_ctx, &r);
2487         if (!NT_STATUS_IS_OK(status)) {
2488                 return status;
2489         }
2490
2491         memcpy(servername, r.out.info.info0.name, 16);
2492         servername[16] = '\0';
2493
2494         if (!pull_ascii_talloc(mem_ctx, name, servername, &converted_size)) {
2495                 return NT_STATUS_NO_MEMORY;
2496         }
2497
2498         return NT_STATUS_OK;
2499 }
2500
2501 static bool rap_get_servername(struct torture_context *tctx,
2502                                char **servername)
2503 {
2504         struct smbcli_state *cli;
2505
2506         torture_assert(tctx,
2507                 torture_open_connection_share(tctx, &cli, tctx, torture_setting_string(tctx, "host", NULL),
2508                                               "IPC$", tctx->ev),
2509                 "IPC$ connection failed");
2510
2511         torture_assert_ntstatus_ok(tctx,
2512                 get_servername(tctx, cli->tree, servername),
2513                 "get_servername failed");
2514
2515         talloc_free(cli);
2516
2517         return true;
2518 }
2519
2520 static bool find_printers(struct torture_context *tctx,
2521                           struct dcerpc_pipe *p,
2522                           const char ***printers,
2523                           int *num_printers)
2524 {
2525         struct srvsvc_NetShareEnum r;
2526         struct srvsvc_NetShareInfoCtr info_ctr;
2527         struct srvsvc_NetShareCtr1 c1_in;
2528         struct srvsvc_NetShareCtr1 *c1;
2529         uint32_t totalentries = 0;
2530         int i;
2531         struct dcerpc_binding_handle *b = p->binding_handle;
2532
2533         ZERO_STRUCT(c1_in);
2534         info_ctr.level = 1;
2535         info_ctr.ctr.ctr1 = &c1_in;
2536
2537         r.in.server_unc = talloc_asprintf(
2538                 tctx, "\\\\%s", dcerpc_server_name(p));
2539         r.in.info_ctr = &info_ctr;
2540         r.in.max_buffer = (uint32_t)-1;
2541         r.in.resume_handle = NULL;
2542         r.out.totalentries = &totalentries;
2543         r.out.info_ctr = &info_ctr;
2544
2545         torture_assert_ntstatus_ok(tctx,
2546                 dcerpc_srvsvc_NetShareEnum_r(b, tctx, &r),
2547                 "NetShareEnum level 1 failed");
2548         torture_assert_werr_ok(tctx, r.out.result,
2549                 "NetShareEnum level 1 failed");
2550
2551         *printers = NULL;
2552         *num_printers = 0;
2553         c1 = r.out.info_ctr->ctr.ctr1;
2554         for (i=0; i<c1->count; i++) {
2555                 if (c1->array[i].type != STYPE_PRINTQ) {
2556                         continue;
2557                 }
2558                 if (!add_string_to_array(tctx, c1->array[i].name,
2559                                          printers, num_printers)) {
2560                         return false;
2561                 }
2562         }
2563
2564         return true;
2565 }
2566
2567 static bool enumprinters(struct torture_context *tctx,
2568                          struct dcerpc_binding_handle *b,
2569                          const char *servername, int level, int *num_printers)
2570 {
2571         struct spoolss_EnumPrinters r;
2572         DATA_BLOB blob;
2573         uint32_t needed;
2574         uint32_t count;
2575         union spoolss_PrinterInfo *info;
2576
2577         r.in.flags = PRINTER_ENUM_LOCAL;
2578         r.in.server = talloc_asprintf(tctx, "\\\\%s", servername);
2579         r.in.level = level;
2580         r.in.buffer = NULL;
2581         r.in.offered = 0;
2582         r.out.needed = &needed;
2583         r.out.count = &count;
2584         r.out.info = &info;
2585
2586         torture_assert_ntstatus_ok(tctx,
2587                 dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
2588                 "dcerpc_spoolss_EnumPrinters failed");
2589         torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
2590                 "EnumPrinters unexpected return code should be WERR_INSUFFICIENT_BUFFER");
2591
2592         blob = data_blob_talloc_zero(tctx, needed);
2593         if (blob.data == NULL) {
2594                 return false;
2595         }
2596
2597         r.in.buffer = &blob;
2598         r.in.offered = needed;
2599
2600         torture_assert_ntstatus_ok(tctx,
2601                 dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
2602                 "dcerpc_spoolss_EnumPrinters failed");
2603         torture_assert_werr_ok(tctx, r.out.result,
2604                 "dcerpc_spoolss_EnumPrinters failed");
2605
2606         *num_printers = count;
2607
2608         return true;
2609 }
2610
2611 static bool getprinterinfo(struct torture_context *tctx,
2612                            struct dcerpc_binding_handle *b,
2613                            struct policy_handle *handle, int level,
2614                            union spoolss_PrinterInfo **res)
2615 {
2616         struct spoolss_GetPrinter r;
2617         DATA_BLOB blob;
2618         uint32_t needed;
2619
2620         r.in.handle = handle;
2621         r.in.level = level;
2622         r.in.buffer = NULL;
2623         r.in.offered = 0;
2624         r.out.needed = &needed;
2625
2626         torture_assert_ntstatus_ok(tctx,
2627                 dcerpc_spoolss_GetPrinter_r(b, tctx, &r),
2628                 "dcerpc_spoolss_GetPrinter failed");
2629         torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
2630                 "GetPrinter unexpected return code should be WERR_INSUFFICIENT_BUFFER");
2631
2632         r.in.handle = handle;
2633         r.in.level = level;
2634         blob = data_blob_talloc_zero(tctx, needed);
2635         if (blob.data == NULL) {
2636                 return false;
2637         }
2638         r.in.buffer = &blob;
2639         r.in.offered = needed;
2640
2641         torture_assert_ntstatus_ok(tctx,
2642                 dcerpc_spoolss_GetPrinter_r(b, tctx, &r),
2643                 "dcerpc_spoolss_GetPrinter failed");
2644         torture_assert_werr_ok(tctx, r.out.result,
2645                 "dcerpc_spoolss_GetPrinter failed");
2646
2647         if (res != NULL) {
2648                 *res = talloc_steal(tctx, r.out.info);
2649         }
2650
2651         return true;
2652 }
2653
2654 static bool torture_samba3_rpc_spoolss(struct torture_context *torture)
2655 {
2656         struct dcerpc_pipe *p, *p2;
2657         struct dcerpc_binding_handle *b;
2658         struct policy_handle server_handle, printer_handle;
2659         const char **printers;
2660         int num_printers;
2661         struct spoolss_UserLevel1 userlevel1;
2662         char *servername;
2663
2664         torture_assert(torture,
2665                 rap_get_servername(torture, &servername),
2666                 "failed to rap servername");
2667
2668         torture_assert_ntstatus_ok(torture,
2669                 torture_rpc_connection(torture, &p2, &ndr_table_srvsvc),
2670                 "failed to setup srvsvc");
2671
2672         torture_assert(torture,
2673                 find_printers(torture, p2, &printers, &num_printers),
2674                 "failed to find printers via srvsvc");
2675
2676         talloc_free(p2);
2677
2678         if (num_printers == 0) {
2679                 torture_skip(torture, "Did not find printers\n");
2680                 return true;
2681         }
2682
2683         torture_assert_ntstatus_ok(torture,
2684                 torture_rpc_connection(torture, &p, &ndr_table_spoolss),
2685                 "failed to setup spoolss");
2686
2687         b = p->binding_handle;
2688
2689         ZERO_STRUCT(userlevel1);
2690         userlevel1.client = talloc_asprintf(
2691                 torture, "\\\\%s", lpcfg_netbios_name(torture->lp_ctx));
2692         userlevel1.user = cli_credentials_get_username(cmdline_credentials);
2693         userlevel1.build = 2600;
2694         userlevel1.major = 3;
2695         userlevel1.minor = 0;
2696         userlevel1.processor = 0;
2697
2698         {
2699                 struct spoolss_OpenPrinterEx r;
2700
2701                 ZERO_STRUCT(r);
2702                 r.in.printername = talloc_asprintf(torture, "\\\\%s",
2703                                                    servername);
2704                 r.in.datatype = NULL;
2705                 r.in.access_mask = 0;
2706                 r.in.level = 1;
2707                 r.in.userlevel.level1 = &userlevel1;
2708                 r.out.handle = &server_handle;
2709
2710                 torture_assert_ntstatus_ok(torture,
2711                         dcerpc_spoolss_OpenPrinterEx_r(b, torture, &r),
2712                         "dcerpc_spoolss_OpenPrinterEx failed");
2713                 torture_assert_werr_ok(torture, r.out.result,
2714                         "dcerpc_spoolss_OpenPrinterEx failed");
2715         }
2716
2717         {
2718                 struct spoolss_ClosePrinter r;
2719
2720                 r.in.handle = &server_handle;
2721                 r.out.handle = &server_handle;
2722
2723                 torture_assert_ntstatus_ok(torture,
2724                         dcerpc_spoolss_ClosePrinter_r(b, torture, &r),
2725                         "dcerpc_spoolss_ClosePrinter failed");
2726                 torture_assert_werr_ok(torture, r.out.result,
2727                         "dcerpc_spoolss_ClosePrinter failed");
2728         }
2729
2730         {
2731                 struct spoolss_OpenPrinterEx r;
2732
2733                 ZERO_STRUCT(r);
2734                 r.in.printername = talloc_asprintf(
2735                         torture, "\\\\%s\\%s", servername, printers[0]);
2736                 r.in.datatype = NULL;
2737                 r.in.access_mask = 0;
2738                 r.in.level = 1;
2739                 r.in.userlevel.level1 = &userlevel1;
2740                 r.out.handle = &printer_handle;
2741
2742                 torture_assert_ntstatus_ok(torture,
2743                         dcerpc_spoolss_OpenPrinterEx_r(b, torture, &r),
2744                         "dcerpc_spoolss_OpenPrinterEx failed");
2745                 torture_assert_werr_ok(torture, r.out.result,
2746                         "dcerpc_spoolss_OpenPrinterEx failed");
2747         }
2748
2749         {
2750                 int i;
2751
2752                 for (i=0; i<8; i++) {
2753                         torture_assert(torture,
2754                                 getprinterinfo(torture, b, &printer_handle, i, NULL),
2755                                 talloc_asprintf(torture, "getprinterinfo %d failed", i));
2756                 }
2757         }
2758
2759         {
2760                 struct spoolss_ClosePrinter r;
2761
2762                 r.in.handle = &printer_handle;
2763                 r.out.handle = &printer_handle;
2764
2765                 torture_assert_ntstatus_ok(torture,
2766                         dcerpc_spoolss_ClosePrinter_r(b, torture, &r),
2767                         "dcerpc_spoolss_ClosePrinter failed");
2768                 torture_assert_werr_ok(torture, r.out.result,
2769                         "dcerpc_spoolss_ClosePrinter failed");
2770         }
2771
2772         {
2773                 int num_enumerated;
2774
2775                 torture_assert(torture,
2776                         enumprinters(torture, b, servername, 1, &num_enumerated),
2777                         "enumprinters failed");
2778
2779                 torture_assert_int_equal(torture, num_printers, num_enumerated,
2780                         "netshareenum / enumprinters lvl 1 numprinter mismatch");
2781         }
2782
2783         {
2784                 int num_enumerated;
2785
2786                 torture_assert(torture,
2787                         enumprinters(torture, b, servername, 2, &num_enumerated),
2788                         "enumprinters failed");
2789
2790                 torture_assert_int_equal(torture, num_printers, num_enumerated,
2791                         "netshareenum / enumprinters lvl 2 numprinter mismatch");
2792         }
2793
2794         return true;
2795 }
2796
2797 static bool torture_samba3_rpc_wkssvc(struct torture_context *torture)
2798 {
2799         struct dcerpc_pipe *p;
2800         struct dcerpc_binding_handle *b;
2801         char *servername;
2802
2803         torture_assert(torture,
2804                 rap_get_servername(torture, &servername),
2805                 "failed to rap servername");
2806
2807         torture_assert_ntstatus_ok(torture,
2808                 torture_rpc_connection(torture, &p, &ndr_table_wkssvc),
2809                 "failed to setup wkssvc");
2810
2811         b = p->binding_handle;
2812
2813         {
2814                 struct wkssvc_NetWkstaInfo100 wks100;
2815                 union wkssvc_NetWkstaInfo info;
2816                 struct wkssvc_NetWkstaGetInfo r;
2817
2818                 r.in.server_name = "\\foo";
2819                 r.in.level = 100;
2820                 info.info100 = &wks100;
2821                 r.out.info = &info;
2822
2823                 torture_assert_ntstatus_ok(torture,
2824                         dcerpc_wkssvc_NetWkstaGetInfo_r(b, torture, &r),
2825                         "dcerpc_wkssvc_NetWksGetInfo failed");
2826                 torture_assert_werr_ok(torture, r.out.result,
2827                         "dcerpc_wkssvc_NetWksGetInfo failed");
2828
2829                 torture_assert_str_equal(torture, servername, r.out.info->info100->server_name,
2830                         "servername RAP / DCERPC inconsistency");
2831         }
2832
2833         return true;
2834 }
2835
2836 static bool winreg_close(struct torture_context *tctx,
2837                          struct dcerpc_binding_handle *b,
2838                          struct policy_handle *handle)
2839 {
2840         struct winreg_CloseKey c;
2841
2842         c.in.handle = c.out.handle = handle;
2843
2844         torture_assert_ntstatus_ok(tctx,
2845                 dcerpc_winreg_CloseKey_r(b, tctx, &c),
2846                 "winreg_CloseKey failed");
2847         torture_assert_werr_ok(tctx, c.out.result,
2848                 "winreg_CloseKey failed");
2849
2850         return true;
2851 }
2852
2853 static bool enumvalues(struct torture_context *tctx,
2854                        struct dcerpc_binding_handle *b,
2855                        struct policy_handle *handle)
2856 {
2857         uint32_t enum_index = 0;
2858
2859         while (1) {
2860                 struct winreg_EnumValue r;
2861                 struct winreg_ValNameBuf name;
2862                 enum winreg_Type type = 0;
2863                 uint8_t buf8[1024];
2864                 NTSTATUS status;
2865                 uint32_t size, length;
2866
2867                 r.in.handle = handle;
2868                 r.in.enum_index = enum_index;
2869                 name.name = "";
2870                 name.size = 1024;
2871                 r.in.name = r.out.name = &name;
2872                 size = 1024;
2873                 length = 5;
2874                 r.in.type = &type;
2875                 r.in.value = buf8;
2876                 r.in.size = &size;
2877                 r.in.length = &length;
2878
2879                 status = dcerpc_winreg_EnumValue_r(b, tctx, &r);
2880                 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2881                         return true;
2882                 }
2883                 enum_index += 1;
2884         }
2885 }
2886
2887 static bool enumkeys(struct torture_context *tctx,
2888                      struct dcerpc_binding_handle *b,
2889                      struct policy_handle *handle,
2890                      int depth)
2891 {
2892         struct winreg_EnumKey r;
2893         struct winreg_StringBuf kclass, name;
2894         NTSTATUS status;
2895         NTTIME t = 0;
2896
2897         if (depth <= 0) {
2898                 return true;
2899         }
2900
2901         kclass.name   = "";
2902         kclass.size   = 1024;
2903
2904         r.in.handle = handle;
2905         r.in.enum_index = 0;
2906         r.in.name = &name;
2907         r.in.keyclass = &kclass;
2908         r.out.name = &name;
2909         r.in.last_changed_time = &t;
2910
2911         do {
2912                 struct winreg_OpenKey o;
2913                 struct policy_handle key_handle;
2914                 int i;
2915
2916                 name.name = NULL;
2917                 name.size = 1024;
2918
2919                 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
2920                 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2921                         /* We're done enumerating */
2922                         return true;
2923                 }
2924
2925                 for (i=0; i<10-depth; i++) {
2926                         torture_comment(tctx, " ");
2927                 }
2928                 torture_comment(tctx, "%s\n", r.out.name->name);
2929
2930                 o.in.parent_handle = handle;
2931                 o.in.keyname.name = r.out.name->name;
2932                 o.in.options = 0;
2933                 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2934                 o.out.handle = &key_handle;
2935
2936                 status = dcerpc_winreg_OpenKey_r(b, tctx, &o);
2937                 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(o.out.result)) {
2938                         enumkeys(tctx, b, &key_handle, depth-1);
2939                         enumvalues(tctx, b, &key_handle);
2940                         torture_assert(tctx, winreg_close(tctx, b, &key_handle), "");
2941                 }
2942
2943                 r.in.enum_index += 1;
2944         } while(true);
2945
2946         return true;
2947 }
2948
2949 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2950
2951 static bool test_Open3(struct torture_context *tctx,
2952                        struct dcerpc_binding_handle *b,
2953                        const char *name, winreg_open_fn open_fn)
2954 {
2955         struct policy_handle handle;
2956         struct winreg_OpenHKLM r;
2957
2958         r.in.system_name = 0;
2959         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2960         r.out.handle = &handle;
2961
2962         torture_assert_ntstatus_ok(tctx,
2963                 open_fn(b, tctx, &r),
2964                 talloc_asprintf(tctx, "%s failed", name));
2965         torture_assert_werr_ok(tctx, r.out.result,
2966                 talloc_asprintf(tctx, "%s failed", name));
2967
2968         enumkeys(tctx, b, &handle, 4);
2969
2970         torture_assert(tctx,
2971                 winreg_close(tctx, b, &handle),
2972                 "dcerpc_CloseKey failed");
2973
2974         return true;
2975 }
2976
2977 static bool torture_samba3_rpc_winreg(struct torture_context *torture)
2978 {
2979         struct dcerpc_pipe *p;
2980         struct dcerpc_binding_handle *b;
2981         bool ret = true;
2982         struct {
2983                 const char *name;
2984                 winreg_open_fn fn;
2985         } open_fns[] = {
2986                 {"OpenHKLM", (winreg_open_fn)dcerpc_winreg_OpenHKLM_r },
2987                 {"OpenHKU",  (winreg_open_fn)dcerpc_winreg_OpenHKU_r },
2988                 {"OpenHKPD", (winreg_open_fn)dcerpc_winreg_OpenHKPD_r },
2989                 {"OpenHKPT", (winreg_open_fn)dcerpc_winreg_OpenHKPT_r },
2990                 {"OpenHKCR", (winreg_open_fn)dcerpc_winreg_OpenHKCR_r }};
2991 #if 0
2992         int i;
2993 #endif
2994
2995         torture_assert_ntstatus_ok(torture,
2996                 torture_rpc_connection(torture, &p, &ndr_table_winreg),
2997                 "failed to setup winreg");
2998
2999         b = p->binding_handle;
3000
3001 #if 1
3002         ret = test_Open3(torture, b, open_fns[0].name, open_fns[0].fn);
3003 #else
3004         for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
3005                 if (!test_Open3(torture, b, open_fns[i].name, open_fns[i].fn))
3006                         ret = false;
3007         }
3008 #endif
3009         return ret;
3010 }
3011
3012 static bool get_shareinfo(struct torture_context *tctx,
3013                           struct dcerpc_binding_handle *b,
3014                           const char *servername,
3015                           const char *share,
3016                           struct srvsvc_NetShareInfo502 **info502)
3017 {
3018         struct srvsvc_NetShareGetInfo r;
3019         union srvsvc_NetShareInfo info;
3020
3021         r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", servername);
3022         r.in.share_name = share;
3023         r.in.level = 502;
3024         r.out.info = &info;
3025
3026         torture_assert_ntstatus_ok(tctx,
3027                 dcerpc_srvsvc_NetShareGetInfo_r(b, tctx, &r),
3028                 "srvsvc_NetShareGetInfo failed");
3029         torture_assert_werr_ok(tctx, r.out.result,
3030                 "srvsvc_NetShareGetInfo failed");
3031
3032         *info502 = talloc_move(tctx, &info.info502);
3033
3034         return true;
3035 }
3036
3037 /*
3038  * Get us a handle on HKLM\
3039  */
3040
3041 static bool get_hklm_handle(struct torture_context *tctx,
3042                             struct dcerpc_binding_handle *b,
3043                             struct policy_handle *handle)
3044 {
3045         struct winreg_OpenHKLM r;
3046         struct policy_handle result;
3047
3048         r.in.system_name = 0;
3049         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3050         r.out.handle = &result;
3051
3052         torture_assert_ntstatus_ok(tctx,
3053                 dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
3054                 "OpenHKLM failed");
3055         torture_assert_werr_ok(tctx, r.out.result,
3056                 "OpenHKLM failed");
3057
3058         *handle = result;
3059
3060         return true;
3061 }
3062
3063 static bool torture_samba3_createshare(struct torture_context *tctx,
3064                                        struct dcerpc_binding_handle *b,
3065                                        const char *sharename)
3066 {
3067         struct policy_handle hklm;
3068         struct policy_handle new_handle;
3069         struct winreg_CreateKey c;
3070         struct winreg_CloseKey cl;
3071         enum winreg_CreateAction action_taken;
3072
3073         c.in.handle = &hklm;
3074         c.in.name.name = talloc_asprintf(
3075                 tctx, "software\\samba\\smbconf\\%s", sharename);
3076         torture_assert(tctx, c.in.name.name, "talloc_asprintf failed");
3077
3078         c.in.keyclass.name = "";
3079         c.in.options = 0;
3080         c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3081         c.in.secdesc = NULL;
3082         c.in.action_taken = &action_taken;
3083         c.out.new_handle = &new_handle;
3084         c.out.action_taken = &action_taken;
3085
3086         torture_assert_ntstatus_ok(tctx,
3087                 dcerpc_winreg_CreateKey_r(b, tctx, &c),
3088                 "OpenKey failed");
3089         torture_assert_werr_ok(tctx, c.out.result,
3090                 "OpenKey failed");
3091
3092         cl.in.handle = &new_handle;
3093         cl.out.handle = &new_handle;
3094
3095         torture_assert_ntstatus_ok(tctx,
3096                 dcerpc_winreg_CloseKey_r(b, tctx, &cl),
3097                 "CloseKey failed");
3098         torture_assert_werr_ok(tctx, cl.out.result,
3099                 "CloseKey failed");
3100
3101         return true;
3102 }
3103
3104 static bool torture_samba3_deleteshare(struct torture_context *tctx,
3105                                        struct dcerpc_binding_handle *b,
3106                                        const char *sharename)
3107 {
3108         struct policy_handle hklm;
3109         struct winreg_DeleteKey d;
3110
3111         torture_assert(tctx,
3112                 get_hklm_handle(tctx, b, &hklm),
3113                 "get_hklm_handle failed");
3114
3115         d.in.handle = &hklm;
3116         d.in.key.name = talloc_asprintf(
3117                 tctx, "software\\samba\\smbconf\\%s", sharename);
3118         torture_assert(tctx, d.in.key.name, "talloc_asprintf failed");
3119
3120         torture_assert_ntstatus_ok(tctx,
3121                 dcerpc_winreg_DeleteKey_r(b, tctx, &d),
3122                 "DeleteKey failed");
3123         torture_assert_werr_ok(tctx, d.out.result,
3124                 "DeleteKey failed");
3125
3126         return true;
3127 }
3128
3129 static bool torture_samba3_setconfig(struct torture_context *tctx,
3130                                      struct dcerpc_binding_handle *b,
3131                                      const char *sharename,
3132                                      const char *parameter,
3133                                      const char *value)
3134 {
3135         struct policy_handle hklm, key_handle;
3136         struct winreg_OpenKey o;
3137         struct winreg_SetValue s;
3138         uint32_t type;
3139         DATA_BLOB val;
3140
3141         torture_assert(tctx,
3142                 get_hklm_handle(tctx, b, &hklm),
3143                 "get_hklm_handle failed");
3144
3145         o.in.parent_handle = &hklm;
3146         o.in.keyname.name = talloc_asprintf(
3147                 tctx, "software\\samba\\smbconf\\%s", sharename);
3148         torture_assert(tctx, o.in.keyname.name, "talloc_asprintf failed");
3149
3150         o.in.options = 0;
3151         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3152         o.out.handle = &key_handle;
3153
3154         torture_assert_ntstatus_ok(tctx,
3155                 dcerpc_winreg_OpenKey_r(b, tctx, &o),
3156                 "OpenKey failed");
3157         torture_assert_werr_ok(tctx, o.out.result,
3158                 "OpenKey failed");
3159
3160         torture_assert(tctx,
3161                 reg_string_to_val(tctx, "REG_SZ", value, &type, &val),
3162                 "reg_string_to_val failed");
3163
3164         s.in.handle = &key_handle;
3165         s.in.name.name = parameter;
3166         s.in.type = type;
3167         s.in.data = val.data;
3168         s.in.size = val.length;
3169
3170         torture_assert_ntstatus_ok(tctx,
3171                 dcerpc_winreg_SetValue_r(b, tctx, &s),
3172                 "SetValue failed");
3173         torture_assert_werr_ok(tctx, s.out.result,
3174                 "SetValue failed");
3175
3176         return true;
3177 }
3178
3179 static bool torture_samba3_regconfig(struct torture_context *torture)
3180 {
3181         struct srvsvc_NetShareInfo502 *i = NULL;
3182         const char *comment = "Dummer Kommentar";
3183         struct dcerpc_pipe *srvsvc_pipe, *winreg_pipe;
3184
3185         torture_assert_ntstatus_ok(torture,
3186                 torture_rpc_connection(torture, &srvsvc_pipe, &ndr_table_srvsvc),
3187                 "failed to setup srvsvc");
3188
3189         torture_assert_ntstatus_ok(torture,
3190                 torture_rpc_connection(torture, &winreg_pipe, &ndr_table_winreg),
3191                 "failed to setup winreg");
3192
3193         torture_assert(torture,
3194                 torture_samba3_createshare(torture, winreg_pipe->binding_handle, "blubber"),
3195                 "torture_samba3_createshare failed");
3196
3197         torture_assert(torture,
3198                 torture_samba3_setconfig(torture, winreg_pipe->binding_handle, "blubber", "comment", comment),
3199                 "torture_samba3_setconfig failed");
3200
3201         torture_assert(torture,
3202                 get_shareinfo(torture, srvsvc_pipe->binding_handle, dcerpc_server_name(srvsvc_pipe), "blubber", &i),
3203                 "get_shareinfo failed");
3204
3205         torture_assert_str_equal(torture, comment, i->comment,
3206                 "got unexpected comment");
3207
3208         torture_assert(torture,
3209                 torture_samba3_deleteshare(torture, winreg_pipe->binding_handle, "blubber"),
3210                 "torture_samba3_deleteshare failed");
3211
3212         return true;
3213 }
3214
3215 /*
3216  * Test that even with a result of 0 rids the array is returned as a
3217  * non-NULL pointer. Yes, XP does notice.
3218  */
3219
3220 bool torture_samba3_getaliasmembership_0(struct torture_context *torture)
3221 {
3222         struct dcerpc_pipe *p;
3223         struct dcerpc_binding_handle *b;
3224         struct samr_Connect2 c;
3225         struct samr_OpenDomain o;
3226         struct dom_sid sid;
3227         struct lsa_SidPtr ptr;
3228         struct lsa_SidArray sids;
3229         struct samr_GetAliasMembership g;
3230         struct samr_Ids rids;
3231         struct policy_handle samr, domain;
3232
3233         torture_assert_ntstatus_ok(torture,
3234                 torture_rpc_connection(torture, &p, &ndr_table_samr),
3235                 "failed to setup samr");
3236
3237         b = p->binding_handle;
3238
3239         c.in.system_name = NULL;
3240         c.in.access_mask = SAMR_ACCESS_LOOKUP_DOMAIN;
3241         c.out.connect_handle = &samr;
3242         torture_assert_ntstatus_ok(torture,
3243                 dcerpc_samr_Connect2_r(b, torture, &c),
3244                 "");
3245         torture_assert_ntstatus_ok(torture, c.out.result,
3246                 "");
3247         dom_sid_parse("S-1-5-32", &sid);
3248         o.in.connect_handle = &samr;
3249         o.in.access_mask = SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS;
3250         o.in.sid = &sid;
3251         o.out.domain_handle = &domain;
3252         torture_assert_ntstatus_ok(torture,
3253                 dcerpc_samr_OpenDomain_r(b, torture, &o),
3254                 "");
3255         torture_assert_ntstatus_ok(torture, o.out.result,
3256                 "");
3257         dom_sid_parse("S-1-2-3-4-5", &sid);
3258         ptr.sid = &sid;
3259         sids.num_sids = 1;
3260         sids.sids = &ptr;
3261         g.in.domain_handle = &domain;
3262         g.in.sids = &sids;
3263         g.out.rids = &rids;
3264         torture_assert_ntstatus_ok(torture,
3265                 dcerpc_samr_GetAliasMembership_r(b, torture, &g),
3266                 "");
3267         torture_assert_ntstatus_ok(torture, g.out.result,
3268                 "");
3269         if (rids.ids == NULL) {
3270                 /* This is the piece to test here */
3271                 torture_fail(torture,
3272                         "torture_samba3_getaliasmembership_0: "
3273                         "Server returns NULL rids array\n");
3274         }
3275
3276         return true;
3277 }
3278
3279 /**
3280  * Test smb reauthentication while rpc pipe is in use.
3281  */
3282 static bool torture_rpc_smb_reauth1(struct torture_context *torture)
3283 {
3284         TALLOC_CTX *mem_ctx;
3285         NTSTATUS status;
3286         bool ret = false;
3287         struct smbcli_state *cli;
3288         struct smbcli_options options;
3289         struct smbcli_session_options session_options;
3290
3291         struct dcerpc_pipe *lsa_pipe;
3292         struct dcerpc_binding_handle *lsa_handle;
3293         struct lsa_GetUserName r;
3294         struct lsa_String *authority_name_p = NULL;
3295         char *authority_name_saved = NULL;
3296         struct lsa_String *account_name_p = NULL;
3297         char *account_name_saved = NULL;
3298         struct cli_credentials *anon_creds = NULL;
3299         struct smb_composite_sesssetup io;
3300
3301         mem_ctx = talloc_init("torture_samba3_reauth");
3302         torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
3303
3304         lpcfg_smbcli_options(torture->lp_ctx, &options);
3305         lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
3306
3307         status = smbcli_full_connection(mem_ctx, &cli,
3308                                         torture_setting_string(torture, "host", NULL),
3309                                         lpcfg_smb_ports(torture->lp_ctx),
3310                                         "IPC$", NULL,
3311                                         lpcfg_socket_options(torture->lp_ctx),
3312                                         cmdline_credentials,
3313                                         lpcfg_resolve_context(torture->lp_ctx),
3314                                         torture->ev, &options, &session_options,
3315                                         lpcfg_gensec_settings(torture, torture->lp_ctx));
3316         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3317                                         "smbcli_full_connection failed");
3318
3319         lsa_pipe = dcerpc_pipe_init(mem_ctx, torture->ev);
3320         torture_assert_goto(torture, (lsa_pipe != NULL), ret, done,
3321                             "dcerpc_pipe_init failed");
3322         lsa_handle = lsa_pipe->binding_handle;
3323
3324         status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
3325         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3326                                         "dcerpc_pipe_open failed");
3327
3328         status = dcerpc_bind_auth_none(lsa_pipe, &ndr_table_lsarpc);
3329         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3330                                         "dcerpc_bind_auth_none failed");
3331
3332         /* lsa getusername */
3333
3334         ZERO_STRUCT(r);
3335         r.in.system_name = "\\";
3336         r.in.account_name = &account_name_p;
3337         r.in.authority_name = &authority_name_p;
3338         r.out.account_name = &account_name_p;
3339
3340         status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3341
3342         authority_name_p = *r.out.authority_name;
3343
3344         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3345                                         "GetUserName failed");
3346         torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3347                                         "GetUserName failed");
3348
3349         torture_comment(torture, "lsa_GetUserName gave '%s\\%s'\n",
3350                         authority_name_p->string,
3351                         account_name_p->string);
3352
3353         account_name_saved = talloc_strdup(mem_ctx, account_name_p->string);
3354         torture_assert_goto(torture, (account_name_saved != NULL), ret, done,
3355                             "talloc failed");
3356         authority_name_saved = talloc_strdup(mem_ctx, authority_name_p->string);
3357         torture_assert_goto(torture, (authority_name_saved != NULL), ret, done,
3358                             "talloc failed");
3359
3360         /* smb re-authenticate as anonymous */
3361
3362         anon_creds = cli_credentials_init_anon(mem_ctx);
3363
3364         ZERO_STRUCT(io);
3365         io.in.sesskey         = cli->transport->negotiate.sesskey;
3366         io.in.capabilities    = cli->transport->negotiate.capabilities;
3367         io.in.credentials     = anon_creds;
3368         io.in.workgroup       = lpcfg_workgroup(torture->lp_ctx);
3369         io.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
3370
3371         status = smb_composite_sesssetup(cli->session, &io);
3372         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3373                                         "session reauth to anon failed");
3374
3375         /* re-do lsa getusername after reauth */
3376
3377         TALLOC_FREE(authority_name_p);
3378         TALLOC_FREE(account_name_p);
3379         ZERO_STRUCT(r);
3380         r.in.system_name = "\\";
3381         r.in.account_name = &account_name_p;
3382         r.in.authority_name = &authority_name_p;
3383         r.out.account_name = &account_name_p;
3384
3385         status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3386
3387         authority_name_p = *r.out.authority_name;
3388
3389         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3390                                         "GetUserName failed");
3391         torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3392                                         "GetUserName failed");
3393
3394         torture_assert_goto(torture, (strcmp(authority_name_p->string, authority_name_saved) == 0),
3395                             ret, done, "authority_name not equal after reauth to anon");
3396         torture_assert_goto(torture, (strcmp(account_name_p->string, account_name_saved) == 0),
3397                             ret, done, "account_name not equal after reauth to anon");
3398
3399         /* smb re-auth again to the original user */
3400
3401         ZERO_STRUCT(io);
3402         io.in.sesskey         = cli->transport->negotiate.sesskey;
3403         io.in.capabilities    = cli->transport->negotiate.capabilities;
3404         io.in.credentials     = cmdline_credentials;
3405         io.in.workgroup       = lpcfg_workgroup(torture->lp_ctx);
3406         io.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
3407
3408         status = smb_composite_sesssetup(cli->session, &io);
3409         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3410                                         "session reauth to anon failed");
3411
3412         /* re-do lsa getusername */
3413
3414         TALLOC_FREE(authority_name_p);
3415         TALLOC_FREE(account_name_p);
3416         ZERO_STRUCT(r);
3417         r.in.system_name = "\\";
3418         r.in.account_name = &account_name_p;
3419         r.in.authority_name = &authority_name_p;
3420         r.out.account_name = &account_name_p;
3421
3422         status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3423
3424         authority_name_p = *r.out.authority_name;
3425
3426         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3427                                         "GetUserName failed");
3428         torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3429                                         "GetUserName failed");
3430
3431         torture_assert_goto(torture, (strcmp(authority_name_p->string, authority_name_saved) == 0),
3432                             ret, done, "authority_name not equal after reauth to anon");
3433         torture_assert_goto(torture, (strcmp(account_name_p->string, account_name_saved) == 0),
3434                             ret, done, "account_name not equal after reauth to anon");
3435
3436         ret = true;
3437
3438 done:
3439         talloc_free(mem_ctx);
3440         return ret;
3441 }
3442
3443 /**
3444  * Test smb reauthentication while rpc pipe is in use.
3445  * Open a second lsa bind after reauth to anon.
3446  * Do lsa getusername on that second bind.
3447  */
3448 static bool torture_rpc_smb_reauth2(struct torture_context *torture)
3449 {
3450         TALLOC_CTX *mem_ctx;
3451         NTSTATUS status;
3452         bool ret = false;
3453         struct smbcli_state *cli;
3454         struct smbcli_options options;
3455         struct smbcli_session_options session_options;
3456
3457         struct dcerpc_pipe *lsa_pipe;
3458         struct dcerpc_binding_handle *lsa_handle;
3459         struct lsa_GetUserName r;
3460         struct lsa_String *authority_name_p = NULL;
3461         char *authority_name_saved = NULL;
3462         struct lsa_String *account_name_p = NULL;
3463         char *account_name_saved = NULL;
3464         struct cli_credentials *anon_creds = NULL;
3465         struct smb_composite_sesssetup io;
3466
3467         mem_ctx = talloc_init("torture_samba3_reauth");
3468         torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
3469
3470         lpcfg_smbcli_options(torture->lp_ctx, &options);
3471         lpcfg_smbcli_session_options(torture->lp_ctx, &session_options);
3472
3473         status = smbcli_full_connection(mem_ctx, &cli,
3474                                         torture_setting_string(torture, "host", NULL),
3475                                         lpcfg_smb_ports(torture->lp_ctx),
3476                                         "IPC$", NULL,
3477                                         lpcfg_socket_options(torture->lp_ctx),
3478                                         cmdline_credentials,
3479                                         lpcfg_resolve_context(torture->lp_ctx),
3480                                         torture->ev, &options, &session_options,
3481                                         lpcfg_gensec_settings(torture, torture->lp_ctx));
3482         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3483                                         "smbcli_full_connection failed");
3484
3485         /* smb re-authenticate as anonymous */
3486
3487         anon_creds = cli_credentials_init_anon(mem_ctx);
3488
3489         ZERO_STRUCT(io);
3490         io.in.sesskey         = cli->transport->negotiate.sesskey;
3491         io.in.capabilities    = cli->transport->negotiate.capabilities;
3492         io.in.credentials     = anon_creds;
3493         io.in.workgroup       = lpcfg_workgroup(torture->lp_ctx);
3494         io.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
3495
3496         status = smb_composite_sesssetup(cli->session, &io);
3497         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3498                                         "session reauth to anon failed");
3499
3500         /* open the lsa pipe */
3501
3502         lsa_pipe = dcerpc_pipe_init(mem_ctx, torture->ev);
3503         torture_assert_goto(torture, (lsa_pipe != NULL), ret, done,
3504                             "dcerpc_pipe_init failed");
3505         lsa_handle = lsa_pipe->binding_handle;
3506
3507         status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
3508         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3509                                         "dcerpc_pipe_open failed");
3510
3511         status = dcerpc_bind_auth_none(lsa_pipe, &ndr_table_lsarpc);
3512         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3513                                         "dcerpc_bind_auth_none failed");
3514
3515         /* lsa getusername */
3516
3517         ZERO_STRUCT(r);
3518         r.in.system_name = "\\";
3519         r.in.account_name = &account_name_p;
3520         r.in.authority_name = &authority_name_p;
3521         r.out.account_name = &account_name_p;
3522
3523         status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3524
3525         authority_name_p = *r.out.authority_name;
3526
3527         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3528                                         "GetUserName failed");
3529         torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3530                                         "GetUserName failed");
3531
3532         torture_comment(torture, "lsa_GetUserName gave '%s\\%s'\n",
3533                         authority_name_p->string,
3534                         account_name_p->string);
3535
3536         account_name_saved = talloc_strdup(mem_ctx, account_name_p->string);
3537         torture_assert_goto(torture, (account_name_saved != NULL), ret, done,
3538                             "talloc failed");
3539         authority_name_saved = talloc_strdup(mem_ctx, authority_name_p->string);
3540         torture_assert_goto(torture, (authority_name_saved != NULL), ret, done,
3541                             "talloc failed");
3542
3543         /* smb re-auth again to the original user */
3544
3545         ZERO_STRUCT(io);
3546         io.in.sesskey         = cli->transport->negotiate.sesskey;
3547         io.in.capabilities    = cli->transport->negotiate.capabilities;
3548         io.in.credentials     = cmdline_credentials;
3549         io.in.workgroup       = lpcfg_workgroup(torture->lp_ctx);
3550         io.in.gensec_settings = lpcfg_gensec_settings(torture, torture->lp_ctx);
3551
3552         status = smb_composite_sesssetup(cli->session, &io);
3553         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3554                                         "session reauth to anon failed");
3555
3556         /* re-do lsa getusername after reauth */
3557
3558         TALLOC_FREE(authority_name_p);
3559         TALLOC_FREE(account_name_p);
3560         ZERO_STRUCT(r);
3561         r.in.system_name = "\\";
3562         r.in.account_name = &account_name_p;
3563         r.in.authority_name = &authority_name_p;
3564         r.out.account_name = &account_name_p;
3565
3566         status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3567
3568         authority_name_p = *r.out.authority_name;
3569
3570         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3571                                         "GetUserName failed");
3572         torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3573                                         "GetUserName failed");
3574
3575         torture_assert_goto(torture, (strcmp(authority_name_p->string, authority_name_saved) == 0),
3576                             ret, done, "authority_name not equal after reauth to anon");
3577         torture_assert_goto(torture, (strcmp(account_name_p->string, account_name_saved) == 0),
3578                             ret, done, "account_name not equal after reauth to anon");
3579
3580         ret = true;
3581
3582 done:
3583         talloc_free(mem_ctx);
3584         return ret;
3585 }
3586
3587 /**
3588  * Test smb2 reauthentication while rpc pipe is in use.
3589  */
3590 static bool torture_rpc_smb2_reauth1(struct torture_context *torture)
3591 {
3592         TALLOC_CTX *mem_ctx;
3593         NTSTATUS status;
3594         bool ret = false;
3595         struct smbcli_options options;
3596
3597         struct dcerpc_pipe *lsa_pipe;
3598         struct dcerpc_binding_handle *lsa_handle;
3599         struct lsa_GetUserName r;
3600         struct lsa_String *authority_name_p = NULL;
3601         char *authority_name_saved = NULL;
3602         struct lsa_String *account_name_p = NULL;
3603         char *account_name_saved = NULL;
3604         struct cli_credentials *anon_creds = NULL;
3605         const char *host = torture_setting_string(torture, "host", NULL);
3606         struct smb2_tree *tree;
3607
3608         mem_ctx = talloc_init("torture_samba3_reauth");
3609         torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
3610
3611         lpcfg_smbcli_options(torture->lp_ctx, &options);
3612
3613         status = smb2_connect(mem_ctx,
3614                               host,
3615                               lpcfg_smb_ports(torture->lp_ctx),
3616                               "IPC$",
3617                               lpcfg_resolve_context(torture->lp_ctx),
3618                               cmdline_credentials,
3619                               &tree,
3620                               torture->ev,
3621                               &options,
3622                               lpcfg_socket_options(torture->lp_ctx),
3623                               lpcfg_gensec_settings(torture, torture->lp_ctx)
3624                               );
3625         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3626                                         "smb2_connect failed");
3627
3628         lsa_pipe = dcerpc_pipe_init(mem_ctx, torture->ev);
3629         torture_assert_goto(torture, (lsa_pipe != NULL), ret, done,
3630                             "dcerpc_pipe_init failed");
3631         lsa_handle = lsa_pipe->binding_handle;
3632
3633         status = dcerpc_pipe_open_smb2(lsa_pipe, tree, "lsarpc");
3634         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3635                                         "dcerpc_pipe_open_smb2 failed");
3636
3637         status = dcerpc_bind_auth_none(lsa_pipe, &ndr_table_lsarpc);
3638         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3639                                         "dcerpc_bind_auth_none failed");
3640
3641         /* lsa getusername */
3642
3643         ZERO_STRUCT(r);
3644         r.in.system_name = "\\";
3645         r.in.account_name = &account_name_p;
3646         r.in.authority_name = &authority_name_p;
3647         r.out.account_name = &account_name_p;
3648
3649         status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3650
3651         authority_name_p = *r.out.authority_name;
3652
3653         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3654                                         "GetUserName failed");
3655         torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3656                                         "GetUserName failed");
3657
3658         torture_comment(torture, "lsa_GetUserName gave '%s\\%s'\n",
3659                         authority_name_p->string,
3660                         account_name_p->string);
3661
3662         account_name_saved = talloc_strdup(mem_ctx, account_name_p->string);
3663         torture_assert_goto(torture, (account_name_saved != NULL), ret, done,
3664                             "talloc failed");
3665         authority_name_saved = talloc_strdup(mem_ctx, authority_name_p->string);
3666         torture_assert_goto(torture, (authority_name_saved != NULL), ret, done,
3667                             "talloc failed");
3668
3669         /* smb re-authenticate as anonymous */
3670
3671         anon_creds = cli_credentials_init_anon(mem_ctx);
3672
3673         status = smb2_session_setup_spnego(tree->session,
3674                                            anon_creds,
3675                                            0 /* previous_session_id */);
3676         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3677                                         "session reauth to anon failed");
3678
3679         /* re-do lsa getusername after reauth */
3680
3681         TALLOC_FREE(authority_name_p);
3682         TALLOC_FREE(account_name_p);
3683         ZERO_STRUCT(r);
3684         r.in.system_name = "\\";
3685         r.in.account_name = &account_name_p;
3686         r.in.authority_name = &authority_name_p;
3687         r.out.account_name = &account_name_p;
3688
3689         status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3690
3691         authority_name_p = *r.out.authority_name;
3692
3693         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3694                                         "GetUserName failed");
3695         torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3696                                         "GetUserName failed");
3697
3698         torture_assert_goto(torture, (strcmp(authority_name_p->string, authority_name_saved) == 0),
3699                             ret, done, "authority_name not equal after reauth to anon");
3700         torture_assert_goto(torture, (strcmp(account_name_p->string, account_name_saved) == 0),
3701                             ret, done, "account_name not equal after reauth to anon");
3702
3703         /* smb re-auth again to the original user */
3704
3705         status = smb2_session_setup_spnego(tree->session,
3706                                            cmdline_credentials,
3707                                            0 /* previous_session_id */);
3708         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3709                                         "session reauth to anon failed");
3710
3711         /* re-do lsa getusername */
3712
3713         TALLOC_FREE(authority_name_p);
3714         TALLOC_FREE(account_name_p);
3715         ZERO_STRUCT(r);
3716         r.in.system_name = "\\";
3717         r.in.account_name = &account_name_p;
3718         r.in.authority_name = &authority_name_p;
3719         r.out.account_name = &account_name_p;
3720
3721         status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3722
3723         authority_name_p = *r.out.authority_name;
3724
3725         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3726                                         "GetUserName failed");
3727         torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3728                                         "GetUserName failed");
3729
3730         torture_assert_goto(torture, (strcmp(authority_name_p->string, authority_name_saved) == 0),
3731                             ret, done, "authority_name not equal after reauth to anon");
3732         torture_assert_goto(torture, (strcmp(account_name_p->string, account_name_saved) == 0),
3733                             ret, done, "account_name not equal after reauth to anon");
3734
3735         ret = true;
3736
3737 done:
3738         talloc_free(mem_ctx);
3739         return ret;
3740 }
3741
3742 /**
3743  * Test smb2reauthentication while rpc pipe is in use.
3744  * Open a second lsa bind after reauth to anon.
3745  * Do lsa getusername on that second bind.
3746  */
3747 static bool torture_rpc_smb2_reauth2(struct torture_context *torture)
3748 {
3749         TALLOC_CTX *mem_ctx;
3750         NTSTATUS status;
3751         bool ret = false;
3752         struct smbcli_options options;
3753
3754         struct dcerpc_pipe *lsa_pipe;
3755         struct dcerpc_binding_handle *lsa_handle;
3756         struct lsa_GetUserName r;
3757         struct lsa_String *authority_name_p = NULL;
3758         char *authority_name_saved = NULL;
3759         struct lsa_String *account_name_p = NULL;
3760         char *account_name_saved = NULL;
3761         struct cli_credentials *anon_creds = NULL;
3762         const char *host = torture_setting_string(torture, "host", NULL);
3763         struct smb2_tree *tree;
3764
3765         mem_ctx = talloc_init("torture_samba3_reauth");
3766         torture_assert(torture, (mem_ctx != NULL), "talloc_init failed");
3767
3768         lpcfg_smbcli_options(torture->lp_ctx, &options);
3769
3770         status = smb2_connect(mem_ctx,
3771                               host,
3772                               lpcfg_smb_ports(torture->lp_ctx),
3773                               "IPC$",
3774                               lpcfg_resolve_context(torture->lp_ctx),
3775                               cmdline_credentials,
3776                               &tree,
3777                               torture->ev,
3778                               &options,
3779                               lpcfg_socket_options(torture->lp_ctx),
3780                               lpcfg_gensec_settings(torture, torture->lp_ctx)
3781                               );
3782         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3783                                         "smb2_connect failed");
3784
3785         /* smb re-authenticate as anonymous */
3786
3787         anon_creds = cli_credentials_init_anon(mem_ctx);
3788
3789         status = smb2_session_setup_spnego(tree->session,
3790                                            anon_creds,
3791                                            0 /* previous_session_id */);
3792         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3793                                         "session reauth to anon failed");
3794
3795         /* open the lsa pipe */
3796
3797         lsa_pipe = dcerpc_pipe_init(mem_ctx, torture->ev);
3798         torture_assert_goto(torture, (lsa_pipe != NULL), ret, done,
3799                             "dcerpc_pipe_init failed");
3800         lsa_handle = lsa_pipe->binding_handle;
3801
3802         status = dcerpc_pipe_open_smb2(lsa_pipe, tree, "lsarpc");
3803         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3804                                         "dcerpc_pipe_open_smb2 failed");
3805
3806         status = dcerpc_bind_auth_none(lsa_pipe, &ndr_table_lsarpc);
3807         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3808                                         "dcerpc_bind_auth_none failed");
3809
3810         /* lsa getusername */
3811
3812         ZERO_STRUCT(r);
3813         r.in.system_name = "\\";
3814         r.in.account_name = &account_name_p;
3815         r.in.authority_name = &authority_name_p;
3816         r.out.account_name = &account_name_p;
3817
3818         status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3819
3820         authority_name_p = *r.out.authority_name;
3821
3822         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3823                                         "GetUserName failed");
3824         torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3825                                         "GetUserName failed");
3826
3827         torture_comment(torture, "lsa_GetUserName gave '%s\\%s'\n",
3828                         authority_name_p->string,
3829                         account_name_p->string);
3830
3831         account_name_saved = talloc_strdup(mem_ctx, account_name_p->string);
3832         torture_assert_goto(torture, (account_name_saved != NULL), ret, done,
3833                             "talloc failed");
3834         authority_name_saved = talloc_strdup(mem_ctx, authority_name_p->string);
3835         torture_assert_goto(torture, (authority_name_saved != NULL), ret, done,
3836                             "talloc failed");
3837
3838         /* smb re-auth again to the original user */
3839
3840         status = smb2_session_setup_spnego(tree->session,
3841                                            cmdline_credentials,
3842                                            0 /* previous_session_id */);
3843         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3844                                         "session reauth to anon failed");
3845
3846         /* re-do lsa getusername */
3847
3848         TALLOC_FREE(authority_name_p);
3849         TALLOC_FREE(account_name_p);
3850         ZERO_STRUCT(r);
3851         r.in.system_name = "\\";
3852         r.in.account_name = &account_name_p;
3853         r.in.authority_name = &authority_name_p;
3854         r.out.account_name = &account_name_p;
3855
3856         status = dcerpc_lsa_GetUserName_r(lsa_handle, mem_ctx, &r);
3857
3858         authority_name_p = *r.out.authority_name;
3859
3860         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
3861                                         "GetUserName failed");
3862         torture_assert_ntstatus_ok_goto(torture, r.out.result, ret, done,
3863                                         "GetUserName failed");
3864
3865         torture_assert_goto(torture, (strcmp(authority_name_p->string, authority_name_saved) == 0),
3866                             ret, done, "authority_name not equal after reauth to anon");
3867         torture_assert_goto(torture, (strcmp(account_name_p->string, account_name_saved) == 0),
3868                             ret, done, "account_name not equal after reauth to anon");
3869
3870         ret = true;
3871
3872 done:
3873         talloc_free(mem_ctx);
3874         return ret;
3875 }
3876
3877 struct torture_suite *torture_rpc_samba3(TALLOC_CTX *mem_ctx)
3878 {
3879         struct torture_suite *suite = torture_suite_create(mem_ctx, "samba3");
3880
3881         torture_suite_add_simple_test(suite, "bind", torture_bind_samba3);
3882         torture_suite_add_simple_test(suite, "netlogon", torture_netlogon_samba3);
3883         torture_suite_add_simple_test(suite, "sessionkey", torture_samba3_sessionkey);
3884         torture_suite_add_simple_test(suite, "srvsvc", torture_samba3_rpc_srvsvc);
3885         torture_suite_add_simple_test(suite, "sharesec", torture_samba3_rpc_sharesec);
3886         torture_suite_add_simple_test(suite, "getusername", torture_samba3_rpc_getusername);
3887         torture_suite_add_simple_test(suite, "randomauth2", torture_samba3_rpc_randomauth2);
3888         torture_suite_add_simple_test(suite, "lsa", torture_samba3_rpc_lsa);
3889         torture_suite_add_simple_test(suite, "spoolss", torture_samba3_rpc_spoolss);
3890         torture_suite_add_simple_test(suite, "wkssvc", torture_samba3_rpc_wkssvc);
3891         torture_suite_add_simple_test(suite, "winreg", torture_samba3_rpc_winreg);
3892         torture_suite_add_simple_test(suite, "getaliasmembership-0", torture_samba3_getaliasmembership_0);
3893         torture_suite_add_simple_test(suite, "regconfig", torture_samba3_regconfig);
3894         torture_suite_add_simple_test(suite, "smb-reauth1", torture_rpc_smb_reauth1);
3895         torture_suite_add_simple_test(suite, "smb-reauth2", torture_rpc_smb_reauth2);
3896         torture_suite_add_simple_test(suite, "smb2-reauth1", torture_rpc_smb2_reauth1);
3897         torture_suite_add_simple_test(suite, "smb2-reauth2", torture_rpc_smb2_reauth2);
3898
3899         suite->description = talloc_strdup(suite, "samba3 DCERPC interface tests");
3900
3901         return suite;
3902 }