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