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