r23231: Fix make test on build farm for 64-bit hosts. There's no reason this should
[Samba/bb.git] / source4 / torture / rpc / samba3rpc.c
blobd5a00557cf5df6ca0d5e0d12dc23520bf1c666d5
1 /*
2 Unix SMB/CIFS implementation.
4 dcerpc torture tests, designed to walk Samba3 code paths
6 Copyright (C) Volker Lendecke 2006
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 2 of the License, or
11 (at your option) any later version.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "includes.h"
24 #include "libcli/raw/libcliraw.h"
25 #include "libcli/rap/rap.h"
26 #include "torture/torture.h"
27 #include "torture/util.h"
28 #include "torture/rap/proto.h"
29 #include "librpc/gen_ndr/ndr_lsa.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "librpc/gen_ndr/ndr_samr.h"
32 #include "librpc/gen_ndr/ndr_samr_c.h"
33 #include "librpc/gen_ndr/ndr_netlogon.h"
34 #include "librpc/gen_ndr/ndr_netlogon_c.h"
35 #include "librpc/gen_ndr/ndr_srvsvc.h"
36 #include "librpc/gen_ndr/ndr_srvsvc_c.h"
37 #include "librpc/gen_ndr/ndr_spoolss.h"
38 #include "librpc/gen_ndr/ndr_spoolss_c.h"
39 #include "librpc/gen_ndr/ndr_winreg.h"
40 #include "librpc/gen_ndr/ndr_winreg_c.h"
41 #include "librpc/gen_ndr/ndr_wkssvc.h"
42 #include "librpc/gen_ndr/ndr_wkssvc_c.h"
43 #include "lib/cmdline/popt_common.h"
44 #include "librpc/rpc/dcerpc.h"
45 #include "torture/rpc/rpc.h"
46 #include "libcli/libcli.h"
47 #include "libcli/composite/composite.h"
48 #include "libcli/smb_composite/smb_composite.h"
49 #include "libcli/auth/libcli_auth.h"
50 #include "lib/crypto/crypto.h"
51 #include "libcli/security/proto.h"
53 static struct cli_credentials *create_anon_creds(TALLOC_CTX *mem_ctx)
55 struct cli_credentials *result;
57 if (!(result = cli_credentials_init(mem_ctx))) {
58 return NULL;
61 cli_credentials_set_conf(result);
62 cli_credentials_set_anonymous(result);
64 return result;
68 * This tests a RPC call using an invalid vuid
71 BOOL torture_bind_authcontext(struct torture_context *torture)
73 TALLOC_CTX *mem_ctx;
74 NTSTATUS status;
75 BOOL ret = False;
76 struct lsa_ObjectAttribute objectattr;
77 struct lsa_OpenPolicy2 openpolicy;
78 struct policy_handle handle;
79 struct lsa_Close close_handle;
80 struct smbcli_session *tmp;
81 struct smbcli_session *session2;
82 struct smbcli_state *cli;
83 struct dcerpc_pipe *lsa_pipe;
84 struct cli_credentials *anon_creds;
85 struct smb_composite_sesssetup setup;
87 mem_ctx = talloc_init("torture_bind_authcontext");
89 if (mem_ctx == NULL) {
90 d_printf("talloc_init failed\n");
91 return False;
94 status = smbcli_full_connection(mem_ctx, &cli,
95 torture_setting_string(torture, "host", NULL),
96 "IPC$", NULL, cmdline_credentials,
97 NULL);
98 if (!NT_STATUS_IS_OK(status)) {
99 d_printf("smbcli_full_connection failed: %s\n",
100 nt_errstr(status));
101 goto done;
104 lsa_pipe = dcerpc_pipe_init(mem_ctx, cli->transport->socket->event.ctx);
105 if (lsa_pipe == NULL) {
106 d_printf("dcerpc_pipe_init failed\n");
107 goto done;
110 status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
111 if (!NT_STATUS_IS_OK(status)) {
112 d_printf("dcerpc_pipe_open_smb failed: %s\n",
113 nt_errstr(status));
114 goto done;
117 status = dcerpc_bind_auth_none(lsa_pipe, &dcerpc_table_lsarpc);
118 if (!NT_STATUS_IS_OK(status)) {
119 d_printf("dcerpc_bind_auth_none failed: %s\n",
120 nt_errstr(status));
121 goto done;
124 openpolicy.in.system_name =talloc_asprintf(
125 mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
126 ZERO_STRUCT(objectattr);
127 openpolicy.in.attr = &objectattr;
128 openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
129 openpolicy.out.handle = &handle;
131 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
133 if (!NT_STATUS_IS_OK(status)) {
134 d_printf("dcerpc_lsa_OpenPolicy2 failed: %s\n",
135 nt_errstr(status));
136 goto done;
139 close_handle.in.handle = &handle;
140 close_handle.out.handle = &handle;
142 status = dcerpc_lsa_Close(lsa_pipe, mem_ctx, &close_handle);
143 if (!NT_STATUS_IS_OK(status)) {
144 d_printf("dcerpc_lsa_Close failed: %s\n",
145 nt_errstr(status));
146 goto done;
149 session2 = smbcli_session_init(cli->transport, mem_ctx, False);
150 if (session2 == NULL) {
151 d_printf("smbcli_session_init failed\n");
152 goto done;
155 if (!(anon_creds = create_anon_creds(mem_ctx))) {
156 d_printf("create_anon_creds failed\n");
157 goto done;
160 setup.in.sesskey = cli->transport->negotiate.sesskey;
161 setup.in.capabilities = cli->transport->negotiate.capabilities;
162 setup.in.workgroup = "";
163 setup.in.credentials = anon_creds;
165 status = smb_composite_sesssetup(session2, &setup);
166 if (!NT_STATUS_IS_OK(status)) {
167 d_printf("anon session setup failed: %s\n",
168 nt_errstr(status));
169 goto done;
171 session2->vuid = setup.out.vuid;
173 tmp = cli->tree->session;
174 cli->tree->session = session2;
176 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
178 cli->tree->session = tmp;
179 talloc_free(lsa_pipe);
180 lsa_pipe = NULL;
182 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
183 d_printf("dcerpc_lsa_OpenPolicy2 with wrong vuid gave %s, "
184 "expected NT_STATUS_INVALID_HANDLE\n",
185 nt_errstr(status));
186 goto done;
189 ret = True;
190 done:
191 talloc_free(mem_ctx);
192 return ret;
196 * Bind to lsa using a specific auth method
199 static BOOL bindtest(struct smbcli_state *cli,
200 struct cli_credentials *credentials,
201 uint8_t auth_type, uint8_t auth_level)
203 TALLOC_CTX *mem_ctx;
204 BOOL ret = False;
205 NTSTATUS status;
207 struct dcerpc_pipe *lsa_pipe;
208 struct lsa_ObjectAttribute objectattr;
209 struct lsa_OpenPolicy2 openpolicy;
210 struct lsa_QueryInfoPolicy query;
211 struct policy_handle handle;
212 struct lsa_Close close_handle;
214 if ((mem_ctx = talloc_init("bindtest")) == NULL) {
215 d_printf("talloc_init failed\n");
216 return False;
219 lsa_pipe = dcerpc_pipe_init(mem_ctx,
220 cli->transport->socket->event.ctx);
221 if (lsa_pipe == NULL) {
222 d_printf("dcerpc_pipe_init failed\n");
223 goto done;
226 status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
227 if (!NT_STATUS_IS_OK(status)) {
228 d_printf("dcerpc_pipe_open_smb failed: %s\n",
229 nt_errstr(status));
230 goto done;
233 status = dcerpc_bind_auth(lsa_pipe, &dcerpc_table_lsarpc,
234 credentials, auth_type, auth_level,
235 NULL);
236 if (!NT_STATUS_IS_OK(status)) {
237 d_printf("dcerpc_bind_auth failed: %s\n", nt_errstr(status));
238 goto done;
241 openpolicy.in.system_name =talloc_asprintf(
242 mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
243 ZERO_STRUCT(objectattr);
244 openpolicy.in.attr = &objectattr;
245 openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
246 openpolicy.out.handle = &handle;
248 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
250 if (!NT_STATUS_IS_OK(status)) {
251 d_printf("dcerpc_lsa_OpenPolicy2 failed: %s\n",
252 nt_errstr(status));
253 goto done;
256 query.in.handle = &handle;
257 query.in.level = LSA_POLICY_INFO_DOMAIN;
259 status = dcerpc_lsa_QueryInfoPolicy(lsa_pipe, mem_ctx, &query);
260 if (!NT_STATUS_IS_OK(status)) {
261 d_printf("dcerpc_lsa_QueryInfoPolicy failed: %s\n",
262 nt_errstr(status));
263 goto done;
266 close_handle.in.handle = &handle;
267 close_handle.out.handle = &handle;
269 status = dcerpc_lsa_Close(lsa_pipe, mem_ctx, &close_handle);
270 if (!NT_STATUS_IS_OK(status)) {
271 d_printf("dcerpc_lsa_Close failed: %s\n",
272 nt_errstr(status));
273 goto done;
276 ret = True;
277 done:
278 talloc_free(mem_ctx);
279 return ret;
283 * test authenticated RPC binds with the variants Samba3 does support
286 BOOL torture_bind_samba3(struct torture_context *torture)
288 TALLOC_CTX *mem_ctx;
289 NTSTATUS status;
290 BOOL ret = False;
291 struct smbcli_state *cli;
293 mem_ctx = talloc_init("torture_bind_authcontext");
295 if (mem_ctx == NULL) {
296 d_printf("talloc_init failed\n");
297 return False;
300 status = smbcli_full_connection(mem_ctx, &cli,
301 torture_setting_string(torture, "host", NULL),
302 "IPC$", NULL, cmdline_credentials,
303 NULL);
304 if (!NT_STATUS_IS_OK(status)) {
305 d_printf("smbcli_full_connection failed: %s\n",
306 nt_errstr(status));
307 goto done;
310 ret = True;
312 ret &= bindtest(cli, cmdline_credentials, DCERPC_AUTH_TYPE_NTLMSSP,
313 DCERPC_AUTH_LEVEL_INTEGRITY);
314 ret &= bindtest(cli, cmdline_credentials, DCERPC_AUTH_TYPE_NTLMSSP,
315 DCERPC_AUTH_LEVEL_PRIVACY);
316 ret &= bindtest(cli, cmdline_credentials, DCERPC_AUTH_TYPE_SPNEGO,
317 DCERPC_AUTH_LEVEL_INTEGRITY);
318 ret &= bindtest(cli, cmdline_credentials, DCERPC_AUTH_TYPE_SPNEGO,
319 DCERPC_AUTH_LEVEL_PRIVACY);
321 done:
322 talloc_free(mem_ctx);
323 return ret;
327 * Lookup or create a user and return all necessary info
330 static NTSTATUS get_usr_handle(struct smbcli_state *cli,
331 TALLOC_CTX *mem_ctx,
332 struct cli_credentials *admin_creds,
333 uint8_t auth_type,
334 uint8_t auth_level,
335 const char *username,
336 char **domain,
337 struct dcerpc_pipe **result_pipe,
338 struct policy_handle **result_handle,
339 struct dom_sid **sid)
341 struct dcerpc_pipe *samr_pipe;
342 NTSTATUS status;
343 struct policy_handle conn_handle;
344 struct policy_handle domain_handle;
345 struct policy_handle *user_handle;
346 struct samr_Connect2 conn;
347 struct samr_EnumDomains enumdom;
348 uint32_t resume_handle = 0;
349 struct samr_LookupDomain l;
350 int dom_idx;
351 struct lsa_String domain_name;
352 struct lsa_String user_name;
353 struct samr_OpenDomain o;
354 struct samr_CreateUser2 c;
355 uint32_t user_rid,access_granted;
357 samr_pipe = dcerpc_pipe_init(mem_ctx,
358 cli->transport->socket->event.ctx);
359 if (samr_pipe == NULL) {
360 d_printf("dcerpc_pipe_init failed\n");
361 status = NT_STATUS_NO_MEMORY;
362 goto fail;
365 status = dcerpc_pipe_open_smb(samr_pipe, cli->tree, "\\samr");
366 if (!NT_STATUS_IS_OK(status)) {
367 d_printf("dcerpc_pipe_open_smb failed: %s\n",
368 nt_errstr(status));
369 goto fail;
372 if (admin_creds != NULL) {
373 status = dcerpc_bind_auth(samr_pipe, &dcerpc_table_samr,
374 admin_creds, auth_type, auth_level,
375 NULL);
376 if (!NT_STATUS_IS_OK(status)) {
377 d_printf("dcerpc_bind_auth failed: %s\n",
378 nt_errstr(status));
379 goto fail;
381 } else {
382 /* We must have an authenticated SMB connection */
383 status = dcerpc_bind_auth_none(samr_pipe, &dcerpc_table_samr);
384 if (!NT_STATUS_IS_OK(status)) {
385 d_printf("dcerpc_bind_auth_none failed: %s\n",
386 nt_errstr(status));
387 goto fail;
391 conn.in.system_name = talloc_asprintf(
392 mem_ctx, "\\\\%s", dcerpc_server_name(samr_pipe));
393 conn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
394 conn.out.connect_handle = &conn_handle;
396 status = dcerpc_samr_Connect2(samr_pipe, mem_ctx, &conn);
397 if (!NT_STATUS_IS_OK(status)) {
398 d_printf("samr_Connect2 failed: %s\n", nt_errstr(status));
399 goto fail;
402 enumdom.in.connect_handle = &conn_handle;
403 enumdom.in.resume_handle = &resume_handle;
404 enumdom.in.buf_size = (uint32_t)-1;
405 enumdom.out.resume_handle = &resume_handle;
407 status = dcerpc_samr_EnumDomains(samr_pipe, mem_ctx, &enumdom);
408 if (!NT_STATUS_IS_OK(status)) {
409 d_printf("samr_EnumDomains failed: %s\n", nt_errstr(status));
410 goto fail;
413 if (enumdom.out.num_entries != 2) {
414 d_printf("samr_EnumDomains returned %d entries, expected 2\n",
415 enumdom.out.num_entries);
416 status = NT_STATUS_UNSUCCESSFUL;
417 goto fail;
420 dom_idx = strequal(enumdom.out.sam->entries[0].name.string,
421 "builtin") ? 1:0;
423 l.in.connect_handle = &conn_handle;
424 domain_name.string = enumdom.out.sam->entries[0].name.string;
425 *domain = talloc_strdup(mem_ctx, domain_name.string);
426 l.in.domain_name = &domain_name;
428 status = dcerpc_samr_LookupDomain(samr_pipe, mem_ctx, &l);
429 if (!NT_STATUS_IS_OK(status)) {
430 d_printf("samr_LookupDomain failed: %s\n", nt_errstr(status));
431 goto fail;
434 o.in.connect_handle = &conn_handle;
435 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
436 o.in.sid = l.out.sid;
437 o.out.domain_handle = &domain_handle;
439 status = dcerpc_samr_OpenDomain(samr_pipe, mem_ctx, &o);
440 if (!NT_STATUS_IS_OK(status)) {
441 d_printf("samr_OpenDomain failed: %s\n", nt_errstr(status));
442 goto fail;
445 c.in.domain_handle = &domain_handle;
446 user_name.string = username;
447 c.in.account_name = &user_name;
448 c.in.acct_flags = ACB_NORMAL;
449 c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
450 user_handle = talloc(mem_ctx, struct policy_handle);
451 c.out.user_handle = user_handle;
452 c.out.access_granted = &access_granted;
453 c.out.rid = &user_rid;
455 status = dcerpc_samr_CreateUser2(samr_pipe, mem_ctx, &c);
457 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
458 struct samr_LookupNames ln;
459 struct samr_OpenUser ou;
461 ln.in.domain_handle = &domain_handle;
462 ln.in.num_names = 1;
463 ln.in.names = &user_name;
465 status = dcerpc_samr_LookupNames(samr_pipe, mem_ctx, &ln);
466 if (!NT_STATUS_IS_OK(status)) {
467 d_printf("samr_LookupNames failed: %s\n",
468 nt_errstr(status));
469 goto fail;
472 ou.in.domain_handle = &domain_handle;
473 ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
474 user_rid = ou.in.rid = ln.out.rids.ids[0];
475 ou.out.user_handle = user_handle;
477 status = dcerpc_samr_OpenUser(samr_pipe, mem_ctx, &ou);
478 if (!NT_STATUS_IS_OK(status)) {
479 d_printf("samr_OpenUser failed: %s\n",
480 nt_errstr(status));
481 goto fail;
485 if (!NT_STATUS_IS_OK(status)) {
486 d_printf("samr_CreateUser failed: %s\n", nt_errstr(status));
487 goto fail;
490 *result_pipe = samr_pipe;
491 *result_handle = user_handle;
492 if (sid != NULL) {
493 *sid = dom_sid_add_rid(mem_ctx, l.out.sid, user_rid);
495 return NT_STATUS_OK;
497 fail:
498 return status;
502 * Create a test user
505 static BOOL create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
506 struct cli_credentials *admin_creds,
507 const char *username, const char *password,
508 char **domain_name,
509 struct dom_sid **user_sid)
511 TALLOC_CTX *tmp_ctx;
512 NTSTATUS status;
513 struct dcerpc_pipe *samr_pipe;
514 struct policy_handle *wks_handle;
515 BOOL ret = False;
517 if (!(tmp_ctx = talloc_new(mem_ctx))) {
518 d_printf("talloc_init failed\n");
519 return False;
522 status = get_usr_handle(cli, tmp_ctx, admin_creds,
523 DCERPC_AUTH_TYPE_NTLMSSP,
524 DCERPC_AUTH_LEVEL_INTEGRITY,
525 username, domain_name, &samr_pipe, &wks_handle,
526 user_sid);
527 if (!NT_STATUS_IS_OK(status)) {
528 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
529 goto done;
533 struct samr_SetUserInfo2 sui2;
534 struct samr_SetUserInfo sui;
535 struct samr_QueryUserInfo qui;
536 union samr_UserInfo u_info;
537 DATA_BLOB session_key;
539 encode_pw_buffer(u_info.info24.password.data, password,
540 STR_UNICODE);
541 u_info.info24.pw_len = strlen_m(password)*2;
543 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
544 if (!NT_STATUS_IS_OK(status)) {
545 d_printf("dcerpc_fetch_session_key failed\n");
546 goto done;
548 arcfour_crypt_blob(u_info.info24.password.data, 516,
549 &session_key);
550 sui2.in.user_handle = wks_handle;
551 sui2.in.info = &u_info;
552 sui2.in.level = 24;
554 status = dcerpc_samr_SetUserInfo2(samr_pipe, tmp_ctx, &sui2);
555 if (!NT_STATUS_IS_OK(status)) {
556 d_printf("samr_SetUserInfo(24) failed: %s\n",
557 nt_errstr(status));
558 goto done;
561 u_info.info16.acct_flags = ACB_NORMAL;
562 sui.in.user_handle = wks_handle;
563 sui.in.info = &u_info;
564 sui.in.level = 16;
566 status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
567 if (!NT_STATUS_IS_OK(status)) {
568 d_printf("samr_SetUserInfo(16) failed\n");
569 goto done;
572 qui.in.user_handle = wks_handle;
573 qui.in.level = 21;
575 status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
576 if (!NT_STATUS_IS_OK(status)) {
577 d_printf("samr_QueryUserInfo(21) failed\n");
578 goto done;
581 qui.out.info->info21.allow_password_change = 0;
582 qui.out.info->info21.force_password_change = 0;
583 qui.out.info->info21.account_name.string = NULL;
584 qui.out.info->info21.rid = 0;
585 qui.out.info->info21.acct_expiry = 0;
586 qui.out.info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
588 u_info.info21 = qui.out.info->info21;
589 sui.in.user_handle = wks_handle;
590 sui.in.info = &u_info;
591 sui.in.level = 21;
593 status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
594 if (!NT_STATUS_IS_OK(status)) {
595 d_printf("samr_SetUserInfo(21) failed\n");
596 goto done;
600 *domain_name= talloc_steal(mem_ctx, *domain_name);
601 *user_sid = talloc_steal(mem_ctx, *user_sid);
602 ret = True;
603 done:
604 talloc_free(tmp_ctx);
605 return ret;
609 * Delete a test user
612 static BOOL delete_user(struct smbcli_state *cli,
613 struct cli_credentials *admin_creds,
614 const char *username)
616 TALLOC_CTX *mem_ctx;
617 NTSTATUS status;
618 char *dom_name;
619 struct dcerpc_pipe *samr_pipe;
620 struct policy_handle *user_handle;
621 BOOL ret = False;
623 if ((mem_ctx = talloc_init("leave")) == NULL) {
624 d_printf("talloc_init failed\n");
625 return False;
628 status = get_usr_handle(cli, mem_ctx, admin_creds,
629 DCERPC_AUTH_TYPE_NTLMSSP,
630 DCERPC_AUTH_LEVEL_INTEGRITY,
631 username, &dom_name, &samr_pipe,
632 &user_handle, NULL);
634 if (!NT_STATUS_IS_OK(status)) {
635 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
636 goto done;
640 struct samr_DeleteUser d;
642 d.in.user_handle = user_handle;
643 d.out.user_handle = user_handle;
645 status = dcerpc_samr_DeleteUser(samr_pipe, mem_ctx, &d);
646 if (!NT_STATUS_IS_OK(status)) {
647 d_printf("samr_DeleteUser failed\n");
648 goto done;
652 ret = True;
654 done:
655 talloc_free(mem_ctx);
656 return ret;
660 * Do a Samba3-style join
663 static BOOL join3(struct smbcli_state *cli,
664 BOOL use_level25,
665 struct cli_credentials *admin_creds,
666 struct cli_credentials *wks_creds)
668 TALLOC_CTX *mem_ctx;
669 NTSTATUS status;
670 char *dom_name;
671 struct dcerpc_pipe *samr_pipe;
672 struct policy_handle *wks_handle;
673 BOOL ret = False;
675 if ((mem_ctx = talloc_init("join3")) == NULL) {
676 d_printf("talloc_init failed\n");
677 return False;
680 status = get_usr_handle(
681 cli, mem_ctx, admin_creds,
682 DCERPC_AUTH_TYPE_NTLMSSP,
683 DCERPC_AUTH_LEVEL_PRIVACY,
684 talloc_asprintf(mem_ctx, "%s$",
685 cli_credentials_get_workstation(wks_creds)),
686 &dom_name, &samr_pipe, &wks_handle, NULL);
688 if (!NT_STATUS_IS_OK(status)) {
689 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
690 goto done;
693 cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);
695 if (use_level25) {
696 struct samr_SetUserInfo2 sui2;
697 union samr_UserInfo u_info;
698 struct samr_UserInfo21 *i21 = &u_info.info25.info;
699 DATA_BLOB session_key;
700 DATA_BLOB confounded_session_key = data_blob_talloc(
701 mem_ctx, NULL, 16);
702 struct MD5Context ctx;
703 uint8_t confounder[16];
705 ZERO_STRUCT(u_info);
707 i21->full_name.string = talloc_asprintf(
708 mem_ctx, "%s$",
709 cli_credentials_get_workstation(wks_creds));
710 i21->acct_flags = ACB_WSTRUST;
711 i21->fields_present = SAMR_FIELD_FULL_NAME |
712 SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_PASSWORD;
714 encode_pw_buffer(u_info.info25.password.data,
715 cli_credentials_get_password(wks_creds),
716 STR_UNICODE);
717 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
718 if (!NT_STATUS_IS_OK(status)) {
719 d_printf("dcerpc_fetch_session_key failed: %s\n",
720 nt_errstr(status));
721 goto done;
723 generate_random_buffer((uint8_t *)confounder, 16);
725 MD5Init(&ctx);
726 MD5Update(&ctx, confounder, 16);
727 MD5Update(&ctx, session_key.data, session_key.length);
728 MD5Final(confounded_session_key.data, &ctx);
730 arcfour_crypt_blob(u_info.info25.password.data, 516,
731 &confounded_session_key);
732 memcpy(&u_info.info25.password.data[516], confounder, 16);
734 sui2.in.user_handle = wks_handle;
735 sui2.in.level = 25;
736 sui2.in.info = &u_info;
738 status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2);
739 if (!NT_STATUS_IS_OK(status)) {
740 d_printf("samr_SetUserInfo2(25) failed: %s\n",
741 nt_errstr(status));
742 goto done;
744 } else {
745 struct samr_SetUserInfo2 sui2;
746 struct samr_SetUserInfo sui;
747 union samr_UserInfo u_info;
748 DATA_BLOB session_key;
750 encode_pw_buffer(u_info.info24.password.data,
751 cli_credentials_get_password(wks_creds),
752 STR_UNICODE);
753 u_info.info24.pw_len =
754 strlen_m(cli_credentials_get_password(wks_creds))*2;
756 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
757 if (!NT_STATUS_IS_OK(status)) {
758 d_printf("dcerpc_fetch_session_key failed\n");
759 goto done;
761 arcfour_crypt_blob(u_info.info24.password.data, 516,
762 &session_key);
763 sui2.in.user_handle = wks_handle;
764 sui2.in.info = &u_info;
765 sui2.in.level = 24;
767 status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2);
768 if (!NT_STATUS_IS_OK(status)) {
769 d_printf("samr_SetUserInfo(24) failed: %s\n",
770 nt_errstr(status));
771 goto done;
774 u_info.info16.acct_flags = ACB_WSTRUST;
775 sui.in.user_handle = wks_handle;
776 sui.in.info = &u_info;
777 sui.in.level = 16;
779 status = dcerpc_samr_SetUserInfo(samr_pipe, mem_ctx, &sui);
780 if (!NT_STATUS_IS_OK(status)) {
781 d_printf("samr_SetUserInfo(16) failed\n");
782 goto done;
786 ret = True;
788 done:
789 talloc_free(mem_ctx);
790 return ret;
794 * Do a ReqChallenge/Auth2 and get the wks creds
797 static BOOL auth2(struct smbcli_state *cli,
798 struct cli_credentials *wks_cred)
800 TALLOC_CTX *mem_ctx;
801 struct dcerpc_pipe *net_pipe;
802 BOOL result = False;
803 NTSTATUS status;
804 struct netr_ServerReqChallenge r;
805 struct netr_Credential netr_cli_creds;
806 struct netr_Credential netr_srv_creds;
807 uint32_t negotiate_flags;
808 struct netr_ServerAuthenticate2 a;
809 struct creds_CredentialState *creds_state;
810 struct netr_Credential netr_cred;
811 struct samr_Password mach_pw;
813 mem_ctx = talloc_new(NULL);
814 if (mem_ctx == NULL) {
815 d_printf("talloc_new failed\n");
816 return False;
819 net_pipe = dcerpc_pipe_init(mem_ctx,
820 cli->transport->socket->event.ctx);
821 if (net_pipe == NULL) {
822 d_printf("dcerpc_pipe_init failed\n");
823 goto done;
826 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
827 if (!NT_STATUS_IS_OK(status)) {
828 d_printf("dcerpc_pipe_open_smb failed: %s\n",
829 nt_errstr(status));
830 goto done;
833 status = dcerpc_bind_auth_none(net_pipe, &dcerpc_table_netlogon);
834 if (!NT_STATUS_IS_OK(status)) {
835 d_printf("dcerpc_bind_auth_none failed: %s\n",
836 nt_errstr(status));
837 goto done;
840 r.in.computer_name = cli_credentials_get_workstation(wks_cred);
841 r.in.server_name = talloc_asprintf(
842 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
843 if (r.in.server_name == NULL) {
844 d_printf("talloc_asprintf failed\n");
845 goto done;
847 generate_random_buffer(netr_cli_creds.data,
848 sizeof(netr_cli_creds.data));
849 r.in.credentials = &netr_cli_creds;
850 r.out.credentials = &netr_srv_creds;
852 status = dcerpc_netr_ServerReqChallenge(net_pipe, mem_ctx, &r);
853 if (!NT_STATUS_IS_OK(status)) {
854 d_printf("netr_ServerReqChallenge failed: %s\n",
855 nt_errstr(status));
856 goto done;
859 negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
860 E_md4hash(cli_credentials_get_password(wks_cred), mach_pw.hash);
862 creds_state = talloc(mem_ctx, struct creds_CredentialState);
863 creds_client_init(creds_state, r.in.credentials,
864 r.out.credentials, &mach_pw,
865 &netr_cred, negotiate_flags);
867 a.in.server_name = talloc_asprintf(
868 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
869 a.in.account_name = talloc_asprintf(
870 mem_ctx, "%s$", cli_credentials_get_workstation(wks_cred));
871 a.in.computer_name = cli_credentials_get_workstation(wks_cred);
872 a.in.secure_channel_type = SEC_CHAN_WKSTA;
873 a.in.negotiate_flags = &negotiate_flags;
874 a.out.negotiate_flags = &negotiate_flags;
875 a.in.credentials = &netr_cred;
876 a.out.credentials = &netr_cred;
878 status = dcerpc_netr_ServerAuthenticate2(net_pipe, mem_ctx, &a);
879 if (!NT_STATUS_IS_OK(status)) {
880 d_printf("netr_ServerServerAuthenticate2 failed: %s\n",
881 nt_errstr(status));
882 goto done;
885 if (!creds_client_check(creds_state, a.out.credentials)) {
886 d_printf("creds_client_check failed\n");
887 goto done;
890 cli_credentials_set_netlogon_creds(wks_cred, creds_state);
892 result = True;
894 done:
895 talloc_free(mem_ctx);
896 return result;
900 * Do a couple of schannel protected Netlogon ops: Interactive and Network
901 * login, and change the wks password
904 static BOOL schan(struct smbcli_state *cli,
905 struct cli_credentials *wks_creds,
906 struct cli_credentials *user_creds)
908 TALLOC_CTX *mem_ctx;
909 NTSTATUS status;
910 BOOL ret = False;
911 struct dcerpc_pipe *net_pipe;
912 int i;
914 mem_ctx = talloc_new(NULL);
915 if (mem_ctx == NULL) {
916 d_printf("talloc_new failed\n");
917 return False;
920 net_pipe = dcerpc_pipe_init(mem_ctx,
921 cli->transport->socket->event.ctx);
922 if (net_pipe == NULL) {
923 d_printf("dcerpc_pipe_init failed\n");
924 goto done;
927 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
928 if (!NT_STATUS_IS_OK(status)) {
929 d_printf("dcerpc_pipe_open_smb failed: %s\n",
930 nt_errstr(status));
931 goto done;
934 #if 0
935 net_pipe->conn->flags |= DCERPC_DEBUG_PRINT_IN |
936 DCERPC_DEBUG_PRINT_OUT;
937 #endif
938 #if 1
939 net_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL);
940 status = dcerpc_bind_auth(net_pipe, &dcerpc_table_netlogon,
941 wks_creds, DCERPC_AUTH_TYPE_SCHANNEL,
942 DCERPC_AUTH_LEVEL_PRIVACY,
943 NULL);
944 #else
945 status = dcerpc_bind_auth_none(net_pipe, &dcerpc_table_netlogon);
946 #endif
947 if (!NT_STATUS_IS_OK(status)) {
948 d_printf("schannel bind failed: %s\n", nt_errstr(status));
949 goto done;
953 for (i=2; i<4; i++) {
954 int flags;
955 DATA_BLOB chal, nt_resp, lm_resp, names_blob, session_key;
956 struct creds_CredentialState *creds_state;
957 struct netr_Authenticator netr_auth, netr_auth2;
958 struct netr_NetworkInfo ninfo;
959 struct netr_PasswordInfo pinfo;
960 struct netr_LogonSamLogon r;
962 flags = CLI_CRED_LANMAN_AUTH | CLI_CRED_NTLM_AUTH |
963 CLI_CRED_NTLMv2_AUTH;
965 chal = data_blob_talloc(mem_ctx, NULL, 8);
966 if (chal.data == NULL) {
967 d_printf("data_blob_talloc failed\n");
968 goto done;
971 generate_random_buffer(chal.data, chal.length);
972 names_blob = NTLMv2_generate_names_blob(
973 mem_ctx, cli_credentials_get_workstation(user_creds),
974 cli_credentials_get_domain(user_creds));
975 status = cli_credentials_get_ntlm_response(
976 user_creds, mem_ctx, &flags, chal, names_blob,
977 &lm_resp, &nt_resp, NULL, NULL);
978 if (!NT_STATUS_IS_OK(status)) {
979 d_printf("cli_credentials_get_ntlm_response failed:"
980 " %s\n", nt_errstr(status));
981 goto done;
984 creds_state = cli_credentials_get_netlogon_creds(wks_creds);
985 creds_client_authenticator(creds_state, &netr_auth);
987 ninfo.identity_info.account_name.string =
988 cli_credentials_get_username(user_creds);
989 ninfo.identity_info.domain_name.string =
990 cli_credentials_get_domain(user_creds);
991 ninfo.identity_info.parameter_control = 0;
992 ninfo.identity_info.logon_id_low = 0;
993 ninfo.identity_info.logon_id_high = 0;
994 ninfo.identity_info.workstation.string =
995 cli_credentials_get_workstation(user_creds);
996 memcpy(ninfo.challenge, chal.data, sizeof(ninfo.challenge));
997 ninfo.nt.length = nt_resp.length;
998 ninfo.nt.data = nt_resp.data;
999 ninfo.lm.length = lm_resp.length;
1000 ninfo.lm.data = lm_resp.data;
1002 r.in.server_name = talloc_asprintf(
1003 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1004 ZERO_STRUCT(netr_auth2);
1005 r.in.computer_name =
1006 cli_credentials_get_workstation(wks_creds);
1007 r.in.credential = &netr_auth;
1008 r.in.return_authenticator = &netr_auth2;
1009 r.in.logon_level = 2;
1010 r.in.validation_level = i;
1011 r.in.logon.network = &ninfo;
1012 r.out.return_authenticator = NULL;
1014 status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r);
1015 if (!NT_STATUS_IS_OK(status)) {
1016 d_printf("netr_LogonSamLogon failed: %s\n",
1017 nt_errstr(status));
1018 goto done;
1021 if ((r.out.return_authenticator == NULL) ||
1022 (!creds_client_check(creds_state,
1023 &r.out.return_authenticator->cred))) {
1024 d_printf("Credentials check failed!\n");
1025 goto done;
1028 creds_client_authenticator(creds_state, &netr_auth);
1030 pinfo.identity_info = ninfo.identity_info;
1031 ZERO_STRUCT(pinfo.lmpassword.hash);
1032 E_md4hash(cli_credentials_get_password(user_creds),
1033 pinfo.ntpassword.hash);
1034 session_key = data_blob_talloc(mem_ctx,
1035 creds_state->session_key, 16);
1036 arcfour_crypt_blob(pinfo.ntpassword.hash,
1037 sizeof(pinfo.ntpassword.hash),
1038 &session_key);
1040 r.in.logon_level = 1;
1041 r.in.logon.password = &pinfo;
1042 r.out.return_authenticator = NULL;
1044 status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r);
1045 if (!NT_STATUS_IS_OK(status)) {
1046 d_printf("netr_LogonSamLogon failed: %s\n",
1047 nt_errstr(status));
1048 goto done;
1051 if ((r.out.return_authenticator == NULL) ||
1052 (!creds_client_check(creds_state,
1053 &r.out.return_authenticator->cred))) {
1054 d_printf("Credentials check failed!\n");
1055 goto done;
1060 struct netr_ServerPasswordSet s;
1061 char *password = generate_random_str(wks_creds, 8);
1062 struct creds_CredentialState *creds_state;
1064 s.in.server_name = talloc_asprintf(
1065 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1066 s.in.computer_name = cli_credentials_get_workstation(wks_creds);
1067 s.in.account_name = talloc_asprintf(
1068 mem_ctx, "%s$", s.in.computer_name);
1069 s.in.secure_channel_type = SEC_CHAN_WKSTA;
1070 E_md4hash(password, s.in.new_password.hash);
1072 creds_state = cli_credentials_get_netlogon_creds(wks_creds);
1073 creds_des_encrypt(creds_state, &s.in.new_password);
1074 creds_client_authenticator(creds_state, &s.in.credential);
1076 status = dcerpc_netr_ServerPasswordSet(net_pipe, mem_ctx, &s);
1077 if (!NT_STATUS_IS_OK(status)) {
1078 printf("ServerPasswordSet - %s\n", nt_errstr(status));
1079 goto done;
1082 if (!creds_client_check(creds_state,
1083 &s.out.return_authenticator.cred)) {
1084 printf("Credential chaining failed\n");
1087 cli_credentials_set_password(wks_creds, password,
1088 CRED_SPECIFIED);
1091 ret = True;
1092 done:
1093 talloc_free(mem_ctx);
1094 return ret;
1098 * Delete the wks account again
1101 static BOOL leave(struct smbcli_state *cli,
1102 struct cli_credentials *admin_creds,
1103 struct cli_credentials *wks_creds)
1105 char *wks_name = talloc_asprintf(
1106 NULL, "%s$", cli_credentials_get_workstation(wks_creds));
1107 BOOL ret;
1109 ret = delete_user(cli, admin_creds, wks_name);
1110 talloc_free(wks_name);
1111 return ret;
1115 * Test the Samba3 DC code a bit. Join, do some schan netlogon ops, leave
1118 BOOL torture_netlogon_samba3(struct torture_context *torture)
1120 TALLOC_CTX *mem_ctx;
1121 NTSTATUS status;
1122 BOOL ret = False;
1123 struct smbcli_state *cli;
1124 struct cli_credentials *anon_creds;
1125 struct cli_credentials *wks_creds;
1126 const char *wks_name;
1127 int i;
1129 wks_name = torture_setting_string(torture, "wksname", NULL);
1130 if (wks_name == NULL) {
1131 wks_name = get_myname();
1134 mem_ctx = talloc_init("torture_netlogon_samba3");
1136 if (mem_ctx == NULL) {
1137 d_printf("talloc_init failed\n");
1138 return False;
1141 if (!(anon_creds = create_anon_creds(mem_ctx))) {
1142 d_printf("create_anon_creds failed\n");
1143 goto done;
1146 status = smbcli_full_connection(mem_ctx, &cli,
1147 torture_setting_string(torture, "host", NULL),
1148 "IPC$", NULL, anon_creds, NULL);
1149 if (!NT_STATUS_IS_OK(status)) {
1150 d_printf("smbcli_full_connection failed: %s\n",
1151 nt_errstr(status));
1152 goto done;
1155 wks_creds = cli_credentials_init(mem_ctx);
1156 if (wks_creds == NULL) {
1157 d_printf("cli_credentials_init failed\n");
1158 goto done;
1161 cli_credentials_set_conf(wks_creds);
1162 cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1163 cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1164 cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1165 cli_credentials_set_password(wks_creds,
1166 generate_random_str(wks_creds, 8),
1167 CRED_SPECIFIED);
1169 if (!join3(cli, False, cmdline_credentials, wks_creds)) {
1170 d_printf("join failed\n");
1171 goto done;
1174 cli_credentials_set_domain(
1175 cmdline_credentials, cli_credentials_get_domain(wks_creds),
1176 CRED_SPECIFIED);
1178 for (i=0; i<2; i++) {
1180 /* Do this more than once, the routine "schan" changes
1181 * the workstation password using the netlogon
1182 * password change routine */
1184 int j;
1186 if (!auth2(cli, wks_creds)) {
1187 d_printf("auth2 failed\n");
1188 goto done;
1191 for (j=0; j<2; j++) {
1192 if (!schan(cli, wks_creds, cmdline_credentials)) {
1193 d_printf("schan failed\n");
1194 goto done;
1199 if (!leave(cli, cmdline_credentials, wks_creds)) {
1200 d_printf("leave failed\n");
1201 goto done;
1204 ret = True;
1206 done:
1207 talloc_free(mem_ctx);
1208 return ret;
1212 * Do a simple join, testjoin and leave using specified smb and samr
1213 * credentials
1216 static BOOL test_join3(TALLOC_CTX *mem_ctx,
1217 BOOL use_level25,
1218 struct cli_credentials *smb_creds,
1219 struct cli_credentials *samr_creds,
1220 const char *wks_name)
1222 NTSTATUS status;
1223 BOOL ret = False;
1224 struct smbcli_state *cli;
1225 struct cli_credentials *wks_creds;
1227 status = smbcli_full_connection(mem_ctx, &cli,
1228 lp_parm_string(-1, "torture", "host"),
1229 "IPC$", NULL, smb_creds, NULL);
1230 if (!NT_STATUS_IS_OK(status)) {
1231 d_printf("smbcli_full_connection failed: %s\n",
1232 nt_errstr(status));
1233 goto done;
1236 wks_creds = cli_credentials_init(cli);
1237 if (wks_creds == NULL) {
1238 d_printf("cli_credentials_init failed\n");
1239 goto done;
1242 cli_credentials_set_conf(wks_creds);
1243 cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1244 cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1245 cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1246 cli_credentials_set_password(wks_creds,
1247 generate_random_str(wks_creds, 8),
1248 CRED_SPECIFIED);
1250 if (!join3(cli, use_level25, samr_creds, wks_creds)) {
1251 d_printf("join failed\n");
1252 goto done;
1255 cli_credentials_set_domain(
1256 cmdline_credentials, cli_credentials_get_domain(wks_creds),
1257 CRED_SPECIFIED);
1259 if (!auth2(cli, wks_creds)) {
1260 d_printf("auth2 failed\n");
1261 goto done;
1264 if (!leave(cli, samr_creds, wks_creds)) {
1265 d_printf("leave failed\n");
1266 goto done;
1269 talloc_free(cli);
1271 ret = True;
1273 done:
1274 return ret;
1278 * Test the different session key variants. Do it by joining, this uses the
1279 * session key in the setpassword routine. Test the join by doing the auth2.
1282 BOOL torture_samba3_sessionkey(struct torture_context *torture)
1284 TALLOC_CTX *mem_ctx;
1285 BOOL ret = False;
1286 struct cli_credentials *anon_creds;
1287 const char *wks_name;
1289 wks_name = torture_setting_string(torture, "wksname", get_myname());
1291 mem_ctx = talloc_init("torture_samba3_sessionkey");
1293 if (mem_ctx == NULL) {
1294 d_printf("talloc_init failed\n");
1295 return False;
1298 if (!(anon_creds = create_anon_creds(mem_ctx))) {
1299 d_printf("create_anon_creds failed\n");
1300 goto done;
1303 ret = True;
1305 if (!torture_setting_bool(torture, "samba3", False)) {
1307 /* Samba3 in the build farm right now does this happily. Need
1308 * to fix :-) */
1310 if (test_join3(mem_ctx, False, anon_creds, NULL, wks_name)) {
1311 d_printf("join using anonymous bind on an anonymous smb "
1312 "connection succeeded -- HUH??\n");
1313 ret = False;
1317 if (!test_join3(mem_ctx, False, anon_creds, cmdline_credentials,
1318 wks_name)) {
1319 d_printf("join using ntlmssp bind on an anonymous smb "
1320 "connection failed\n");
1321 ret = False;
1324 if (!test_join3(mem_ctx, False, cmdline_credentials, NULL, wks_name)) {
1325 d_printf("join using anonymous bind on an authenticated smb "
1326 "connection failed\n");
1327 ret = False;
1330 if (!test_join3(mem_ctx, False, cmdline_credentials,
1331 cmdline_credentials,
1332 wks_name)) {
1333 d_printf("join using ntlmssp bind on an authenticated smb "
1334 "connection failed\n");
1335 ret = False;
1339 * The following two are tests for setuserinfolevel 25
1342 if (!test_join3(mem_ctx, True, anon_creds, cmdline_credentials,
1343 wks_name)) {
1344 d_printf("join using ntlmssp bind on an anonymous smb "
1345 "connection failed\n");
1346 ret = False;
1349 if (!test_join3(mem_ctx, True, cmdline_credentials, NULL, wks_name)) {
1350 d_printf("join using anonymous bind on an authenticated smb "
1351 "connection failed\n");
1352 ret = False;
1355 done:
1357 return ret;
1361 * open pipe and bind, given an IPC$ context
1364 static NTSTATUS pipe_bind_smb(TALLOC_CTX *mem_ctx,
1365 struct smbcli_tree *tree,
1366 const char *pipe_name,
1367 const struct dcerpc_interface_table *iface,
1368 struct dcerpc_pipe **p)
1370 struct dcerpc_pipe *result;
1371 NTSTATUS status;
1373 if (!(result = dcerpc_pipe_init(
1374 mem_ctx, tree->session->transport->socket->event.ctx))) {
1375 return NT_STATUS_NO_MEMORY;
1378 status = dcerpc_pipe_open_smb(result, tree, pipe_name);
1379 if (!NT_STATUS_IS_OK(status)) {
1380 d_printf("dcerpc_pipe_open_smb failed: %s\n",
1381 nt_errstr(status));
1382 talloc_free(result);
1383 return status;
1386 status = dcerpc_bind_auth_none(result, iface);
1387 if (!NT_STATUS_IS_OK(status)) {
1388 d_printf("schannel bind failed: %s\n", nt_errstr(status));
1389 talloc_free(result);
1390 return status;
1393 *p = result;
1394 return NT_STATUS_OK;
1398 * Sane wrapper around lsa_LookupNames
1401 static struct dom_sid *name2sid(TALLOC_CTX *mem_ctx,
1402 struct dcerpc_pipe *p,
1403 const char *name,
1404 const char *domain)
1406 struct lsa_ObjectAttribute attr;
1407 struct lsa_QosInfo qos;
1408 struct lsa_OpenPolicy2 r;
1409 struct lsa_Close c;
1410 NTSTATUS status;
1411 struct policy_handle handle;
1412 struct lsa_LookupNames l;
1413 struct lsa_TransSidArray sids;
1414 struct lsa_String lsa_name;
1415 uint32_t count = 0;
1416 struct dom_sid *result;
1417 TALLOC_CTX *tmp_ctx;
1419 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1420 return NULL;
1423 qos.len = 0;
1424 qos.impersonation_level = 2;
1425 qos.context_mode = 1;
1426 qos.effective_only = 0;
1428 attr.len = 0;
1429 attr.root_dir = NULL;
1430 attr.object_name = NULL;
1431 attr.attributes = 0;
1432 attr.sec_desc = NULL;
1433 attr.sec_qos = &qos;
1435 r.in.system_name = "\\";
1436 r.in.attr = &attr;
1437 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1438 r.out.handle = &handle;
1440 status = dcerpc_lsa_OpenPolicy2(p, tmp_ctx, &r);
1441 if (!NT_STATUS_IS_OK(status)) {
1442 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
1443 talloc_free(tmp_ctx);
1444 return NULL;
1447 sids.count = 0;
1448 sids.sids = NULL;
1450 lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, name);
1452 l.in.handle = &handle;
1453 l.in.num_names = 1;
1454 l.in.names = &lsa_name;
1455 l.in.sids = &sids;
1456 l.in.level = 1;
1457 l.in.count = &count;
1458 l.out.count = &count;
1459 l.out.sids = &sids;
1461 status = dcerpc_lsa_LookupNames(p, tmp_ctx, &l);
1462 if (!NT_STATUS_IS_OK(status)) {
1463 printf("LookupNames of %s failed - %s\n", lsa_name.string,
1464 nt_errstr(status));
1465 talloc_free(tmp_ctx);
1466 return NULL;
1469 result = dom_sid_add_rid(mem_ctx, l.out.domains->domains[0].sid,
1470 l.out.sids->sids[0].rid);
1472 c.in.handle = &handle;
1473 c.out.handle = &handle;
1475 status = dcerpc_lsa_Close(p, tmp_ctx, &c);
1476 if (!NT_STATUS_IS_OK(status)) {
1477 printf("dcerpc_lsa_Close failed - %s\n", nt_errstr(status));
1478 talloc_free(tmp_ctx);
1479 return NULL;
1482 talloc_free(tmp_ctx);
1483 return result;
1487 * Find out the user SID on this connection
1490 static struct dom_sid *whoami(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree)
1492 struct dcerpc_pipe *lsa;
1493 struct lsa_GetUserName r;
1494 NTSTATUS status;
1495 struct lsa_StringPointer authority_name_p;
1496 struct dom_sid *result;
1498 status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\lsarpc",
1499 &dcerpc_table_lsarpc, &lsa);
1500 if (!NT_STATUS_IS_OK(status)) {
1501 d_printf("(%s) Could not bind to LSA: %s\n",
1502 __location__, nt_errstr(status));
1503 return NULL;
1506 r.in.system_name = "\\";
1507 r.in.account_name = NULL;
1508 authority_name_p.string = NULL;
1509 r.in.authority_name = &authority_name_p;
1511 status = dcerpc_lsa_GetUserName(lsa, mem_ctx, &r);
1513 if (!NT_STATUS_IS_OK(status)) {
1514 printf("(%s) GetUserName failed - %s\n",
1515 __location__, nt_errstr(status));
1516 talloc_free(lsa);
1517 return NULL;
1520 result = name2sid(mem_ctx, lsa, r.out.account_name->string,
1521 r.out.authority_name->string->string);
1523 talloc_free(lsa);
1524 return result;
1528 * Do a tcon, given a session
1531 NTSTATUS secondary_tcon(TALLOC_CTX *mem_ctx,
1532 struct smbcli_session *session,
1533 const char *sharename,
1534 struct smbcli_tree **res)
1536 struct smbcli_tree *result;
1537 TALLOC_CTX *tmp_ctx;
1538 union smb_tcon tcon;
1539 NTSTATUS status;
1541 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1542 return NT_STATUS_NO_MEMORY;
1545 if (!(result = smbcli_tree_init(session, mem_ctx, False))) {
1546 talloc_free(tmp_ctx);
1547 return NT_STATUS_NO_MEMORY;
1550 tcon.generic.level = RAW_TCON_TCONX;
1551 tcon.tconx.in.flags = 0;
1552 tcon.tconx.in.password = data_blob(NULL, 0);
1553 tcon.tconx.in.path = sharename;
1554 tcon.tconx.in.device = "?????";
1556 status = smb_raw_tcon(result, tmp_ctx, &tcon);
1557 if (!NT_STATUS_IS_OK(status)) {
1558 d_printf("(%s) smb_raw_tcon failed: %s\n", __location__,
1559 nt_errstr(status));
1560 talloc_free(tmp_ctx);
1561 return status;
1564 result->tid = tcon.tconx.out.tid;
1565 result = talloc_steal(mem_ctx, result);
1566 talloc_free(tmp_ctx);
1567 *res = result;
1568 return NT_STATUS_OK;
1572 * Test the getusername behaviour
1575 BOOL torture_samba3_rpc_getusername(struct torture_context *torture)
1577 NTSTATUS status;
1578 struct smbcli_state *cli;
1579 TALLOC_CTX *mem_ctx;
1580 BOOL ret = True;
1581 struct dom_sid *user_sid;
1582 struct dom_sid *created_sid;
1583 struct cli_credentials *anon_creds;
1584 struct cli_credentials *user_creds;
1585 char *domain_name;
1587 if (!(mem_ctx = talloc_new(torture))) {
1588 return False;
1591 status = smbcli_full_connection(
1592 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1593 "IPC$", NULL, cmdline_credentials, NULL);
1594 if (!NT_STATUS_IS_OK(status)) {
1595 d_printf("(%s) smbcli_full_connection failed: %s\n",
1596 __location__, nt_errstr(status));
1597 ret = False;
1598 goto done;
1601 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
1602 d_printf("(%s) whoami on auth'ed connection failed\n",
1603 __location__);
1604 ret = False;
1607 talloc_free(cli);
1609 if (!(anon_creds = create_anon_creds(mem_ctx))) {
1610 d_printf("(%s) create_anon_creds failed\n", __location__);
1611 ret = False;
1612 goto done;
1615 status = smbcli_full_connection(
1616 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1617 "IPC$", NULL, anon_creds, NULL);
1618 if (!NT_STATUS_IS_OK(status)) {
1619 d_printf("(%s) anon smbcli_full_connection failed: %s\n",
1620 __location__, nt_errstr(status));
1621 ret = False;
1622 goto done;
1625 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
1626 d_printf("(%s) whoami on anon connection failed\n",
1627 __location__);
1628 ret = False;
1629 goto done;
1632 if (!dom_sid_equal(user_sid,
1633 dom_sid_parse_talloc(mem_ctx, "s-1-5-7"))) {
1634 d_printf("(%s) Anon lsa_GetUserName returned %s, expected "
1635 "S-1-5-7", __location__,
1636 dom_sid_string(mem_ctx, user_sid));
1637 ret = False;
1640 if (!(user_creds = cli_credentials_init(mem_ctx))) {
1641 d_printf("(%s) cli_credentials_init failed\n", __location__);
1642 ret = False;
1643 goto done;
1646 cli_credentials_set_conf(user_creds);
1647 cli_credentials_set_username(user_creds, "torture_username",
1648 CRED_SPECIFIED);
1649 cli_credentials_set_password(user_creds,
1650 generate_random_str(user_creds, 8),
1651 CRED_SPECIFIED);
1653 if (!create_user(mem_ctx, cli, cmdline_credentials,
1654 cli_credentials_get_username(user_creds),
1655 cli_credentials_get_password(user_creds),
1656 &domain_name, &created_sid)) {
1657 d_printf("(%s) create_user failed\n", __location__);
1658 ret = False;
1659 goto done;
1662 cli_credentials_set_domain(user_creds, domain_name,
1663 CRED_SPECIFIED);
1666 struct smbcli_session *session2;
1667 struct smb_composite_sesssetup setup;
1668 struct smbcli_tree *tree;
1670 session2 = smbcli_session_init(cli->transport, mem_ctx, False);
1671 if (session2 == NULL) {
1672 d_printf("(%s) smbcli_session_init failed\n",
1673 __location__);
1674 goto done;
1677 setup.in.sesskey = cli->transport->negotiate.sesskey;
1678 setup.in.capabilities = cli->transport->negotiate.capabilities;
1679 setup.in.workgroup = "";
1680 setup.in.credentials = user_creds;
1682 status = smb_composite_sesssetup(session2, &setup);
1683 if (!NT_STATUS_IS_OK(status)) {
1684 d_printf("(%s) session setup with new user failed: "
1685 "%s\n", __location__, nt_errstr(status));
1686 ret = False;
1687 goto done;
1689 session2->vuid = setup.out.vuid;
1691 if (!NT_STATUS_IS_OK(secondary_tcon(mem_ctx, session2,
1692 "IPC$", &tree))) {
1693 d_printf("(%s) secondary_tcon failed\n",
1694 __location__);
1695 ret = False;
1696 goto done;
1699 if (!(user_sid = whoami(mem_ctx, tree))) {
1700 d_printf("(%s) whoami on user connection failed\n",
1701 __location__);
1702 ret = False;
1703 goto delete;
1706 talloc_free(tree);
1709 d_printf("Created %s, found %s\n",
1710 dom_sid_string(mem_ctx, created_sid),
1711 dom_sid_string(mem_ctx, user_sid));
1713 if (!dom_sid_equal(created_sid, user_sid)) {
1714 ret = False;
1717 delete:
1718 if (!delete_user(cli, cmdline_credentials,
1719 cli_credentials_get_username(user_creds))) {
1720 d_printf("(%s) delete_user failed\n", __location__);
1721 ret = False;
1724 done:
1725 talloc_free(mem_ctx);
1726 return ret;
1729 static BOOL test_NetShareGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1730 const char *sharename)
1732 NTSTATUS status;
1733 struct srvsvc_NetShareGetInfo r;
1734 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007, 1501 };
1735 int i;
1736 BOOL ret = True;
1738 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s",
1739 dcerpc_server_name(p));
1740 r.in.share_name = sharename;
1742 for (i=0;i<ARRAY_SIZE(levels);i++) {
1743 r.in.level = levels[i];
1745 ZERO_STRUCT(r.out);
1747 printf("testing NetShareGetInfo level %u on share '%s'\n",
1748 r.in.level, r.in.share_name);
1750 status = dcerpc_srvsvc_NetShareGetInfo(p, mem_ctx, &r);
1751 if (!NT_STATUS_IS_OK(status)) {
1752 printf("NetShareGetInfo level %u on share '%s' failed"
1753 " - %s\n", r.in.level, r.in.share_name,
1754 nt_errstr(status));
1755 ret = False;
1756 continue;
1758 if (!W_ERROR_IS_OK(r.out.result)) {
1759 printf("NetShareGetInfo level %u on share '%s' failed "
1760 "- %s\n", r.in.level, r.in.share_name,
1761 win_errstr(r.out.result));
1762 ret = False;
1763 continue;
1767 return ret;
1770 static BOOL test_NetShareEnum(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1771 const char **one_sharename)
1773 NTSTATUS status;
1774 struct srvsvc_NetShareEnum r;
1775 struct srvsvc_NetShareCtr0 c0;
1776 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007 };
1777 int i;
1778 BOOL ret = True;
1780 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
1781 r.in.ctr.ctr0 = &c0;
1782 r.in.ctr.ctr0->count = 0;
1783 r.in.ctr.ctr0->array = NULL;
1784 r.in.max_buffer = (uint32_t)-1;
1785 r.in.resume_handle = NULL;
1787 for (i=0;i<ARRAY_SIZE(levels);i++) {
1788 r.in.level = levels[i];
1790 ZERO_STRUCT(r.out);
1792 printf("testing NetShareEnum level %u\n", r.in.level);
1793 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r);
1794 if (!NT_STATUS_IS_OK(status)) {
1795 printf("NetShareEnum level %u failed - %s\n",
1796 r.in.level, nt_errstr(status));
1797 ret = False;
1798 continue;
1800 if (!W_ERROR_IS_OK(r.out.result)) {
1801 printf("NetShareEnum level %u failed - %s\n",
1802 r.in.level, win_errstr(r.out.result));
1803 continue;
1805 if (r.in.level == 0) {
1806 struct srvsvc_NetShareCtr0 *ctr = r.out.ctr.ctr0;
1807 if (ctr->count > 0) {
1808 *one_sharename = ctr->array[0].name;
1813 return ret;
1816 BOOL torture_samba3_rpc_srvsvc(struct torture_context *torture)
1818 struct dcerpc_pipe *p;
1819 TALLOC_CTX *mem_ctx;
1820 BOOL ret = True;
1821 const char *sharename = NULL;
1822 struct smbcli_state *cli;
1823 NTSTATUS status;
1825 if (!(mem_ctx = talloc_new(torture))) {
1826 return False;
1829 if (!(torture_open_connection_share(
1830 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1831 "IPC$", NULL))) {
1832 talloc_free(mem_ctx);
1833 return False;
1836 status = pipe_bind_smb(mem_ctx, cli->tree, "\\pipe\\srvsvc",
1837 &dcerpc_table_srvsvc, &p);
1838 if (!NT_STATUS_IS_OK(status)) {
1839 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1840 __location__, nt_errstr(status));
1841 ret = False;
1842 goto done;
1845 ret &= test_NetShareEnum(p, mem_ctx, &sharename);
1846 if (sharename == NULL) {
1847 printf("did not get sharename\n");
1848 } else {
1849 ret &= test_NetShareGetInfo(p, mem_ctx, sharename);
1852 done:
1853 talloc_free(mem_ctx);
1854 return ret;
1857 static struct security_descriptor *get_sharesec(TALLOC_CTX *mem_ctx,
1858 struct smbcli_session *sess,
1859 const char *sharename)
1861 struct smbcli_tree *tree;
1862 TALLOC_CTX *tmp_ctx;
1863 struct dcerpc_pipe *p;
1864 NTSTATUS status;
1865 struct srvsvc_NetShareGetInfo r;
1866 struct security_descriptor *result;
1868 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1869 d_printf("talloc_new failed\n");
1870 return NULL;
1873 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) {
1874 d_printf("secondary_tcon failed\n");
1875 talloc_free(tmp_ctx);
1876 return NULL;
1879 status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\srvsvc",
1880 &dcerpc_table_srvsvc, &p);
1881 if (!NT_STATUS_IS_OK(status)) {
1882 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1883 __location__, nt_errstr(status));
1884 talloc_free(tmp_ctx);
1885 return NULL;
1888 #if 0
1889 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
1890 #endif
1892 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
1893 dcerpc_server_name(p));
1894 r.in.share_name = sharename;
1895 r.in.level = 502;
1897 status = dcerpc_srvsvc_NetShareGetInfo(p, tmp_ctx, &r);
1898 if (!NT_STATUS_IS_OK(status)) {
1899 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
1900 nt_errstr(status));
1901 talloc_free(tmp_ctx);
1902 return NULL;
1905 result = talloc_steal(mem_ctx, r.out.info.info502->sd);
1906 talloc_free(tmp_ctx);
1907 return result;
1910 static NTSTATUS set_sharesec(TALLOC_CTX *mem_ctx,
1911 struct smbcli_session *sess,
1912 const char *sharename,
1913 struct security_descriptor *sd)
1915 struct smbcli_tree *tree;
1916 TALLOC_CTX *tmp_ctx;
1917 struct dcerpc_pipe *p;
1918 NTSTATUS status;
1919 struct sec_desc_buf i;
1920 struct srvsvc_NetShareSetInfo r;
1921 uint32_t error = 0;
1923 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1924 d_printf("talloc_new failed\n");
1925 return NT_STATUS_NO_MEMORY;
1928 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) {
1929 d_printf("secondary_tcon failed\n");
1930 talloc_free(tmp_ctx);
1931 return NT_STATUS_UNSUCCESSFUL;
1934 status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\srvsvc",
1935 &dcerpc_table_srvsvc, &p);
1936 if (!NT_STATUS_IS_OK(status)) {
1937 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1938 __location__, nt_errstr(status));
1939 talloc_free(tmp_ctx);
1940 return NT_STATUS_UNSUCCESSFUL;
1943 #if 0
1944 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
1945 #endif
1947 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
1948 dcerpc_server_name(p));
1949 r.in.share_name = sharename;
1950 r.in.level = 1501;
1951 i.sd = sd;
1952 r.in.info.info1501 = &i;
1953 r.in.parm_error = &error;
1955 status = dcerpc_srvsvc_NetShareSetInfo(p, tmp_ctx, &r);
1956 if (!NT_STATUS_IS_OK(status)) {
1957 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
1958 nt_errstr(status));
1961 talloc_free(tmp_ctx);
1962 return status;
1965 BOOL try_tcon(TALLOC_CTX *mem_ctx,
1966 struct security_descriptor *orig_sd,
1967 struct smbcli_session *session,
1968 const char *sharename, const struct dom_sid *user_sid,
1969 unsigned int access_mask, NTSTATUS expected_tcon,
1970 NTSTATUS expected_mkdir)
1972 TALLOC_CTX *tmp_ctx;
1973 struct smbcli_tree *rmdir_tree, *tree;
1974 struct dom_sid *domain_sid;
1975 uint32_t rid;
1976 struct security_descriptor *sd;
1977 NTSTATUS status;
1978 BOOL ret = True;
1980 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1981 d_printf("talloc_new failed\n");
1982 return False;
1985 status = secondary_tcon(tmp_ctx, session, sharename, &rmdir_tree);
1986 if (!NT_STATUS_IS_OK(status)) {
1987 d_printf("first tcon to delete dir failed\n");
1988 talloc_free(tmp_ctx);
1989 return False;
1992 smbcli_rmdir(rmdir_tree, "sharesec_testdir");
1994 if (!NT_STATUS_IS_OK(dom_sid_split_rid(tmp_ctx, user_sid,
1995 &domain_sid, &rid))) {
1996 d_printf("dom_sid_split_rid failed\n");
1997 talloc_free(tmp_ctx);
1998 return False;
2001 sd = security_descriptor_create(
2002 tmp_ctx, "S-1-5-32-544",
2003 dom_sid_string(mem_ctx, dom_sid_add_rid(mem_ctx, domain_sid,
2004 DOMAIN_RID_USERS)),
2005 dom_sid_string(mem_ctx, user_sid),
2006 SEC_ACE_TYPE_ACCESS_ALLOWED, access_mask, 0, NULL);
2007 if (sd == NULL) {
2008 d_printf("security_descriptor_create failed\n");
2009 talloc_free(tmp_ctx);
2010 return False;
2013 status = set_sharesec(mem_ctx, session, sharename, sd);
2014 if (!NT_STATUS_IS_OK(status)) {
2015 d_printf("custom set_sharesec failed: %s\n",
2016 nt_errstr(status));
2017 talloc_free(tmp_ctx);
2018 return False;
2021 status = secondary_tcon(tmp_ctx, session, sharename, &tree);
2022 if (!NT_STATUS_EQUAL(status, expected_tcon)) {
2023 d_printf("Expected %s, got %s\n", nt_errstr(expected_tcon),
2024 nt_errstr(status));
2025 ret = False;
2026 goto done;
2029 if (!NT_STATUS_IS_OK(status)) {
2030 /* An expected non-access, no point in trying to write */
2031 goto done;
2034 status = smbcli_mkdir(tree, "sharesec_testdir");
2035 if (!NT_STATUS_EQUAL(status, expected_mkdir)) {
2036 d_printf("(%s) Expected %s, got %s\n", __location__,
2037 nt_errstr(expected_mkdir), nt_errstr(status));
2038 ret = False;
2041 done:
2042 smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2044 status = set_sharesec(mem_ctx, session, sharename, orig_sd);
2045 if (!NT_STATUS_IS_OK(status)) {
2046 d_printf("custom set_sharesec failed: %s\n",
2047 nt_errstr(status));
2048 talloc_free(tmp_ctx);
2049 return False;
2052 talloc_free(tmp_ctx);
2053 return ret;
2056 BOOL torture_samba3_rpc_sharesec(struct torture_context *torture)
2058 TALLOC_CTX *mem_ctx;
2059 BOOL ret = True;
2060 struct smbcli_state *cli;
2061 struct security_descriptor *sd;
2062 struct dom_sid *user_sid;
2064 if (!(mem_ctx = talloc_new(torture))) {
2065 return False;
2068 if (!(torture_open_connection_share(
2069 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
2070 "IPC$", NULL))) {
2071 d_printf("IPC$ connection failed\n");
2072 talloc_free(mem_ctx);
2073 return False;
2076 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
2077 d_printf("whoami failed\n");
2078 talloc_free(mem_ctx);
2079 return False;
2082 sd = get_sharesec(mem_ctx, cli->session, torture_setting_string(torture,
2083 "share", NULL));
2085 ret &= try_tcon(mem_ctx, sd, cli->session,
2086 torture_setting_string(torture, "share", NULL),
2087 user_sid, 0, NT_STATUS_ACCESS_DENIED, NT_STATUS_OK);
2089 ret &= try_tcon(mem_ctx, sd, cli->session,
2090 torture_setting_string(torture, "share", NULL),
2091 user_sid, SEC_FILE_READ_DATA, NT_STATUS_OK,
2092 NT_STATUS_MEDIA_WRITE_PROTECTED);
2094 ret &= try_tcon(mem_ctx, sd, cli->session,
2095 torture_setting_string(torture, "share", NULL),
2096 user_sid, SEC_FILE_ALL, NT_STATUS_OK, NT_STATUS_OK);
2098 talloc_free(mem_ctx);
2099 return ret;
2102 BOOL torture_samba3_rpc_lsa(struct torture_context *torture)
2104 TALLOC_CTX *mem_ctx;
2105 BOOL ret = True;
2106 struct smbcli_state *cli;
2107 struct dcerpc_pipe *p;
2108 struct policy_handle lsa_handle;
2109 NTSTATUS status;
2110 struct dom_sid *domain_sid;
2112 if (!(mem_ctx = talloc_new(torture))) {
2113 return False;
2116 if (!(torture_open_connection_share(
2117 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
2118 "IPC$", NULL))) {
2119 d_printf("IPC$ connection failed\n");
2120 talloc_free(mem_ctx);
2121 return False;
2124 status = pipe_bind_smb(mem_ctx, cli->tree, "\\lsarpc",
2125 &dcerpc_table_lsarpc, &p);
2126 if (!NT_STATUS_IS_OK(status)) {
2127 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2128 nt_errstr(status));
2129 talloc_free(mem_ctx);
2130 return False;
2134 struct lsa_ObjectAttribute attr;
2135 struct lsa_OpenPolicy2 o;
2136 o.in.system_name = talloc_asprintf(
2137 mem_ctx, "\\\\%s", dcerpc_server_name(p));
2138 ZERO_STRUCT(attr);
2139 o.in.attr = &attr;
2140 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2141 o.out.handle = &lsa_handle;
2142 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &o);
2143 if (!NT_STATUS_IS_OK(status)) {
2144 d_printf("(%s) dcerpc_lsa_OpenPolicy2 failed: %s\n",
2145 __location__, nt_errstr(status));
2146 talloc_free(mem_ctx);
2147 return False;
2151 #if 0
2152 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2153 #endif
2156 int i;
2157 int levels[] = { 2,3,5,6 };
2159 for (i=0; i<ARRAY_SIZE(levels); i++) {
2160 struct lsa_QueryInfoPolicy r;
2161 r.in.handle = &lsa_handle;
2162 r.in.level = levels[i];
2163 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
2164 if (!NT_STATUS_IS_OK(status)) {
2165 d_printf("(%s) dcerpc_lsa_QueryInfoPolicy %d "
2166 "failed: %s\n", __location__,
2167 levels[i], nt_errstr(status));
2168 talloc_free(mem_ctx);
2169 return False;
2171 if (levels[i] == 5) {
2172 domain_sid = r.out.info->account_domain.sid;
2177 return ret;
2180 static NTSTATUS get_servername(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree,
2181 char **name)
2183 struct rap_WserverGetInfo r;
2184 NTSTATUS status;
2185 char servername[17];
2187 r.in.level = 0;
2188 r.in.bufsize = 0xffff;
2190 status = smbcli_rap_netservergetinfo(tree, mem_ctx, &r);
2191 if (!NT_STATUS_IS_OK(status)) {
2192 return status;
2195 memcpy(servername, r.out.info.info0.name, 16);
2196 servername[16] = '\0';
2198 if (pull_ascii_talloc(mem_ctx, name, servername) < 0) {
2199 return NT_STATUS_NO_MEMORY;
2202 return NT_STATUS_OK;
2206 static NTSTATUS find_printers(TALLOC_CTX *ctx, struct smbcli_tree *tree,
2207 const char ***printers, int *num_printers)
2209 TALLOC_CTX *mem_ctx;
2210 NTSTATUS status;
2211 struct dcerpc_pipe *p;
2212 struct srvsvc_NetShareEnum r;
2213 struct srvsvc_NetShareCtr1 c1_in;
2214 struct srvsvc_NetShareCtr1 *c1;
2215 int i;
2217 mem_ctx = talloc_new(ctx);
2218 if (mem_ctx == NULL) {
2219 return NT_STATUS_NO_MEMORY;
2222 status = pipe_bind_smb(mem_ctx, tree, "\\srvsvc", &dcerpc_table_srvsvc,
2223 &p);
2224 if (!NT_STATUS_IS_OK(status)) {
2225 d_printf("could not bind to srvsvc pipe\n");
2226 talloc_free(mem_ctx);
2227 return status;
2230 r.in.server_unc = talloc_asprintf(
2231 mem_ctx, "\\\\%s", dcerpc_server_name(p));
2232 r.in.level = 1;
2233 ZERO_STRUCT(c1_in);
2234 r.in.ctr.ctr1 = &c1_in;
2235 r.in.max_buffer = (uint32_t)-1;
2236 r.in.resume_handle = NULL;
2238 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r);
2239 if (!NT_STATUS_IS_OK(status)) {
2240 d_printf("NetShareEnum level %u failed - %s\n",
2241 r.in.level, nt_errstr(status));
2242 talloc_free(mem_ctx);
2243 return status;
2246 *printers = NULL;
2247 *num_printers = 0;
2248 c1 = r.out.ctr.ctr1;
2249 for (i=0; i<c1->count; i++) {
2250 if (c1->array[i].type != STYPE_PRINTQ) {
2251 continue;
2253 if (!add_string_to_array(ctx, c1->array[i].name,
2254 printers, num_printers)) {
2255 talloc_free(ctx);
2256 return NT_STATUS_NO_MEMORY;
2260 talloc_free(mem_ctx);
2261 return NT_STATUS_OK;
2264 static BOOL enumprinters(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *pipe,
2265 const char *servername, int level, int *num_printers)
2267 struct spoolss_EnumPrinters r;
2268 NTSTATUS status;
2269 DATA_BLOB blob;
2271 r.in.flags = PRINTER_ENUM_LOCAL;
2272 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", servername);
2273 r.in.level = level;
2274 r.in.buffer = NULL;
2275 r.in.offered = 0;
2277 status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
2278 if (!NT_STATUS_IS_OK(status)) {
2279 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s\n",
2280 __location__, nt_errstr(status));
2281 return False;
2284 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2285 d_printf("(%s) EnumPrinters unexpected return code %s, should "
2286 "be WERR_INSUFFICIENT_BUFFER\n", __location__,
2287 win_errstr(r.out.result));
2288 return False;
2291 blob = data_blob_talloc_zero(mem_ctx, r.out.needed);
2292 if (blob.data == NULL) {
2293 d_printf("(%s) data_blob_talloc failed\n", __location__);
2294 return False;
2297 r.in.buffer = &blob;
2298 r.in.offered = r.out.needed;
2300 status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
2301 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2302 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s, "
2303 "%s\n", __location__, nt_errstr(status),
2304 win_errstr(r.out.result));
2305 return False;
2308 *num_printers = r.out.count;
2310 return True;
2313 static NTSTATUS getprinterinfo(TALLOC_CTX *ctx, struct dcerpc_pipe *pipe,
2314 struct policy_handle *handle, int level,
2315 union spoolss_PrinterInfo **res)
2317 TALLOC_CTX *mem_ctx;
2318 struct spoolss_GetPrinter r;
2319 DATA_BLOB blob;
2320 NTSTATUS status;
2322 mem_ctx = talloc_new(ctx);
2323 if (mem_ctx == NULL) {
2324 return NT_STATUS_NO_MEMORY;
2327 r.in.handle = handle;
2328 r.in.level = level;
2329 r.in.buffer = NULL;
2330 r.in.offered = 0;
2332 status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r);
2333 if (!NT_STATUS_IS_OK(status)) {
2334 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s\n",
2335 __location__, nt_errstr(status));
2336 talloc_free(mem_ctx);
2337 return status;
2340 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2341 printf("GetPrinter unexpected return code %s, should "
2342 "be WERR_INSUFFICIENT_BUFFER\n",
2343 win_errstr(r.out.result));
2344 talloc_free(mem_ctx);
2345 return NT_STATUS_UNSUCCESSFUL;
2348 r.in.handle = handle;
2349 r.in.level = level;
2350 blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
2351 if (blob.data == NULL) {
2352 talloc_free(mem_ctx);
2353 return NT_STATUS_NO_MEMORY;
2355 memset(blob.data, 0, blob.length);
2356 r.in.buffer = &blob;
2357 r.in.offered = r.out.needed;
2359 status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r);
2360 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2361 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s, "
2362 "%s\n", __location__, nt_errstr(status),
2363 win_errstr(r.out.result));
2364 talloc_free(mem_ctx);
2365 return NT_STATUS_IS_OK(status) ?
2366 NT_STATUS_UNSUCCESSFUL : status;
2369 if (res != NULL) {
2370 *res = talloc_steal(ctx, r.out.info);
2373 talloc_free(mem_ctx);
2374 return NT_STATUS_OK;
2377 BOOL torture_samba3_rpc_spoolss(struct torture_context *torture)
2379 TALLOC_CTX *mem_ctx;
2380 BOOL ret = True;
2381 struct smbcli_state *cli;
2382 struct dcerpc_pipe *p;
2383 NTSTATUS status;
2384 struct policy_handle server_handle, printer_handle;
2385 const char **printers;
2386 int num_printers;
2387 struct spoolss_UserLevel1 userlevel1;
2388 char *servername;
2390 if (!(mem_ctx = talloc_new(torture))) {
2391 return False;
2394 if (!(torture_open_connection_share(
2395 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
2396 "IPC$", NULL))) {
2397 d_printf("IPC$ connection failed\n");
2398 talloc_free(mem_ctx);
2399 return False;
2402 status = get_servername(mem_ctx, cli->tree, &servername);
2403 if (!NT_STATUS_IS_OK(status)) {
2404 d_fprintf(stderr, "(%s) get_servername returned %s\n",
2405 __location__, nt_errstr(status));
2406 talloc_free(mem_ctx);
2407 return False;
2410 if (!NT_STATUS_IS_OK(find_printers(mem_ctx, cli->tree,
2411 &printers, &num_printers))) {
2412 talloc_free(mem_ctx);
2413 return False;
2416 if (num_printers == 0) {
2417 d_printf("Did not find printers\n");
2418 talloc_free(mem_ctx);
2419 return True;
2422 status = pipe_bind_smb(mem_ctx, cli->tree, "\\spoolss",
2423 &dcerpc_table_spoolss, &p);
2424 if (!NT_STATUS_IS_OK(status)) {
2425 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2426 nt_errstr(status));
2427 talloc_free(mem_ctx);
2428 return False;
2431 ZERO_STRUCT(userlevel1);
2432 userlevel1.client = talloc_asprintf(
2433 mem_ctx, "\\\\%s", lp_netbios_name());
2434 userlevel1.user = cli_credentials_get_username(cmdline_credentials);
2435 userlevel1.build = 2600;
2436 userlevel1.major = 3;
2437 userlevel1.minor = 0;
2438 userlevel1.processor = 0;
2441 struct spoolss_OpenPrinterEx r;
2443 ZERO_STRUCT(r);
2444 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
2445 servername);
2446 r.in.datatype = NULL;
2447 r.in.access_mask = 0;
2448 r.in.level = 1;
2449 r.in.userlevel.level1 = &userlevel1;
2450 r.out.handle = &server_handle;
2452 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
2453 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2454 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
2455 "%s, %s\n", __location__, nt_errstr(status),
2456 win_errstr(r.out.result));
2457 talloc_free(mem_ctx);
2458 return False;
2463 struct spoolss_ClosePrinter r;
2465 r.in.handle = &server_handle;
2466 r.out.handle = &server_handle;
2468 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
2469 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2470 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
2471 "%s, %s\n", __location__, nt_errstr(status),
2472 win_errstr(r.out.result));
2473 talloc_free(mem_ctx);
2474 return False;
2479 struct spoolss_OpenPrinterEx r;
2481 ZERO_STRUCT(r);
2482 r.in.printername = talloc_asprintf(
2483 mem_ctx, "\\\\%s\\%s", servername, printers[0]);
2484 r.in.datatype = NULL;
2485 r.in.access_mask = 0;
2486 r.in.level = 1;
2487 r.in.userlevel.level1 = &userlevel1;
2488 r.out.handle = &printer_handle;
2490 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
2491 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2492 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
2493 "%s, %s\n", __location__, nt_errstr(status),
2494 win_errstr(r.out.result));
2495 talloc_free(mem_ctx);
2496 return False;
2501 int i;
2503 for (i=0; i<8; i++) {
2504 status = getprinterinfo(mem_ctx, p, &printer_handle,
2505 i, NULL);
2506 if (!NT_STATUS_IS_OK(status)) {
2507 d_printf("(%s) getprinterinfo %d failed: %s\n",
2508 __location__, i, nt_errstr(status));
2509 ret = False;
2515 struct spoolss_ClosePrinter r;
2517 r.in.handle = &printer_handle;
2518 r.out.handle = &printer_handle;
2520 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
2521 if (!NT_STATUS_IS_OK(status)) {
2522 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
2523 "%s\n", __location__, nt_errstr(status));
2524 talloc_free(mem_ctx);
2525 return False;
2530 int num_enumerated;
2531 if (!enumprinters(mem_ctx, p, servername, 1,
2532 &num_enumerated)) {
2533 d_printf("(%s) enumprinters failed\n", __location__);
2534 talloc_free(mem_ctx);
2535 return False;
2537 if (num_printers != num_enumerated) {
2538 d_printf("(%s) netshareenum gave %d printers, "
2539 "enumprinters lvl 1 gave %d\n", __location__,
2540 num_printers, num_enumerated);
2541 talloc_free(mem_ctx);
2542 return False;
2547 int num_enumerated;
2548 if (!enumprinters(mem_ctx, p, servername, 2,
2549 &num_enumerated)) {
2550 d_printf("(%s) enumprinters failed\n", __location__);
2551 talloc_free(mem_ctx);
2552 return False;
2554 if (num_printers != num_enumerated) {
2555 d_printf("(%s) netshareenum gave %d printers, "
2556 "enumprinters lvl 2 gave %d\n", __location__,
2557 num_printers, num_enumerated);
2558 talloc_free(mem_ctx);
2559 return False;
2563 talloc_free(mem_ctx);
2565 return ret;
2568 BOOL torture_samba3_rpc_wkssvc(struct torture_context *torture)
2570 TALLOC_CTX *mem_ctx;
2571 struct smbcli_state *cli;
2572 struct dcerpc_pipe *p;
2573 NTSTATUS status;
2574 char *servername;
2576 if (!(mem_ctx = talloc_new(torture))) {
2577 return False;
2580 if (!(torture_open_connection_share(
2581 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
2582 "IPC$", NULL))) {
2583 d_printf("IPC$ connection failed\n");
2584 talloc_free(mem_ctx);
2585 return False;
2588 status = get_servername(mem_ctx, cli->tree, &servername);
2589 if (!NT_STATUS_IS_OK(status)) {
2590 d_fprintf(stderr, "(%s) get_servername returned %s\n",
2591 __location__, nt_errstr(status));
2592 talloc_free(mem_ctx);
2593 return False;
2596 status = pipe_bind_smb(mem_ctx, cli->tree, "\\wkssvc",
2597 &dcerpc_table_wkssvc, &p);
2598 if (!NT_STATUS_IS_OK(status)) {
2599 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2600 nt_errstr(status));
2601 talloc_free(mem_ctx);
2602 return False;
2606 struct wkssvc_NetWkstaInfo100 wks100;
2607 union wkssvc_NetWkstaInfo info;
2608 struct wkssvc_NetWkstaGetInfo r;
2610 r.in.server_name = "\\foo";
2611 r.in.level = 100;
2612 info.info100 = &wks100;
2613 r.out.info = &info;
2615 status = dcerpc_wkssvc_NetWkstaGetInfo(p, mem_ctx, &r);
2616 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2617 d_printf("(%s) dcerpc_wkssvc_NetWksGetInfo failed: "
2618 "%s, %s\n", __location__, nt_errstr(status),
2619 win_errstr(r.out.result));
2620 talloc_free(mem_ctx);
2621 return False;
2624 if (strcmp(servername,
2625 r.out.info->info100->server_name) != 0) {
2626 d_printf("(%s) servername inconsistency: RAP=%s, "
2627 "dcerpc_wkssvc_NetWksGetInfo=%s",
2628 __location__, servername,
2629 r.out.info->info100->server_name);
2630 talloc_free(mem_ctx);
2631 return False;
2635 talloc_free(mem_ctx);
2636 return True;
2639 static NTSTATUS winreg_close(struct dcerpc_pipe *p,
2640 struct policy_handle *handle)
2642 struct winreg_CloseKey c;
2643 NTSTATUS status;
2644 TALLOC_CTX *mem_ctx;
2646 c.in.handle = c.out.handle = handle;
2648 if (!(mem_ctx = talloc_new(p))) {
2649 return NT_STATUS_NO_MEMORY;
2652 status = dcerpc_winreg_CloseKey(p, mem_ctx, &c);
2653 talloc_free(mem_ctx);
2655 if (!NT_STATUS_IS_OK(status)) {
2656 return status;
2659 if (!W_ERROR_IS_OK(c.out.result)) {
2660 return werror_to_ntstatus(c.out.result);
2663 return NT_STATUS_OK;
2666 static NTSTATUS enumvalues(struct dcerpc_pipe *p, struct policy_handle *handle,
2667 TALLOC_CTX *mem_ctx)
2669 uint32_t enum_index = 0;
2671 while (1) {
2672 struct winreg_EnumValue r;
2673 struct winreg_StringBuf name;
2674 enum winreg_Type type = 0;
2675 uint8_t buf8[1024];
2676 NTSTATUS status;
2677 uint32_t size, length;
2679 r.in.handle = handle;
2680 r.in.enum_index = enum_index;
2681 name.name = "";
2682 name.size = 1024;
2683 r.in.name = r.out.name = &name;
2684 size = 1024;
2685 length = 5;
2686 r.in.type = &type;
2687 r.in.value = buf8;
2688 r.in.size = &size;
2689 r.in.length = &length;
2691 status = dcerpc_winreg_EnumValue(p, mem_ctx, &r);
2692 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2693 return NT_STATUS_OK;
2695 enum_index += 1;
2699 static NTSTATUS enumkeys(struct dcerpc_pipe *p, struct policy_handle *handle,
2700 TALLOC_CTX *mem_ctx, int depth)
2702 struct winreg_EnumKey r;
2703 struct winreg_StringBuf class, name;
2704 NTSTATUS status;
2705 NTTIME t = 0;
2707 if (depth <= 0) {
2708 return NT_STATUS_OK;
2711 class.name = "";
2712 class.size = 1024;
2714 r.in.handle = handle;
2715 r.in.enum_index = 0;
2716 r.in.name = &name;
2717 r.in.keyclass = &class;
2718 r.out.name = &name;
2719 r.in.last_changed_time = &t;
2721 do {
2722 TALLOC_CTX *tmp_ctx;
2723 struct winreg_OpenKey o;
2724 struct policy_handle key_handle;
2725 int i;
2727 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2728 return NT_STATUS_NO_MEMORY;
2731 name.name = NULL;
2732 name.size = 1024;
2734 status = dcerpc_winreg_EnumKey(p, tmp_ctx, &r);
2735 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2736 /* We're done enumerating */
2737 talloc_free(tmp_ctx);
2738 return NT_STATUS_OK;
2741 for (i=0; i<10-depth; i++)
2742 printf(" ");
2743 printf("%s\n", r.out.name->name);
2746 o.in.parent_handle = handle;
2747 o.in.keyname.name = r.out.name->name;
2748 o.in.unknown = 0;
2749 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2750 o.out.handle = &key_handle;
2752 status = dcerpc_winreg_OpenKey(p, tmp_ctx, &o);
2753 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(o.out.result)) {
2754 enumkeys(p, &key_handle, tmp_ctx, depth-1);
2755 enumvalues(p, &key_handle, tmp_ctx);
2756 status = winreg_close(p, &key_handle);
2757 if (!NT_STATUS_IS_OK(status)) {
2758 return status;
2762 talloc_free(tmp_ctx);
2764 r.in.enum_index += 1;
2765 } while(True);
2767 return NT_STATUS_OK;
2770 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
2772 static BOOL test_Open3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2773 const char *name, winreg_open_fn open_fn)
2775 struct policy_handle handle;
2776 struct winreg_OpenHKLM r;
2777 NTSTATUS status;
2779 r.in.system_name = 0;
2780 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2781 r.out.handle = &handle;
2783 status = open_fn(p, mem_ctx, &r);
2784 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2785 d_printf("(%s) %s failed: %s, %s\n", __location__, name,
2786 nt_errstr(status), win_errstr(r.out.result));
2787 return False;
2790 enumkeys(p, &handle, mem_ctx, 4);
2792 status = winreg_close(p, &handle);
2793 if (!NT_STATUS_IS_OK(status)) {
2794 d_printf("(%s) dcerpc_CloseKey failed: %s\n",
2795 __location__, nt_errstr(status));
2796 return False;
2799 return True;
2802 BOOL torture_samba3_rpc_winreg(struct torture_context *torture)
2804 NTSTATUS status;
2805 struct dcerpc_pipe *p;
2806 TALLOC_CTX *mem_ctx;
2807 BOOL ret = True;
2808 struct {
2809 const char *name;
2810 winreg_open_fn fn;
2811 } open_fns[] = {
2812 {"OpenHKLM", (winreg_open_fn)dcerpc_winreg_OpenHKLM },
2813 {"OpenHKU", (winreg_open_fn)dcerpc_winreg_OpenHKU },
2814 {"OpenHKPD", (winreg_open_fn)dcerpc_winreg_OpenHKPD },
2815 {"OpenHKPT", (winreg_open_fn)dcerpc_winreg_OpenHKPT },
2816 {"OpenHKCR", (winreg_open_fn)dcerpc_winreg_OpenHKCR }};
2817 #if 0
2818 int i;
2819 #endif
2821 mem_ctx = talloc_init("torture_rpc_winreg");
2823 status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_winreg);
2825 if (!NT_STATUS_IS_OK(status)) {
2826 talloc_free(mem_ctx);
2827 return False;
2830 #if 1
2831 ret = test_Open3(p, mem_ctx, open_fns[0].name, open_fns[0].fn);
2832 #else
2833 for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
2834 if (!test_Open3(p, mem_ctx, open_fns[i].name, open_fns[i].fn))
2835 ret = False;
2837 #endif
2839 talloc_free(mem_ctx);
2841 return ret;