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