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 3 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, see <http://www.gnu.org/licenses/>.
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/rap/rap.h"
25 #include "torture/torture.h"
26 #include "torture/util.h"
27 #include "torture/rap/proto.h"
28 #include "librpc/gen_ndr/ndr_lsa.h"
29 #include "librpc/gen_ndr/ndr_lsa_c.h"
30 #include "librpc/gen_ndr/ndr_samr.h"
31 #include "librpc/gen_ndr/ndr_samr_c.h"
32 #include "librpc/gen_ndr/ndr_netlogon.h"
33 #include "librpc/gen_ndr/ndr_netlogon_c.h"
34 #include "librpc/gen_ndr/ndr_srvsvc.h"
35 #include "librpc/gen_ndr/ndr_srvsvc_c.h"
36 #include "librpc/gen_ndr/ndr_spoolss.h"
37 #include "librpc/gen_ndr/ndr_spoolss_c.h"
38 #include "librpc/gen_ndr/ndr_winreg.h"
39 #include "librpc/gen_ndr/ndr_winreg_c.h"
40 #include "librpc/gen_ndr/ndr_wkssvc.h"
41 #include "librpc/gen_ndr/ndr_wkssvc_c.h"
42 #include "lib/cmdline/popt_common.h"
43 #include "librpc/rpc/dcerpc.h"
44 #include "torture/rpc/rpc.h"
45 #include "libcli/libcli.h"
46 #include "libcli/composite/composite.h"
47 #include "libcli/smb_composite/smb_composite.h"
48 #include "libcli/auth/libcli_auth.h"
49 #include "lib/crypto/crypto.h"
50 #include "libcli/security/proto.h"
51 #include "param/param.h"
52 #include "lib/registry/registry.h"
53 #include "libcli/resolve/resolve.h"
56 * This tests a RPC call using an invalid vuid
59 bool torture_bind_authcontext(struct torture_context *torture)
64 struct lsa_ObjectAttribute objectattr;
65 struct lsa_OpenPolicy2 openpolicy;
66 struct policy_handle handle;
67 struct lsa_Close close_handle;
68 struct smbcli_session *tmp;
69 struct smbcli_session *session2;
70 struct smbcli_state *cli;
71 struct dcerpc_pipe *lsa_pipe;
72 struct cli_credentials *anon_creds;
73 struct smb_composite_sesssetup setup;
75 mem_ctx = talloc_init("torture_bind_authcontext");
77 if (mem_ctx == NULL) {
78 d_printf("talloc_init failed\n");
82 status = smbcli_full_connection(mem_ctx, &cli,
83 torture_setting_string(torture, "host", NULL),
84 lp_smb_ports(torture->lp_ctx),
85 "IPC$", NULL, cmdline_credentials,
86 lp_resolve_context(torture->lp_ctx),
88 if (!NT_STATUS_IS_OK(status)) {
89 d_printf("smbcli_full_connection failed: %s\n",
94 lsa_pipe = dcerpc_pipe_init(mem_ctx, cli->transport->socket->event.ctx,
95 lp_iconv_convenience(torture->lp_ctx));
96 if (lsa_pipe == NULL) {
97 d_printf("dcerpc_pipe_init failed\n");
101 status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
102 if (!NT_STATUS_IS_OK(status)) {
103 d_printf("dcerpc_pipe_open_smb failed: %s\n",
108 status = dcerpc_bind_auth_none(lsa_pipe, &ndr_table_lsarpc);
109 if (!NT_STATUS_IS_OK(status)) {
110 d_printf("dcerpc_bind_auth_none failed: %s\n",
115 openpolicy.in.system_name =talloc_asprintf(
116 mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
117 ZERO_STRUCT(objectattr);
118 openpolicy.in.attr = &objectattr;
119 openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
120 openpolicy.out.handle = &handle;
122 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
124 if (!NT_STATUS_IS_OK(status)) {
125 d_printf("dcerpc_lsa_OpenPolicy2 failed: %s\n",
130 close_handle.in.handle = &handle;
131 close_handle.out.handle = &handle;
133 status = dcerpc_lsa_Close(lsa_pipe, mem_ctx, &close_handle);
134 if (!NT_STATUS_IS_OK(status)) {
135 d_printf("dcerpc_lsa_Close failed: %s\n",
140 session2 = smbcli_session_init(cli->transport, mem_ctx, false);
141 if (session2 == NULL) {
142 d_printf("smbcli_session_init failed\n");
146 if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) {
147 d_printf("create_anon_creds failed\n");
151 setup.in.sesskey = cli->transport->negotiate.sesskey;
152 setup.in.capabilities = cli->transport->negotiate.capabilities;
153 setup.in.workgroup = "";
154 setup.in.credentials = anon_creds;
156 status = smb_composite_sesssetup(session2, &setup);
157 if (!NT_STATUS_IS_OK(status)) {
158 d_printf("anon session setup failed: %s\n",
162 session2->vuid = setup.out.vuid;
164 tmp = cli->tree->session;
165 cli->tree->session = session2;
167 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
169 cli->tree->session = tmp;
170 talloc_free(lsa_pipe);
173 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
174 d_printf("dcerpc_lsa_OpenPolicy2 with wrong vuid gave %s, "
175 "expected NT_STATUS_INVALID_HANDLE\n",
182 talloc_free(mem_ctx);
187 * Bind to lsa using a specific auth method
190 static bool bindtest(struct smbcli_state *cli,
191 struct cli_credentials *credentials,
192 struct loadparm_context *lp_ctx,
193 uint8_t auth_type, uint8_t auth_level)
199 struct dcerpc_pipe *lsa_pipe;
200 struct lsa_ObjectAttribute objectattr;
201 struct lsa_OpenPolicy2 openpolicy;
202 struct lsa_QueryInfoPolicy query;
203 struct policy_handle handle;
204 struct lsa_Close close_handle;
206 if ((mem_ctx = talloc_init("bindtest")) == NULL) {
207 d_printf("talloc_init failed\n");
211 lsa_pipe = dcerpc_pipe_init(mem_ctx,
212 cli->transport->socket->event.ctx,
213 lp_iconv_convenience(lp_ctx));
214 if (lsa_pipe == NULL) {
215 d_printf("dcerpc_pipe_init failed\n");
219 status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
220 if (!NT_STATUS_IS_OK(status)) {
221 d_printf("dcerpc_pipe_open_smb failed: %s\n",
226 status = dcerpc_bind_auth(lsa_pipe, &ndr_table_lsarpc,
227 credentials, lp_ctx, auth_type, auth_level,
229 if (!NT_STATUS_IS_OK(status)) {
230 d_printf("dcerpc_bind_auth failed: %s\n", nt_errstr(status));
234 openpolicy.in.system_name =talloc_asprintf(
235 mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
236 ZERO_STRUCT(objectattr);
237 openpolicy.in.attr = &objectattr;
238 openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
239 openpolicy.out.handle = &handle;
241 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
243 if (!NT_STATUS_IS_OK(status)) {
244 d_printf("dcerpc_lsa_OpenPolicy2 failed: %s\n",
249 query.in.handle = &handle;
250 query.in.level = LSA_POLICY_INFO_DOMAIN;
252 status = dcerpc_lsa_QueryInfoPolicy(lsa_pipe, mem_ctx, &query);
253 if (!NT_STATUS_IS_OK(status)) {
254 d_printf("dcerpc_lsa_QueryInfoPolicy failed: %s\n",
259 close_handle.in.handle = &handle;
260 close_handle.out.handle = &handle;
262 status = dcerpc_lsa_Close(lsa_pipe, mem_ctx, &close_handle);
263 if (!NT_STATUS_IS_OK(status)) {
264 d_printf("dcerpc_lsa_Close failed: %s\n",
271 talloc_free(mem_ctx);
276 * test authenticated RPC binds with the variants Samba3 does support
279 bool torture_bind_samba3(struct torture_context *torture)
284 struct smbcli_state *cli;
286 mem_ctx = talloc_init("torture_bind_authcontext");
288 if (mem_ctx == NULL) {
289 d_printf("talloc_init failed\n");
293 status = smbcli_full_connection(mem_ctx, &cli,
294 torture_setting_string(torture, "host", NULL),
295 lp_smb_ports(torture->lp_ctx),
296 "IPC$", NULL, cmdline_credentials,
297 lp_resolve_context(torture->lp_ctx),
299 if (!NT_STATUS_IS_OK(status)) {
300 d_printf("smbcli_full_connection failed: %s\n",
307 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_NTLMSSP,
308 DCERPC_AUTH_LEVEL_INTEGRITY);
309 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_NTLMSSP,
310 DCERPC_AUTH_LEVEL_PRIVACY);
311 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_SPNEGO,
312 DCERPC_AUTH_LEVEL_INTEGRITY);
313 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_SPNEGO,
314 DCERPC_AUTH_LEVEL_PRIVACY);
317 talloc_free(mem_ctx);
322 * Lookup or create a user and return all necessary info
325 static NTSTATUS get_usr_handle(struct smbcli_state *cli,
327 struct loadparm_context *lp_ctx,
328 struct cli_credentials *admin_creds,
331 const char *username,
333 struct dcerpc_pipe **result_pipe,
334 struct policy_handle **result_handle,
335 struct dom_sid **sid)
337 struct dcerpc_pipe *samr_pipe;
339 struct policy_handle conn_handle;
340 struct policy_handle domain_handle;
341 struct policy_handle *user_handle;
342 struct samr_Connect2 conn;
343 struct samr_EnumDomains enumdom;
344 uint32_t resume_handle = 0;
345 struct samr_LookupDomain l;
347 struct lsa_String domain_name;
348 struct lsa_String user_name;
349 struct samr_OpenDomain o;
350 struct samr_CreateUser2 c;
351 uint32_t user_rid,access_granted;
353 samr_pipe = dcerpc_pipe_init(mem_ctx,
354 cli->transport->socket->event.ctx,
355 lp_iconv_convenience(lp_ctx));
356 if (samr_pipe == NULL) {
357 d_printf("dcerpc_pipe_init failed\n");
358 status = NT_STATUS_NO_MEMORY;
362 status = dcerpc_pipe_open_smb(samr_pipe, cli->tree, "\\samr");
363 if (!NT_STATUS_IS_OK(status)) {
364 d_printf("dcerpc_pipe_open_smb failed: %s\n",
369 if (admin_creds != NULL) {
370 status = dcerpc_bind_auth(samr_pipe, &ndr_table_samr,
371 admin_creds, lp_ctx, auth_type, auth_level,
373 if (!NT_STATUS_IS_OK(status)) {
374 d_printf("dcerpc_bind_auth failed: %s\n",
379 /* We must have an authenticated SMB connection */
380 status = dcerpc_bind_auth_none(samr_pipe, &ndr_table_samr);
381 if (!NT_STATUS_IS_OK(status)) {
382 d_printf("dcerpc_bind_auth_none failed: %s\n",
388 conn.in.system_name = talloc_asprintf(
389 mem_ctx, "\\\\%s", dcerpc_server_name(samr_pipe));
390 conn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
391 conn.out.connect_handle = &conn_handle;
393 status = dcerpc_samr_Connect2(samr_pipe, mem_ctx, &conn);
394 if (!NT_STATUS_IS_OK(status)) {
395 d_printf("samr_Connect2 failed: %s\n", nt_errstr(status));
399 enumdom.in.connect_handle = &conn_handle;
400 enumdom.in.resume_handle = &resume_handle;
401 enumdom.in.buf_size = (uint32_t)-1;
402 enumdom.out.resume_handle = &resume_handle;
404 status = dcerpc_samr_EnumDomains(samr_pipe, mem_ctx, &enumdom);
405 if (!NT_STATUS_IS_OK(status)) {
406 d_printf("samr_EnumDomains failed: %s\n", nt_errstr(status));
410 if (enumdom.out.num_entries != 2) {
411 d_printf("samr_EnumDomains returned %d entries, expected 2\n",
412 enumdom.out.num_entries);
413 status = NT_STATUS_UNSUCCESSFUL;
417 dom_idx = strequal(enumdom.out.sam->entries[0].name.string,
420 l.in.connect_handle = &conn_handle;
421 domain_name.string = enumdom.out.sam->entries[0].name.string;
422 *domain = talloc_strdup(mem_ctx, domain_name.string);
423 l.in.domain_name = &domain_name;
425 status = dcerpc_samr_LookupDomain(samr_pipe, mem_ctx, &l);
426 if (!NT_STATUS_IS_OK(status)) {
427 d_printf("samr_LookupDomain failed: %s\n", nt_errstr(status));
431 o.in.connect_handle = &conn_handle;
432 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
433 o.in.sid = l.out.sid;
434 o.out.domain_handle = &domain_handle;
436 status = dcerpc_samr_OpenDomain(samr_pipe, mem_ctx, &o);
437 if (!NT_STATUS_IS_OK(status)) {
438 d_printf("samr_OpenDomain failed: %s\n", nt_errstr(status));
442 c.in.domain_handle = &domain_handle;
443 user_name.string = username;
444 c.in.account_name = &user_name;
445 c.in.acct_flags = ACB_NORMAL;
446 c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
447 user_handle = talloc(mem_ctx, struct policy_handle);
448 c.out.user_handle = user_handle;
449 c.out.access_granted = &access_granted;
450 c.out.rid = &user_rid;
452 status = dcerpc_samr_CreateUser2(samr_pipe, mem_ctx, &c);
454 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
455 struct samr_LookupNames ln;
456 struct samr_OpenUser ou;
458 ln.in.domain_handle = &domain_handle;
460 ln.in.names = &user_name;
462 status = dcerpc_samr_LookupNames(samr_pipe, mem_ctx, &ln);
463 if (!NT_STATUS_IS_OK(status)) {
464 d_printf("samr_LookupNames failed: %s\n",
469 ou.in.domain_handle = &domain_handle;
470 ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
471 user_rid = ou.in.rid = ln.out.rids.ids[0];
472 ou.out.user_handle = user_handle;
474 status = dcerpc_samr_OpenUser(samr_pipe, mem_ctx, &ou);
475 if (!NT_STATUS_IS_OK(status)) {
476 d_printf("samr_OpenUser failed: %s\n",
482 if (!NT_STATUS_IS_OK(status)) {
483 d_printf("samr_CreateUser failed: %s\n", nt_errstr(status));
487 *result_pipe = samr_pipe;
488 *result_handle = user_handle;
490 *sid = dom_sid_add_rid(mem_ctx, l.out.sid, user_rid);
502 static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
503 struct loadparm_context *lp_ctx,
504 struct cli_credentials *admin_creds,
505 const char *username, const char *password,
507 struct dom_sid **user_sid)
511 struct dcerpc_pipe *samr_pipe;
512 struct policy_handle *wks_handle;
515 if (!(tmp_ctx = talloc_new(mem_ctx))) {
516 d_printf("talloc_init failed\n");
520 status = get_usr_handle(cli, tmp_ctx, lp_ctx, admin_creds,
521 DCERPC_AUTH_TYPE_NTLMSSP,
522 DCERPC_AUTH_LEVEL_INTEGRITY,
523 username, domain_name, &samr_pipe, &wks_handle,
525 if (!NT_STATUS_IS_OK(status)) {
526 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
531 struct samr_SetUserInfo2 sui2;
532 struct samr_SetUserInfo sui;
533 struct samr_QueryUserInfo qui;
534 union samr_UserInfo u_info;
535 DATA_BLOB session_key;
539 encode_pw_buffer(u_info.info23.password.data, password,
542 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
543 if (!NT_STATUS_IS_OK(status)) {
544 d_printf("dcerpc_fetch_session_key failed\n");
547 arcfour_crypt_blob(u_info.info23.password.data, 516,
549 u_info.info23.info.password_expired = 0;
550 u_info.info23.info.fields_present = SAMR_FIELD_PASSWORD |
551 SAMR_FIELD_PASSWORD2 |
552 SAMR_FIELD_EXPIRED_FLAG;
553 sui2.in.user_handle = wks_handle;
554 sui2.in.info = &u_info;
557 status = dcerpc_samr_SetUserInfo2(samr_pipe, tmp_ctx, &sui2);
558 if (!NT_STATUS_IS_OK(status)) {
559 d_printf("samr_SetUserInfo(23) failed: %s\n",
564 u_info.info16.acct_flags = ACB_NORMAL;
565 sui.in.user_handle = wks_handle;
566 sui.in.info = &u_info;
569 status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
570 if (!NT_STATUS_IS_OK(status)) {
571 d_printf("samr_SetUserInfo(16) failed\n");
575 qui.in.user_handle = wks_handle;
578 status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
579 if (!NT_STATUS_IS_OK(status)) {
580 d_printf("samr_QueryUserInfo(21) failed\n");
584 qui.out.info->info21.allow_password_change = 0;
585 qui.out.info->info21.force_password_change = 0;
586 qui.out.info->info21.account_name.string = NULL;
587 qui.out.info->info21.rid = 0;
588 qui.out.info->info21.acct_expiry = 0;
589 qui.out.info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
591 u_info.info21 = qui.out.info->info21;
592 sui.in.user_handle = wks_handle;
593 sui.in.info = &u_info;
596 status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
597 if (!NT_STATUS_IS_OK(status)) {
598 d_printf("samr_SetUserInfo(21) failed\n");
603 *domain_name= talloc_steal(mem_ctx, *domain_name);
604 *user_sid = talloc_steal(mem_ctx, *user_sid);
607 talloc_free(tmp_ctx);
615 static bool delete_user(struct smbcli_state *cli,
616 struct loadparm_context *lp_ctx,
617 struct cli_credentials *admin_creds,
618 const char *username)
623 struct dcerpc_pipe *samr_pipe;
624 struct policy_handle *user_handle;
627 if ((mem_ctx = talloc_init("leave")) == NULL) {
628 d_printf("talloc_init failed\n");
632 status = get_usr_handle(cli, mem_ctx, lp_ctx, admin_creds,
633 DCERPC_AUTH_TYPE_NTLMSSP,
634 DCERPC_AUTH_LEVEL_INTEGRITY,
635 username, &dom_name, &samr_pipe,
638 if (!NT_STATUS_IS_OK(status)) {
639 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
644 struct samr_DeleteUser d;
646 d.in.user_handle = user_handle;
647 d.out.user_handle = user_handle;
649 status = dcerpc_samr_DeleteUser(samr_pipe, mem_ctx, &d);
650 if (!NT_STATUS_IS_OK(status)) {
651 d_printf("samr_DeleteUser failed %s\n", nt_errstr(status));
659 talloc_free(mem_ctx);
664 * Do a Samba3-style join
667 static bool join3(struct smbcli_state *cli,
668 struct loadparm_context *lp_ctx,
670 struct cli_credentials *admin_creds,
671 struct cli_credentials *wks_creds)
676 struct dcerpc_pipe *samr_pipe;
677 struct policy_handle *wks_handle;
680 if ((mem_ctx = talloc_init("join3")) == NULL) {
681 d_printf("talloc_init failed\n");
685 status = get_usr_handle(
686 cli, mem_ctx, lp_ctx, admin_creds,
687 DCERPC_AUTH_TYPE_NTLMSSP,
688 DCERPC_AUTH_LEVEL_PRIVACY,
689 talloc_asprintf(mem_ctx, "%s$",
690 cli_credentials_get_workstation(wks_creds)),
691 &dom_name, &samr_pipe, &wks_handle, NULL);
693 if (!NT_STATUS_IS_OK(status)) {
694 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
698 cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);
701 struct samr_SetUserInfo2 sui2;
702 union samr_UserInfo u_info;
703 struct samr_UserInfo21 *i21 = &u_info.info25.info;
704 DATA_BLOB session_key;
705 DATA_BLOB confounded_session_key = data_blob_talloc(
707 struct MD5Context ctx;
708 uint8_t confounder[16];
712 i21->full_name.string = talloc_asprintf(
714 cli_credentials_get_workstation(wks_creds));
715 i21->acct_flags = ACB_WSTRUST;
716 i21->fields_present = SAMR_FIELD_FULL_NAME |
717 SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_PASSWORD;
719 encode_pw_buffer(u_info.info25.password.data,
720 cli_credentials_get_password(wks_creds),
722 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
723 if (!NT_STATUS_IS_OK(status)) {
724 d_printf("dcerpc_fetch_session_key failed: %s\n",
728 generate_random_buffer((uint8_t *)confounder, 16);
731 MD5Update(&ctx, confounder, 16);
732 MD5Update(&ctx, session_key.data, session_key.length);
733 MD5Final(confounded_session_key.data, &ctx);
735 arcfour_crypt_blob(u_info.info25.password.data, 516,
736 &confounded_session_key);
737 memcpy(&u_info.info25.password.data[516], confounder, 16);
739 sui2.in.user_handle = wks_handle;
741 sui2.in.info = &u_info;
743 status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2);
744 if (!NT_STATUS_IS_OK(status)) {
745 d_printf("samr_SetUserInfo2(25) failed: %s\n",
750 struct samr_SetUserInfo2 sui2;
751 struct samr_SetUserInfo sui;
752 union samr_UserInfo u_info;
753 DATA_BLOB session_key;
755 encode_pw_buffer(u_info.info24.password.data,
756 cli_credentials_get_password(wks_creds),
758 u_info.info24.pw_len =
759 strlen_m(cli_credentials_get_password(wks_creds))*2;
761 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
762 if (!NT_STATUS_IS_OK(status)) {
763 d_printf("dcerpc_fetch_session_key failed\n");
766 arcfour_crypt_blob(u_info.info24.password.data, 516,
768 sui2.in.user_handle = wks_handle;
769 sui2.in.info = &u_info;
772 status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2);
773 if (!NT_STATUS_IS_OK(status)) {
774 d_printf("samr_SetUserInfo(24) failed: %s\n",
779 u_info.info16.acct_flags = ACB_WSTRUST;
780 sui.in.user_handle = wks_handle;
781 sui.in.info = &u_info;
784 status = dcerpc_samr_SetUserInfo(samr_pipe, mem_ctx, &sui);
785 if (!NT_STATUS_IS_OK(status)) {
786 d_printf("samr_SetUserInfo(16) failed\n");
794 talloc_free(mem_ctx);
799 * Do a ReqChallenge/Auth2 and get the wks creds
802 static bool auth2(struct smbcli_state *cli,
803 struct cli_credentials *wks_cred)
806 struct dcerpc_pipe *net_pipe;
809 struct netr_ServerReqChallenge r;
810 struct netr_Credential netr_cli_creds;
811 struct netr_Credential netr_srv_creds;
812 uint32_t negotiate_flags;
813 struct netr_ServerAuthenticate2 a;
814 struct creds_CredentialState *creds_state;
815 struct netr_Credential netr_cred;
816 struct samr_Password mach_pw;
818 mem_ctx = talloc_new(NULL);
819 if (mem_ctx == NULL) {
820 d_printf("talloc_new failed\n");
824 net_pipe = dcerpc_pipe_init(mem_ctx,
825 cli->transport->socket->event.ctx,
826 lp_iconv_convenience(global_loadparm));
827 if (net_pipe == NULL) {
828 d_printf("dcerpc_pipe_init failed\n");
832 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
833 if (!NT_STATUS_IS_OK(status)) {
834 d_printf("dcerpc_pipe_open_smb failed: %s\n",
839 status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon);
840 if (!NT_STATUS_IS_OK(status)) {
841 d_printf("dcerpc_bind_auth_none failed: %s\n",
846 r.in.computer_name = cli_credentials_get_workstation(wks_cred);
847 r.in.server_name = talloc_asprintf(
848 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
849 if (r.in.server_name == NULL) {
850 d_printf("talloc_asprintf failed\n");
853 generate_random_buffer(netr_cli_creds.data,
854 sizeof(netr_cli_creds.data));
855 r.in.credentials = &netr_cli_creds;
856 r.out.credentials = &netr_srv_creds;
858 status = dcerpc_netr_ServerReqChallenge(net_pipe, mem_ctx, &r);
859 if (!NT_STATUS_IS_OK(status)) {
860 d_printf("netr_ServerReqChallenge failed: %s\n",
865 negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
866 E_md4hash(cli_credentials_get_password(wks_cred), mach_pw.hash);
868 creds_state = talloc(mem_ctx, struct creds_CredentialState);
869 creds_client_init(creds_state, r.in.credentials,
870 r.out.credentials, &mach_pw,
871 &netr_cred, negotiate_flags);
873 a.in.server_name = talloc_asprintf(
874 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
875 a.in.account_name = talloc_asprintf(
876 mem_ctx, "%s$", cli_credentials_get_workstation(wks_cred));
877 a.in.computer_name = cli_credentials_get_workstation(wks_cred);
878 a.in.secure_channel_type = SEC_CHAN_WKSTA;
879 a.in.negotiate_flags = &negotiate_flags;
880 a.out.negotiate_flags = &negotiate_flags;
881 a.in.credentials = &netr_cred;
882 a.out.credentials = &netr_cred;
884 status = dcerpc_netr_ServerAuthenticate2(net_pipe, mem_ctx, &a);
885 if (!NT_STATUS_IS_OK(status)) {
886 d_printf("netr_ServerServerAuthenticate2 failed: %s\n",
891 if (!creds_client_check(creds_state, a.out.credentials)) {
892 d_printf("creds_client_check failed\n");
896 cli_credentials_set_netlogon_creds(wks_cred, creds_state);
901 talloc_free(mem_ctx);
906 * Do a couple of schannel protected Netlogon ops: Interactive and Network
907 * login, and change the wks password
910 static bool schan(struct smbcli_state *cli,
911 struct loadparm_context *lp_ctx,
912 struct cli_credentials *wks_creds,
913 struct cli_credentials *user_creds)
918 struct dcerpc_pipe *net_pipe;
921 mem_ctx = talloc_new(NULL);
922 if (mem_ctx == NULL) {
923 d_printf("talloc_new failed\n");
927 net_pipe = dcerpc_pipe_init(mem_ctx,
928 cli->transport->socket->event.ctx,
929 lp_iconv_convenience(lp_ctx));
930 if (net_pipe == NULL) {
931 d_printf("dcerpc_pipe_init failed\n");
935 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
936 if (!NT_STATUS_IS_OK(status)) {
937 d_printf("dcerpc_pipe_open_smb failed: %s\n",
943 net_pipe->conn->flags |= DCERPC_DEBUG_PRINT_IN |
944 DCERPC_DEBUG_PRINT_OUT;
947 net_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL);
948 status = dcerpc_bind_auth(net_pipe, &ndr_table_netlogon,
949 wks_creds, lp_ctx, DCERPC_AUTH_TYPE_SCHANNEL,
950 DCERPC_AUTH_LEVEL_PRIVACY,
953 status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon);
955 if (!NT_STATUS_IS_OK(status)) {
956 d_printf("schannel bind failed: %s\n", nt_errstr(status));
961 for (i=2; i<4; i++) {
963 DATA_BLOB chal, nt_resp, lm_resp, names_blob, session_key;
964 struct creds_CredentialState *creds_state;
965 struct netr_Authenticator netr_auth, netr_auth2;
966 struct netr_NetworkInfo ninfo;
967 struct netr_PasswordInfo pinfo;
968 struct netr_LogonSamLogon r;
970 flags = CLI_CRED_LANMAN_AUTH | CLI_CRED_NTLM_AUTH |
971 CLI_CRED_NTLMv2_AUTH;
973 chal = data_blob_talloc(mem_ctx, NULL, 8);
974 if (chal.data == NULL) {
975 d_printf("data_blob_talloc failed\n");
979 generate_random_buffer(chal.data, chal.length);
980 names_blob = NTLMv2_generate_names_blob(
981 mem_ctx, cli_credentials_get_workstation(user_creds),
982 cli_credentials_get_domain(user_creds));
983 status = cli_credentials_get_ntlm_response(
984 user_creds, mem_ctx, &flags, chal, names_blob,
985 &lm_resp, &nt_resp, NULL, NULL);
986 if (!NT_STATUS_IS_OK(status)) {
987 d_printf("cli_credentials_get_ntlm_response failed:"
988 " %s\n", nt_errstr(status));
992 creds_state = cli_credentials_get_netlogon_creds(wks_creds);
993 creds_client_authenticator(creds_state, &netr_auth);
995 ninfo.identity_info.account_name.string =
996 cli_credentials_get_username(user_creds);
997 ninfo.identity_info.domain_name.string =
998 cli_credentials_get_domain(user_creds);
999 ninfo.identity_info.parameter_control = 0;
1000 ninfo.identity_info.logon_id_low = 0;
1001 ninfo.identity_info.logon_id_high = 0;
1002 ninfo.identity_info.workstation.string =
1003 cli_credentials_get_workstation(user_creds);
1004 memcpy(ninfo.challenge, chal.data, sizeof(ninfo.challenge));
1005 ninfo.nt.length = nt_resp.length;
1006 ninfo.nt.data = nt_resp.data;
1007 ninfo.lm.length = lm_resp.length;
1008 ninfo.lm.data = lm_resp.data;
1010 r.in.server_name = talloc_asprintf(
1011 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1012 ZERO_STRUCT(netr_auth2);
1013 r.in.computer_name =
1014 cli_credentials_get_workstation(wks_creds);
1015 r.in.credential = &netr_auth;
1016 r.in.return_authenticator = &netr_auth2;
1017 r.in.logon_level = 2;
1018 r.in.validation_level = i;
1019 r.in.logon.network = &ninfo;
1020 r.out.return_authenticator = NULL;
1022 status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r);
1023 if (!NT_STATUS_IS_OK(status)) {
1024 d_printf("netr_LogonSamLogon failed: %s\n",
1029 if ((r.out.return_authenticator == NULL) ||
1030 (!creds_client_check(creds_state,
1031 &r.out.return_authenticator->cred))) {
1032 d_printf("Credentials check failed!\n");
1036 creds_client_authenticator(creds_state, &netr_auth);
1038 pinfo.identity_info = ninfo.identity_info;
1039 ZERO_STRUCT(pinfo.lmpassword.hash);
1040 E_md4hash(cli_credentials_get_password(user_creds),
1041 pinfo.ntpassword.hash);
1042 session_key = data_blob_talloc(mem_ctx,
1043 creds_state->session_key, 16);
1044 arcfour_crypt_blob(pinfo.ntpassword.hash,
1045 sizeof(pinfo.ntpassword.hash),
1048 r.in.logon_level = 1;
1049 r.in.logon.password = &pinfo;
1050 r.out.return_authenticator = NULL;
1052 status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r);
1053 if (!NT_STATUS_IS_OK(status)) {
1054 d_printf("netr_LogonSamLogon failed: %s\n",
1059 if ((r.out.return_authenticator == NULL) ||
1060 (!creds_client_check(creds_state,
1061 &r.out.return_authenticator->cred))) {
1062 d_printf("Credentials check failed!\n");
1068 struct netr_ServerPasswordSet s;
1069 char *password = generate_random_str(wks_creds, 8);
1070 struct creds_CredentialState *creds_state;
1072 s.in.server_name = talloc_asprintf(
1073 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1074 s.in.computer_name = cli_credentials_get_workstation(wks_creds);
1075 s.in.account_name = talloc_asprintf(
1076 mem_ctx, "%s$", s.in.computer_name);
1077 s.in.secure_channel_type = SEC_CHAN_WKSTA;
1078 E_md4hash(password, s.in.new_password.hash);
1080 creds_state = cli_credentials_get_netlogon_creds(wks_creds);
1081 creds_des_encrypt(creds_state, &s.in.new_password);
1082 creds_client_authenticator(creds_state, &s.in.credential);
1084 status = dcerpc_netr_ServerPasswordSet(net_pipe, mem_ctx, &s);
1085 if (!NT_STATUS_IS_OK(status)) {
1086 printf("ServerPasswordSet - %s\n", nt_errstr(status));
1090 if (!creds_client_check(creds_state,
1091 &s.out.return_authenticator.cred)) {
1092 printf("Credential chaining failed\n");
1095 cli_credentials_set_password(wks_creds, password,
1101 talloc_free(mem_ctx);
1106 * Delete the wks account again
1109 static bool leave(struct smbcli_state *cli,
1110 struct loadparm_context *lp_ctx,
1111 struct cli_credentials *admin_creds,
1112 struct cli_credentials *wks_creds)
1114 char *wks_name = talloc_asprintf(
1115 NULL, "%s$", cli_credentials_get_workstation(wks_creds));
1118 ret = delete_user(cli, lp_ctx, admin_creds, wks_name);
1119 talloc_free(wks_name);
1124 * Test the Samba3 DC code a bit. Join, do some schan netlogon ops, leave
1127 bool torture_netlogon_samba3(struct torture_context *torture)
1129 TALLOC_CTX *mem_ctx;
1132 struct smbcli_state *cli;
1133 struct cli_credentials *anon_creds;
1134 struct cli_credentials *wks_creds;
1135 const char *wks_name;
1138 wks_name = torture_setting_string(torture, "wksname", NULL);
1139 if (wks_name == NULL) {
1140 wks_name = get_myname();
1143 mem_ctx = talloc_init("torture_netlogon_samba3");
1145 if (mem_ctx == NULL) {
1146 d_printf("talloc_init failed\n");
1150 if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) {
1151 d_printf("create_anon_creds failed\n");
1155 status = smbcli_full_connection(mem_ctx, &cli,
1156 torture_setting_string(torture, "host", NULL),
1157 lp_smb_ports(torture->lp_ctx),
1158 "IPC$", NULL, anon_creds,
1159 lp_resolve_context(torture->lp_ctx),
1161 if (!NT_STATUS_IS_OK(status)) {
1162 d_printf("smbcli_full_connection failed: %s\n",
1167 wks_creds = cli_credentials_init(mem_ctx);
1168 if (wks_creds == NULL) {
1169 d_printf("cli_credentials_init failed\n");
1173 cli_credentials_set_conf(wks_creds, torture->lp_ctx);
1174 cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1175 cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1176 cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1177 cli_credentials_set_password(wks_creds,
1178 generate_random_str(wks_creds, 8),
1181 if (!join3(cli, torture->lp_ctx, false, cmdline_credentials, wks_creds)) {
1182 d_printf("join failed\n");
1186 cli_credentials_set_domain(
1187 cmdline_credentials, cli_credentials_get_domain(wks_creds),
1190 for (i=0; i<2; i++) {
1192 /* Do this more than once, the routine "schan" changes
1193 * the workstation password using the netlogon
1194 * password change routine */
1198 if (!auth2(cli, wks_creds)) {
1199 d_printf("auth2 failed\n");
1203 for (j=0; j<2; j++) {
1204 if (!schan(cli, torture->lp_ctx, wks_creds, cmdline_credentials)) {
1205 d_printf("schan failed\n");
1211 if (!leave(cli, torture->lp_ctx, cmdline_credentials, wks_creds)) {
1212 d_printf("leave failed\n");
1219 talloc_free(mem_ctx);
1224 * Do a simple join, testjoin and leave using specified smb and samr
1228 static bool test_join3(struct torture_context *tctx,
1230 struct cli_credentials *smb_creds,
1231 struct cli_credentials *samr_creds,
1232 const char *wks_name)
1236 struct smbcli_state *cli;
1237 struct cli_credentials *wks_creds;
1239 status = smbcli_full_connection(tctx, &cli,
1240 torture_setting_string(tctx, "host", NULL),
1241 lp_smb_ports(tctx->lp_ctx),
1242 "IPC$", NULL, smb_creds,
1243 lp_resolve_context(tctx->lp_ctx),
1245 if (!NT_STATUS_IS_OK(status)) {
1246 d_printf("smbcli_full_connection failed: %s\n",
1251 wks_creds = cli_credentials_init(cli);
1252 if (wks_creds == NULL) {
1253 d_printf("cli_credentials_init failed\n");
1257 cli_credentials_set_conf(wks_creds, tctx->lp_ctx);
1258 cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1259 cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1260 cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1261 cli_credentials_set_password(wks_creds,
1262 generate_random_str(wks_creds, 8),
1265 if (!join3(cli, tctx->lp_ctx, use_level25, samr_creds, wks_creds)) {
1266 d_printf("join failed\n");
1270 cli_credentials_set_domain(
1271 cmdline_credentials, cli_credentials_get_domain(wks_creds),
1274 if (!auth2(cli, wks_creds)) {
1275 d_printf("auth2 failed\n");
1279 if (!leave(cli, tctx->lp_ctx, samr_creds, wks_creds)) {
1280 d_printf("leave failed\n");
1293 * Test the different session key variants. Do it by joining, this uses the
1294 * session key in the setpassword routine. Test the join by doing the auth2.
1297 bool torture_samba3_sessionkey(struct torture_context *torture)
1300 struct cli_credentials *anon_creds;
1301 const char *wks_name;
1303 wks_name = torture_setting_string(torture, "wksname", get_myname());
1305 if (!(anon_creds = cli_credentials_init_anon(torture))) {
1306 d_printf("create_anon_creds failed\n");
1312 if (!torture_setting_bool(torture, "samba3", false)) {
1314 /* Samba3 in the build farm right now does this happily. Need
1317 if (test_join3(torture, false, anon_creds, NULL, wks_name)) {
1318 d_printf("join using anonymous bind on an anonymous smb "
1319 "connection succeeded -- HUH??\n");
1324 if (!test_join3(torture, false, anon_creds, cmdline_credentials,
1326 d_printf("join using ntlmssp bind on an anonymous smb "
1327 "connection failed\n");
1331 if (!test_join3(torture, false, cmdline_credentials, NULL, wks_name)) {
1332 d_printf("join using anonymous bind on an authenticated smb "
1333 "connection failed\n");
1337 if (!test_join3(torture, false, cmdline_credentials,
1338 cmdline_credentials,
1340 d_printf("join using ntlmssp bind on an authenticated smb "
1341 "connection failed\n");
1346 * The following two are tests for setuserinfolevel 25
1349 if (!test_join3(torture, true, anon_creds, cmdline_credentials,
1351 d_printf("join using ntlmssp bind on an anonymous smb "
1352 "connection failed\n");
1356 if (!test_join3(torture, true, cmdline_credentials, NULL, wks_name)) {
1357 d_printf("join using anonymous bind on an authenticated smb "
1358 "connection failed\n");
1368 * open pipe and bind, given an IPC$ context
1371 static NTSTATUS pipe_bind_smb(TALLOC_CTX *mem_ctx,
1372 struct smbcli_tree *tree,
1373 const char *pipe_name,
1374 const struct ndr_interface_table *iface,
1375 struct dcerpc_pipe **p)
1377 struct dcerpc_pipe *result;
1380 if (!(result = dcerpc_pipe_init(
1381 mem_ctx, tree->session->transport->socket->event.ctx,
1382 lp_iconv_convenience(global_loadparm)))) {
1383 return NT_STATUS_NO_MEMORY;
1386 status = dcerpc_pipe_open_smb(result, tree, pipe_name);
1387 if (!NT_STATUS_IS_OK(status)) {
1388 d_printf("dcerpc_pipe_open_smb failed: %s\n",
1390 talloc_free(result);
1394 status = dcerpc_bind_auth_none(result, iface);
1395 if (!NT_STATUS_IS_OK(status)) {
1396 d_printf("schannel bind failed: %s\n", nt_errstr(status));
1397 talloc_free(result);
1402 return NT_STATUS_OK;
1406 * Sane wrapper around lsa_LookupNames
1409 static struct dom_sid *name2sid(TALLOC_CTX *mem_ctx,
1410 struct dcerpc_pipe *p,
1414 struct lsa_ObjectAttribute attr;
1415 struct lsa_QosInfo qos;
1416 struct lsa_OpenPolicy2 r;
1419 struct policy_handle handle;
1420 struct lsa_LookupNames l;
1421 struct lsa_TransSidArray sids;
1422 struct lsa_String lsa_name;
1424 struct dom_sid *result;
1425 TALLOC_CTX *tmp_ctx;
1427 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1432 qos.impersonation_level = 2;
1433 qos.context_mode = 1;
1434 qos.effective_only = 0;
1437 attr.root_dir = NULL;
1438 attr.object_name = NULL;
1439 attr.attributes = 0;
1440 attr.sec_desc = NULL;
1441 attr.sec_qos = &qos;
1443 r.in.system_name = "\\";
1445 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1446 r.out.handle = &handle;
1448 status = dcerpc_lsa_OpenPolicy2(p, tmp_ctx, &r);
1449 if (!NT_STATUS_IS_OK(status)) {
1450 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
1451 talloc_free(tmp_ctx);
1458 lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, name);
1460 l.in.handle = &handle;
1462 l.in.names = &lsa_name;
1465 l.in.count = &count;
1466 l.out.count = &count;
1469 status = dcerpc_lsa_LookupNames(p, tmp_ctx, &l);
1470 if (!NT_STATUS_IS_OK(status)) {
1471 printf("LookupNames of %s failed - %s\n", lsa_name.string,
1473 talloc_free(tmp_ctx);
1477 result = dom_sid_add_rid(mem_ctx, l.out.domains->domains[0].sid,
1478 l.out.sids->sids[0].rid);
1480 c.in.handle = &handle;
1481 c.out.handle = &handle;
1483 status = dcerpc_lsa_Close(p, tmp_ctx, &c);
1484 if (!NT_STATUS_IS_OK(status)) {
1485 printf("dcerpc_lsa_Close failed - %s\n", nt_errstr(status));
1486 talloc_free(tmp_ctx);
1490 talloc_free(tmp_ctx);
1495 * Find out the user SID on this connection
1498 static struct dom_sid *whoami(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree)
1500 struct dcerpc_pipe *lsa;
1501 struct lsa_GetUserName r;
1503 struct lsa_StringPointer authority_name_p;
1504 struct dom_sid *result;
1506 status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\lsarpc",
1507 &ndr_table_lsarpc, &lsa);
1508 if (!NT_STATUS_IS_OK(status)) {
1509 d_printf("(%s) Could not bind to LSA: %s\n",
1510 __location__, nt_errstr(status));
1514 r.in.system_name = "\\";
1515 r.in.account_name = NULL;
1516 authority_name_p.string = NULL;
1517 r.in.authority_name = &authority_name_p;
1519 status = dcerpc_lsa_GetUserName(lsa, mem_ctx, &r);
1521 if (!NT_STATUS_IS_OK(status)) {
1522 printf("(%s) GetUserName failed - %s\n",
1523 __location__, nt_errstr(status));
1528 result = name2sid(mem_ctx, lsa, r.out.account_name->string,
1529 r.out.authority_name->string->string);
1535 static int destroy_tree(struct smbcli_tree *tree)
1537 smb_tree_disconnect(tree);
1542 * Do a tcon, given a session
1545 NTSTATUS secondary_tcon(TALLOC_CTX *mem_ctx,
1546 struct smbcli_session *session,
1547 const char *sharename,
1548 struct smbcli_tree **res)
1550 struct smbcli_tree *result;
1551 TALLOC_CTX *tmp_ctx;
1552 union smb_tcon tcon;
1555 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1556 return NT_STATUS_NO_MEMORY;
1559 if (!(result = smbcli_tree_init(session, mem_ctx, false))) {
1560 talloc_free(tmp_ctx);
1561 return NT_STATUS_NO_MEMORY;
1564 tcon.generic.level = RAW_TCON_TCONX;
1565 tcon.tconx.in.flags = 0;
1566 tcon.tconx.in.password = data_blob(NULL, 0);
1567 tcon.tconx.in.path = sharename;
1568 tcon.tconx.in.device = "?????";
1570 status = smb_raw_tcon(result, tmp_ctx, &tcon);
1571 if (!NT_STATUS_IS_OK(status)) {
1572 d_printf("(%s) smb_raw_tcon failed: %s\n", __location__,
1574 talloc_free(tmp_ctx);
1578 result->tid = tcon.tconx.out.tid;
1579 result = talloc_steal(mem_ctx, result);
1580 talloc_set_destructor(result, destroy_tree);
1581 talloc_free(tmp_ctx);
1583 return NT_STATUS_OK;
1587 * Test the getusername behaviour
1590 bool torture_samba3_rpc_getusername(struct torture_context *torture)
1593 struct smbcli_state *cli;
1594 TALLOC_CTX *mem_ctx;
1596 struct dom_sid *user_sid;
1597 struct dom_sid *created_sid;
1598 struct cli_credentials *anon_creds;
1599 struct cli_credentials *user_creds;
1602 if (!(mem_ctx = talloc_new(torture))) {
1606 status = smbcli_full_connection(
1607 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1608 lp_smb_ports(torture->lp_ctx),
1609 "IPC$", NULL, cmdline_credentials,
1610 lp_resolve_context(torture->lp_ctx),
1612 if (!NT_STATUS_IS_OK(status)) {
1613 d_printf("(%s) smbcli_full_connection failed: %s\n",
1614 __location__, nt_errstr(status));
1619 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
1620 d_printf("(%s) whoami on auth'ed connection failed\n",
1627 if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) {
1628 d_printf("(%s) create_anon_creds failed\n", __location__);
1633 status = smbcli_full_connection(
1634 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1635 lp_smb_ports(torture->lp_ctx),
1636 "IPC$", NULL, anon_creds,
1637 lp_resolve_context(torture->lp_ctx),
1639 if (!NT_STATUS_IS_OK(status)) {
1640 d_printf("(%s) anon smbcli_full_connection failed: %s\n",
1641 __location__, nt_errstr(status));
1646 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
1647 d_printf("(%s) whoami on anon connection failed\n",
1653 if (!dom_sid_equal(user_sid,
1654 dom_sid_parse_talloc(mem_ctx, "s-1-5-7"))) {
1655 d_printf("(%s) Anon lsa_GetUserName returned %s, expected "
1656 "S-1-5-7", __location__,
1657 dom_sid_string(mem_ctx, user_sid));
1661 if (!(user_creds = cli_credentials_init(mem_ctx))) {
1662 d_printf("(%s) cli_credentials_init failed\n", __location__);
1667 cli_credentials_set_conf(user_creds, torture->lp_ctx);
1668 cli_credentials_set_username(user_creds, "torture_username",
1670 cli_credentials_set_password(user_creds,
1671 generate_random_str(user_creds, 8),
1674 if (!create_user(mem_ctx, cli, torture->lp_ctx, cmdline_credentials,
1675 cli_credentials_get_username(user_creds),
1676 cli_credentials_get_password(user_creds),
1677 &domain_name, &created_sid)) {
1678 d_printf("(%s) create_user failed\n", __location__);
1683 cli_credentials_set_domain(user_creds, domain_name,
1687 struct smbcli_session *session2;
1688 struct smb_composite_sesssetup setup;
1689 struct smbcli_tree *tree;
1691 session2 = smbcli_session_init(cli->transport, mem_ctx, false);
1692 if (session2 == NULL) {
1693 d_printf("(%s) smbcli_session_init failed\n",
1698 setup.in.sesskey = cli->transport->negotiate.sesskey;
1699 setup.in.capabilities = cli->transport->negotiate.capabilities;
1700 setup.in.workgroup = "";
1701 setup.in.credentials = user_creds;
1703 status = smb_composite_sesssetup(session2, &setup);
1704 if (!NT_STATUS_IS_OK(status)) {
1705 d_printf("(%s) session setup with new user failed: "
1706 "%s\n", __location__, nt_errstr(status));
1710 session2->vuid = setup.out.vuid;
1712 if (!NT_STATUS_IS_OK(secondary_tcon(mem_ctx, session2,
1714 d_printf("(%s) secondary_tcon failed\n",
1720 if (!(user_sid = whoami(mem_ctx, tree))) {
1721 d_printf("(%s) whoami on user connection failed\n",
1730 d_printf("Created %s, found %s\n",
1731 dom_sid_string(mem_ctx, created_sid),
1732 dom_sid_string(mem_ctx, user_sid));
1734 if (!dom_sid_equal(created_sid, user_sid)) {
1739 if (!delete_user(cli, torture->lp_ctx,
1740 cmdline_credentials,
1741 cli_credentials_get_username(user_creds))) {
1742 d_printf("(%s) delete_user failed\n", __location__);
1747 talloc_free(mem_ctx);
1751 static bool test_NetShareGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1752 const char *sharename)
1755 struct srvsvc_NetShareGetInfo r;
1756 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007, 1501 };
1760 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s",
1761 dcerpc_server_name(p));
1762 r.in.share_name = sharename;
1764 for (i=0;i<ARRAY_SIZE(levels);i++) {
1765 r.in.level = levels[i];
1769 printf("testing NetShareGetInfo level %u on share '%s'\n",
1770 r.in.level, r.in.share_name);
1772 status = dcerpc_srvsvc_NetShareGetInfo(p, mem_ctx, &r);
1773 if (!NT_STATUS_IS_OK(status)) {
1774 printf("NetShareGetInfo level %u on share '%s' failed"
1775 " - %s\n", r.in.level, r.in.share_name,
1780 if (!W_ERROR_IS_OK(r.out.result)) {
1781 printf("NetShareGetInfo level %u on share '%s' failed "
1782 "- %s\n", r.in.level, r.in.share_name,
1783 win_errstr(r.out.result));
1792 static bool test_NetShareEnum(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1793 const char **one_sharename)
1796 struct srvsvc_NetShareEnum r;
1797 struct srvsvc_NetShareCtr0 c0;
1798 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007 };
1802 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
1803 r.in.ctr.ctr0 = &c0;
1804 r.in.ctr.ctr0->count = 0;
1805 r.in.ctr.ctr0->array = NULL;
1806 r.in.max_buffer = (uint32_t)-1;
1807 r.in.resume_handle = NULL;
1809 for (i=0;i<ARRAY_SIZE(levels);i++) {
1810 r.in.level = levels[i];
1814 printf("testing NetShareEnum level %u\n", r.in.level);
1815 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r);
1816 if (!NT_STATUS_IS_OK(status)) {
1817 printf("NetShareEnum level %u failed - %s\n",
1818 r.in.level, nt_errstr(status));
1822 if (!W_ERROR_IS_OK(r.out.result)) {
1823 printf("NetShareEnum level %u failed - %s\n",
1824 r.in.level, win_errstr(r.out.result));
1827 if (r.in.level == 0) {
1828 struct srvsvc_NetShareCtr0 *ctr = r.out.ctr.ctr0;
1829 if (ctr->count > 0) {
1830 *one_sharename = ctr->array[0].name;
1838 bool torture_samba3_rpc_srvsvc(struct torture_context *torture)
1840 struct dcerpc_pipe *p;
1841 TALLOC_CTX *mem_ctx;
1843 const char *sharename = NULL;
1844 struct smbcli_state *cli;
1847 if (!(mem_ctx = talloc_new(torture))) {
1851 if (!(torture_open_connection_share(
1852 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
1854 talloc_free(mem_ctx);
1858 status = pipe_bind_smb(mem_ctx, cli->tree, "\\pipe\\srvsvc",
1859 &ndr_table_srvsvc, &p);
1860 if (!NT_STATUS_IS_OK(status)) {
1861 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1862 __location__, nt_errstr(status));
1867 ret &= test_NetShareEnum(p, mem_ctx, &sharename);
1868 if (sharename == NULL) {
1869 printf("did not get sharename\n");
1871 ret &= test_NetShareGetInfo(p, mem_ctx, sharename);
1875 talloc_free(mem_ctx);
1880 * Do a ReqChallenge/Auth2 with a random wks name, make sure it returns
1881 * NT_STATUS_NO_SAM_ACCOUNT
1884 bool torture_samba3_rpc_randomauth2(struct torture_context *torture)
1886 TALLOC_CTX *mem_ctx;
1887 struct dcerpc_pipe *net_pipe;
1889 bool result = false;
1891 struct netr_ServerReqChallenge r;
1892 struct netr_Credential netr_cli_creds;
1893 struct netr_Credential netr_srv_creds;
1894 uint32_t negotiate_flags;
1895 struct netr_ServerAuthenticate2 a;
1896 struct creds_CredentialState *creds_state;
1897 struct netr_Credential netr_cred;
1898 struct samr_Password mach_pw;
1899 struct smbcli_state *cli;
1901 if (!(mem_ctx = talloc_new(torture))) {
1902 d_printf("talloc_new failed\n");
1906 if (!(wksname = generate_random_str_list(
1907 mem_ctx, 14, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"))) {
1908 d_printf("generate_random_str_list failed\n");
1912 if (!(torture_open_connection_share(
1914 torture, torture_setting_string(torture, "host", NULL),
1916 d_printf("IPC$ connection failed\n");
1920 if (!(net_pipe = dcerpc_pipe_init(
1921 mem_ctx, cli->transport->socket->event.ctx,
1922 lp_iconv_convenience(torture->lp_ctx)))) {
1923 d_printf("dcerpc_pipe_init failed\n");
1927 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
1928 if (!NT_STATUS_IS_OK(status)) {
1929 d_printf("dcerpc_pipe_open_smb failed: %s\n",
1934 status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon);
1935 if (!NT_STATUS_IS_OK(status)) {
1936 d_printf("dcerpc_bind_auth_none failed: %s\n",
1941 r.in.computer_name = wksname;
1942 r.in.server_name = talloc_asprintf(
1943 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1944 if (r.in.server_name == NULL) {
1945 d_printf("talloc_asprintf failed\n");
1948 generate_random_buffer(netr_cli_creds.data,
1949 sizeof(netr_cli_creds.data));
1950 r.in.credentials = &netr_cli_creds;
1951 r.out.credentials = &netr_srv_creds;
1953 status = dcerpc_netr_ServerReqChallenge(net_pipe, mem_ctx, &r);
1954 if (!NT_STATUS_IS_OK(status)) {
1955 d_printf("netr_ServerReqChallenge failed: %s\n",
1960 negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
1961 E_md4hash("foobar", mach_pw.hash);
1963 creds_state = talloc(mem_ctx, struct creds_CredentialState);
1964 creds_client_init(creds_state, r.in.credentials,
1965 r.out.credentials, &mach_pw,
1966 &netr_cred, negotiate_flags);
1968 a.in.server_name = talloc_asprintf(
1969 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1970 a.in.account_name = talloc_asprintf(
1971 mem_ctx, "%s$", wksname);
1972 a.in.computer_name = wksname;
1973 a.in.secure_channel_type = SEC_CHAN_WKSTA;
1974 a.in.negotiate_flags = &negotiate_flags;
1975 a.out.negotiate_flags = &negotiate_flags;
1976 a.in.credentials = &netr_cred;
1977 a.out.credentials = &netr_cred;
1979 status = dcerpc_netr_ServerAuthenticate2(net_pipe, mem_ctx, &a);
1981 if (!NT_STATUS_EQUAL(status, NT_STATUS_NO_TRUST_SAM_ACCOUNT)) {
1982 d_printf("dcerpc_netr_ServerAuthenticate2 returned %s, "
1983 "expected NT_STATUS_NO_TRUST_SAM_ACCOUNT\n",
1990 talloc_free(mem_ctx);
1994 static struct security_descriptor *get_sharesec(TALLOC_CTX *mem_ctx,
1995 struct smbcli_session *sess,
1996 const char *sharename)
1998 struct smbcli_tree *tree;
1999 TALLOC_CTX *tmp_ctx;
2000 struct dcerpc_pipe *p;
2002 struct srvsvc_NetShareGetInfo r;
2003 struct security_descriptor *result;
2005 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2006 d_printf("talloc_new failed\n");
2010 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) {
2011 d_printf("secondary_tcon failed\n");
2012 talloc_free(tmp_ctx);
2016 status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\srvsvc",
2017 &ndr_table_srvsvc, &p);
2018 if (!NT_STATUS_IS_OK(status)) {
2019 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
2020 __location__, nt_errstr(status));
2021 talloc_free(tmp_ctx);
2026 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2029 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
2030 dcerpc_server_name(p));
2031 r.in.share_name = sharename;
2034 status = dcerpc_srvsvc_NetShareGetInfo(p, tmp_ctx, &r);
2035 if (!NT_STATUS_IS_OK(status)) {
2036 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
2038 talloc_free(tmp_ctx);
2042 result = talloc_steal(mem_ctx, r.out.info.info502->sd);
2043 talloc_free(tmp_ctx);
2047 static NTSTATUS set_sharesec(TALLOC_CTX *mem_ctx,
2048 struct smbcli_session *sess,
2049 const char *sharename,
2050 struct security_descriptor *sd)
2052 struct smbcli_tree *tree;
2053 TALLOC_CTX *tmp_ctx;
2054 struct dcerpc_pipe *p;
2056 struct sec_desc_buf i;
2057 struct srvsvc_NetShareSetInfo r;
2060 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2061 d_printf("talloc_new failed\n");
2062 return NT_STATUS_NO_MEMORY;
2065 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) {
2066 d_printf("secondary_tcon failed\n");
2067 talloc_free(tmp_ctx);
2068 return NT_STATUS_UNSUCCESSFUL;
2071 status = pipe_bind_smb(mem_ctx, tree, "\\pipe\\srvsvc",
2072 &ndr_table_srvsvc, &p);
2073 if (!NT_STATUS_IS_OK(status)) {
2074 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
2075 __location__, nt_errstr(status));
2076 talloc_free(tmp_ctx);
2077 return NT_STATUS_UNSUCCESSFUL;
2081 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2084 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
2085 dcerpc_server_name(p));
2086 r.in.share_name = sharename;
2089 r.in.info.info1501 = &i;
2090 r.in.parm_error = &error;
2092 status = dcerpc_srvsvc_NetShareSetInfo(p, tmp_ctx, &r);
2093 if (!NT_STATUS_IS_OK(status)) {
2094 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
2098 talloc_free(tmp_ctx);
2102 bool try_tcon(TALLOC_CTX *mem_ctx,
2103 struct security_descriptor *orig_sd,
2104 struct smbcli_session *session,
2105 const char *sharename, const struct dom_sid *user_sid,
2106 unsigned int access_mask, NTSTATUS expected_tcon,
2107 NTSTATUS expected_mkdir)
2109 TALLOC_CTX *tmp_ctx;
2110 struct smbcli_tree *rmdir_tree, *tree;
2111 struct dom_sid *domain_sid;
2113 struct security_descriptor *sd;
2117 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2118 d_printf("talloc_new failed\n");
2122 status = secondary_tcon(tmp_ctx, session, sharename, &rmdir_tree);
2123 if (!NT_STATUS_IS_OK(status)) {
2124 d_printf("first tcon to delete dir failed\n");
2125 talloc_free(tmp_ctx);
2129 smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2131 if (!NT_STATUS_IS_OK(dom_sid_split_rid(tmp_ctx, user_sid,
2132 &domain_sid, &rid))) {
2133 d_printf("dom_sid_split_rid failed\n");
2134 talloc_free(tmp_ctx);
2138 sd = security_descriptor_dacl_create(
2139 tmp_ctx, 0, "S-1-5-32-544",
2140 dom_sid_string(mem_ctx, dom_sid_add_rid(mem_ctx, domain_sid,
2142 dom_sid_string(mem_ctx, user_sid),
2143 SEC_ACE_TYPE_ACCESS_ALLOWED, access_mask, 0, NULL);
2145 d_printf("security_descriptor_dacl_create failed\n");
2146 talloc_free(tmp_ctx);
2150 status = set_sharesec(mem_ctx, session, sharename, sd);
2151 if (!NT_STATUS_IS_OK(status)) {
2152 d_printf("custom set_sharesec failed: %s\n",
2154 talloc_free(tmp_ctx);
2158 status = secondary_tcon(tmp_ctx, session, sharename, &tree);
2159 if (!NT_STATUS_EQUAL(status, expected_tcon)) {
2160 d_printf("Expected %s, got %s\n", nt_errstr(expected_tcon),
2166 if (!NT_STATUS_IS_OK(status)) {
2167 /* An expected non-access, no point in trying to write */
2171 status = smbcli_mkdir(tree, "sharesec_testdir");
2172 if (!NT_STATUS_EQUAL(status, expected_mkdir)) {
2173 d_printf("(%s) Expected %s, got %s\n", __location__,
2174 nt_errstr(expected_mkdir), nt_errstr(status));
2179 smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2181 status = set_sharesec(mem_ctx, session, sharename, orig_sd);
2182 if (!NT_STATUS_IS_OK(status)) {
2183 d_printf("custom set_sharesec failed: %s\n",
2185 talloc_free(tmp_ctx);
2189 talloc_free(tmp_ctx);
2193 bool torture_samba3_rpc_sharesec(struct torture_context *torture)
2195 TALLOC_CTX *mem_ctx;
2197 struct smbcli_state *cli;
2198 struct security_descriptor *sd;
2199 struct dom_sid *user_sid;
2201 if (!(mem_ctx = talloc_new(torture))) {
2205 if (!(torture_open_connection_share(
2206 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
2208 d_printf("IPC$ connection failed\n");
2209 talloc_free(mem_ctx);
2213 if (!(user_sid = whoami(mem_ctx, cli->tree))) {
2214 d_printf("whoami failed\n");
2215 talloc_free(mem_ctx);
2219 sd = get_sharesec(mem_ctx, cli->session, torture_setting_string(torture,
2222 ret &= try_tcon(mem_ctx, sd, cli->session,
2223 torture_setting_string(torture, "share", NULL),
2224 user_sid, 0, NT_STATUS_ACCESS_DENIED, NT_STATUS_OK);
2226 ret &= try_tcon(mem_ctx, sd, cli->session,
2227 torture_setting_string(torture, "share", NULL),
2228 user_sid, SEC_FILE_READ_DATA, NT_STATUS_OK,
2229 NT_STATUS_MEDIA_WRITE_PROTECTED);
2231 ret &= try_tcon(mem_ctx, sd, cli->session,
2232 torture_setting_string(torture, "share", NULL),
2233 user_sid, SEC_FILE_ALL, NT_STATUS_OK, NT_STATUS_OK);
2235 talloc_free(mem_ctx);
2239 bool torture_samba3_rpc_lsa(struct torture_context *torture)
2241 TALLOC_CTX *mem_ctx;
2243 struct smbcli_state *cli;
2244 struct dcerpc_pipe *p;
2245 struct policy_handle lsa_handle;
2247 struct dom_sid *domain_sid;
2249 if (!(mem_ctx = talloc_new(torture))) {
2253 if (!(torture_open_connection_share(
2254 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
2256 d_printf("IPC$ connection failed\n");
2257 talloc_free(mem_ctx);
2261 status = pipe_bind_smb(mem_ctx, cli->tree, "\\lsarpc",
2262 &ndr_table_lsarpc, &p);
2263 if (!NT_STATUS_IS_OK(status)) {
2264 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2266 talloc_free(mem_ctx);
2271 struct lsa_ObjectAttribute attr;
2272 struct lsa_OpenPolicy2 o;
2273 o.in.system_name = talloc_asprintf(
2274 mem_ctx, "\\\\%s", dcerpc_server_name(p));
2277 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2278 o.out.handle = &lsa_handle;
2279 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &o);
2280 if (!NT_STATUS_IS_OK(status)) {
2281 d_printf("(%s) dcerpc_lsa_OpenPolicy2 failed: %s\n",
2282 __location__, nt_errstr(status));
2283 talloc_free(mem_ctx);
2289 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2294 int levels[] = { 2,3,5,6 };
2296 for (i=0; i<ARRAY_SIZE(levels); i++) {
2297 struct lsa_QueryInfoPolicy r;
2298 r.in.handle = &lsa_handle;
2299 r.in.level = levels[i];
2300 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
2301 if (!NT_STATUS_IS_OK(status)) {
2302 d_printf("(%s) dcerpc_lsa_QueryInfoPolicy %d "
2303 "failed: %s\n", __location__,
2304 levels[i], nt_errstr(status));
2305 talloc_free(mem_ctx);
2308 if (levels[i] == 5) {
2309 domain_sid = r.out.info->account_domain.sid;
2317 static NTSTATUS get_servername(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree,
2320 struct rap_WserverGetInfo r;
2322 char servername[17];
2325 r.in.bufsize = 0xffff;
2327 status = smbcli_rap_netservergetinfo(tree, mem_ctx, &r);
2328 if (!NT_STATUS_IS_OK(status)) {
2332 memcpy(servername, r.out.info.info0.name, 16);
2333 servername[16] = '\0';
2335 if (pull_ascii_talloc(mem_ctx, lp_iconv_convenience(global_loadparm),
2336 name, servername) < 0) {
2337 return NT_STATUS_NO_MEMORY;
2340 return NT_STATUS_OK;
2344 static NTSTATUS find_printers(TALLOC_CTX *ctx, struct smbcli_tree *tree,
2345 const char ***printers, int *num_printers)
2347 TALLOC_CTX *mem_ctx;
2349 struct dcerpc_pipe *p;
2350 struct srvsvc_NetShareEnum r;
2351 struct srvsvc_NetShareCtr1 c1_in;
2352 struct srvsvc_NetShareCtr1 *c1;
2355 mem_ctx = talloc_new(ctx);
2356 if (mem_ctx == NULL) {
2357 return NT_STATUS_NO_MEMORY;
2360 status = pipe_bind_smb(mem_ctx, tree, "\\srvsvc", &ndr_table_srvsvc,
2362 if (!NT_STATUS_IS_OK(status)) {
2363 d_printf("could not bind to srvsvc pipe\n");
2364 talloc_free(mem_ctx);
2368 r.in.server_unc = talloc_asprintf(
2369 mem_ctx, "\\\\%s", dcerpc_server_name(p));
2372 r.in.ctr.ctr1 = &c1_in;
2373 r.in.max_buffer = (uint32_t)-1;
2374 r.in.resume_handle = NULL;
2376 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r);
2377 if (!NT_STATUS_IS_OK(status)) {
2378 d_printf("NetShareEnum level %u failed - %s\n",
2379 r.in.level, nt_errstr(status));
2380 talloc_free(mem_ctx);
2386 c1 = r.out.ctr.ctr1;
2387 for (i=0; i<c1->count; i++) {
2388 if (c1->array[i].type != STYPE_PRINTQ) {
2391 if (!add_string_to_array(ctx, c1->array[i].name,
2392 printers, num_printers)) {
2394 return NT_STATUS_NO_MEMORY;
2398 talloc_free(mem_ctx);
2399 return NT_STATUS_OK;
2402 static bool enumprinters(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *pipe,
2403 const char *servername, int level, int *num_printers)
2405 struct spoolss_EnumPrinters r;
2409 r.in.flags = PRINTER_ENUM_LOCAL;
2410 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", servername);
2415 status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
2416 if (!NT_STATUS_IS_OK(status)) {
2417 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s\n",
2418 __location__, nt_errstr(status));
2422 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2423 d_printf("(%s) EnumPrinters unexpected return code %s, should "
2424 "be WERR_INSUFFICIENT_BUFFER\n", __location__,
2425 win_errstr(r.out.result));
2429 blob = data_blob_talloc_zero(mem_ctx, r.out.needed);
2430 if (blob.data == NULL) {
2431 d_printf("(%s) data_blob_talloc failed\n", __location__);
2435 r.in.buffer = &blob;
2436 r.in.offered = r.out.needed;
2438 status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
2439 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2440 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s, "
2441 "%s\n", __location__, nt_errstr(status),
2442 win_errstr(r.out.result));
2446 *num_printers = r.out.count;
2451 static NTSTATUS getprinterinfo(TALLOC_CTX *ctx, struct dcerpc_pipe *pipe,
2452 struct policy_handle *handle, int level,
2453 union spoolss_PrinterInfo **res)
2455 TALLOC_CTX *mem_ctx;
2456 struct spoolss_GetPrinter r;
2460 mem_ctx = talloc_new(ctx);
2461 if (mem_ctx == NULL) {
2462 return NT_STATUS_NO_MEMORY;
2465 r.in.handle = handle;
2470 status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r);
2471 if (!NT_STATUS_IS_OK(status)) {
2472 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s\n",
2473 __location__, nt_errstr(status));
2474 talloc_free(mem_ctx);
2478 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2479 printf("GetPrinter unexpected return code %s, should "
2480 "be WERR_INSUFFICIENT_BUFFER\n",
2481 win_errstr(r.out.result));
2482 talloc_free(mem_ctx);
2483 return NT_STATUS_UNSUCCESSFUL;
2486 r.in.handle = handle;
2488 blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
2489 if (blob.data == NULL) {
2490 talloc_free(mem_ctx);
2491 return NT_STATUS_NO_MEMORY;
2493 memset(blob.data, 0, blob.length);
2494 r.in.buffer = &blob;
2495 r.in.offered = r.out.needed;
2497 status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r);
2498 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2499 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s, "
2500 "%s\n", __location__, nt_errstr(status),
2501 win_errstr(r.out.result));
2502 talloc_free(mem_ctx);
2503 return NT_STATUS_IS_OK(status) ?
2504 NT_STATUS_UNSUCCESSFUL : status;
2508 *res = talloc_steal(ctx, r.out.info);
2511 talloc_free(mem_ctx);
2512 return NT_STATUS_OK;
2515 bool torture_samba3_rpc_spoolss(struct torture_context *torture)
2517 TALLOC_CTX *mem_ctx;
2519 struct smbcli_state *cli;
2520 struct dcerpc_pipe *p;
2522 struct policy_handle server_handle, printer_handle;
2523 const char **printers;
2525 struct spoolss_UserLevel1 userlevel1;
2528 if (!(mem_ctx = talloc_new(torture))) {
2532 if (!(torture_open_connection_share(
2533 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
2535 d_printf("IPC$ connection failed\n");
2536 talloc_free(mem_ctx);
2540 status = get_servername(mem_ctx, cli->tree, &servername);
2541 if (!NT_STATUS_IS_OK(status)) {
2542 d_fprintf(stderr, "(%s) get_servername returned %s\n",
2543 __location__, nt_errstr(status));
2544 talloc_free(mem_ctx);
2548 if (!NT_STATUS_IS_OK(find_printers(mem_ctx, cli->tree,
2549 &printers, &num_printers))) {
2550 talloc_free(mem_ctx);
2554 if (num_printers == 0) {
2555 d_printf("Did not find printers\n");
2556 talloc_free(mem_ctx);
2560 status = pipe_bind_smb(mem_ctx, cli->tree, "\\spoolss",
2561 &ndr_table_spoolss, &p);
2562 if (!NT_STATUS_IS_OK(status)) {
2563 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2565 talloc_free(mem_ctx);
2569 ZERO_STRUCT(userlevel1);
2570 userlevel1.client = talloc_asprintf(
2571 mem_ctx, "\\\\%s", lp_netbios_name(torture->lp_ctx));
2572 userlevel1.user = cli_credentials_get_username(cmdline_credentials);
2573 userlevel1.build = 2600;
2574 userlevel1.major = 3;
2575 userlevel1.minor = 0;
2576 userlevel1.processor = 0;
2579 struct spoolss_OpenPrinterEx r;
2582 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
2584 r.in.datatype = NULL;
2585 r.in.access_mask = 0;
2587 r.in.userlevel.level1 = &userlevel1;
2588 r.out.handle = &server_handle;
2590 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
2591 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2592 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
2593 "%s, %s\n", __location__, nt_errstr(status),
2594 win_errstr(r.out.result));
2595 talloc_free(mem_ctx);
2601 struct spoolss_ClosePrinter r;
2603 r.in.handle = &server_handle;
2604 r.out.handle = &server_handle;
2606 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
2607 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2608 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
2609 "%s, %s\n", __location__, nt_errstr(status),
2610 win_errstr(r.out.result));
2611 talloc_free(mem_ctx);
2617 struct spoolss_OpenPrinterEx r;
2620 r.in.printername = talloc_asprintf(
2621 mem_ctx, "\\\\%s\\%s", servername, printers[0]);
2622 r.in.datatype = NULL;
2623 r.in.access_mask = 0;
2625 r.in.userlevel.level1 = &userlevel1;
2626 r.out.handle = &printer_handle;
2628 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
2629 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2630 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
2631 "%s, %s\n", __location__, nt_errstr(status),
2632 win_errstr(r.out.result));
2633 talloc_free(mem_ctx);
2641 for (i=0; i<8; i++) {
2642 status = getprinterinfo(mem_ctx, p, &printer_handle,
2644 if (!NT_STATUS_IS_OK(status)) {
2645 d_printf("(%s) getprinterinfo %d failed: %s\n",
2646 __location__, i, nt_errstr(status));
2653 struct spoolss_ClosePrinter r;
2655 r.in.handle = &printer_handle;
2656 r.out.handle = &printer_handle;
2658 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
2659 if (!NT_STATUS_IS_OK(status)) {
2660 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
2661 "%s\n", __location__, nt_errstr(status));
2662 talloc_free(mem_ctx);
2669 if (!enumprinters(mem_ctx, p, servername, 1,
2671 d_printf("(%s) enumprinters failed\n", __location__);
2672 talloc_free(mem_ctx);
2675 if (num_printers != num_enumerated) {
2676 d_printf("(%s) netshareenum gave %d printers, "
2677 "enumprinters lvl 1 gave %d\n", __location__,
2678 num_printers, num_enumerated);
2679 talloc_free(mem_ctx);
2686 if (!enumprinters(mem_ctx, p, servername, 2,
2688 d_printf("(%s) enumprinters failed\n", __location__);
2689 talloc_free(mem_ctx);
2692 if (num_printers != num_enumerated) {
2693 d_printf("(%s) netshareenum gave %d printers, "
2694 "enumprinters lvl 2 gave %d\n", __location__,
2695 num_printers, num_enumerated);
2696 talloc_free(mem_ctx);
2701 talloc_free(mem_ctx);
2706 bool torture_samba3_rpc_wkssvc(struct torture_context *torture)
2708 TALLOC_CTX *mem_ctx;
2709 struct smbcli_state *cli;
2710 struct dcerpc_pipe *p;
2714 if (!(mem_ctx = talloc_new(torture))) {
2718 if (!(torture_open_connection_share(
2719 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
2721 d_printf("IPC$ connection failed\n");
2722 talloc_free(mem_ctx);
2726 status = get_servername(mem_ctx, cli->tree, &servername);
2727 if (!NT_STATUS_IS_OK(status)) {
2728 d_fprintf(stderr, "(%s) get_servername returned %s\n",
2729 __location__, nt_errstr(status));
2730 talloc_free(mem_ctx);
2734 status = pipe_bind_smb(mem_ctx, cli->tree, "\\wkssvc",
2735 &ndr_table_wkssvc, &p);
2736 if (!NT_STATUS_IS_OK(status)) {
2737 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2739 talloc_free(mem_ctx);
2744 struct wkssvc_NetWkstaInfo100 wks100;
2745 union wkssvc_NetWkstaInfo info;
2746 struct wkssvc_NetWkstaGetInfo r;
2748 r.in.server_name = "\\foo";
2750 info.info100 = &wks100;
2753 status = dcerpc_wkssvc_NetWkstaGetInfo(p, mem_ctx, &r);
2754 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2755 d_printf("(%s) dcerpc_wkssvc_NetWksGetInfo failed: "
2756 "%s, %s\n", __location__, nt_errstr(status),
2757 win_errstr(r.out.result));
2758 talloc_free(mem_ctx);
2762 if (strcmp(servername,
2763 r.out.info->info100->server_name) != 0) {
2764 d_printf("(%s) servername inconsistency: RAP=%s, "
2765 "dcerpc_wkssvc_NetWksGetInfo=%s",
2766 __location__, servername,
2767 r.out.info->info100->server_name);
2768 talloc_free(mem_ctx);
2773 talloc_free(mem_ctx);
2777 static NTSTATUS winreg_close(struct dcerpc_pipe *p,
2778 struct policy_handle *handle)
2780 struct winreg_CloseKey c;
2782 TALLOC_CTX *mem_ctx;
2784 c.in.handle = c.out.handle = handle;
2786 if (!(mem_ctx = talloc_new(p))) {
2787 return NT_STATUS_NO_MEMORY;
2790 status = dcerpc_winreg_CloseKey(p, mem_ctx, &c);
2791 talloc_free(mem_ctx);
2793 if (!NT_STATUS_IS_OK(status)) {
2797 if (!W_ERROR_IS_OK(c.out.result)) {
2798 return werror_to_ntstatus(c.out.result);
2801 return NT_STATUS_OK;
2804 static NTSTATUS enumvalues(struct dcerpc_pipe *p, struct policy_handle *handle,
2805 TALLOC_CTX *mem_ctx)
2807 uint32_t enum_index = 0;
2810 struct winreg_EnumValue r;
2811 struct winreg_StringBuf name;
2812 enum winreg_Type type = 0;
2815 uint32_t size, length;
2817 r.in.handle = handle;
2818 r.in.enum_index = enum_index;
2821 r.in.name = r.out.name = &name;
2827 r.in.length = &length;
2829 status = dcerpc_winreg_EnumValue(p, mem_ctx, &r);
2830 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2831 return NT_STATUS_OK;
2837 static NTSTATUS enumkeys(struct dcerpc_pipe *p, struct policy_handle *handle,
2838 TALLOC_CTX *mem_ctx, int depth)
2840 struct winreg_EnumKey r;
2841 struct winreg_StringBuf class, name;
2846 return NT_STATUS_OK;
2852 r.in.handle = handle;
2853 r.in.enum_index = 0;
2855 r.in.keyclass = &class;
2857 r.in.last_changed_time = &t;
2860 TALLOC_CTX *tmp_ctx;
2861 struct winreg_OpenKey o;
2862 struct policy_handle key_handle;
2865 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2866 return NT_STATUS_NO_MEMORY;
2872 status = dcerpc_winreg_EnumKey(p, tmp_ctx, &r);
2873 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2874 /* We're done enumerating */
2875 talloc_free(tmp_ctx);
2876 return NT_STATUS_OK;
2879 for (i=0; i<10-depth; i++)
2881 printf("%s\n", r.out.name->name);
2884 o.in.parent_handle = handle;
2885 o.in.keyname.name = r.out.name->name;
2887 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2888 o.out.handle = &key_handle;
2890 status = dcerpc_winreg_OpenKey(p, tmp_ctx, &o);
2891 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(o.out.result)) {
2892 enumkeys(p, &key_handle, tmp_ctx, depth-1);
2893 enumvalues(p, &key_handle, tmp_ctx);
2894 status = winreg_close(p, &key_handle);
2895 if (!NT_STATUS_IS_OK(status)) {
2900 talloc_free(tmp_ctx);
2902 r.in.enum_index += 1;
2905 return NT_STATUS_OK;
2908 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
2910 static bool test_Open3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2911 const char *name, winreg_open_fn open_fn)
2913 struct policy_handle handle;
2914 struct winreg_OpenHKLM r;
2917 r.in.system_name = 0;
2918 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2919 r.out.handle = &handle;
2921 status = open_fn(p, mem_ctx, &r);
2922 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2923 d_printf("(%s) %s failed: %s, %s\n", __location__, name,
2924 nt_errstr(status), win_errstr(r.out.result));
2928 enumkeys(p, &handle, mem_ctx, 4);
2930 status = winreg_close(p, &handle);
2931 if (!NT_STATUS_IS_OK(status)) {
2932 d_printf("(%s) dcerpc_CloseKey failed: %s\n",
2933 __location__, nt_errstr(status));
2940 bool torture_samba3_rpc_winreg(struct torture_context *torture)
2943 struct dcerpc_pipe *p;
2944 TALLOC_CTX *mem_ctx;
2950 {"OpenHKLM", (winreg_open_fn)dcerpc_winreg_OpenHKLM },
2951 {"OpenHKU", (winreg_open_fn)dcerpc_winreg_OpenHKU },
2952 {"OpenHKPD", (winreg_open_fn)dcerpc_winreg_OpenHKPD },
2953 {"OpenHKPT", (winreg_open_fn)dcerpc_winreg_OpenHKPT },
2954 {"OpenHKCR", (winreg_open_fn)dcerpc_winreg_OpenHKCR }};
2959 mem_ctx = talloc_init("torture_rpc_winreg");
2961 status = torture_rpc_connection(torture, &p, &ndr_table_winreg);
2963 if (!NT_STATUS_IS_OK(status)) {
2964 talloc_free(mem_ctx);
2969 ret = test_Open3(p, mem_ctx, open_fns[0].name, open_fns[0].fn);
2971 for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
2972 if (!test_Open3(p, mem_ctx, open_fns[i].name, open_fns[i].fn))
2977 talloc_free(mem_ctx);
2982 static NTSTATUS get_shareinfo(TALLOC_CTX *mem_ctx,
2983 struct smbcli_state *cli,
2985 struct srvsvc_NetShareInfo502 **info)
2987 struct smbcli_tree *ipc;
2988 struct dcerpc_pipe *p;
2989 struct srvsvc_NetShareGetInfo r;
2992 if (!(p = dcerpc_pipe_init(cli,
2993 cli->transport->socket->event.ctx,
2994 lp_iconv_convenience(global_loadparm)))) {
2995 status = NT_STATUS_NO_MEMORY;
2999 status = secondary_tcon(p, cli->session, "IPC$", &ipc);
3000 if (!NT_STATUS_IS_OK(status)) {
3004 status = dcerpc_pipe_open_smb(p, ipc, "\\pipe\\srvsvc");
3005 if (!NT_STATUS_IS_OK(status)) {
3006 d_printf("dcerpc_pipe_open_smb failed: %s\n",
3011 status = dcerpc_bind_auth_none(p, &ndr_table_srvsvc);
3012 if (!NT_STATUS_IS_OK(status)) {
3013 d_printf("dcerpc_bind_auth_none failed: %s\n",
3018 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s",
3019 dcerpc_server_name(p));
3020 r.in.share_name = share;
3023 status = dcerpc_srvsvc_NetShareGetInfo(p, p, &r);
3024 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
3025 d_printf("(%s) OpenHKLM failed: %s, %s\n", __location__,
3026 nt_errstr(status), win_errstr(r.out.result));
3030 *info = talloc_move(mem_ctx, &r.out.info.info502);
3031 return NT_STATUS_OK;
3039 * Get us a handle on HKLM\
3042 static NTSTATUS get_hklm_handle(TALLOC_CTX *mem_ctx,
3043 struct smbcli_state *cli,
3044 struct dcerpc_pipe **pipe_p,
3045 struct policy_handle **handle)
3047 struct smbcli_tree *ipc;
3048 struct dcerpc_pipe *p;
3049 struct winreg_OpenHKLM r;
3051 struct policy_handle *result;
3053 result = talloc(mem_ctx, struct policy_handle);
3055 if (result == NULL) {
3056 return NT_STATUS_NO_MEMORY;
3059 if (!(p = dcerpc_pipe_init(result,
3060 cli->transport->socket->event.ctx,
3061 lp_iconv_convenience(global_loadparm)))) {
3062 status = NT_STATUS_NO_MEMORY;
3066 status = secondary_tcon(p, cli->session, "IPC$", &ipc);
3067 if (!NT_STATUS_IS_OK(status)) {
3071 status = dcerpc_pipe_open_smb(p, ipc, "\\winreg");
3072 if (!NT_STATUS_IS_OK(status)) {
3073 d_printf("dcerpc_pipe_open_smb failed: %s\n",
3078 status = dcerpc_bind_auth_none(p, &ndr_table_winreg);
3079 if (!NT_STATUS_IS_OK(status)) {
3080 d_printf("dcerpc_bind_auth_none failed: %s\n",
3085 r.in.system_name = 0;
3086 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3087 r.out.handle = result;
3089 status = dcerpc_winreg_OpenHKLM(p, p, &r);
3090 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
3091 d_printf("(%s) OpenHKLM failed: %s, %s\n", __location__,
3092 nt_errstr(status), win_errstr(r.out.result));
3098 return NT_STATUS_OK;
3101 talloc_free(result);
3105 static NTSTATUS torture_samba3_createshare(struct smbcli_state *cli,
3106 const char *sharename)
3108 struct dcerpc_pipe *p;
3109 struct policy_handle *hklm = NULL;
3110 struct policy_handle new_handle;
3111 struct winreg_CreateKey c;
3112 struct winreg_CloseKey cl;
3113 enum winreg_CreateAction action_taken;
3115 TALLOC_CTX *mem_ctx;
3117 mem_ctx = talloc_new(cli);
3118 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
3120 status = get_hklm_handle(mem_ctx, cli, &p, &hklm);
3121 if (!NT_STATUS_IS_OK(status)) {
3122 d_printf("get_hklm_handle failed: %s\n", nt_errstr(status));
3127 c.in.name.name = talloc_asprintf(
3128 mem_ctx, "software\\samba\\smbconf\\%s", sharename);
3129 if (c.in.name.name == NULL) {
3130 d_printf("talloc_asprintf failed\n");
3131 status = NT_STATUS_NO_MEMORY;
3134 c.in.keyclass.name = "";
3136 c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3137 c.in.secdesc = NULL;
3138 c.in.action_taken = &action_taken;
3139 c.out.new_handle = &new_handle;
3140 c.out.action_taken = &action_taken;
3142 status = dcerpc_winreg_CreateKey(p, p, &c);
3143 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(c.out.result)) {
3144 d_printf("(%s) OpenKey failed: %s, %s\n", __location__,
3145 nt_errstr(status), win_errstr(c.out.result));
3149 cl.in.handle = &new_handle;
3150 cl.out.handle = &new_handle;
3151 status = dcerpc_winreg_CloseKey(p, p, &cl);
3152 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(cl.out.result)) {
3153 d_printf("(%s) OpenKey failed: %s, %s\n", __location__,
3154 nt_errstr(status), win_errstr(cl.out.result));
3160 talloc_free(mem_ctx);
3164 static NTSTATUS torture_samba3_deleteshare(struct smbcli_state *cli,
3165 const char *sharename)
3167 struct dcerpc_pipe *p;
3168 struct policy_handle *hklm = NULL;
3169 struct winreg_DeleteKey d;
3171 TALLOC_CTX *mem_ctx;
3173 mem_ctx = talloc_new(cli);
3174 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
3176 status = get_hklm_handle(cli, cli, &p, &hklm);
3177 if (!NT_STATUS_IS_OK(status)) {
3178 d_printf("get_hklm_handle failed: %s\n", nt_errstr(status));
3183 d.in.key.name = talloc_asprintf(
3184 mem_ctx, "software\\samba\\smbconf\\%s", sharename);
3185 if (d.in.key.name == NULL) {
3186 d_printf("talloc_asprintf failed\n");
3187 status = NT_STATUS_NO_MEMORY;
3190 status = dcerpc_winreg_DeleteKey(p, p, &d);
3191 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(d.out.result)) {
3192 d_printf("(%s) OpenKey failed: %s, %s\n", __location__,
3193 nt_errstr(status), win_errstr(d.out.result));
3198 talloc_free(mem_ctx);
3202 static NTSTATUS torture_samba3_setconfig(struct smbcli_state *cli,
3203 const char *sharename,
3204 const char *parameter,
3207 struct dcerpc_pipe *p = NULL;
3208 struct policy_handle *hklm = NULL, key_handle;
3209 struct winreg_OpenKey o;
3210 struct winreg_SetValue s;
3215 status = get_hklm_handle(cli, cli, &p, &hklm);
3216 if (!NT_STATUS_IS_OK(status)) {
3217 d_printf("get_hklm_handle failed: %s\n", nt_errstr(status));
3221 o.in.parent_handle = hklm;
3222 o.in.keyname.name = talloc_asprintf(
3223 hklm, "software\\samba\\smbconf\\%s", sharename);
3224 if (o.in.keyname.name == NULL) {
3225 d_printf("talloc_asprintf failed\n");
3226 status = NT_STATUS_NO_MEMORY;
3230 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3231 o.out.handle = &key_handle;
3233 status = dcerpc_winreg_OpenKey(p, p, &o);
3234 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(o.out.result)) {
3235 d_printf("(%s) OpenKey failed: %s, %s\n", __location__,
3236 nt_errstr(status), win_errstr(o.out.result));
3240 if (!reg_string_to_val(hklm, "REG_SZ", value, &type, &val)) {
3241 d_printf("(%s) reg_string_to_val failed\n", __location__);
3245 s.in.handle = &key_handle;
3246 s.in.name.name = parameter;
3248 s.in.data = val.data;
3249 s.in.size = val.length;
3251 status = dcerpc_winreg_SetValue(p, p, &s);
3252 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(s.out.result)) {
3253 d_printf("(%s) SetValue failed: %s, %s\n", __location__,
3254 nt_errstr(status), win_errstr(s.out.result));
3263 bool torture_samba3_regconfig(struct torture_context *torture)
3265 struct smbcli_state *cli;
3266 struct srvsvc_NetShareInfo502 *i = NULL;
3269 const char *comment = "Dummer Kommentar";
3271 if (!(torture_open_connection(&cli, torture, 0))) {
3275 status = torture_samba3_createshare(cli, "blubber");
3276 if (!NT_STATUS_IS_OK(status)) {
3277 torture_warning(torture, "torture_samba3_createshare failed: "
3278 "%s\n", nt_errstr(status));
3282 status = torture_samba3_setconfig(cli, "blubber", "comment", comment);
3283 if (!NT_STATUS_IS_OK(status)) {
3284 torture_warning(torture, "torture_samba3_setconfig failed: "
3285 "%s\n", nt_errstr(status));
3289 status = get_shareinfo(torture, cli, "blubber", &i);
3290 if (!NT_STATUS_IS_OK(status)) {
3291 torture_warning(torture, "get_shareinfo failed: "
3292 "%s\n", nt_errstr(status));
3296 if (strcmp(comment, i->comment) != 0) {
3297 torture_warning(torture, "Expected comment [%s], got [%s]\n",
3298 comment, i->comment);
3302 status = torture_samba3_deleteshare(cli, "blubber");
3303 if (!NT_STATUS_IS_OK(status)) {
3304 torture_warning(torture, "torture_samba3_deleteshare failed: "
3305 "%s\n", nt_errstr(status));