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