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.
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 "libcli/auth/credentials.h"
51 #include "lib/crypto/crypto.h"
52 #include "libcli/security/proto.h"
54 static struct cli_credentials *create_anon_creds(TALLOC_CTX *mem_ctx)
56 struct cli_credentials *result;
58 if (!(result = cli_credentials_init(mem_ctx))) {
62 cli_credentials_set_conf(result);
63 cli_credentials_set_anonymous(result);
69 * This tests a RPC call using an invalid vuid
72 BOOL torture_bind_authcontext(struct torture_context *torture)
77 struct lsa_ObjectAttribute objectattr;
78 struct lsa_OpenPolicy2 openpolicy;
79 struct policy_handle handle;
80 struct lsa_Close close_handle;
81 struct smbcli_session *tmp;
82 struct smbcli_session *session2;
83 struct smbcli_state *cli;
84 struct dcerpc_pipe *lsa_pipe;
85 struct cli_credentials *anon_creds;
86 struct smb_composite_sesssetup setup;
88 mem_ctx = talloc_init("torture_bind_authcontext");
90 if (mem_ctx == NULL) {
91 d_printf("talloc_init failed\n");
95 status = smbcli_full_connection(mem_ctx, &cli,
96 lp_parm_string(-1, "torture", "host"),
97 "IPC$", NULL, cmdline_credentials,
99 if (!NT_STATUS_IS_OK(status)) {
100 d_printf("smbcli_full_connection failed: %s\n",
105 lsa_pipe = dcerpc_pipe_init(mem_ctx, cli->transport->socket->event.ctx);
106 if (lsa_pipe == NULL) {
107 d_printf("dcerpc_pipe_init failed\n");
111 status = dcerpc_pipe_open_smb(lsa_pipe->conn, cli->tree, "\\lsarpc");
112 if (!NT_STATUS_IS_OK(status)) {
113 d_printf("dcerpc_pipe_open_smb failed: %s\n",
118 status = dcerpc_bind_auth_none(lsa_pipe, &dcerpc_table_lsarpc);
119 if (!NT_STATUS_IS_OK(status)) {
120 d_printf("dcerpc_bind_auth_none failed: %s\n",
125 openpolicy.in.system_name =talloc_asprintf(
126 mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
127 ZERO_STRUCT(objectattr);
128 openpolicy.in.attr = &objectattr;
129 openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
130 openpolicy.out.handle = &handle;
132 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
134 if (!NT_STATUS_IS_OK(status)) {
135 d_printf("dcerpc_lsa_OpenPolicy2 failed: %s\n",
140 close_handle.in.handle = &handle;
141 close_handle.out.handle = &handle;
143 status = dcerpc_lsa_Close(lsa_pipe, mem_ctx, &close_handle);
144 if (!NT_STATUS_IS_OK(status)) {
145 d_printf("dcerpc_lsa_Close failed: %s\n",
150 session2 = smbcli_session_init(cli->transport, mem_ctx, False);
151 if (session2 == NULL) {
152 d_printf("smbcli_session_init failed\n");
156 if (!(anon_creds = create_anon_creds(mem_ctx))) {
157 d_printf("create_anon_creds failed\n");
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;
166 status = smb_composite_sesssetup(session2, &setup);
167 if (!NT_STATUS_IS_OK(status)) {
168 d_printf("anon session setup failed: %s\n",
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);
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",
191 talloc_free(mem_ctx);
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)
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");
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");
226 status = dcerpc_pipe_open_smb(lsa_pipe->conn, cli->tree, "\\lsarpc");
227 if (!NT_STATUS_IS_OK(status)) {
228 d_printf("dcerpc_pipe_open_smb failed: %s\n",
233 status = dcerpc_bind_auth(lsa_pipe, &dcerpc_table_lsarpc,
234 credentials, auth_type, auth_level,
236 if (!NT_STATUS_IS_OK(status)) {
237 d_printf("dcerpc_bind_auth failed: %s\n", nt_errstr(status));
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",
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",
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",
278 talloc_free(mem_ctx);
283 * test authenticated RPC binds with the variants Samba3 does support
286 BOOL torture_bind_samba3(struct torture_context *torture)
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");
300 status = smbcli_full_connection(mem_ctx, &cli,
301 lp_parm_string(-1, "torture", "host"),
302 "IPC$", NULL, cmdline_credentials,
304 if (!NT_STATUS_IS_OK(status)) {
305 d_printf("smbcli_full_connection failed: %s\n",
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);
322 talloc_free(mem_ctx);
327 * Lookup or create a user and return all necessary info
330 static NTSTATUS get_usr_handle(struct smbcli_state *cli,
332 struct cli_credentials *admin_creds,
335 const char *username,
337 struct dcerpc_pipe **result_pipe,
338 struct policy_handle **result_handle,
339 struct dom_sid **sid)
341 struct dcerpc_pipe *samr_pipe;
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;
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;
365 status = dcerpc_pipe_open_smb(samr_pipe->conn, cli->tree, "\\samr");
366 if (!NT_STATUS_IS_OK(status)) {
367 d_printf("dcerpc_pipe_open_smb failed: %s\n",
372 if (admin_creds != NULL) {
373 status = dcerpc_bind_auth(samr_pipe, &dcerpc_table_samr,
374 admin_creds, auth_type, auth_level,
376 if (!NT_STATUS_IS_OK(status)) {
377 d_printf("dcerpc_bind_auth failed: %s\n",
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",
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));
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));
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;
420 dom_idx = strequal(enumdom.out.sam->entries[0].name.string,
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));
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));
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;
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",
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",
485 if (!NT_STATUS_IS_OK(status)) {
486 d_printf("samr_CreateUser failed: %s\n", nt_errstr(status));
490 *result_pipe = samr_pipe;
491 *result_handle = user_handle;
493 *sid = dom_sid_add_rid(mem_ctx, l.out.sid, user_rid);
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,
509 struct dom_sid **user_sid)
513 struct dcerpc_pipe *samr_pipe;
514 struct policy_handle *wks_handle;
517 if (!(tmp_ctx = talloc_new(mem_ctx))) {
518 d_printf("talloc_init failed\n");
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,
527 if (!NT_STATUS_IS_OK(status)) {
528 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
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,
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");
548 arcfour_crypt_blob(u_info.info24.password.data, 516,
550 sui2.in.user_handle = wks_handle;
551 sui2.in.info = &u_info;
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",
561 u_info.info16.acct_flags = ACB_NORMAL;
562 sui.in.user_handle = wks_handle;
563 sui.in.info = &u_info;
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");
572 qui.in.user_handle = wks_handle;
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");
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.fields_present = 0x81827fa; /* copy usrmgr.exe */
587 u_info.info21 = qui.out.info->info21;
588 sui.in.user_handle = wks_handle;
589 sui.in.info = &u_info;
592 status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
593 if (!NT_STATUS_IS_OK(status)) {
594 d_printf("samr_SetUserInfo(21) failed\n");
599 *domain_name= talloc_steal(mem_ctx, *domain_name);
600 *user_sid = talloc_steal(mem_ctx, *user_sid);
603 talloc_free(tmp_ctx);
611 static BOOL delete_user(struct smbcli_state *cli,
612 struct cli_credentials *admin_creds,
613 const char *username)
618 struct dcerpc_pipe *samr_pipe;
619 struct policy_handle *user_handle;
622 if ((mem_ctx = talloc_init("leave")) == NULL) {
623 d_printf("talloc_init failed\n");
627 status = get_usr_handle(cli, mem_ctx, admin_creds,
628 DCERPC_AUTH_TYPE_NTLMSSP,
629 DCERPC_AUTH_LEVEL_INTEGRITY,
630 username, &dom_name, &samr_pipe,
633 if (!NT_STATUS_IS_OK(status)) {
634 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
639 struct samr_DeleteUser d;
641 d.in.user_handle = user_handle;
642 d.out.user_handle = user_handle;
644 status = dcerpc_samr_DeleteUser(samr_pipe, mem_ctx, &d);
645 if (!NT_STATUS_IS_OK(status)) {
646 d_printf("samr_DeleteUser failed\n");
654 talloc_free(mem_ctx);
659 * Do a Samba3-style join
662 static BOOL join3(struct smbcli_state *cli,
664 struct cli_credentials *admin_creds,
665 struct cli_credentials *wks_creds)
670 struct dcerpc_pipe *samr_pipe;
671 struct policy_handle *wks_handle;
674 if ((mem_ctx = talloc_init("join3")) == NULL) {
675 d_printf("talloc_init failed\n");
679 status = get_usr_handle(
680 cli, mem_ctx, admin_creds,
681 DCERPC_AUTH_TYPE_NTLMSSP,
682 DCERPC_AUTH_LEVEL_PRIVACY,
683 talloc_asprintf(mem_ctx, "%s$",
684 cli_credentials_get_workstation(wks_creds)),
685 &dom_name, &samr_pipe, &wks_handle, NULL);
687 if (!NT_STATUS_IS_OK(status)) {
688 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
692 cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);
695 struct samr_SetUserInfo2 sui2;
696 union samr_UserInfo u_info;
697 struct samr_UserInfo21 *i21 = &u_info.info25.info;
698 DATA_BLOB session_key;
699 DATA_BLOB confounded_session_key = data_blob_talloc(
701 struct MD5Context ctx;
702 uint8_t confounder[16];
706 i21->full_name.string = talloc_asprintf(
708 cli_credentials_get_workstation(wks_creds));
709 i21->acct_flags = ACB_WSTRUST;
710 i21->fields_present = SAMR_FIELD_FULL_NAME |
711 SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_PASSWORD;
713 encode_pw_buffer(u_info.info25.password.data,
714 cli_credentials_get_password(wks_creds),
716 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
717 if (!NT_STATUS_IS_OK(status)) {
718 d_printf("dcerpc_fetch_session_key failed: %s\n",
722 generate_random_buffer((uint8_t *)confounder, 16);
725 MD5Update(&ctx, confounder, 16);
726 MD5Update(&ctx, session_key.data, session_key.length);
727 MD5Final(confounded_session_key.data, &ctx);
729 arcfour_crypt_blob(u_info.info25.password.data, 516,
730 &confounded_session_key);
731 memcpy(&u_info.info25.password.data[516], confounder, 16);
733 sui2.in.user_handle = wks_handle;
735 sui2.in.info = &u_info;
737 status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2);
738 if (!NT_STATUS_IS_OK(status)) {
739 d_printf("samr_SetUserInfo2(25) failed: %s\n",
744 struct samr_SetUserInfo2 sui2;
745 struct samr_SetUserInfo sui;
746 union samr_UserInfo u_info;
747 DATA_BLOB session_key;
749 encode_pw_buffer(u_info.info24.password.data,
750 cli_credentials_get_password(wks_creds),
752 u_info.info24.pw_len =
753 strlen_m(cli_credentials_get_password(wks_creds))*2;
755 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
756 if (!NT_STATUS_IS_OK(status)) {
757 d_printf("dcerpc_fetch_session_key failed\n");
760 arcfour_crypt_blob(u_info.info24.password.data, 516,
762 sui2.in.user_handle = wks_handle;
763 sui2.in.info = &u_info;
766 status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2);
767 if (!NT_STATUS_IS_OK(status)) {
768 d_printf("samr_SetUserInfo(24) failed: %s\n",
773 u_info.info16.acct_flags = ACB_WSTRUST;
774 sui.in.user_handle = wks_handle;
775 sui.in.info = &u_info;
778 status = dcerpc_samr_SetUserInfo(samr_pipe, mem_ctx, &sui);
779 if (!NT_STATUS_IS_OK(status)) {
780 d_printf("samr_SetUserInfo(16) failed\n");
788 talloc_free(mem_ctx);
793 * Do a ReqChallenge/Auth2 and get the wks creds
796 static BOOL auth2(struct smbcli_state *cli,
797 struct cli_credentials *wks_cred)
800 struct dcerpc_pipe *net_pipe;
803 struct netr_ServerReqChallenge r;
804 struct netr_Credential netr_cli_creds;
805 struct netr_Credential netr_srv_creds;
806 uint32_t negotiate_flags;
807 struct netr_ServerAuthenticate2 a;
808 struct creds_CredentialState *creds_state;
809 struct netr_Credential netr_cred;
810 struct samr_Password mach_pw;
812 mem_ctx = talloc_new(NULL);
813 if (mem_ctx == NULL) {
814 d_printf("talloc_new failed\n");
818 net_pipe = dcerpc_pipe_init(mem_ctx,
819 cli->transport->socket->event.ctx);
820 if (net_pipe == NULL) {
821 d_printf("dcerpc_pipe_init failed\n");
825 status = dcerpc_pipe_open_smb(net_pipe->conn, cli->tree, "\\netlogon");
826 if (!NT_STATUS_IS_OK(status)) {
827 d_printf("dcerpc_pipe_open_smb failed: %s\n",
832 status = dcerpc_bind_auth_none(net_pipe, &dcerpc_table_netlogon);
833 if (!NT_STATUS_IS_OK(status)) {
834 d_printf("dcerpc_bind_auth_none failed: %s\n",
839 r.in.computer_name = cli_credentials_get_workstation(wks_cred);
840 r.in.server_name = talloc_asprintf(
841 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
842 if (r.in.server_name == NULL) {
843 d_printf("talloc_asprintf failed\n");
846 generate_random_buffer(netr_cli_creds.data,
847 sizeof(netr_cli_creds.data));
848 r.in.credentials = &netr_cli_creds;
849 r.out.credentials = &netr_srv_creds;
851 status = dcerpc_netr_ServerReqChallenge(net_pipe, mem_ctx, &r);
852 if (!NT_STATUS_IS_OK(status)) {
853 d_printf("netr_ServerReqChallenge failed: %s\n",
858 negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
859 E_md4hash(cli_credentials_get_password(wks_cred), mach_pw.hash);
861 creds_state = talloc(mem_ctx, struct creds_CredentialState);
862 creds_client_init(creds_state, r.in.credentials,
863 r.out.credentials, &mach_pw,
864 &netr_cred, negotiate_flags);
866 a.in.server_name = talloc_asprintf(
867 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
868 a.in.account_name = talloc_asprintf(
869 mem_ctx, "%s$", cli_credentials_get_workstation(wks_cred));
870 a.in.computer_name = cli_credentials_get_workstation(wks_cred);
871 a.in.secure_channel_type = SEC_CHAN_WKSTA;
872 a.in.negotiate_flags = &negotiate_flags;
873 a.out.negotiate_flags = &negotiate_flags;
874 a.in.credentials = &netr_cred;
875 a.out.credentials = &netr_cred;
877 status = dcerpc_netr_ServerAuthenticate2(net_pipe, mem_ctx, &a);
878 if (!NT_STATUS_IS_OK(status)) {
879 d_printf("netr_ServerServerAuthenticate2 failed: %s\n",
884 if (!creds_client_check(creds_state, a.out.credentials)) {
885 d_printf("creds_client_check failed\n");
889 cli_credentials_set_netlogon_creds(wks_cred, creds_state);
894 talloc_free(mem_ctx);
899 * Do a couple of schannel protected Netlogon ops: Interactive and Network
900 * login, and change the wks password
903 static BOOL schan(struct smbcli_state *cli,
904 struct cli_credentials *wks_creds,
905 struct cli_credentials *user_creds)
910 struct dcerpc_pipe *net_pipe;
913 mem_ctx = talloc_new(NULL);
914 if (mem_ctx == NULL) {
915 d_printf("talloc_new failed\n");
919 net_pipe = dcerpc_pipe_init(mem_ctx,
920 cli->transport->socket->event.ctx);
921 if (net_pipe == NULL) {
922 d_printf("dcerpc_pipe_init failed\n");
926 status = dcerpc_pipe_open_smb(net_pipe->conn, cli->tree, "\\netlogon");
927 if (!NT_STATUS_IS_OK(status)) {
928 d_printf("dcerpc_pipe_open_smb failed: %s\n",
934 net_pipe->conn->flags |= DCERPC_DEBUG_PRINT_IN |
935 DCERPC_DEBUG_PRINT_OUT;
938 net_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL);
939 status = dcerpc_bind_auth(net_pipe, &dcerpc_table_netlogon,
940 wks_creds, DCERPC_AUTH_TYPE_SCHANNEL,
941 DCERPC_AUTH_LEVEL_PRIVACY,
944 status = dcerpc_bind_auth_none(net_pipe, &dcerpc_table_netlogon);
946 if (!NT_STATUS_IS_OK(status)) {
947 d_printf("schannel bind failed: %s\n", nt_errstr(status));
952 for (i=2; i<4; i++) {
954 DATA_BLOB chal, nt_resp, lm_resp, names_blob, session_key;
955 struct creds_CredentialState *creds_state;
956 struct netr_Authenticator netr_auth, netr_auth2;
957 struct netr_NetworkInfo ninfo;
958 struct netr_PasswordInfo pinfo;
959 struct netr_LogonSamLogon r;
961 flags = CLI_CRED_LANMAN_AUTH | CLI_CRED_NTLM_AUTH |
962 CLI_CRED_NTLMv2_AUTH;
964 chal = data_blob_talloc(mem_ctx, NULL, 8);
965 if (chal.data == NULL) {
966 d_printf("data_blob_talloc failed\n");
970 generate_random_buffer(chal.data, chal.length);
971 names_blob = NTLMv2_generate_names_blob(
972 mem_ctx, cli_credentials_get_workstation(user_creds),
973 cli_credentials_get_domain(user_creds));
974 status = cli_credentials_get_ntlm_response(
975 user_creds, mem_ctx, &flags, chal, names_blob,
976 &lm_resp, &nt_resp, NULL, NULL);
977 if (!NT_STATUS_IS_OK(status)) {
978 d_printf("cli_credentials_get_ntlm_response failed:"
979 " %s\n", nt_errstr(status));
983 creds_state = cli_credentials_get_netlogon_creds(wks_creds);
984 creds_client_authenticator(creds_state, &netr_auth);
986 ninfo.identity_info.account_name.string =
987 cli_credentials_get_username(user_creds);
988 ninfo.identity_info.domain_name.string =
989 cli_credentials_get_domain(user_creds);
990 ninfo.identity_info.parameter_control = 0;
991 ninfo.identity_info.logon_id_low = 0;
992 ninfo.identity_info.logon_id_high = 0;
993 ninfo.identity_info.workstation.string =
994 cli_credentials_get_workstation(user_creds);
995 memcpy(ninfo.challenge, chal.data, sizeof(ninfo.challenge));
996 ninfo.nt.length = nt_resp.length;
997 ninfo.nt.data = nt_resp.data;
998 ninfo.lm.length = lm_resp.length;
999 ninfo.lm.data = lm_resp.data;
1001 r.in.server_name = talloc_asprintf(
1002 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1003 ZERO_STRUCT(netr_auth2);
1004 r.in.computer_name =
1005 cli_credentials_get_workstation(wks_creds);
1006 r.in.credential = &netr_auth;
1007 r.in.return_authenticator = &netr_auth2;
1008 r.in.logon_level = 2;
1009 r.in.validation_level = i;
1010 r.in.logon.network = &ninfo;
1011 r.out.return_authenticator = NULL;
1013 status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r);
1014 if (!NT_STATUS_IS_OK(status)) {
1015 d_printf("netr_LogonSamLogon failed: %s\n",
1020 if ((r.out.return_authenticator == NULL) ||
1021 (!creds_client_check(creds_state,
1022 &r.out.return_authenticator->cred))) {
1023 d_printf("Credentials check failed!\n");
1027 creds_client_authenticator(creds_state, &netr_auth);
1029 pinfo.identity_info = ninfo.identity_info;
1030 ZERO_STRUCT(pinfo.lmpassword.hash);
1031 E_md4hash(cli_credentials_get_password(user_creds),
1032 pinfo.ntpassword.hash);
1033 session_key = data_blob_talloc(mem_ctx,
1034 creds_state->session_key, 16);
1035 arcfour_crypt_blob(pinfo.ntpassword.hash,
1036 sizeof(pinfo.ntpassword.hash),
1039 r.in.logon_level = 1;
1040 r.in.logon.password = &pinfo;
1041 r.out.return_authenticator = NULL;
1043 status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r);
1044 if (!NT_STATUS_IS_OK(status)) {
1045 d_printf("netr_LogonSamLogon failed: %s\n",
1050 if ((r.out.return_authenticator == NULL) ||
1051 (!creds_client_check(creds_state,
1052 &r.out.return_authenticator->cred))) {
1053 d_printf("Credentials check failed!\n");
1059 struct netr_ServerPasswordSet s;
1060 char *password = generate_random_str(wks_creds, 8);
1061 struct creds_CredentialState *creds_state;
1063 s.in.server_name = talloc_asprintf(
1064 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1065 s.in.computer_name = cli_credentials_get_workstation(wks_creds);
1066 s.in.account_name = talloc_asprintf(
1067 mem_ctx, "%s$", s.in.computer_name);
1068 s.in.secure_channel_type = SEC_CHAN_WKSTA;
1069 E_md4hash(password, s.in.new_password.hash);
1071 creds_state = cli_credentials_get_netlogon_creds(wks_creds);
1072 creds_des_encrypt(creds_state, &s.in.new_password);
1073 creds_client_authenticator(creds_state, &s.in.credential);
1075 status = dcerpc_netr_ServerPasswordSet(net_pipe, mem_ctx, &s);
1076 if (!NT_STATUS_IS_OK(status)) {
1077 printf("ServerPasswordSet - %s\n", nt_errstr(status));
1081 if (!creds_client_check(creds_state,
1082 &s.out.return_authenticator.cred)) {
1083 printf("Credential chaining failed\n");
1086 cli_credentials_set_password(wks_creds, password,
1092 talloc_free(mem_ctx);
1097 * Delete the wks account again
1100 static BOOL leave(struct smbcli_state *cli,
1101 struct cli_credentials *admin_creds,
1102 struct cli_credentials *wks_creds)
1104 char *wks_name = talloc_asprintf(
1105 NULL, "%s$", cli_credentials_get_workstation(wks_creds));
1108 ret = delete_user(cli, admin_creds, wks_name);
1109 talloc_free(wks_name);
1114 * Test the Samba3 DC code a bit. Join, do some schan netlogon ops, leave
1117 BOOL torture_netlogon_samba3(struct torture_context *torture)
1119 TALLOC_CTX *mem_ctx;
1122 struct smbcli_state *cli;
1123 struct cli_credentials *anon_creds;
1124 struct cli_credentials *wks_creds;
1125 const char *wks_name;
1128 wks_name = lp_parm_string(-1, "torture", "wksname");
1129 if (wks_name == NULL) {
1130 wks_name = get_myname();
1133 mem_ctx = talloc_init("torture_bind_authcontext");
1135 if (mem_ctx == NULL) {
1136 d_printf("talloc_init failed\n");
1140 if (!(anon_creds = create_anon_creds(mem_ctx))) {
1141 d_printf("create_anon_creds failed\n");
1145 status = smbcli_full_connection(mem_ctx, &cli,
1146 lp_parm_string(-1, "torture", "host"),
1147 "IPC$", NULL, anon_creds, NULL);
1148 if (!NT_STATUS_IS_OK(status)) {
1149 d_printf("smbcli_full_connection failed: %s\n",
1154 wks_creds = cli_credentials_init(mem_ctx);
1155 if (wks_creds == NULL) {
1156 d_printf("cli_credentials_init failed\n");
1160 cli_credentials_set_conf(wks_creds);
1161 cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1162 cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1163 cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1164 cli_credentials_set_password(wks_creds,
1165 generate_random_str(wks_creds, 8),
1168 if (!join3(cli, False, cmdline_credentials, wks_creds)) {
1169 d_printf("join failed\n");
1173 cli_credentials_set_domain(
1174 cmdline_credentials, cli_credentials_get_domain(wks_creds),
1177 for (i=0; i<2; i++) {
1179 /* Do this more than once, the routine "schan" changes
1180 * the workstation password using the netlogon
1181 * password change routine */
1185 if (!auth2(cli, wks_creds)) {
1186 d_printf("auth2 failed\n");
1190 for (j=0; j<2; j++) {
1191 if (!schan(cli, wks_creds, cmdline_credentials)) {
1192 d_printf("schan failed\n");
1198 if (!leave(cli, cmdline_credentials, wks_creds)) {
1199 d_printf("leave failed\n");
1206 talloc_free(mem_ctx);
1211 * Do a simple join, testjoin and leave using specified smb and samr
1215 static BOOL test_join3(TALLOC_CTX *mem_ctx,
1217 struct cli_credentials *smb_creds,
1218 struct cli_credentials *samr_creds,
1219 const char *wks_name)
1223 struct smbcli_state *cli;
1224 struct cli_credentials *wks_creds;
1226 status = smbcli_full_connection(mem_ctx, &cli,
1227 lp_parm_string(-1, "torture", "host"),
1228 "IPC$", NULL, smb_creds, NULL);
1229 if (!NT_STATUS_IS_OK(status)) {
1230 d_printf("smbcli_full_connection failed: %s\n",
1235 wks_creds = cli_credentials_init(cli);
1236 if (wks_creds == NULL) {
1237 d_printf("cli_credentials_init failed\n");
1241 cli_credentials_set_conf(wks_creds);
1242 cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1243 cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1244 cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1245 cli_credentials_set_password(wks_creds,
1246 generate_random_str(wks_creds, 8),
1249 if (!join3(cli, use_level25, samr_creds, wks_creds)) {
1250 d_printf("join failed\n");
1254 cli_credentials_set_domain(
1255 cmdline_credentials, cli_credentials_get_domain(wks_creds),
1258 if (!auth2(cli, wks_creds)) {
1259 d_printf("auth2 failed\n");
1263 if (!leave(cli, samr_creds, wks_creds)) {
1264 d_printf("leave failed\n");
1277 * Test the different session key variants. Do it by joining, this uses the
1278 * session key in the setpassword routine. Test the join by doing the auth2.
1281 BOOL torture_samba3_sessionkey(struct torture_context *torture)
1283 TALLOC_CTX *mem_ctx;
1285 struct cli_credentials *anon_creds;
1286 const char *wks_name;
1288 wks_name = lp_parm_string(-1, "torture", "wksname");
1289 if (wks_name == NULL) {
1290 wks_name = get_myname();
1293 mem_ctx = talloc_init("torture_samba3_sessionkey");
1295 if (mem_ctx == NULL) {
1296 d_printf("talloc_init failed\n");
1300 if (!(anon_creds = create_anon_creds(mem_ctx))) {
1301 d_printf("create_anon_creds failed\n");
1307 if (!lp_parm_bool(-1, "target", "samba3", False)) {
1309 /* Samba3 in the build farm right now does this happily. Need
1312 if (test_join3(mem_ctx, False, anon_creds, NULL, wks_name)) {
1313 d_printf("join using anonymous bind on an anonymous smb "
1314 "connection succeeded -- HUH??\n");
1319 if (!test_join3(mem_ctx, False, anon_creds, cmdline_credentials,
1321 d_printf("join using ntlmssp bind on an anonymous smb "
1322 "connection failed\n");
1326 if (!test_join3(mem_ctx, False, cmdline_credentials, NULL, wks_name)) {
1327 d_printf("join using anonymous bind on an authenticated smb "
1328 "connection failed\n");
1332 if (!test_join3(mem_ctx, False, cmdline_credentials,
1333 cmdline_credentials,
1335 d_printf("join using ntlmssp bind on an authenticated smb "
1336 "connection failed\n");
1341 * The following two are tests for setuserinfolevel 25
1344 if (!test_join3(mem_ctx, True, anon_creds, cmdline_credentials,
1346 d_printf("join using ntlmssp bind on an anonymous smb "
1347 "connection failed\n");
1351 if (!test_join3(mem_ctx, True, cmdline_credentials, NULL, wks_name)) {
1352 d_printf("join using anonymous bind on an authenticated smb "
1353 "connection failed\n");
1363 * open pipe and bind, given an IPC$ context
1366 static NTSTATUS pipe_bind_smb(TALLOC_CTX *mem_ctx,
1367 struct smbcli_tree *tree,
1368 const char *pipe_name,
1369 const struct dcerpc_interface_table *iface,
1370 struct dcerpc_pipe **p)
1372 struct dcerpc_pipe *result;
1375 if (!(result = dcerpc_pipe_init(
1376 mem_ctx, tree->session->transport->socket->event.ctx))) {
1377 return NT_STATUS_NO_MEMORY;
1380 status = dcerpc_pipe_open_smb(result->conn, tree, pipe_name);
1381 if (!NT_STATUS_IS_OK(status)) {
1382 d_printf("dcerpc_pipe_open_smb failed: %s\n",
1384 talloc_free(result);
1388 status = dcerpc_bind_auth_none(result, iface);
1389 if (!NT_STATUS_IS_OK(status)) {
1390 d_printf("schannel bind failed: %s\n", nt_errstr(status));
1391 talloc_free(result);
1396 return NT_STATUS_OK;
1400 * Sane wrapper around lsa_LookupNames
1403 static struct dom_sid *name2sid(TALLOC_CTX *mem_ctx,
1404 struct dcerpc_pipe *p,
1408 struct lsa_ObjectAttribute attr;
1409 struct lsa_QosInfo qos;
1410 struct lsa_OpenPolicy2 r;
1413 struct policy_handle handle;
1414 struct lsa_LookupNames l;
1415 struct lsa_TransSidArray sids;
1416 struct lsa_String lsa_name;
1418 struct dom_sid *result;
1419 TALLOC_CTX *tmp_ctx;
1421 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1426 qos.impersonation_level = 2;
1427 qos.context_mode = 1;
1428 qos.effective_only = 0;
1431 attr.root_dir = NULL;
1432 attr.object_name = NULL;
1433 attr.attributes = 0;
1434 attr.sec_desc = NULL;
1435 attr.sec_qos = &qos;
1437 r.in.system_name = "\\";
1439 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1440 r.out.handle = &handle;
1442 status = dcerpc_lsa_OpenPolicy2(p, tmp_ctx, &r);
1443 if (!NT_STATUS_IS_OK(status)) {
1444 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
1445 talloc_free(tmp_ctx);
1452 lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, name);
1454 l.in.handle = &handle;
1456 l.in.names = &lsa_name;
1459 l.in.count = &count;
1460 l.out.count = &count;
1463 status = dcerpc_lsa_LookupNames(p, tmp_ctx, &l);
1464 if (!NT_STATUS_IS_OK(status)) {
1465 printf("LookupNames failed - %s\n", nt_errstr(status));
1466 talloc_free(tmp_ctx);
1470 result = dom_sid_add_rid(mem_ctx, l.out.domains->domains[0].sid,
1471 l.out.sids->sids[0].rid);
1473 c.in.handle = &handle;
1474 c.out.handle = &handle;
1476 status = dcerpc_lsa_Close(p, tmp_ctx, &c);
1477 if (!NT_STATUS_IS_OK(status)) {
1478 printf("dcerpc_lsa_Close failed - %s\n", nt_errstr(status));
1479 talloc_free(tmp_ctx);
1483 talloc_free(tmp_ctx);
1488 * Find out the user SID on this connection
1491 static struct dom_sid *whoami(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree)
1493 struct dcerpc_pipe *lsa;
1494 struct lsa_GetUserName r;
1496 struct lsa_StringPointer authority_name_p;
1497 struct dom_sid *result;
1499 status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\lsarpc",
1500 &dcerpc_table_lsarpc, &lsa);
1501 if (!NT_STATUS_IS_OK(status)) {
1502 d_printf("(%s) Could not bind to LSA: %s\n",
1503 __location__, nt_errstr(status));
1507 r.in.system_name = "\\";
1508 r.in.account_name = NULL;
1509 authority_name_p.string = NULL;
1510 r.in.authority_name = &authority_name_p;
1512 status = dcerpc_lsa_GetUserName(lsa, mem_ctx, &r);
1514 if (!NT_STATUS_IS_OK(status)) {
1515 printf("(%s) GetUserName failed - %s\n",
1516 __location__, nt_errstr(status));
1521 result = name2sid(mem_ctx, lsa, r.out.account_name->string,
1522 r.out.authority_name->string->string);
1529 * Do a tcon, given a session
1532 NTSTATUS secondary_tcon(TALLOC_CTX *mem_ctx,
1533 struct smbcli_session *session,
1534 const char *sharename,
1535 struct smbcli_tree **res)
1537 struct smbcli_tree *result;
1538 TALLOC_CTX *tmp_ctx;
1539 union smb_tcon tcon;
1542 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1543 return NT_STATUS_NO_MEMORY;
1546 if (!(result = smbcli_tree_init(session, mem_ctx, False))) {
1547 talloc_free(tmp_ctx);
1548 return NT_STATUS_NO_MEMORY;
1551 tcon.generic.level = RAW_TCON_TCONX;
1552 tcon.tconx.in.flags = 0;
1553 tcon.tconx.in.password = data_blob(NULL, 0);
1554 tcon.tconx.in.path = sharename;
1555 tcon.tconx.in.device = "?????";
1557 status = smb_raw_tcon(result, tmp_ctx, &tcon);
1558 if (!NT_STATUS_IS_OK(status)) {
1559 d_printf("(%s) smb_raw_tcon failed: %s\n", __location__,
1561 talloc_free(tmp_ctx);
1565 result->tid = tcon.tconx.out.tid;
1566 result = talloc_steal(mem_ctx, result);
1567 talloc_free(tmp_ctx);
1569 return NT_STATUS_OK;
1573 * Test the getusername behaviour
1576 BOOL torture_samba3_rpc_getusername(struct torture_context *torture)
1579 struct smbcli_state *cli;
1580 TALLOC_CTX *mem_ctx;
1582 struct dom_sid *user_sid;
1583 struct dom_sid *created_sid;
1584 struct cli_credentials *anon_creds;
1585 struct cli_credentials *user_creds;
1588 if (!(mem_ctx = talloc_new(torture))) {
1592 status = smbcli_full_connection(
1593 mem_ctx, &cli, lp_parm_string(-1, "torture", "host"),
1594 "IPC$", NULL, cmdline_credentials, NULL);
1595 if (!NT_STATUS_IS_OK(status)) {
1596 d_printf("(%s) smbcli_full_connection failed: %s\n",
1597 __location__, nt_errstr(status));
1602 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
1603 d_printf("(%s) whoami on auth'ed connection failed\n",
1610 if (!(anon_creds = create_anon_creds(mem_ctx))) {
1611 d_printf("(%s) create_anon_creds failed\n", __location__);
1616 status = smbcli_full_connection(
1617 mem_ctx, &cli, lp_parm_string(-1, "torture", "host"),
1618 "IPC$", NULL, anon_creds, NULL);
1619 if (!NT_STATUS_IS_OK(status)) {
1620 d_printf("(%s) anon smbcli_full_connection failed: %s\n",
1621 __location__, nt_errstr(status));
1626 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
1627 d_printf("(%s) whoami on anon connection failed\n",
1633 if (!dom_sid_equal(user_sid,
1634 dom_sid_parse_talloc(mem_ctx, "s-1-5-7"))) {
1635 d_printf("(%s) Anon lsa_GetUserName returned %s, expected "
1636 "S-1-5-7", __location__,
1637 dom_sid_string(mem_ctx, user_sid));
1641 if (!(user_creds = cli_credentials_init(mem_ctx))) {
1642 d_printf("(%s) cli_credentials_init failed\n", __location__);
1647 cli_credentials_set_conf(user_creds);
1648 cli_credentials_set_username(user_creds, "torture_username",
1650 cli_credentials_set_password(user_creds,
1651 generate_random_str(user_creds, 8),
1654 if (!create_user(mem_ctx, cli, cmdline_credentials,
1655 cli_credentials_get_username(user_creds),
1656 cli_credentials_get_password(user_creds),
1657 &domain_name, &created_sid)) {
1658 d_printf("(%s) create_user failed\n", __location__);
1663 cli_credentials_set_domain(user_creds, domain_name,
1667 struct smbcli_session *session2;
1668 struct smb_composite_sesssetup setup;
1669 struct smbcli_tree *tree;
1671 session2 = smbcli_session_init(cli->transport, mem_ctx, False);
1672 if (session2 == NULL) {
1673 d_printf("(%s) smbcli_session_init failed\n",
1678 setup.in.sesskey = cli->transport->negotiate.sesskey;
1679 setup.in.capabilities = cli->transport->negotiate.capabilities;
1680 setup.in.workgroup = "";
1681 setup.in.credentials = user_creds;
1683 status = smb_composite_sesssetup(session2, &setup);
1684 if (!NT_STATUS_IS_OK(status)) {
1685 d_printf("(%s) session setup with new user failed: "
1686 "%s\n", __location__, nt_errstr(status));
1691 if (!NT_STATUS_IS_OK(secondary_tcon(mem_ctx, session2,
1693 d_printf("(%s) secondary_tcon failed\n",
1699 if (!(user_sid = whoami(mem_ctx, tree))) {
1700 d_printf("(%s) whoami on user connection failed\n",
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)) {
1718 if (!delete_user(cli, cmdline_credentials,
1719 cli_credentials_get_username(user_creds))) {
1720 d_printf("(%s) delete_user failed\n", __location__);
1725 talloc_free(mem_ctx);
1729 static BOOL test_NetShareGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1730 const char *sharename)
1733 struct srvsvc_NetShareGetInfo r;
1734 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007, 1501 };
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];
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,
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));
1770 static BOOL test_NetShareEnum(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1771 const char **one_sharename)
1774 struct srvsvc_NetShareEnum r;
1775 struct srvsvc_NetShareCtr0 c0;
1776 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007 };
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];
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));
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));
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;
1816 BOOL torture_samba3_rpc_srvsvc(struct torture_context *torture)
1818 struct dcerpc_pipe *p;
1819 TALLOC_CTX *mem_ctx;
1821 const char *sharename = NULL;
1822 struct smbcli_state *cli;
1825 if (!(mem_ctx = talloc_new(torture))) {
1829 if (!(torture_open_connection_share(
1830 mem_ctx, &cli, lp_parm_string(-1, "torture", "host"),
1832 talloc_free(mem_ctx);
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));
1845 ret &= test_NetShareEnum(p, mem_ctx, &sharename);
1846 if (sharename == NULL) {
1847 printf("did not get sharename\n");
1849 ret &= test_NetShareGetInfo(p, mem_ctx, sharename);
1853 talloc_free(mem_ctx);
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;
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");
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);
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);
1889 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
1892 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
1893 dcerpc_server_name(p));
1894 r.in.share_name = sharename;
1897 status = dcerpc_srvsvc_NetShareGetInfo(p, tmp_ctx, &r);
1898 if (!NT_STATUS_IS_OK(status)) {
1899 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
1901 talloc_free(tmp_ctx);
1905 result = talloc_steal(mem_ctx, r.out.info.info502->sd);
1906 talloc_free(tmp_ctx);
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;
1919 struct sec_desc_buf i;
1920 struct srvsvc_NetShareSetInfo r;
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;
1944 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
1947 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
1948 dcerpc_server_name(p));
1949 r.in.share_name = sharename;
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",
1961 talloc_free(tmp_ctx);
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;
1976 struct security_descriptor *sd;
1980 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1981 d_printf("talloc_new failed\n");
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);
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);
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,
2005 dom_sid_string(mem_ctx, user_sid),
2006 SEC_ACE_TYPE_ACCESS_ALLOWED, access_mask, 0, NULL);
2008 d_printf("security_descriptor_create failed\n");
2009 talloc_free(tmp_ctx);
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",
2017 talloc_free(tmp_ctx);
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),
2029 if (!NT_STATUS_IS_OK(status)) {
2030 /* An expected non-access, no point in trying to write */
2034 status = smbcli_mkdir(tree, "sharesec_testdir");
2035 if (!NT_STATUS_EQUAL(status, expected_mkdir)) {
2036 d_printf("Expected %s, got %s\n", nt_errstr(expected_mkdir),
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",
2048 talloc_free(tmp_ctx);
2052 talloc_free(tmp_ctx);
2056 BOOL torture_samba3_rpc_sharesec(struct torture_context *torture)
2058 TALLOC_CTX *mem_ctx;
2060 struct smbcli_state *cli;
2061 struct security_descriptor *sd;
2062 struct dom_sid *user_sid;
2064 if (!(mem_ctx = talloc_new(torture))) {
2068 if (!(torture_open_connection_share(
2069 mem_ctx, &cli, lp_parm_string(-1, "torture", "host"),
2071 d_printf("IPC$ connection failed\n");
2072 talloc_free(mem_ctx);
2076 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
2077 d_printf("whoami failed\n");
2078 talloc_free(mem_ctx);
2082 sd = get_sharesec(mem_ctx, cli->session, lp_parm_string(-1, "torture",
2085 ret &= try_tcon(mem_ctx, sd, cli->session,
2086 lp_parm_string(-1, "torture", "share"),
2087 user_sid, 0, NT_STATUS_ACCESS_DENIED, NT_STATUS_OK);
2089 ret &= try_tcon(mem_ctx, sd, cli->session,
2090 lp_parm_string(-1, "torture", "share"),
2091 user_sid, SEC_FILE_READ_DATA, NT_STATUS_OK,
2092 NT_STATUS_NETWORK_ACCESS_DENIED);
2094 ret &= try_tcon(mem_ctx, sd, cli->session,
2095 lp_parm_string(-1, "torture", "share"),
2096 user_sid, SEC_FILE_ALL, NT_STATUS_OK, NT_STATUS_OK);
2098 talloc_free(mem_ctx);
2102 BOOL torture_samba3_rpc_lsa(struct torture_context *torture)
2104 TALLOC_CTX *mem_ctx;
2106 struct smbcli_state *cli;
2107 struct dcerpc_pipe *p;
2108 struct policy_handle lsa_handle;
2110 struct dom_sid *domain_sid;
2112 if (!(mem_ctx = talloc_new(torture))) {
2116 if (!(torture_open_connection_share(
2117 mem_ctx, &cli, lp_parm_string(-1, "torture", "host"),
2119 d_printf("IPC$ connection failed\n");
2120 talloc_free(mem_ctx);
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__,
2129 talloc_free(mem_ctx);
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));
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);
2152 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
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);
2171 if (levels[i] == 5) {
2172 domain_sid = r.out.info->account_domain.sid;
2180 static NTSTATUS get_servername(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree,
2183 struct rap_WserverGetInfo r;
2185 char servername[17];
2188 r.in.bufsize = 0xffff;
2190 status = smbcli_rap_netservergetinfo(tree, mem_ctx, &r);
2191 if (!NT_STATUS_IS_OK(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;
2211 struct dcerpc_pipe *p;
2212 struct srvsvc_NetShareEnum r;
2213 struct srvsvc_NetShareCtr1 c1_in;
2214 struct srvsvc_NetShareCtr1 *c1;
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,
2224 if (!NT_STATUS_IS_OK(status)) {
2225 d_printf("could not bind to srvsvc pipe\n");
2226 talloc_free(mem_ctx);
2230 r.in.server_unc = talloc_asprintf(
2231 mem_ctx, "\\\\%s", dcerpc_server_name(p));
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);
2248 c1 = r.out.ctr.ctr1;
2249 for (i=0; i<c1->count; i++) {
2250 if (c1->array[i].type != STYPE_PRINTQ) {
2253 if (!add_string_to_array(ctx, c1->array[i].name,
2254 printers, num_printers)) {
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;
2271 r.in.flags = PRINTER_ENUM_LOCAL;
2272 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", servername);
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));
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));
2291 blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
2292 if (blob.data == NULL) {
2293 d_printf("(%s) data_blob_talloc failed\n", __location__);
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));
2308 *num_printers = r.out.count;
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;
2322 mem_ctx = talloc_new(ctx);
2323 if (mem_ctx == NULL) {
2324 return NT_STATUS_NO_MEMORY;
2327 r.in.handle = handle;
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);
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;
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;
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;
2381 struct smbcli_state *cli;
2382 struct dcerpc_pipe *p;
2384 struct policy_handle server_handle, printer_handle;
2385 const char **printers;
2387 struct spoolss_UserLevel1 userlevel1;
2390 if (!(mem_ctx = talloc_new(torture))) {
2394 if (!(torture_open_connection_share(
2395 mem_ctx, &cli, lp_parm_string(-1, "torture", "host"),
2397 d_printf("IPC$ connection failed\n");
2398 talloc_free(mem_ctx);
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);
2410 if (!NT_STATUS_IS_OK(find_printers(mem_ctx, cli->tree,
2411 &printers, &num_printers))) {
2412 talloc_free(mem_ctx);
2416 if (num_printers == 0) {
2417 d_printf("Did not find printers\n");
2418 talloc_free(mem_ctx);
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__,
2427 talloc_free(mem_ctx);
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;
2444 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
2446 r.in.datatype = NULL;
2447 r.in.access_mask = 0;
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);
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);
2479 struct spoolss_OpenPrinterEx 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;
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);
2503 for (i=0; i<8; i++) {
2504 status = getprinterinfo(mem_ctx, p, &printer_handle,
2506 if (!NT_STATUS_IS_OK(status)) {
2507 d_printf("(%s) getprinterinfo %d failed: %s\n",
2508 __location__, i, nt_errstr(status));
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);
2531 if (!enumprinters(mem_ctx, p, servername, 1,
2533 d_printf("(%s) enumprinters failed\n", __location__);
2534 talloc_free(mem_ctx);
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);
2548 if (!enumprinters(mem_ctx, p, servername, 2,
2550 d_printf("(%s) enumprinters failed\n", __location__);
2551 talloc_free(mem_ctx);
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);
2563 talloc_free(mem_ctx);
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;
2576 if (!(mem_ctx = talloc_new(torture))) {
2580 if (!(torture_open_connection_share(
2581 mem_ctx, &cli, lp_parm_string(-1, "torture", "host"),
2583 d_printf("IPC$ connection failed\n");
2584 talloc_free(mem_ctx);
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);
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__,
2601 talloc_free(mem_ctx);
2606 struct wkssvc_NetWkstaInfo100 wks100;
2607 union wkssvc_NetWkstaInfo info;
2608 struct wkssvc_NetWkstaGetInfo r;
2610 r.in.server_name = "\\foo";
2612 info.info100 = &wks100;
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);
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);
2635 talloc_free(mem_ctx);
2639 static NTSTATUS winreg_close(struct dcerpc_pipe *p,
2640 struct policy_handle *handle)
2642 struct winreg_CloseKey c;
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)) {
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;
2672 struct winreg_EnumValue r;
2673 struct winreg_StringBuf name;
2674 enum winreg_Type type = 0;
2677 uint32_t size, length;
2679 r.in.handle = handle;
2680 r.in.enum_index = enum_index;
2683 r.in.name = r.out.name = &name;
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;
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;
2708 return NT_STATUS_OK;
2714 r.in.handle = handle;
2715 r.in.enum_index = 0;
2717 r.in.keyclass = &class;
2719 r.in.last_changed_time = &t;
2722 TALLOC_CTX *tmp_ctx;
2723 struct winreg_OpenKey o;
2724 struct policy_handle key_handle;
2727 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2728 return NT_STATUS_NO_MEMORY;
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++)
2743 printf("%s\n", r.out.name->name);
2746 o.in.parent_handle = handle;
2747 o.in.keyname.name = r.out.name->name;
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)) {
2762 talloc_free(tmp_ctx);
2764 r.in.enum_index += 1;
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;
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));
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));
2802 BOOL torture_samba3_rpc_winreg(struct torture_context *torture)
2805 struct dcerpc_pipe *p;
2806 TALLOC_CTX *mem_ctx;
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 }};
2819 mem_ctx = talloc_init("torture_rpc_winreg");
2821 status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_winreg);
2823 if (!NT_STATUS_IS_OK(status)) {
2824 talloc_free(mem_ctx);
2829 ret = test_Open3(p, mem_ctx, open_fns[0].name, open_fns[0].fn);
2831 for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
2832 if (!test_Open3(p, mem_ctx, open_fns[i].name, open_fns[i].fn))
2837 talloc_free(mem_ctx);