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/raw/raw_proto.h"
25 #include "libcli/rap/rap.h"
26 #include "torture/torture.h"
27 #include "torture/util.h"
28 #include "torture/rap/proto.h"
29 #include "librpc/gen_ndr/ndr_lsa.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "librpc/gen_ndr/ndr_samr.h"
32 #include "librpc/gen_ndr/ndr_samr_c.h"
33 #include "librpc/gen_ndr/ndr_netlogon.h"
34 #include "librpc/gen_ndr/ndr_netlogon_c.h"
35 #include "librpc/gen_ndr/ndr_srvsvc.h"
36 #include "librpc/gen_ndr/ndr_srvsvc_c.h"
37 #include "librpc/gen_ndr/ndr_spoolss.h"
38 #include "librpc/gen_ndr/ndr_spoolss_c.h"
39 #include "librpc/gen_ndr/ndr_winreg.h"
40 #include "librpc/gen_ndr/ndr_winreg_c.h"
41 #include "librpc/gen_ndr/ndr_wkssvc.h"
42 #include "librpc/gen_ndr/ndr_wkssvc_c.h"
43 #include "lib/cmdline/popt_common.h"
44 #include "librpc/rpc/dcerpc.h"
45 #include "torture/rpc/rpc.h"
46 #include "libcli/libcli.h"
47 #include "libcli/composite/composite.h"
48 #include "libcli/smb_composite/smb_composite.h"
49 #include "libcli/auth/libcli_auth.h"
50 #include "../lib/crypto/crypto.h"
51 #include "auth/ntlmssp/ntlmssp.h"
52 #include "libcli/security/proto.h"
53 #include "param/param.h"
54 #include "lib/registry/registry.h"
55 #include "libcli/resolve/resolve.h"
58 * This tests a RPC call using an invalid vuid
61 bool torture_bind_authcontext(struct torture_context *torture)
66 struct lsa_ObjectAttribute objectattr;
67 struct lsa_OpenPolicy2 openpolicy;
68 struct policy_handle handle;
69 struct lsa_Close close_handle;
70 struct smbcli_session *tmp;
71 struct smbcli_session *session2;
72 struct smbcli_state *cli;
73 struct dcerpc_pipe *lsa_pipe;
74 struct cli_credentials *anon_creds;
75 struct smb_composite_sesssetup setup;
76 struct smbcli_options options;
77 struct smbcli_session_options session_options;
79 mem_ctx = talloc_init("torture_bind_authcontext");
81 if (mem_ctx == NULL) {
82 d_printf("talloc_init failed\n");
86 lp_smbcli_options(torture->lp_ctx, &options);
87 lp_smbcli_session_options(torture->lp_ctx, &session_options);
89 status = smbcli_full_connection(mem_ctx, &cli,
90 torture_setting_string(torture, "host", NULL),
91 lp_smb_ports(torture->lp_ctx),
92 "IPC$", NULL, cmdline_credentials,
93 lp_resolve_context(torture->lp_ctx),
94 torture->ev, &options);
95 if (!NT_STATUS_IS_OK(status)) {
96 d_printf("smbcli_full_connection failed: %s\n",
101 lsa_pipe = dcerpc_pipe_init(mem_ctx, cli->transport->socket->event.ctx,
102 lp_iconv_convenience(torture->lp_ctx));
103 if (lsa_pipe == NULL) {
104 d_printf("dcerpc_pipe_init failed\n");
108 status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
109 if (!NT_STATUS_IS_OK(status)) {
110 d_printf("dcerpc_pipe_open_smb failed: %s\n",
115 status = dcerpc_bind_auth_none(lsa_pipe, &ndr_table_lsarpc);
116 if (!NT_STATUS_IS_OK(status)) {
117 d_printf("dcerpc_bind_auth_none failed: %s\n",
122 openpolicy.in.system_name =talloc_asprintf(
123 mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
124 ZERO_STRUCT(objectattr);
125 openpolicy.in.attr = &objectattr;
126 openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
127 openpolicy.out.handle = &handle;
129 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
131 if (!NT_STATUS_IS_OK(status)) {
132 d_printf("dcerpc_lsa_OpenPolicy2 failed: %s\n",
137 close_handle.in.handle = &handle;
138 close_handle.out.handle = &handle;
140 status = dcerpc_lsa_Close(lsa_pipe, mem_ctx, &close_handle);
141 if (!NT_STATUS_IS_OK(status)) {
142 d_printf("dcerpc_lsa_Close failed: %s\n",
147 session2 = smbcli_session_init(cli->transport, mem_ctx, false, session_options);
148 if (session2 == NULL) {
149 d_printf("smbcli_session_init failed\n");
153 if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) {
154 d_printf("create_anon_creds failed\n");
158 setup.in.sesskey = cli->transport->negotiate.sesskey;
159 setup.in.capabilities = cli->transport->negotiate.capabilities;
160 setup.in.workgroup = "";
161 setup.in.credentials = anon_creds;
163 status = smb_composite_sesssetup(session2, &setup);
164 if (!NT_STATUS_IS_OK(status)) {
165 d_printf("anon session setup failed: %s\n",
169 session2->vuid = setup.out.vuid;
171 tmp = cli->tree->session;
172 cli->tree->session = session2;
174 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
176 cli->tree->session = tmp;
177 talloc_free(lsa_pipe);
180 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
181 d_printf("dcerpc_lsa_OpenPolicy2 with wrong vuid gave %s, "
182 "expected NT_STATUS_INVALID_HANDLE\n",
189 talloc_free(mem_ctx);
194 * Bind to lsa using a specific auth method
197 static bool bindtest(struct smbcli_state *cli,
198 struct cli_credentials *credentials,
199 struct loadparm_context *lp_ctx,
200 uint8_t auth_type, uint8_t auth_level)
206 struct dcerpc_pipe *lsa_pipe;
207 struct lsa_ObjectAttribute objectattr;
208 struct lsa_OpenPolicy2 openpolicy;
209 struct lsa_QueryInfoPolicy query;
210 struct policy_handle handle;
211 struct lsa_Close close_handle;
213 if ((mem_ctx = talloc_init("bindtest")) == NULL) {
214 d_printf("talloc_init failed\n");
218 lsa_pipe = dcerpc_pipe_init(mem_ctx,
219 cli->transport->socket->event.ctx,
220 lp_iconv_convenience(lp_ctx));
221 if (lsa_pipe == NULL) {
222 d_printf("dcerpc_pipe_init failed\n");
226 status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
227 if (!NT_STATUS_IS_OK(status)) {
228 d_printf("dcerpc_pipe_open_smb failed: %s\n",
233 status = dcerpc_bind_auth(lsa_pipe, &ndr_table_lsarpc,
234 credentials, lp_ctx, 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;
292 struct smbcli_options options;
294 mem_ctx = talloc_init("torture_bind_authcontext");
296 if (mem_ctx == NULL) {
297 d_printf("talloc_init failed\n");
301 lp_smbcli_options(torture->lp_ctx, &options);
303 status = smbcli_full_connection(mem_ctx, &cli,
304 torture_setting_string(torture, "host", NULL),
305 lp_smb_ports(torture->lp_ctx),
306 "IPC$", NULL, cmdline_credentials,
307 lp_resolve_context(torture->lp_ctx),
308 torture->ev, &options);
309 if (!NT_STATUS_IS_OK(status)) {
310 d_printf("smbcli_full_connection failed: %s\n",
317 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_NTLMSSP,
318 DCERPC_AUTH_LEVEL_INTEGRITY);
319 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_NTLMSSP,
320 DCERPC_AUTH_LEVEL_PRIVACY);
321 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_SPNEGO,
322 DCERPC_AUTH_LEVEL_INTEGRITY);
323 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_SPNEGO,
324 DCERPC_AUTH_LEVEL_PRIVACY);
327 talloc_free(mem_ctx);
332 * Lookup or create a user and return all necessary info
335 static NTSTATUS get_usr_handle(struct smbcli_state *cli,
337 struct loadparm_context *lp_ctx,
338 struct cli_credentials *admin_creds,
341 const char *username,
343 struct dcerpc_pipe **result_pipe,
344 struct policy_handle **result_handle,
345 struct dom_sid **sid)
347 struct dcerpc_pipe *samr_pipe;
349 struct policy_handle conn_handle;
350 struct policy_handle domain_handle;
351 struct policy_handle *user_handle;
352 struct samr_Connect2 conn;
353 struct samr_EnumDomains enumdom;
354 uint32_t resume_handle = 0;
355 struct samr_LookupDomain l;
357 struct lsa_String domain_name;
358 struct lsa_String user_name;
359 struct samr_OpenDomain o;
360 struct samr_CreateUser2 c;
361 uint32_t user_rid,access_granted;
363 samr_pipe = dcerpc_pipe_init(mem_ctx,
364 cli->transport->socket->event.ctx,
365 lp_iconv_convenience(lp_ctx));
366 if (samr_pipe == NULL) {
367 d_printf("dcerpc_pipe_init failed\n");
368 status = NT_STATUS_NO_MEMORY;
372 status = dcerpc_pipe_open_smb(samr_pipe, cli->tree, "\\samr");
373 if (!NT_STATUS_IS_OK(status)) {
374 d_printf("dcerpc_pipe_open_smb failed: %s\n",
379 if (admin_creds != NULL) {
380 status = dcerpc_bind_auth(samr_pipe, &ndr_table_samr,
381 admin_creds, lp_ctx, auth_type, auth_level,
383 if (!NT_STATUS_IS_OK(status)) {
384 d_printf("dcerpc_bind_auth failed: %s\n",
389 /* We must have an authenticated SMB connection */
390 status = dcerpc_bind_auth_none(samr_pipe, &ndr_table_samr);
391 if (!NT_STATUS_IS_OK(status)) {
392 d_printf("dcerpc_bind_auth_none failed: %s\n",
398 conn.in.system_name = talloc_asprintf(
399 mem_ctx, "\\\\%s", dcerpc_server_name(samr_pipe));
400 conn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
401 conn.out.connect_handle = &conn_handle;
403 status = dcerpc_samr_Connect2(samr_pipe, mem_ctx, &conn);
404 if (!NT_STATUS_IS_OK(status)) {
405 d_printf("samr_Connect2 failed: %s\n", nt_errstr(status));
409 enumdom.in.connect_handle = &conn_handle;
410 enumdom.in.resume_handle = &resume_handle;
411 enumdom.in.buf_size = (uint32_t)-1;
412 enumdom.out.resume_handle = &resume_handle;
414 status = dcerpc_samr_EnumDomains(samr_pipe, mem_ctx, &enumdom);
415 if (!NT_STATUS_IS_OK(status)) {
416 d_printf("samr_EnumDomains failed: %s\n", nt_errstr(status));
420 if (enumdom.out.num_entries != 2) {
421 d_printf("samr_EnumDomains returned %d entries, expected 2\n",
422 enumdom.out.num_entries);
423 status = NT_STATUS_UNSUCCESSFUL;
427 dom_idx = strequal(enumdom.out.sam->entries[0].name.string,
430 l.in.connect_handle = &conn_handle;
431 domain_name.string = enumdom.out.sam->entries[dom_idx].name.string;
432 *domain = talloc_strdup(mem_ctx, domain_name.string);
433 l.in.domain_name = &domain_name;
435 status = dcerpc_samr_LookupDomain(samr_pipe, mem_ctx, &l);
436 if (!NT_STATUS_IS_OK(status)) {
437 d_printf("samr_LookupDomain failed: %s\n", nt_errstr(status));
441 o.in.connect_handle = &conn_handle;
442 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
443 o.in.sid = l.out.sid;
444 o.out.domain_handle = &domain_handle;
446 status = dcerpc_samr_OpenDomain(samr_pipe, mem_ctx, &o);
447 if (!NT_STATUS_IS_OK(status)) {
448 d_printf("samr_OpenDomain failed: %s\n", nt_errstr(status));
452 c.in.domain_handle = &domain_handle;
453 user_name.string = username;
454 c.in.account_name = &user_name;
455 c.in.acct_flags = ACB_NORMAL;
456 c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
457 user_handle = talloc(mem_ctx, struct policy_handle);
458 c.out.user_handle = user_handle;
459 c.out.access_granted = &access_granted;
460 c.out.rid = &user_rid;
462 status = dcerpc_samr_CreateUser2(samr_pipe, mem_ctx, &c);
464 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
465 struct samr_LookupNames ln;
466 struct samr_OpenUser ou;
468 ln.in.domain_handle = &domain_handle;
470 ln.in.names = &user_name;
472 status = dcerpc_samr_LookupNames(samr_pipe, mem_ctx, &ln);
473 if (!NT_STATUS_IS_OK(status)) {
474 d_printf("samr_LookupNames failed: %s\n",
479 ou.in.domain_handle = &domain_handle;
480 ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
481 user_rid = ou.in.rid = ln.out.rids.ids[0];
482 ou.out.user_handle = user_handle;
484 status = dcerpc_samr_OpenUser(samr_pipe, mem_ctx, &ou);
485 if (!NT_STATUS_IS_OK(status)) {
486 d_printf("samr_OpenUser failed: %s\n",
492 if (!NT_STATUS_IS_OK(status)) {
493 d_printf("samr_CreateUser failed: %s\n", nt_errstr(status));
497 *result_pipe = samr_pipe;
498 *result_handle = user_handle;
500 *sid = dom_sid_add_rid(mem_ctx, l.out.sid, user_rid);
512 static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
513 struct loadparm_context *lp_ctx,
514 struct cli_credentials *admin_creds,
515 const char *username, const char *password,
517 struct dom_sid **user_sid)
521 struct dcerpc_pipe *samr_pipe;
522 struct policy_handle *wks_handle;
525 if (!(tmp_ctx = talloc_new(mem_ctx))) {
526 d_printf("talloc_init failed\n");
530 status = get_usr_handle(cli, tmp_ctx, lp_ctx, admin_creds,
531 DCERPC_AUTH_TYPE_NTLMSSP,
532 DCERPC_AUTH_LEVEL_INTEGRITY,
533 username, domain_name, &samr_pipe, &wks_handle,
535 if (!NT_STATUS_IS_OK(status)) {
536 d_printf("get_usr_handle failed: %s\n", nt_errstr(status));
541 struct samr_SetUserInfo2 sui2;
542 struct samr_SetUserInfo sui;
543 struct samr_QueryUserInfo qui;
544 union samr_UserInfo u_info;
545 DATA_BLOB session_key;
549 encode_pw_buffer(u_info.info23.password.data, password,
552 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
553 if (!NT_STATUS_IS_OK(status)) {
554 d_printf("dcerpc_fetch_session_key failed\n");
557 arcfour_crypt_blob(u_info.info23.password.data, 516,
559 u_info.info23.info.password_expired = 0;
560 u_info.info23.info.fields_present = SAMR_FIELD_PASSWORD |
561 SAMR_FIELD_PASSWORD2 |
562 SAMR_FIELD_EXPIRED_FLAG;
563 sui2.in.user_handle = wks_handle;
564 sui2.in.info = &u_info;
567 status = dcerpc_samr_SetUserInfo2(samr_pipe, tmp_ctx, &sui2);
568 if (!NT_STATUS_IS_OK(status)) {
569 d_printf("samr_SetUserInfo(23) failed: %s\n",
574 u_info.info16.acct_flags = ACB_NORMAL;
575 sui.in.user_handle = wks_handle;
576 sui.in.info = &u_info;
579 status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
580 if (!NT_STATUS_IS_OK(status)) {
581 d_printf("samr_SetUserInfo(16) failed\n");
585 qui.in.user_handle = wks_handle;
588 status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
589 if (!NT_STATUS_IS_OK(status)) {
590 d_printf("samr_QueryUserInfo(21) failed\n");
594 qui.out.info->info21.allow_password_change = 0;
595 qui.out.info->info21.force_password_change = 0;
596 qui.out.info->info21.account_name.string = NULL;
597 qui.out.info->info21.rid = 0;
598 qui.out.info->info21.acct_expiry = 0;
599 qui.out.info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
601 u_info.info21 = qui.out.info->info21;
602 sui.in.user_handle = wks_handle;
603 sui.in.info = &u_info;
606 status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
607 if (!NT_STATUS_IS_OK(status)) {
608 d_printf("samr_SetUserInfo(21) failed\n");
613 *domain_name= talloc_steal(mem_ctx, *domain_name);
614 *user_sid = talloc_steal(mem_ctx, *user_sid);
617 talloc_free(tmp_ctx);
625 static bool delete_user(struct smbcli_state *cli,
626 struct loadparm_context *lp_ctx,
627 struct cli_credentials *admin_creds,
628 const char *username)
633 struct dcerpc_pipe *samr_pipe;
634 struct policy_handle *user_handle;
637 if ((mem_ctx = talloc_init("leave")) == NULL) {
638 d_printf("talloc_init failed\n");
642 status = get_usr_handle(cli, mem_ctx, lp_ctx, admin_creds,
643 DCERPC_AUTH_TYPE_NTLMSSP,
644 DCERPC_AUTH_LEVEL_INTEGRITY,
645 username, &dom_name, &samr_pipe,
648 if (!NT_STATUS_IS_OK(status)) {
649 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
654 struct samr_DeleteUser d;
656 d.in.user_handle = user_handle;
657 d.out.user_handle = user_handle;
659 status = dcerpc_samr_DeleteUser(samr_pipe, mem_ctx, &d);
660 if (!NT_STATUS_IS_OK(status)) {
661 d_printf("samr_DeleteUser failed %s\n", nt_errstr(status));
669 talloc_free(mem_ctx);
674 * Do a Samba3-style join
677 static bool join3(struct smbcli_state *cli,
678 struct loadparm_context *lp_ctx,
680 struct cli_credentials *admin_creds,
681 struct cli_credentials *wks_creds)
686 struct dcerpc_pipe *samr_pipe;
687 struct policy_handle *wks_handle;
689 NTTIME last_password_change;
691 if ((mem_ctx = talloc_init("join3")) == NULL) {
692 d_printf("talloc_init failed\n");
696 status = get_usr_handle(
697 cli, mem_ctx, lp_ctx, admin_creds,
698 DCERPC_AUTH_TYPE_NTLMSSP,
699 DCERPC_AUTH_LEVEL_PRIVACY,
700 talloc_asprintf(mem_ctx, "%s$",
701 cli_credentials_get_workstation(wks_creds)),
702 &dom_name, &samr_pipe, &wks_handle, NULL);
704 if (!NT_STATUS_IS_OK(status)) {
705 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
710 struct samr_QueryUserInfo q;
712 q.in.user_handle = wks_handle;
715 status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q);
716 if (!NT_STATUS_IS_OK(status)) {
717 d_printf("(%s) QueryUserInfo failed: %s\n",
718 __location__, nt_errstr(status));
722 last_password_change = q.out.info->info21.last_password_change;
725 cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);
728 struct samr_SetUserInfo2 sui2;
729 union samr_UserInfo u_info;
730 struct samr_UserInfo21 *i21 = &u_info.info25.info;
731 DATA_BLOB session_key;
732 DATA_BLOB confounded_session_key = data_blob_talloc(
734 struct MD5Context ctx;
735 uint8_t confounder[16];
739 i21->full_name.string = talloc_asprintf(
741 cli_credentials_get_workstation(wks_creds));
742 i21->acct_flags = ACB_WSTRUST;
743 i21->fields_present = SAMR_FIELD_FULL_NAME |
744 SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_PASSWORD;
746 encode_pw_buffer(u_info.info25.password.data,
747 cli_credentials_get_password(wks_creds),
749 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
750 if (!NT_STATUS_IS_OK(status)) {
751 d_printf("dcerpc_fetch_session_key failed: %s\n",
755 generate_random_buffer((uint8_t *)confounder, 16);
758 MD5Update(&ctx, confounder, 16);
759 MD5Update(&ctx, session_key.data, session_key.length);
760 MD5Final(confounded_session_key.data, &ctx);
762 arcfour_crypt_blob(u_info.info25.password.data, 516,
763 &confounded_session_key);
764 memcpy(&u_info.info25.password.data[516], confounder, 16);
766 sui2.in.user_handle = wks_handle;
768 sui2.in.info = &u_info;
770 status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2);
771 if (!NT_STATUS_IS_OK(status)) {
772 d_printf("samr_SetUserInfo2(25) failed: %s\n",
777 struct samr_SetUserInfo2 sui2;
778 struct samr_SetUserInfo sui;
779 union samr_UserInfo u_info;
780 DATA_BLOB session_key;
782 encode_pw_buffer(u_info.info24.password.data,
783 cli_credentials_get_password(wks_creds),
785 u_info.info24.pw_len =
786 strlen_m(cli_credentials_get_password(wks_creds))*2;
788 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
789 if (!NT_STATUS_IS_OK(status)) {
790 d_printf("dcerpc_fetch_session_key failed\n");
793 arcfour_crypt_blob(u_info.info24.password.data, 516,
795 sui2.in.user_handle = wks_handle;
796 sui2.in.info = &u_info;
799 status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2);
800 if (!NT_STATUS_IS_OK(status)) {
801 d_printf("samr_SetUserInfo(24) failed: %s\n",
806 u_info.info16.acct_flags = ACB_WSTRUST;
807 sui.in.user_handle = wks_handle;
808 sui.in.info = &u_info;
811 status = dcerpc_samr_SetUserInfo(samr_pipe, mem_ctx, &sui);
812 if (!NT_STATUS_IS_OK(status)) {
813 d_printf("samr_SetUserInfo(16) failed\n");
819 struct samr_QueryUserInfo q;
821 q.in.user_handle = wks_handle;
824 status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q);
825 if (!NT_STATUS_IS_OK(status)) {
826 d_printf("(%s) QueryUserInfo failed: %s\n",
827 __location__, nt_errstr(status));
832 if (last_password_change
833 == q.out.info->info21.last_password_change) {
834 d_printf("(%s) last_password_change unchanged "
835 "during join, level25 must change "
836 "it\n", __location__);
841 if (last_password_change
842 != q.out.info->info21.last_password_change) {
843 d_printf("(%s) last_password_change changed "
844 "during join, level24 doesn't "
845 "change it\n", __location__);
854 talloc_free(mem_ctx);
859 * Do a ReqChallenge/Auth2 and get the wks creds
862 static bool auth2(struct smbcli_state *cli,
863 struct loadparm_context *lp_ctx,
864 struct cli_credentials *wks_cred)
867 struct dcerpc_pipe *net_pipe;
870 struct netr_ServerReqChallenge r;
871 struct netr_Credential netr_cli_creds;
872 struct netr_Credential netr_srv_creds;
873 uint32_t negotiate_flags;
874 struct netr_ServerAuthenticate2 a;
875 struct creds_CredentialState *creds_state;
876 struct netr_Credential netr_cred;
877 struct samr_Password mach_pw;
879 mem_ctx = talloc_new(NULL);
880 if (mem_ctx == NULL) {
881 d_printf("talloc_new failed\n");
885 net_pipe = dcerpc_pipe_init(mem_ctx,
886 cli->transport->socket->event.ctx,
887 lp_iconv_convenience(lp_ctx));
888 if (net_pipe == NULL) {
889 d_printf("dcerpc_pipe_init failed\n");
893 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
894 if (!NT_STATUS_IS_OK(status)) {
895 d_printf("dcerpc_pipe_open_smb failed: %s\n",
900 status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon);
901 if (!NT_STATUS_IS_OK(status)) {
902 d_printf("dcerpc_bind_auth_none failed: %s\n",
907 r.in.computer_name = cli_credentials_get_workstation(wks_cred);
908 r.in.server_name = talloc_asprintf(
909 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
910 if (r.in.server_name == NULL) {
911 d_printf("talloc_asprintf failed\n");
914 generate_random_buffer(netr_cli_creds.data,
915 sizeof(netr_cli_creds.data));
916 r.in.credentials = &netr_cli_creds;
917 r.out.credentials = &netr_srv_creds;
919 status = dcerpc_netr_ServerReqChallenge(net_pipe, mem_ctx, &r);
920 if (!NT_STATUS_IS_OK(status)) {
921 d_printf("netr_ServerReqChallenge failed: %s\n",
926 negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
927 E_md4hash(cli_credentials_get_password(wks_cred), mach_pw.hash);
929 creds_state = talloc(mem_ctx, struct creds_CredentialState);
930 creds_client_init(creds_state, r.in.credentials,
931 r.out.credentials, &mach_pw,
932 &netr_cred, negotiate_flags);
934 a.in.server_name = talloc_asprintf(
935 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
936 a.in.account_name = talloc_asprintf(
937 mem_ctx, "%s$", cli_credentials_get_workstation(wks_cred));
938 a.in.computer_name = cli_credentials_get_workstation(wks_cred);
939 a.in.secure_channel_type = SEC_CHAN_WKSTA;
940 a.in.negotiate_flags = &negotiate_flags;
941 a.out.negotiate_flags = &negotiate_flags;
942 a.in.credentials = &netr_cred;
943 a.out.credentials = &netr_cred;
945 status = dcerpc_netr_ServerAuthenticate2(net_pipe, mem_ctx, &a);
946 if (!NT_STATUS_IS_OK(status)) {
947 d_printf("netr_ServerServerAuthenticate2 failed: %s\n",
952 if (!creds_client_check(creds_state, a.out.credentials)) {
953 d_printf("creds_client_check failed\n");
957 cli_credentials_set_netlogon_creds(wks_cred, creds_state);
962 talloc_free(mem_ctx);
967 * Do a couple of schannel protected Netlogon ops: Interactive and Network
968 * login, and change the wks password
971 static bool schan(struct smbcli_state *cli,
972 struct loadparm_context *lp_ctx,
973 struct cli_credentials *wks_creds,
974 struct cli_credentials *user_creds)
979 struct dcerpc_pipe *net_pipe;
982 mem_ctx = talloc_new(NULL);
983 if (mem_ctx == NULL) {
984 d_printf("talloc_new failed\n");
988 net_pipe = dcerpc_pipe_init(mem_ctx,
989 cli->transport->socket->event.ctx,
990 lp_iconv_convenience(lp_ctx));
991 if (net_pipe == NULL) {
992 d_printf("dcerpc_pipe_init failed\n");
996 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
997 if (!NT_STATUS_IS_OK(status)) {
998 d_printf("dcerpc_pipe_open_smb failed: %s\n",
1004 net_pipe->conn->flags |= DCERPC_DEBUG_PRINT_IN |
1005 DCERPC_DEBUG_PRINT_OUT;
1008 net_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL);
1009 status = dcerpc_bind_auth(net_pipe, &ndr_table_netlogon,
1010 wks_creds, lp_ctx, DCERPC_AUTH_TYPE_SCHANNEL,
1011 DCERPC_AUTH_LEVEL_PRIVACY,
1014 status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon);
1016 if (!NT_STATUS_IS_OK(status)) {
1017 d_printf("schannel bind failed: %s\n", nt_errstr(status));
1022 for (i=2; i<4; i++) {
1024 DATA_BLOB chal, nt_resp, lm_resp, names_blob, session_key;
1025 struct creds_CredentialState *creds_state;
1026 struct netr_Authenticator netr_auth, netr_auth2;
1027 struct netr_NetworkInfo ninfo;
1028 struct netr_PasswordInfo pinfo;
1029 struct netr_LogonSamLogon r;
1031 flags = CLI_CRED_LANMAN_AUTH | CLI_CRED_NTLM_AUTH |
1032 CLI_CRED_NTLMv2_AUTH;
1034 chal = data_blob_talloc(mem_ctx, NULL, 8);
1035 if (chal.data == NULL) {
1036 d_printf("data_blob_talloc failed\n");
1040 generate_random_buffer(chal.data, chal.length);
1041 names_blob = NTLMv2_generate_names_blob(
1042 mem_ctx, lp_iconv_convenience(lp_ctx),
1043 cli_credentials_get_workstation(user_creds),
1044 cli_credentials_get_domain(user_creds));
1045 status = cli_credentials_get_ntlm_response(
1046 user_creds, mem_ctx, &flags, chal, names_blob,
1047 &lm_resp, &nt_resp, NULL, NULL);
1048 if (!NT_STATUS_IS_OK(status)) {
1049 d_printf("cli_credentials_get_ntlm_response failed:"
1050 " %s\n", nt_errstr(status));
1054 creds_state = cli_credentials_get_netlogon_creds(wks_creds);
1055 creds_client_authenticator(creds_state, &netr_auth);
1057 ninfo.identity_info.account_name.string =
1058 cli_credentials_get_username(user_creds);
1059 ninfo.identity_info.domain_name.string =
1060 cli_credentials_get_domain(user_creds);
1061 ninfo.identity_info.parameter_control = 0;
1062 ninfo.identity_info.logon_id_low = 0;
1063 ninfo.identity_info.logon_id_high = 0;
1064 ninfo.identity_info.workstation.string =
1065 cli_credentials_get_workstation(user_creds);
1066 memcpy(ninfo.challenge, chal.data, sizeof(ninfo.challenge));
1067 ninfo.nt.length = nt_resp.length;
1068 ninfo.nt.data = nt_resp.data;
1069 ninfo.lm.length = lm_resp.length;
1070 ninfo.lm.data = lm_resp.data;
1072 r.in.server_name = talloc_asprintf(
1073 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1074 ZERO_STRUCT(netr_auth2);
1075 r.in.computer_name =
1076 cli_credentials_get_workstation(wks_creds);
1077 r.in.credential = &netr_auth;
1078 r.in.return_authenticator = &netr_auth2;
1079 r.in.logon_level = 2;
1080 r.in.validation_level = i;
1081 r.in.logon.network = &ninfo;
1082 r.out.return_authenticator = NULL;
1084 status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r);
1085 if (!NT_STATUS_IS_OK(status)) {
1086 d_printf("netr_LogonSamLogon failed: %s\n",
1091 if ((r.out.return_authenticator == NULL) ||
1092 (!creds_client_check(creds_state,
1093 &r.out.return_authenticator->cred))) {
1094 d_printf("Credentials check failed!\n");
1098 creds_client_authenticator(creds_state, &netr_auth);
1100 pinfo.identity_info = ninfo.identity_info;
1101 ZERO_STRUCT(pinfo.lmpassword.hash);
1102 E_md4hash(cli_credentials_get_password(user_creds),
1103 pinfo.ntpassword.hash);
1104 session_key = data_blob_talloc(mem_ctx,
1105 creds_state->session_key, 16);
1106 arcfour_crypt_blob(pinfo.ntpassword.hash,
1107 sizeof(pinfo.ntpassword.hash),
1110 r.in.logon_level = 1;
1111 r.in.logon.password = &pinfo;
1112 r.out.return_authenticator = NULL;
1114 status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r);
1115 if (!NT_STATUS_IS_OK(status)) {
1116 d_printf("netr_LogonSamLogon failed: %s\n",
1121 if ((r.out.return_authenticator == NULL) ||
1122 (!creds_client_check(creds_state,
1123 &r.out.return_authenticator->cred))) {
1124 d_printf("Credentials check failed!\n");
1130 struct netr_ServerPasswordSet s;
1131 char *password = generate_random_str(wks_creds, 8);
1132 struct creds_CredentialState *creds_state;
1134 s.in.server_name = talloc_asprintf(
1135 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1136 s.in.computer_name = cli_credentials_get_workstation(wks_creds);
1137 s.in.account_name = talloc_asprintf(
1138 mem_ctx, "%s$", s.in.computer_name);
1139 s.in.secure_channel_type = SEC_CHAN_WKSTA;
1140 E_md4hash(password, s.in.new_password.hash);
1142 creds_state = cli_credentials_get_netlogon_creds(wks_creds);
1143 creds_des_encrypt(creds_state, &s.in.new_password);
1144 creds_client_authenticator(creds_state, &s.in.credential);
1146 status = dcerpc_netr_ServerPasswordSet(net_pipe, mem_ctx, &s);
1147 if (!NT_STATUS_IS_OK(status)) {
1148 printf("ServerPasswordSet - %s\n", nt_errstr(status));
1152 if (!creds_client_check(creds_state,
1153 &s.out.return_authenticator.cred)) {
1154 printf("Credential chaining failed\n");
1157 cli_credentials_set_password(wks_creds, password,
1163 talloc_free(mem_ctx);
1168 * Delete the wks account again
1171 static bool leave(struct smbcli_state *cli,
1172 struct loadparm_context *lp_ctx,
1173 struct cli_credentials *admin_creds,
1174 struct cli_credentials *wks_creds)
1176 char *wks_name = talloc_asprintf(
1177 NULL, "%s$", cli_credentials_get_workstation(wks_creds));
1180 ret = delete_user(cli, lp_ctx, admin_creds, wks_name);
1181 talloc_free(wks_name);
1186 * Test the Samba3 DC code a bit. Join, do some schan netlogon ops, leave
1189 bool torture_netlogon_samba3(struct torture_context *torture)
1191 TALLOC_CTX *mem_ctx;
1194 struct smbcli_state *cli;
1195 struct cli_credentials *anon_creds;
1196 struct cli_credentials *wks_creds;
1197 const char *wks_name;
1199 struct smbcli_options options;
1201 wks_name = torture_setting_string(torture, "wksname", NULL);
1202 if (wks_name == NULL) {
1203 wks_name = get_myname();
1206 mem_ctx = talloc_init("torture_netlogon_samba3");
1208 if (mem_ctx == NULL) {
1209 d_printf("talloc_init failed\n");
1213 if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) {
1214 d_printf("create_anon_creds failed\n");
1218 lp_smbcli_options(torture->lp_ctx, &options);
1220 status = smbcli_full_connection(mem_ctx, &cli,
1221 torture_setting_string(torture, "host", NULL),
1222 lp_smb_ports(torture->lp_ctx),
1223 "IPC$", NULL, anon_creds,
1224 lp_resolve_context(torture->lp_ctx),
1225 torture->ev, &options);
1226 if (!NT_STATUS_IS_OK(status)) {
1227 d_printf("smbcli_full_connection failed: %s\n",
1232 wks_creds = cli_credentials_init(mem_ctx);
1233 if (wks_creds == NULL) {
1234 d_printf("cli_credentials_init failed\n");
1238 cli_credentials_set_conf(wks_creds, torture->lp_ctx);
1239 cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1240 cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1241 cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1242 cli_credentials_set_password(wks_creds,
1243 generate_random_str(wks_creds, 8),
1246 if (!join3(cli, torture->lp_ctx, false, cmdline_credentials, wks_creds)) {
1247 d_printf("join failed\n");
1251 cli_credentials_set_domain(
1252 cmdline_credentials, cli_credentials_get_domain(wks_creds),
1255 for (i=0; i<2; i++) {
1257 /* Do this more than once, the routine "schan" changes
1258 * the workstation password using the netlogon
1259 * password change routine */
1263 if (!auth2(cli, torture->lp_ctx, wks_creds)) {
1264 d_printf("auth2 failed\n");
1268 for (j=0; j<2; j++) {
1269 if (!schan(cli, torture->lp_ctx, wks_creds, cmdline_credentials)) {
1270 d_printf("schan failed\n");
1276 if (!leave(cli, torture->lp_ctx, cmdline_credentials, wks_creds)) {
1277 d_printf("leave failed\n");
1284 talloc_free(mem_ctx);
1289 * Do a simple join, testjoin and leave using specified smb and samr
1293 static bool test_join3(struct torture_context *tctx,
1295 struct cli_credentials *smb_creds,
1296 struct cli_credentials *samr_creds,
1297 const char *wks_name)
1301 struct smbcli_state *cli;
1302 struct cli_credentials *wks_creds;
1303 struct smbcli_options options;
1305 lp_smbcli_options(tctx->lp_ctx, &options);
1307 status = smbcli_full_connection(tctx, &cli,
1308 torture_setting_string(tctx, "host", NULL),
1309 lp_smb_ports(tctx->lp_ctx),
1310 "IPC$", NULL, smb_creds,
1311 lp_resolve_context(tctx->lp_ctx),
1312 tctx->ev, &options);
1313 if (!NT_STATUS_IS_OK(status)) {
1314 d_printf("smbcli_full_connection failed: %s\n",
1319 wks_creds = cli_credentials_init(cli);
1320 if (wks_creds == NULL) {
1321 d_printf("cli_credentials_init failed\n");
1325 cli_credentials_set_conf(wks_creds, tctx->lp_ctx);
1326 cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1327 cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1328 cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1329 cli_credentials_set_password(wks_creds,
1330 generate_random_str(wks_creds, 8),
1333 if (!join3(cli, tctx->lp_ctx, use_level25, samr_creds, wks_creds)) {
1334 d_printf("join failed\n");
1338 cli_credentials_set_domain(
1339 cmdline_credentials, cli_credentials_get_domain(wks_creds),
1342 if (!auth2(cli, tctx->lp_ctx, wks_creds)) {
1343 d_printf("auth2 failed\n");
1347 if (!leave(cli, tctx->lp_ctx, samr_creds, wks_creds)) {
1348 d_printf("leave failed\n");
1361 * Test the different session key variants. Do it by joining, this uses the
1362 * session key in the setpassword routine. Test the join by doing the auth2.
1365 bool torture_samba3_sessionkey(struct torture_context *torture)
1368 struct cli_credentials *anon_creds;
1369 const char *wks_name;
1371 wks_name = torture_setting_string(torture, "wksname", get_myname());
1373 if (!(anon_creds = cli_credentials_init_anon(torture))) {
1374 d_printf("create_anon_creds failed\n");
1378 cli_credentials_set_workstation(anon_creds, wks_name, CRED_SPECIFIED);
1382 if (!torture_setting_bool(torture, "samba3", false)) {
1384 /* Samba3 in the build farm right now does this happily. Need
1387 if (test_join3(torture, false, anon_creds, NULL, wks_name)) {
1388 d_printf("join using anonymous bind on an anonymous smb "
1389 "connection succeeded -- HUH??\n");
1394 if (!test_join3(torture, false, anon_creds, cmdline_credentials,
1396 d_printf("join using ntlmssp bind on an anonymous smb "
1397 "connection failed\n");
1401 if (!test_join3(torture, false, cmdline_credentials, NULL, wks_name)) {
1402 d_printf("join using anonymous bind on an authenticated smb "
1403 "connection failed\n");
1407 if (!test_join3(torture, false, cmdline_credentials,
1408 cmdline_credentials,
1410 d_printf("join using ntlmssp bind on an authenticated smb "
1411 "connection failed\n");
1416 * The following two are tests for setuserinfolevel 25
1419 if (!test_join3(torture, true, anon_creds, cmdline_credentials,
1421 d_printf("join using ntlmssp bind on an anonymous smb "
1422 "connection failed\n");
1426 if (!test_join3(torture, true, cmdline_credentials, NULL, wks_name)) {
1427 d_printf("join using anonymous bind on an authenticated smb "
1428 "connection failed\n");
1438 * open pipe and bind, given an IPC$ context
1441 static NTSTATUS pipe_bind_smb(TALLOC_CTX *mem_ctx,
1442 struct loadparm_context *lp_ctx,
1443 struct smbcli_tree *tree,
1444 const char *pipe_name,
1445 const struct ndr_interface_table *iface,
1446 struct dcerpc_pipe **p)
1448 struct dcerpc_pipe *result;
1451 if (!(result = dcerpc_pipe_init(
1452 mem_ctx, tree->session->transport->socket->event.ctx,
1453 lp_iconv_convenience(lp_ctx)))) {
1454 return NT_STATUS_NO_MEMORY;
1457 status = dcerpc_pipe_open_smb(result, tree, pipe_name);
1458 if (!NT_STATUS_IS_OK(status)) {
1459 d_printf("dcerpc_pipe_open_smb failed: %s\n",
1461 talloc_free(result);
1465 status = dcerpc_bind_auth_none(result, iface);
1466 if (!NT_STATUS_IS_OK(status)) {
1467 d_printf("schannel bind failed: %s\n", nt_errstr(status));
1468 talloc_free(result);
1473 return NT_STATUS_OK;
1477 * Sane wrapper around lsa_LookupNames
1480 static struct dom_sid *name2sid(TALLOC_CTX *mem_ctx,
1481 struct dcerpc_pipe *p,
1485 struct lsa_ObjectAttribute attr;
1486 struct lsa_QosInfo qos;
1487 struct lsa_OpenPolicy2 r;
1490 struct policy_handle handle;
1491 struct lsa_LookupNames l;
1492 struct lsa_TransSidArray sids;
1493 struct lsa_String lsa_name;
1495 struct dom_sid *result;
1496 TALLOC_CTX *tmp_ctx;
1498 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1503 qos.impersonation_level = 2;
1504 qos.context_mode = 1;
1505 qos.effective_only = 0;
1508 attr.root_dir = NULL;
1509 attr.object_name = NULL;
1510 attr.attributes = 0;
1511 attr.sec_desc = NULL;
1512 attr.sec_qos = &qos;
1514 r.in.system_name = "\\";
1516 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1517 r.out.handle = &handle;
1519 status = dcerpc_lsa_OpenPolicy2(p, tmp_ctx, &r);
1520 if (!NT_STATUS_IS_OK(status)) {
1521 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
1522 talloc_free(tmp_ctx);
1529 lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, name);
1531 l.in.handle = &handle;
1533 l.in.names = &lsa_name;
1536 l.in.count = &count;
1537 l.out.count = &count;
1540 status = dcerpc_lsa_LookupNames(p, tmp_ctx, &l);
1541 if (!NT_STATUS_IS_OK(status)) {
1542 printf("LookupNames of %s failed - %s\n", lsa_name.string,
1544 talloc_free(tmp_ctx);
1548 result = dom_sid_add_rid(mem_ctx, l.out.domains->domains[0].sid,
1549 l.out.sids->sids[0].rid);
1551 c.in.handle = &handle;
1552 c.out.handle = &handle;
1554 status = dcerpc_lsa_Close(p, tmp_ctx, &c);
1555 if (!NT_STATUS_IS_OK(status)) {
1556 printf("dcerpc_lsa_Close failed - %s\n", nt_errstr(status));
1557 talloc_free(tmp_ctx);
1561 talloc_free(tmp_ctx);
1566 * Find out the user SID on this connection
1569 static struct dom_sid *whoami(TALLOC_CTX *mem_ctx,
1570 struct loadparm_context *lp_ctx,
1571 struct smbcli_tree *tree)
1573 struct dcerpc_pipe *lsa;
1574 struct lsa_GetUserName r;
1576 struct lsa_StringPointer authority_name_p;
1577 struct dom_sid *result;
1579 status = pipe_bind_smb(mem_ctx, lp_ctx, tree, "\\pipe\\lsarpc",
1580 &ndr_table_lsarpc, &lsa);
1581 if (!NT_STATUS_IS_OK(status)) {
1582 d_printf("(%s) Could not bind to LSA: %s\n",
1583 __location__, nt_errstr(status));
1587 r.in.system_name = "\\";
1588 r.in.account_name = NULL;
1589 authority_name_p.string = NULL;
1590 r.in.authority_name = &authority_name_p;
1592 status = dcerpc_lsa_GetUserName(lsa, mem_ctx, &r);
1594 if (!NT_STATUS_IS_OK(status)) {
1595 printf("(%s) GetUserName failed - %s\n",
1596 __location__, nt_errstr(status));
1601 result = name2sid(mem_ctx, lsa, r.out.account_name->string,
1602 r.out.authority_name->string->string);
1608 static int destroy_tree(struct smbcli_tree *tree)
1610 smb_tree_disconnect(tree);
1615 * Do a tcon, given a session
1618 NTSTATUS secondary_tcon(TALLOC_CTX *mem_ctx,
1619 struct smbcli_session *session,
1620 const char *sharename,
1621 struct smbcli_tree **res)
1623 struct smbcli_tree *result;
1624 TALLOC_CTX *tmp_ctx;
1625 union smb_tcon tcon;
1628 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1629 return NT_STATUS_NO_MEMORY;
1632 if (!(result = smbcli_tree_init(session, mem_ctx, false))) {
1633 talloc_free(tmp_ctx);
1634 return NT_STATUS_NO_MEMORY;
1637 tcon.generic.level = RAW_TCON_TCONX;
1638 tcon.tconx.in.flags = 0;
1639 tcon.tconx.in.password = data_blob(NULL, 0);
1640 tcon.tconx.in.path = sharename;
1641 tcon.tconx.in.device = "?????";
1643 status = smb_raw_tcon(result, tmp_ctx, &tcon);
1644 if (!NT_STATUS_IS_OK(status)) {
1645 d_printf("(%s) smb_raw_tcon failed: %s\n", __location__,
1647 talloc_free(tmp_ctx);
1651 result->tid = tcon.tconx.out.tid;
1652 result = talloc_steal(mem_ctx, result);
1653 talloc_set_destructor(result, destroy_tree);
1654 talloc_free(tmp_ctx);
1656 return NT_STATUS_OK;
1660 * Test the getusername behaviour
1663 bool torture_samba3_rpc_getusername(struct torture_context *torture)
1666 struct smbcli_state *cli;
1667 TALLOC_CTX *mem_ctx;
1669 struct dom_sid *user_sid;
1670 struct dom_sid *created_sid;
1671 struct cli_credentials *anon_creds;
1672 struct cli_credentials *user_creds;
1674 struct smbcli_options options;
1675 struct smbcli_session_options session_options;
1677 if (!(mem_ctx = talloc_new(torture))) {
1681 lp_smbcli_options(torture->lp_ctx, &options);
1682 lp_smbcli_session_options(torture->lp_ctx, &session_options);
1684 status = smbcli_full_connection(
1685 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1686 lp_smb_ports(torture->lp_ctx),
1687 "IPC$", NULL, cmdline_credentials,
1688 lp_resolve_context(torture->lp_ctx),
1689 torture->ev, &options);
1690 if (!NT_STATUS_IS_OK(status)) {
1691 d_printf("(%s) smbcli_full_connection failed: %s\n",
1692 __location__, nt_errstr(status));
1697 if (!(user_sid = whoami(mem_ctx, torture->lp_ctx, cli->tree))) {
1698 d_printf("(%s) whoami on auth'ed connection failed\n",
1705 if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) {
1706 d_printf("(%s) create_anon_creds failed\n", __location__);
1711 status = smbcli_full_connection(
1712 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1713 lp_smb_ports(torture->lp_ctx),
1714 "IPC$", NULL, anon_creds,
1715 lp_resolve_context(torture->lp_ctx),
1716 torture->ev, &options);
1717 if (!NT_STATUS_IS_OK(status)) {
1718 d_printf("(%s) anon smbcli_full_connection failed: %s\n",
1719 __location__, nt_errstr(status));
1724 if (!(user_sid = whoami(mem_ctx, torture->lp_ctx, cli->tree))) {
1725 d_printf("(%s) whoami on anon connection failed\n",
1731 if (!dom_sid_equal(user_sid,
1732 dom_sid_parse_talloc(mem_ctx, "s-1-5-7"))) {
1733 d_printf("(%s) Anon lsa_GetUserName returned %s, expected "
1734 "S-1-5-7", __location__,
1735 dom_sid_string(mem_ctx, user_sid));
1739 if (!(user_creds = cli_credentials_init(mem_ctx))) {
1740 d_printf("(%s) cli_credentials_init failed\n", __location__);
1745 cli_credentials_set_conf(user_creds, torture->lp_ctx);
1746 cli_credentials_set_username(user_creds, "torture_username",
1748 cli_credentials_set_password(user_creds,
1749 generate_random_str(user_creds, 8),
1752 if (!create_user(mem_ctx, cli, torture->lp_ctx, cmdline_credentials,
1753 cli_credentials_get_username(user_creds),
1754 cli_credentials_get_password(user_creds),
1755 &domain_name, &created_sid)) {
1756 d_printf("(%s) create_user failed\n", __location__);
1761 cli_credentials_set_domain(user_creds, domain_name,
1765 struct smbcli_session *session2;
1766 struct smb_composite_sesssetup setup;
1767 struct smbcli_tree *tree;
1769 session2 = smbcli_session_init(cli->transport, mem_ctx, false, session_options);
1770 if (session2 == NULL) {
1771 d_printf("(%s) smbcli_session_init failed\n",
1776 setup.in.sesskey = cli->transport->negotiate.sesskey;
1777 setup.in.capabilities = cli->transport->negotiate.capabilities;
1778 setup.in.workgroup = "";
1779 setup.in.credentials = user_creds;
1781 status = smb_composite_sesssetup(session2, &setup);
1782 if (!NT_STATUS_IS_OK(status)) {
1783 d_printf("(%s) session setup with new user failed: "
1784 "%s\n", __location__, nt_errstr(status));
1788 session2->vuid = setup.out.vuid;
1790 if (!NT_STATUS_IS_OK(secondary_tcon(mem_ctx, session2,
1792 d_printf("(%s) secondary_tcon failed\n",
1798 if (!(user_sid = whoami(mem_ctx, torture->lp_ctx, tree))) {
1799 d_printf("(%s) whoami on user connection failed\n",
1808 d_printf("Created %s, found %s\n",
1809 dom_sid_string(mem_ctx, created_sid),
1810 dom_sid_string(mem_ctx, user_sid));
1812 if (!dom_sid_equal(created_sid, user_sid)) {
1817 if (!delete_user(cli, torture->lp_ctx,
1818 cmdline_credentials,
1819 cli_credentials_get_username(user_creds))) {
1820 d_printf("(%s) delete_user failed\n", __location__);
1825 talloc_free(mem_ctx);
1829 static bool test_NetShareGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1830 const char *sharename)
1833 struct srvsvc_NetShareGetInfo r;
1834 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007, 1501 };
1838 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s",
1839 dcerpc_server_name(p));
1840 r.in.share_name = sharename;
1842 for (i=0;i<ARRAY_SIZE(levels);i++) {
1843 r.in.level = levels[i];
1847 printf("testing NetShareGetInfo level %u on share '%s'\n",
1848 r.in.level, r.in.share_name);
1850 status = dcerpc_srvsvc_NetShareGetInfo(p, mem_ctx, &r);
1851 if (!NT_STATUS_IS_OK(status)) {
1852 printf("NetShareGetInfo level %u on share '%s' failed"
1853 " - %s\n", r.in.level, r.in.share_name,
1858 if (!W_ERROR_IS_OK(r.out.result)) {
1859 printf("NetShareGetInfo level %u on share '%s' failed "
1860 "- %s\n", r.in.level, r.in.share_name,
1861 win_errstr(r.out.result));
1870 static bool test_NetShareEnum(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1871 const char **one_sharename)
1874 struct srvsvc_NetShareEnum r;
1875 struct srvsvc_NetShareCtr0 c0;
1876 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007 };
1880 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
1881 r.in.ctr.ctr0 = &c0;
1882 r.in.ctr.ctr0->count = 0;
1883 r.in.ctr.ctr0->array = NULL;
1884 r.in.max_buffer = (uint32_t)-1;
1885 r.in.resume_handle = NULL;
1887 for (i=0;i<ARRAY_SIZE(levels);i++) {
1888 r.in.level = levels[i];
1892 printf("testing NetShareEnum level %u\n", r.in.level);
1893 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r);
1894 if (!NT_STATUS_IS_OK(status)) {
1895 printf("NetShareEnum level %u failed - %s\n",
1896 r.in.level, nt_errstr(status));
1900 if (!W_ERROR_IS_OK(r.out.result)) {
1901 printf("NetShareEnum level %u failed - %s\n",
1902 r.in.level, win_errstr(r.out.result));
1905 if (r.in.level == 0) {
1906 struct srvsvc_NetShareCtr0 *ctr = r.out.ctr.ctr0;
1907 if (ctr->count > 0) {
1908 *one_sharename = ctr->array[0].name;
1916 bool torture_samba3_rpc_srvsvc(struct torture_context *torture)
1918 struct dcerpc_pipe *p;
1919 TALLOC_CTX *mem_ctx;
1921 const char *sharename = NULL;
1922 struct smbcli_state *cli;
1925 if (!(mem_ctx = talloc_new(torture))) {
1929 if (!(torture_open_connection_share(
1930 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
1931 "IPC$", torture->ev))) {
1932 talloc_free(mem_ctx);
1936 status = pipe_bind_smb(mem_ctx, torture->lp_ctx, cli->tree,
1937 "\\pipe\\srvsvc", &ndr_table_srvsvc, &p);
1938 if (!NT_STATUS_IS_OK(status)) {
1939 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1940 __location__, nt_errstr(status));
1945 ret &= test_NetShareEnum(p, mem_ctx, &sharename);
1946 if (sharename == NULL) {
1947 printf("did not get sharename\n");
1949 ret &= test_NetShareGetInfo(p, mem_ctx, sharename);
1953 talloc_free(mem_ctx);
1958 * Do a ReqChallenge/Auth2 with a random wks name, make sure it returns
1959 * NT_STATUS_NO_SAM_ACCOUNT
1962 bool torture_samba3_rpc_randomauth2(struct torture_context *torture)
1964 TALLOC_CTX *mem_ctx;
1965 struct dcerpc_pipe *net_pipe;
1967 bool result = false;
1969 struct netr_ServerReqChallenge r;
1970 struct netr_Credential netr_cli_creds;
1971 struct netr_Credential netr_srv_creds;
1972 uint32_t negotiate_flags;
1973 struct netr_ServerAuthenticate2 a;
1974 struct creds_CredentialState *creds_state;
1975 struct netr_Credential netr_cred;
1976 struct samr_Password mach_pw;
1977 struct smbcli_state *cli;
1979 if (!(mem_ctx = talloc_new(torture))) {
1980 d_printf("talloc_new failed\n");
1984 if (!(wksname = generate_random_str_list(
1985 mem_ctx, 14, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"))) {
1986 d_printf("generate_random_str_list failed\n");
1990 if (!(torture_open_connection_share(
1992 torture, torture_setting_string(torture, "host", NULL),
1993 "IPC$", torture->ev))) {
1994 d_printf("IPC$ connection failed\n");
1998 if (!(net_pipe = dcerpc_pipe_init(
1999 mem_ctx, cli->transport->socket->event.ctx,
2000 lp_iconv_convenience(torture->lp_ctx)))) {
2001 d_printf("dcerpc_pipe_init failed\n");
2005 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
2006 if (!NT_STATUS_IS_OK(status)) {
2007 d_printf("dcerpc_pipe_open_smb failed: %s\n",
2012 status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon);
2013 if (!NT_STATUS_IS_OK(status)) {
2014 d_printf("dcerpc_bind_auth_none failed: %s\n",
2019 r.in.computer_name = wksname;
2020 r.in.server_name = talloc_asprintf(
2021 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
2022 if (r.in.server_name == NULL) {
2023 d_printf("talloc_asprintf failed\n");
2026 generate_random_buffer(netr_cli_creds.data,
2027 sizeof(netr_cli_creds.data));
2028 r.in.credentials = &netr_cli_creds;
2029 r.out.credentials = &netr_srv_creds;
2031 status = dcerpc_netr_ServerReqChallenge(net_pipe, mem_ctx, &r);
2032 if (!NT_STATUS_IS_OK(status)) {
2033 d_printf("netr_ServerReqChallenge failed: %s\n",
2038 negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
2039 E_md4hash("foobar", mach_pw.hash);
2041 creds_state = talloc(mem_ctx, struct creds_CredentialState);
2042 creds_client_init(creds_state, r.in.credentials,
2043 r.out.credentials, &mach_pw,
2044 &netr_cred, negotiate_flags);
2046 a.in.server_name = talloc_asprintf(
2047 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
2048 a.in.account_name = talloc_asprintf(
2049 mem_ctx, "%s$", wksname);
2050 a.in.computer_name = wksname;
2051 a.in.secure_channel_type = SEC_CHAN_WKSTA;
2052 a.in.negotiate_flags = &negotiate_flags;
2053 a.out.negotiate_flags = &negotiate_flags;
2054 a.in.credentials = &netr_cred;
2055 a.out.credentials = &netr_cred;
2057 status = dcerpc_netr_ServerAuthenticate2(net_pipe, mem_ctx, &a);
2059 if (!NT_STATUS_EQUAL(status, NT_STATUS_NO_TRUST_SAM_ACCOUNT)) {
2060 d_printf("dcerpc_netr_ServerAuthenticate2 returned %s, "
2061 "expected NT_STATUS_NO_TRUST_SAM_ACCOUNT\n",
2068 talloc_free(mem_ctx);
2072 static struct security_descriptor *get_sharesec(TALLOC_CTX *mem_ctx,
2073 struct loadparm_context *lp_ctx,
2074 struct smbcli_session *sess,
2075 const char *sharename)
2077 struct smbcli_tree *tree;
2078 TALLOC_CTX *tmp_ctx;
2079 struct dcerpc_pipe *p;
2081 struct srvsvc_NetShareGetInfo r;
2082 struct security_descriptor *result;
2084 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2085 d_printf("talloc_new failed\n");
2089 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) {
2090 d_printf("secondary_tcon failed\n");
2091 talloc_free(tmp_ctx);
2095 status = pipe_bind_smb(mem_ctx, lp_ctx, tree, "\\pipe\\srvsvc",
2096 &ndr_table_srvsvc, &p);
2097 if (!NT_STATUS_IS_OK(status)) {
2098 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
2099 __location__, nt_errstr(status));
2100 talloc_free(tmp_ctx);
2105 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2108 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
2109 dcerpc_server_name(p));
2110 r.in.share_name = sharename;
2113 status = dcerpc_srvsvc_NetShareGetInfo(p, tmp_ctx, &r);
2114 if (!NT_STATUS_IS_OK(status)) {
2115 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
2117 talloc_free(tmp_ctx);
2121 result = talloc_steal(mem_ctx, r.out.info.info502->sd);
2122 talloc_free(tmp_ctx);
2126 static NTSTATUS set_sharesec(TALLOC_CTX *mem_ctx,
2127 struct loadparm_context *lp_ctx,
2128 struct smbcli_session *sess,
2129 const char *sharename,
2130 struct security_descriptor *sd)
2132 struct smbcli_tree *tree;
2133 TALLOC_CTX *tmp_ctx;
2134 struct dcerpc_pipe *p;
2136 struct sec_desc_buf i;
2137 struct srvsvc_NetShareSetInfo r;
2140 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2141 d_printf("talloc_new failed\n");
2142 return NT_STATUS_NO_MEMORY;
2145 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) {
2146 d_printf("secondary_tcon failed\n");
2147 talloc_free(tmp_ctx);
2148 return NT_STATUS_UNSUCCESSFUL;
2151 status = pipe_bind_smb(mem_ctx, lp_ctx, tree, "\\pipe\\srvsvc",
2152 &ndr_table_srvsvc, &p);
2153 if (!NT_STATUS_IS_OK(status)) {
2154 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
2155 __location__, nt_errstr(status));
2156 talloc_free(tmp_ctx);
2157 return NT_STATUS_UNSUCCESSFUL;
2161 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2164 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
2165 dcerpc_server_name(p));
2166 r.in.share_name = sharename;
2169 r.in.info.info1501 = &i;
2170 r.in.parm_error = &error;
2172 status = dcerpc_srvsvc_NetShareSetInfo(p, tmp_ctx, &r);
2173 if (!NT_STATUS_IS_OK(status)) {
2174 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
2178 talloc_free(tmp_ctx);
2182 bool try_tcon(TALLOC_CTX *mem_ctx,
2183 struct loadparm_context *lp_ctx,
2184 struct security_descriptor *orig_sd,
2185 struct smbcli_session *session,
2186 const char *sharename, const struct dom_sid *user_sid,
2187 unsigned int access_mask, NTSTATUS expected_tcon,
2188 NTSTATUS expected_mkdir)
2190 TALLOC_CTX *tmp_ctx;
2191 struct smbcli_tree *rmdir_tree, *tree;
2192 struct dom_sid *domain_sid;
2194 struct security_descriptor *sd;
2198 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2199 d_printf("talloc_new failed\n");
2203 status = secondary_tcon(tmp_ctx, session, sharename, &rmdir_tree);
2204 if (!NT_STATUS_IS_OK(status)) {
2205 d_printf("first tcon to delete dir failed\n");
2206 talloc_free(tmp_ctx);
2210 smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2212 if (!NT_STATUS_IS_OK(dom_sid_split_rid(tmp_ctx, user_sid,
2213 &domain_sid, &rid))) {
2214 d_printf("dom_sid_split_rid failed\n");
2215 talloc_free(tmp_ctx);
2219 sd = security_descriptor_dacl_create(
2220 tmp_ctx, 0, "S-1-5-32-544",
2221 dom_sid_string(mem_ctx, dom_sid_add_rid(mem_ctx, domain_sid,
2223 dom_sid_string(mem_ctx, user_sid),
2224 SEC_ACE_TYPE_ACCESS_ALLOWED, access_mask, 0, NULL);
2226 d_printf("security_descriptor_dacl_create failed\n");
2227 talloc_free(tmp_ctx);
2231 status = set_sharesec(mem_ctx, lp_ctx, session, sharename, sd);
2232 if (!NT_STATUS_IS_OK(status)) {
2233 d_printf("custom set_sharesec failed: %s\n",
2235 talloc_free(tmp_ctx);
2239 status = secondary_tcon(tmp_ctx, session, sharename, &tree);
2240 if (!NT_STATUS_EQUAL(status, expected_tcon)) {
2241 d_printf("Expected %s, got %s\n", nt_errstr(expected_tcon),
2247 if (!NT_STATUS_IS_OK(status)) {
2248 /* An expected non-access, no point in trying to write */
2252 status = smbcli_mkdir(tree, "sharesec_testdir");
2253 if (!NT_STATUS_EQUAL(status, expected_mkdir)) {
2254 d_printf("(%s) Expected %s, got %s\n", __location__,
2255 nt_errstr(expected_mkdir), nt_errstr(status));
2260 smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2262 status = set_sharesec(mem_ctx, lp_ctx, session, sharename, orig_sd);
2263 if (!NT_STATUS_IS_OK(status)) {
2264 d_printf("custom set_sharesec failed: %s\n",
2266 talloc_free(tmp_ctx);
2270 talloc_free(tmp_ctx);
2274 bool torture_samba3_rpc_sharesec(struct torture_context *torture)
2276 TALLOC_CTX *mem_ctx;
2278 struct smbcli_state *cli;
2279 struct security_descriptor *sd;
2280 struct dom_sid *user_sid;
2282 if (!(mem_ctx = talloc_new(torture))) {
2286 if (!(torture_open_connection_share(
2287 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
2288 "IPC$", torture->ev))) {
2289 d_printf("IPC$ connection failed\n");
2290 talloc_free(mem_ctx);
2294 if (!(user_sid = whoami(mem_ctx, torture->lp_ctx, cli->tree))) {
2295 d_printf("whoami failed\n");
2296 talloc_free(mem_ctx);
2300 sd = get_sharesec(mem_ctx, torture->lp_ctx, cli->session,
2301 torture_setting_string(torture, "share", NULL));
2303 ret &= try_tcon(mem_ctx, torture->lp_ctx, sd, cli->session,
2304 torture_setting_string(torture, "share", NULL),
2305 user_sid, 0, NT_STATUS_ACCESS_DENIED, NT_STATUS_OK);
2307 ret &= try_tcon(mem_ctx, torture->lp_ctx, sd, cli->session,
2308 torture_setting_string(torture, "share", NULL),
2309 user_sid, SEC_FILE_READ_DATA, NT_STATUS_OK,
2310 NT_STATUS_MEDIA_WRITE_PROTECTED);
2312 ret &= try_tcon(mem_ctx, torture->lp_ctx, sd, cli->session,
2313 torture_setting_string(torture, "share", NULL),
2314 user_sid, SEC_FILE_ALL, NT_STATUS_OK, NT_STATUS_OK);
2316 talloc_free(mem_ctx);
2320 bool torture_samba3_rpc_lsa(struct torture_context *torture)
2322 TALLOC_CTX *mem_ctx;
2324 struct smbcli_state *cli;
2325 struct dcerpc_pipe *p;
2326 struct policy_handle lsa_handle;
2328 struct dom_sid *domain_sid;
2330 if (!(mem_ctx = talloc_new(torture))) {
2334 if (!(torture_open_connection_share(
2335 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
2336 "IPC$", torture->ev))) {
2337 d_printf("IPC$ connection failed\n");
2338 talloc_free(mem_ctx);
2342 status = pipe_bind_smb(mem_ctx, torture->lp_ctx, cli->tree, "\\lsarpc",
2343 &ndr_table_lsarpc, &p);
2344 if (!NT_STATUS_IS_OK(status)) {
2345 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2347 talloc_free(mem_ctx);
2352 struct lsa_ObjectAttribute attr;
2353 struct lsa_OpenPolicy2 o;
2354 o.in.system_name = talloc_asprintf(
2355 mem_ctx, "\\\\%s", dcerpc_server_name(p));
2358 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2359 o.out.handle = &lsa_handle;
2360 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &o);
2361 if (!NT_STATUS_IS_OK(status)) {
2362 d_printf("(%s) dcerpc_lsa_OpenPolicy2 failed: %s\n",
2363 __location__, nt_errstr(status));
2364 talloc_free(mem_ctx);
2370 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2375 int levels[] = { 2,3,5,6 };
2377 for (i=0; i<ARRAY_SIZE(levels); i++) {
2378 struct lsa_QueryInfoPolicy r;
2379 r.in.handle = &lsa_handle;
2380 r.in.level = levels[i];
2381 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
2382 if (!NT_STATUS_IS_OK(status)) {
2383 d_printf("(%s) dcerpc_lsa_QueryInfoPolicy %d "
2384 "failed: %s\n", __location__,
2385 levels[i], nt_errstr(status));
2386 talloc_free(mem_ctx);
2389 if (levels[i] == 5) {
2390 domain_sid = r.out.info->account_domain.sid;
2398 static NTSTATUS get_servername(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree,
2399 struct smb_iconv_convenience *iconv_convenience,
2402 struct rap_WserverGetInfo r;
2404 char servername[17];
2407 r.in.bufsize = 0xffff;
2409 status = smbcli_rap_netservergetinfo(tree, iconv_convenience, mem_ctx, &r);
2410 if (!NT_STATUS_IS_OK(status)) {
2414 memcpy(servername, r.out.info.info0.name, 16);
2415 servername[16] = '\0';
2417 if (pull_ascii_talloc(mem_ctx, iconv_convenience,
2418 name, servername) < 0) {
2419 return NT_STATUS_NO_MEMORY;
2422 return NT_STATUS_OK;
2426 static NTSTATUS find_printers(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx,
2427 struct smbcli_tree *tree,
2428 const char ***printers, int *num_printers)
2430 TALLOC_CTX *mem_ctx;
2432 struct dcerpc_pipe *p;
2433 struct srvsvc_NetShareEnum r;
2434 struct srvsvc_NetShareCtr1 c1_in;
2435 struct srvsvc_NetShareCtr1 *c1;
2438 mem_ctx = talloc_new(ctx);
2439 if (mem_ctx == NULL) {
2440 return NT_STATUS_NO_MEMORY;
2443 status = pipe_bind_smb(mem_ctx, lp_ctx,
2444 tree, "\\srvsvc", &ndr_table_srvsvc,
2446 if (!NT_STATUS_IS_OK(status)) {
2447 d_printf("could not bind to srvsvc pipe\n");
2448 talloc_free(mem_ctx);
2452 r.in.server_unc = talloc_asprintf(
2453 mem_ctx, "\\\\%s", dcerpc_server_name(p));
2456 r.in.ctr.ctr1 = &c1_in;
2457 r.in.max_buffer = (uint32_t)-1;
2458 r.in.resume_handle = NULL;
2460 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r);
2461 if (!NT_STATUS_IS_OK(status)) {
2462 d_printf("NetShareEnum level %u failed - %s\n",
2463 r.in.level, nt_errstr(status));
2464 talloc_free(mem_ctx);
2470 c1 = r.out.ctr.ctr1;
2471 for (i=0; i<c1->count; i++) {
2472 if (c1->array[i].type != STYPE_PRINTQ) {
2475 if (!add_string_to_array(ctx, c1->array[i].name,
2476 printers, num_printers)) {
2478 return NT_STATUS_NO_MEMORY;
2482 talloc_free(mem_ctx);
2483 return NT_STATUS_OK;
2486 static bool enumprinters(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *pipe,
2487 const char *servername, int level, int *num_printers)
2489 struct spoolss_EnumPrinters r;
2493 r.in.flags = PRINTER_ENUM_LOCAL;
2494 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", servername);
2499 status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
2500 if (!NT_STATUS_IS_OK(status)) {
2501 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s\n",
2502 __location__, nt_errstr(status));
2506 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2507 d_printf("(%s) EnumPrinters unexpected return code %s, should "
2508 "be WERR_INSUFFICIENT_BUFFER\n", __location__,
2509 win_errstr(r.out.result));
2513 blob = data_blob_talloc_zero(mem_ctx, r.out.needed);
2514 if (blob.data == NULL) {
2515 d_printf("(%s) data_blob_talloc failed\n", __location__);
2519 r.in.buffer = &blob;
2520 r.in.offered = r.out.needed;
2522 status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
2523 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2524 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s, "
2525 "%s\n", __location__, nt_errstr(status),
2526 win_errstr(r.out.result));
2530 *num_printers = r.out.count;
2535 static NTSTATUS getprinterinfo(TALLOC_CTX *ctx, struct dcerpc_pipe *pipe,
2536 struct policy_handle *handle, int level,
2537 union spoolss_PrinterInfo **res)
2539 TALLOC_CTX *mem_ctx;
2540 struct spoolss_GetPrinter r;
2544 mem_ctx = talloc_new(ctx);
2545 if (mem_ctx == NULL) {
2546 return NT_STATUS_NO_MEMORY;
2549 r.in.handle = handle;
2554 status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r);
2555 if (!NT_STATUS_IS_OK(status)) {
2556 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s\n",
2557 __location__, nt_errstr(status));
2558 talloc_free(mem_ctx);
2562 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2563 printf("GetPrinter unexpected return code %s, should "
2564 "be WERR_INSUFFICIENT_BUFFER\n",
2565 win_errstr(r.out.result));
2566 talloc_free(mem_ctx);
2567 return NT_STATUS_UNSUCCESSFUL;
2570 r.in.handle = handle;
2572 blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
2573 if (blob.data == NULL) {
2574 talloc_free(mem_ctx);
2575 return NT_STATUS_NO_MEMORY;
2577 memset(blob.data, 0, blob.length);
2578 r.in.buffer = &blob;
2579 r.in.offered = r.out.needed;
2581 status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r);
2582 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2583 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s, "
2584 "%s\n", __location__, nt_errstr(status),
2585 win_errstr(r.out.result));
2586 talloc_free(mem_ctx);
2587 return NT_STATUS_IS_OK(status) ?
2588 NT_STATUS_UNSUCCESSFUL : status;
2592 *res = talloc_steal(ctx, r.out.info);
2595 talloc_free(mem_ctx);
2596 return NT_STATUS_OK;
2599 bool torture_samba3_rpc_spoolss(struct torture_context *torture)
2601 TALLOC_CTX *mem_ctx;
2603 struct smbcli_state *cli;
2604 struct dcerpc_pipe *p;
2606 struct policy_handle server_handle, printer_handle;
2607 const char **printers;
2609 struct spoolss_UserLevel1 userlevel1;
2612 if (!(mem_ctx = talloc_new(torture))) {
2616 if (!(torture_open_connection_share(
2617 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
2618 "IPC$", torture->ev))) {
2619 d_printf("IPC$ connection failed\n");
2620 talloc_free(mem_ctx);
2624 status = get_servername(mem_ctx, cli->tree, lp_iconv_convenience(torture->lp_ctx), &servername);
2625 if (!NT_STATUS_IS_OK(status)) {
2626 d_fprintf(stderr, "(%s) get_servername returned %s\n",
2627 __location__, nt_errstr(status));
2628 talloc_free(mem_ctx);
2632 if (!NT_STATUS_IS_OK(find_printers(mem_ctx, torture->lp_ctx, cli->tree,
2633 &printers, &num_printers))) {
2634 talloc_free(mem_ctx);
2638 if (num_printers == 0) {
2639 d_printf("Did not find printers\n");
2640 talloc_free(mem_ctx);
2644 status = pipe_bind_smb(mem_ctx, torture->lp_ctx, cli->tree, "\\spoolss",
2645 &ndr_table_spoolss, &p);
2646 if (!NT_STATUS_IS_OK(status)) {
2647 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2649 talloc_free(mem_ctx);
2653 ZERO_STRUCT(userlevel1);
2654 userlevel1.client = talloc_asprintf(
2655 mem_ctx, "\\\\%s", lp_netbios_name(torture->lp_ctx));
2656 userlevel1.user = cli_credentials_get_username(cmdline_credentials);
2657 userlevel1.build = 2600;
2658 userlevel1.major = 3;
2659 userlevel1.minor = 0;
2660 userlevel1.processor = 0;
2663 struct spoolss_OpenPrinterEx r;
2666 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
2668 r.in.datatype = NULL;
2669 r.in.access_mask = 0;
2671 r.in.userlevel.level1 = &userlevel1;
2672 r.out.handle = &server_handle;
2674 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
2675 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2676 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
2677 "%s, %s\n", __location__, nt_errstr(status),
2678 win_errstr(r.out.result));
2679 talloc_free(mem_ctx);
2685 struct spoolss_ClosePrinter r;
2687 r.in.handle = &server_handle;
2688 r.out.handle = &server_handle;
2690 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
2691 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2692 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
2693 "%s, %s\n", __location__, nt_errstr(status),
2694 win_errstr(r.out.result));
2695 talloc_free(mem_ctx);
2701 struct spoolss_OpenPrinterEx r;
2704 r.in.printername = talloc_asprintf(
2705 mem_ctx, "\\\\%s\\%s", servername, printers[0]);
2706 r.in.datatype = NULL;
2707 r.in.access_mask = 0;
2709 r.in.userlevel.level1 = &userlevel1;
2710 r.out.handle = &printer_handle;
2712 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
2713 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2714 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
2715 "%s, %s\n", __location__, nt_errstr(status),
2716 win_errstr(r.out.result));
2717 talloc_free(mem_ctx);
2725 for (i=0; i<8; i++) {
2726 status = getprinterinfo(mem_ctx, p, &printer_handle,
2728 if (!NT_STATUS_IS_OK(status)) {
2729 d_printf("(%s) getprinterinfo %d failed: %s\n",
2730 __location__, i, nt_errstr(status));
2737 struct spoolss_ClosePrinter r;
2739 r.in.handle = &printer_handle;
2740 r.out.handle = &printer_handle;
2742 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
2743 if (!NT_STATUS_IS_OK(status)) {
2744 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
2745 "%s\n", __location__, nt_errstr(status));
2746 talloc_free(mem_ctx);
2753 if (!enumprinters(mem_ctx, p, servername, 1,
2755 d_printf("(%s) enumprinters failed\n", __location__);
2756 talloc_free(mem_ctx);
2759 if (num_printers != num_enumerated) {
2760 d_printf("(%s) netshareenum gave %d printers, "
2761 "enumprinters lvl 1 gave %d\n", __location__,
2762 num_printers, num_enumerated);
2763 talloc_free(mem_ctx);
2770 if (!enumprinters(mem_ctx, p, servername, 2,
2772 d_printf("(%s) enumprinters failed\n", __location__);
2773 talloc_free(mem_ctx);
2776 if (num_printers != num_enumerated) {
2777 d_printf("(%s) netshareenum gave %d printers, "
2778 "enumprinters lvl 2 gave %d\n", __location__,
2779 num_printers, num_enumerated);
2780 talloc_free(mem_ctx);
2785 talloc_free(mem_ctx);
2790 bool torture_samba3_rpc_wkssvc(struct torture_context *torture)
2792 TALLOC_CTX *mem_ctx;
2793 struct smbcli_state *cli;
2794 struct dcerpc_pipe *p;
2798 if (!(mem_ctx = talloc_new(torture))) {
2802 if (!(torture_open_connection_share(
2803 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
2804 "IPC$", torture->ev))) {
2805 d_printf("IPC$ connection failed\n");
2806 talloc_free(mem_ctx);
2810 status = get_servername(mem_ctx, cli->tree, lp_iconv_convenience(torture->lp_ctx), &servername);
2811 if (!NT_STATUS_IS_OK(status)) {
2812 d_fprintf(stderr, "(%s) get_servername returned %s\n",
2813 __location__, nt_errstr(status));
2814 talloc_free(mem_ctx);
2818 status = pipe_bind_smb(mem_ctx, torture->lp_ctx, cli->tree, "\\wkssvc",
2819 &ndr_table_wkssvc, &p);
2820 if (!NT_STATUS_IS_OK(status)) {
2821 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2823 talloc_free(mem_ctx);
2828 struct wkssvc_NetWkstaInfo100 wks100;
2829 union wkssvc_NetWkstaInfo info;
2830 struct wkssvc_NetWkstaGetInfo r;
2832 r.in.server_name = "\\foo";
2834 info.info100 = &wks100;
2837 status = dcerpc_wkssvc_NetWkstaGetInfo(p, mem_ctx, &r);
2838 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2839 d_printf("(%s) dcerpc_wkssvc_NetWksGetInfo failed: "
2840 "%s, %s\n", __location__, nt_errstr(status),
2841 win_errstr(r.out.result));
2842 talloc_free(mem_ctx);
2846 if (strcmp(servername,
2847 r.out.info->info100->server_name) != 0) {
2848 d_printf("(%s) servername inconsistency: RAP=%s, "
2849 "dcerpc_wkssvc_NetWksGetInfo=%s",
2850 __location__, servername,
2851 r.out.info->info100->server_name);
2852 talloc_free(mem_ctx);
2857 talloc_free(mem_ctx);
2861 static NTSTATUS winreg_close(struct dcerpc_pipe *p,
2862 struct policy_handle *handle)
2864 struct winreg_CloseKey c;
2866 TALLOC_CTX *mem_ctx;
2868 c.in.handle = c.out.handle = handle;
2870 if (!(mem_ctx = talloc_new(p))) {
2871 return NT_STATUS_NO_MEMORY;
2874 status = dcerpc_winreg_CloseKey(p, mem_ctx, &c);
2875 talloc_free(mem_ctx);
2877 if (!NT_STATUS_IS_OK(status)) {
2881 if (!W_ERROR_IS_OK(c.out.result)) {
2882 return werror_to_ntstatus(c.out.result);
2885 return NT_STATUS_OK;
2888 static NTSTATUS enumvalues(struct dcerpc_pipe *p, struct policy_handle *handle,
2889 TALLOC_CTX *mem_ctx)
2891 uint32_t enum_index = 0;
2894 struct winreg_EnumValue r;
2895 struct winreg_StringBuf name;
2896 enum winreg_Type type = 0;
2899 uint32_t size, length;
2901 r.in.handle = handle;
2902 r.in.enum_index = enum_index;
2905 r.in.name = r.out.name = &name;
2911 r.in.length = &length;
2913 status = dcerpc_winreg_EnumValue(p, mem_ctx, &r);
2914 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2915 return NT_STATUS_OK;
2921 static NTSTATUS enumkeys(struct dcerpc_pipe *p, struct policy_handle *handle,
2922 TALLOC_CTX *mem_ctx, int depth)
2924 struct winreg_EnumKey r;
2925 struct winreg_StringBuf class, name;
2930 return NT_STATUS_OK;
2936 r.in.handle = handle;
2937 r.in.enum_index = 0;
2939 r.in.keyclass = &class;
2941 r.in.last_changed_time = &t;
2944 TALLOC_CTX *tmp_ctx;
2945 struct winreg_OpenKey o;
2946 struct policy_handle key_handle;
2949 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2950 return NT_STATUS_NO_MEMORY;
2956 status = dcerpc_winreg_EnumKey(p, tmp_ctx, &r);
2957 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2958 /* We're done enumerating */
2959 talloc_free(tmp_ctx);
2960 return NT_STATUS_OK;
2963 for (i=0; i<10-depth; i++)
2965 printf("%s\n", r.out.name->name);
2968 o.in.parent_handle = handle;
2969 o.in.keyname.name = r.out.name->name;
2971 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2972 o.out.handle = &key_handle;
2974 status = dcerpc_winreg_OpenKey(p, tmp_ctx, &o);
2975 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(o.out.result)) {
2976 enumkeys(p, &key_handle, tmp_ctx, depth-1);
2977 enumvalues(p, &key_handle, tmp_ctx);
2978 status = winreg_close(p, &key_handle);
2979 if (!NT_STATUS_IS_OK(status)) {
2984 talloc_free(tmp_ctx);
2986 r.in.enum_index += 1;
2989 return NT_STATUS_OK;
2992 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
2994 static bool test_Open3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2995 const char *name, winreg_open_fn open_fn)
2997 struct policy_handle handle;
2998 struct winreg_OpenHKLM r;
3001 r.in.system_name = 0;
3002 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3003 r.out.handle = &handle;
3005 status = open_fn(p, mem_ctx, &r);
3006 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
3007 d_printf("(%s) %s failed: %s, %s\n", __location__, name,
3008 nt_errstr(status), win_errstr(r.out.result));
3012 enumkeys(p, &handle, mem_ctx, 4);
3014 status = winreg_close(p, &handle);
3015 if (!NT_STATUS_IS_OK(status)) {
3016 d_printf("(%s) dcerpc_CloseKey failed: %s\n",
3017 __location__, nt_errstr(status));
3024 bool torture_samba3_rpc_winreg(struct torture_context *torture)
3027 struct dcerpc_pipe *p;
3028 TALLOC_CTX *mem_ctx;
3034 {"OpenHKLM", (winreg_open_fn)dcerpc_winreg_OpenHKLM },
3035 {"OpenHKU", (winreg_open_fn)dcerpc_winreg_OpenHKU },
3036 {"OpenHKPD", (winreg_open_fn)dcerpc_winreg_OpenHKPD },
3037 {"OpenHKPT", (winreg_open_fn)dcerpc_winreg_OpenHKPT },
3038 {"OpenHKCR", (winreg_open_fn)dcerpc_winreg_OpenHKCR }};
3043 mem_ctx = talloc_init("torture_rpc_winreg");
3045 status = torture_rpc_connection(torture, &p, &ndr_table_winreg);
3047 if (!NT_STATUS_IS_OK(status)) {
3048 talloc_free(mem_ctx);
3053 ret = test_Open3(p, mem_ctx, open_fns[0].name, open_fns[0].fn);
3055 for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
3056 if (!test_Open3(p, mem_ctx, open_fns[i].name, open_fns[i].fn))
3061 talloc_free(mem_ctx);
3066 static NTSTATUS get_shareinfo(TALLOC_CTX *mem_ctx,
3067 struct loadparm_context *lp_ctx,
3068 struct smbcli_state *cli,
3070 struct srvsvc_NetShareInfo502 **info)
3072 struct smbcli_tree *ipc;
3073 struct dcerpc_pipe *p;
3074 struct srvsvc_NetShareGetInfo r;
3077 if (!(p = dcerpc_pipe_init(cli,
3078 cli->transport->socket->event.ctx,
3079 lp_iconv_convenience(lp_ctx)))) {
3080 status = NT_STATUS_NO_MEMORY;
3084 status = secondary_tcon(p, cli->session, "IPC$", &ipc);
3085 if (!NT_STATUS_IS_OK(status)) {
3089 status = dcerpc_pipe_open_smb(p, ipc, "\\pipe\\srvsvc");
3090 if (!NT_STATUS_IS_OK(status)) {
3091 d_printf("dcerpc_pipe_open_smb failed: %s\n",
3096 status = dcerpc_bind_auth_none(p, &ndr_table_srvsvc);
3097 if (!NT_STATUS_IS_OK(status)) {
3098 d_printf("dcerpc_bind_auth_none failed: %s\n",
3103 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s",
3104 dcerpc_server_name(p));
3105 r.in.share_name = share;
3108 status = dcerpc_srvsvc_NetShareGetInfo(p, p, &r);
3109 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
3110 d_printf("(%s) OpenHKLM failed: %s, %s\n", __location__,
3111 nt_errstr(status), win_errstr(r.out.result));
3115 *info = talloc_move(mem_ctx, &r.out.info.info502);
3116 return NT_STATUS_OK;
3124 * Get us a handle on HKLM\
3127 static NTSTATUS get_hklm_handle(TALLOC_CTX *mem_ctx,
3128 struct smbcli_state *cli,
3129 struct smb_iconv_convenience *iconv_convenience,
3130 struct dcerpc_pipe **pipe_p,
3131 struct policy_handle **handle)
3133 struct smbcli_tree *ipc;
3134 struct dcerpc_pipe *p;
3135 struct winreg_OpenHKLM r;
3137 struct policy_handle *result;
3139 result = talloc(mem_ctx, struct policy_handle);
3141 if (result == NULL) {
3142 return NT_STATUS_NO_MEMORY;
3145 if (!(p = dcerpc_pipe_init(result,
3146 cli->transport->socket->event.ctx,
3147 iconv_convenience))) {
3148 status = NT_STATUS_NO_MEMORY;
3152 status = secondary_tcon(p, cli->session, "IPC$", &ipc);
3153 if (!NT_STATUS_IS_OK(status)) {
3157 status = dcerpc_pipe_open_smb(p, ipc, "\\winreg");
3158 if (!NT_STATUS_IS_OK(status)) {
3159 d_printf("dcerpc_pipe_open_smb failed: %s\n",
3164 status = dcerpc_bind_auth_none(p, &ndr_table_winreg);
3165 if (!NT_STATUS_IS_OK(status)) {
3166 d_printf("dcerpc_bind_auth_none failed: %s\n",
3171 r.in.system_name = 0;
3172 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3173 r.out.handle = result;
3175 status = dcerpc_winreg_OpenHKLM(p, p, &r);
3176 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
3177 d_printf("(%s) OpenHKLM failed: %s, %s\n", __location__,
3178 nt_errstr(status), win_errstr(r.out.result));
3184 return NT_STATUS_OK;
3187 talloc_free(result);
3191 static NTSTATUS torture_samba3_createshare(struct smbcli_state *cli,
3192 struct smb_iconv_convenience *iconv_convenience,
3193 const char *sharename)
3195 struct dcerpc_pipe *p;
3196 struct policy_handle *hklm = NULL;
3197 struct policy_handle new_handle;
3198 struct winreg_CreateKey c;
3199 struct winreg_CloseKey cl;
3200 enum winreg_CreateAction action_taken;
3202 TALLOC_CTX *mem_ctx;
3204 mem_ctx = talloc_new(cli);
3205 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
3207 status = get_hklm_handle(mem_ctx, cli, iconv_convenience, &p, &hklm);
3208 if (!NT_STATUS_IS_OK(status)) {
3209 d_printf("get_hklm_handle failed: %s\n", nt_errstr(status));
3214 c.in.name.name = talloc_asprintf(
3215 mem_ctx, "software\\samba\\smbconf\\%s", sharename);
3216 if (c.in.name.name == NULL) {
3217 d_printf("talloc_asprintf failed\n");
3218 status = NT_STATUS_NO_MEMORY;
3221 c.in.keyclass.name = "";
3223 c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3224 c.in.secdesc = NULL;
3225 c.in.action_taken = &action_taken;
3226 c.out.new_handle = &new_handle;
3227 c.out.action_taken = &action_taken;
3229 status = dcerpc_winreg_CreateKey(p, p, &c);
3230 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(c.out.result)) {
3231 d_printf("(%s) OpenKey failed: %s, %s\n", __location__,
3232 nt_errstr(status), win_errstr(c.out.result));
3236 cl.in.handle = &new_handle;
3237 cl.out.handle = &new_handle;
3238 status = dcerpc_winreg_CloseKey(p, p, &cl);
3239 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(cl.out.result)) {
3240 d_printf("(%s) OpenKey failed: %s, %s\n", __location__,
3241 nt_errstr(status), win_errstr(cl.out.result));
3247 talloc_free(mem_ctx);
3251 static NTSTATUS torture_samba3_deleteshare(struct torture_context *torture,
3252 struct smbcli_state *cli,
3253 const char *sharename)
3255 struct dcerpc_pipe *p;
3256 struct policy_handle *hklm = NULL;
3257 struct winreg_DeleteKey d;
3259 TALLOC_CTX *mem_ctx;
3261 mem_ctx = talloc_new(cli);
3262 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
3264 status = get_hklm_handle(cli, cli, lp_iconv_convenience(torture->lp_ctx),
3266 if (!NT_STATUS_IS_OK(status)) {
3267 d_printf("get_hklm_handle failed: %s\n", nt_errstr(status));
3272 d.in.key.name = talloc_asprintf(
3273 mem_ctx, "software\\samba\\smbconf\\%s", sharename);
3274 if (d.in.key.name == NULL) {
3275 d_printf("talloc_asprintf failed\n");
3276 status = NT_STATUS_NO_MEMORY;
3279 status = dcerpc_winreg_DeleteKey(p, p, &d);
3280 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(d.out.result)) {
3281 d_printf("(%s) OpenKey failed: %s, %s\n", __location__,
3282 nt_errstr(status), win_errstr(d.out.result));
3287 talloc_free(mem_ctx);
3291 static NTSTATUS torture_samba3_setconfig(struct smbcli_state *cli,
3292 struct loadparm_context *lp_ctx,
3293 const char *sharename,
3294 const char *parameter,
3297 struct dcerpc_pipe *p = NULL;
3298 struct policy_handle *hklm = NULL, key_handle;
3299 struct winreg_OpenKey o;
3300 struct winreg_SetValue s;
3305 status = get_hklm_handle(cli, cli, lp_iconv_convenience(lp_ctx), &p, &hklm);
3306 if (!NT_STATUS_IS_OK(status)) {
3307 d_printf("get_hklm_handle failed: %s\n", nt_errstr(status));
3311 o.in.parent_handle = hklm;
3312 o.in.keyname.name = talloc_asprintf(
3313 hklm, "software\\samba\\smbconf\\%s", sharename);
3314 if (o.in.keyname.name == NULL) {
3315 d_printf("talloc_asprintf failed\n");
3316 status = NT_STATUS_NO_MEMORY;
3320 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3321 o.out.handle = &key_handle;
3323 status = dcerpc_winreg_OpenKey(p, p, &o);
3324 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(o.out.result)) {
3325 d_printf("(%s) OpenKey failed: %s, %s\n", __location__,
3326 nt_errstr(status), win_errstr(o.out.result));
3330 if (!reg_string_to_val(hklm, lp_iconv_convenience(lp_ctx), "REG_SZ",
3331 value, &type, &val)) {
3332 d_printf("(%s) reg_string_to_val failed\n", __location__);
3336 s.in.handle = &key_handle;
3337 s.in.name.name = parameter;
3339 s.in.data = val.data;
3340 s.in.size = val.length;
3342 status = dcerpc_winreg_SetValue(p, p, &s);
3343 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(s.out.result)) {
3344 d_printf("(%s) SetValue failed: %s, %s\n", __location__,
3345 nt_errstr(status), win_errstr(s.out.result));
3354 bool torture_samba3_regconfig(struct torture_context *torture)
3356 struct smbcli_state *cli;
3357 struct srvsvc_NetShareInfo502 *i = NULL;
3360 const char *comment = "Dummer Kommentar";
3362 if (!(torture_open_connection(&cli, torture, 0))) {
3366 status = torture_samba3_createshare(cli, lp_iconv_convenience(torture->lp_ctx), "blubber");
3367 if (!NT_STATUS_IS_OK(status)) {
3368 torture_warning(torture, "torture_samba3_createshare failed: "
3369 "%s\n", nt_errstr(status));
3373 status = torture_samba3_setconfig(cli, torture->lp_ctx, "blubber", "comment", comment);
3374 if (!NT_STATUS_IS_OK(status)) {
3375 torture_warning(torture, "torture_samba3_setconfig failed: "
3376 "%s\n", nt_errstr(status));
3380 status = get_shareinfo(torture, torture->lp_ctx, cli, "blubber", &i);
3381 if (!NT_STATUS_IS_OK(status)) {
3382 torture_warning(torture, "get_shareinfo failed: "
3383 "%s\n", nt_errstr(status));
3387 if (strcmp(comment, i->comment) != 0) {
3388 torture_warning(torture, "Expected comment [%s], got [%s]\n",
3389 comment, i->comment);
3393 status = torture_samba3_deleteshare(torture, cli, "blubber");
3394 if (!NT_STATUS_IS_OK(status)) {
3395 torture_warning(torture, "torture_samba3_deleteshare failed: "
3396 "%s\n", nt_errstr(status));