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