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;
74 struct smbcli_options options;
76 mem_ctx = talloc_init("torture_bind_authcontext");
78 if (mem_ctx == NULL) {
79 d_printf("talloc_init failed\n");
83 lp_smbcli_options(torture->lp_ctx, &options);
85 status = smbcli_full_connection(mem_ctx, &cli,
86 torture_setting_string(torture, "host", NULL),
87 lp_smb_ports(torture->lp_ctx),
88 "IPC$", NULL, cmdline_credentials,
89 lp_resolve_context(torture->lp_ctx),
91 if (!NT_STATUS_IS_OK(status)) {
92 d_printf("smbcli_full_connection failed: %s\n",
97 lsa_pipe = dcerpc_pipe_init(mem_ctx, cli->transport->socket->event.ctx,
98 lp_iconv_convenience(torture->lp_ctx));
99 if (lsa_pipe == NULL) {
100 d_printf("dcerpc_pipe_init failed\n");
104 status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
105 if (!NT_STATUS_IS_OK(status)) {
106 d_printf("dcerpc_pipe_open_smb failed: %s\n",
111 status = dcerpc_bind_auth_none(lsa_pipe, &ndr_table_lsarpc);
112 if (!NT_STATUS_IS_OK(status)) {
113 d_printf("dcerpc_bind_auth_none failed: %s\n",
118 openpolicy.in.system_name =talloc_asprintf(
119 mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
120 ZERO_STRUCT(objectattr);
121 openpolicy.in.attr = &objectattr;
122 openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
123 openpolicy.out.handle = &handle;
125 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
127 if (!NT_STATUS_IS_OK(status)) {
128 d_printf("dcerpc_lsa_OpenPolicy2 failed: %s\n",
133 close_handle.in.handle = &handle;
134 close_handle.out.handle = &handle;
136 status = dcerpc_lsa_Close(lsa_pipe, mem_ctx, &close_handle);
137 if (!NT_STATUS_IS_OK(status)) {
138 d_printf("dcerpc_lsa_Close failed: %s\n",
143 session2 = smbcli_session_init(cli->transport, mem_ctx, false);
144 if (session2 == NULL) {
145 d_printf("smbcli_session_init failed\n");
149 if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) {
150 d_printf("create_anon_creds failed\n");
154 setup.in.sesskey = cli->transport->negotiate.sesskey;
155 setup.in.capabilities = cli->transport->negotiate.capabilities;
156 setup.in.workgroup = "";
157 setup.in.credentials = anon_creds;
159 status = smb_composite_sesssetup(session2, &setup);
160 if (!NT_STATUS_IS_OK(status)) {
161 d_printf("anon session setup failed: %s\n",
165 session2->vuid = setup.out.vuid;
167 tmp = cli->tree->session;
168 cli->tree->session = session2;
170 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
172 cli->tree->session = tmp;
173 talloc_free(lsa_pipe);
176 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
177 d_printf("dcerpc_lsa_OpenPolicy2 with wrong vuid gave %s, "
178 "expected NT_STATUS_INVALID_HANDLE\n",
185 talloc_free(mem_ctx);
190 * Bind to lsa using a specific auth method
193 static bool bindtest(struct smbcli_state *cli,
194 struct cli_credentials *credentials,
195 struct loadparm_context *lp_ctx,
196 uint8_t auth_type, uint8_t auth_level)
202 struct dcerpc_pipe *lsa_pipe;
203 struct lsa_ObjectAttribute objectattr;
204 struct lsa_OpenPolicy2 openpolicy;
205 struct lsa_QueryInfoPolicy query;
206 struct policy_handle handle;
207 struct lsa_Close close_handle;
209 if ((mem_ctx = talloc_init("bindtest")) == NULL) {
210 d_printf("talloc_init failed\n");
214 lsa_pipe = dcerpc_pipe_init(mem_ctx,
215 cli->transport->socket->event.ctx,
216 lp_iconv_convenience(lp_ctx));
217 if (lsa_pipe == NULL) {
218 d_printf("dcerpc_pipe_init failed\n");
222 status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc");
223 if (!NT_STATUS_IS_OK(status)) {
224 d_printf("dcerpc_pipe_open_smb failed: %s\n",
229 status = dcerpc_bind_auth(lsa_pipe, &ndr_table_lsarpc,
230 credentials, lp_ctx, auth_type, auth_level,
232 if (!NT_STATUS_IS_OK(status)) {
233 d_printf("dcerpc_bind_auth failed: %s\n", nt_errstr(status));
237 openpolicy.in.system_name =talloc_asprintf(
238 mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe));
239 ZERO_STRUCT(objectattr);
240 openpolicy.in.attr = &objectattr;
241 openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
242 openpolicy.out.handle = &handle;
244 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy);
246 if (!NT_STATUS_IS_OK(status)) {
247 d_printf("dcerpc_lsa_OpenPolicy2 failed: %s\n",
252 query.in.handle = &handle;
253 query.in.level = LSA_POLICY_INFO_DOMAIN;
255 status = dcerpc_lsa_QueryInfoPolicy(lsa_pipe, mem_ctx, &query);
256 if (!NT_STATUS_IS_OK(status)) {
257 d_printf("dcerpc_lsa_QueryInfoPolicy failed: %s\n",
262 close_handle.in.handle = &handle;
263 close_handle.out.handle = &handle;
265 status = dcerpc_lsa_Close(lsa_pipe, mem_ctx, &close_handle);
266 if (!NT_STATUS_IS_OK(status)) {
267 d_printf("dcerpc_lsa_Close failed: %s\n",
274 talloc_free(mem_ctx);
279 * test authenticated RPC binds with the variants Samba3 does support
282 bool torture_bind_samba3(struct torture_context *torture)
287 struct smbcli_state *cli;
288 struct smbcli_options options;
290 mem_ctx = talloc_init("torture_bind_authcontext");
292 if (mem_ctx == NULL) {
293 d_printf("talloc_init failed\n");
297 lp_smbcli_options(torture->lp_ctx, &options);
299 status = smbcli_full_connection(mem_ctx, &cli,
300 torture_setting_string(torture, "host", NULL),
301 lp_smb_ports(torture->lp_ctx),
302 "IPC$", NULL, cmdline_credentials,
303 lp_resolve_context(torture->lp_ctx),
305 if (!NT_STATUS_IS_OK(status)) {
306 d_printf("smbcli_full_connection failed: %s\n",
313 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_NTLMSSP,
314 DCERPC_AUTH_LEVEL_INTEGRITY);
315 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_NTLMSSP,
316 DCERPC_AUTH_LEVEL_PRIVACY);
317 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_SPNEGO,
318 DCERPC_AUTH_LEVEL_INTEGRITY);
319 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_SPNEGO,
320 DCERPC_AUTH_LEVEL_PRIVACY);
323 talloc_free(mem_ctx);
328 * Lookup or create a user and return all necessary info
331 static NTSTATUS get_usr_handle(struct smbcli_state *cli,
333 struct loadparm_context *lp_ctx,
334 struct cli_credentials *admin_creds,
337 const char *username,
339 struct dcerpc_pipe **result_pipe,
340 struct policy_handle **result_handle,
341 struct dom_sid **sid)
343 struct dcerpc_pipe *samr_pipe;
345 struct policy_handle conn_handle;
346 struct policy_handle domain_handle;
347 struct policy_handle *user_handle;
348 struct samr_Connect2 conn;
349 struct samr_EnumDomains enumdom;
350 uint32_t resume_handle = 0;
351 struct samr_LookupDomain l;
353 struct lsa_String domain_name;
354 struct lsa_String user_name;
355 struct samr_OpenDomain o;
356 struct samr_CreateUser2 c;
357 uint32_t user_rid,access_granted;
359 samr_pipe = dcerpc_pipe_init(mem_ctx,
360 cli->transport->socket->event.ctx,
361 lp_iconv_convenience(lp_ctx));
362 if (samr_pipe == NULL) {
363 d_printf("dcerpc_pipe_init failed\n");
364 status = NT_STATUS_NO_MEMORY;
368 status = dcerpc_pipe_open_smb(samr_pipe, cli->tree, "\\samr");
369 if (!NT_STATUS_IS_OK(status)) {
370 d_printf("dcerpc_pipe_open_smb failed: %s\n",
375 if (admin_creds != NULL) {
376 status = dcerpc_bind_auth(samr_pipe, &ndr_table_samr,
377 admin_creds, lp_ctx, auth_type, auth_level,
379 if (!NT_STATUS_IS_OK(status)) {
380 d_printf("dcerpc_bind_auth failed: %s\n",
385 /* We must have an authenticated SMB connection */
386 status = dcerpc_bind_auth_none(samr_pipe, &ndr_table_samr);
387 if (!NT_STATUS_IS_OK(status)) {
388 d_printf("dcerpc_bind_auth_none failed: %s\n",
394 conn.in.system_name = talloc_asprintf(
395 mem_ctx, "\\\\%s", dcerpc_server_name(samr_pipe));
396 conn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
397 conn.out.connect_handle = &conn_handle;
399 status = dcerpc_samr_Connect2(samr_pipe, mem_ctx, &conn);
400 if (!NT_STATUS_IS_OK(status)) {
401 d_printf("samr_Connect2 failed: %s\n", nt_errstr(status));
405 enumdom.in.connect_handle = &conn_handle;
406 enumdom.in.resume_handle = &resume_handle;
407 enumdom.in.buf_size = (uint32_t)-1;
408 enumdom.out.resume_handle = &resume_handle;
410 status = dcerpc_samr_EnumDomains(samr_pipe, mem_ctx, &enumdom);
411 if (!NT_STATUS_IS_OK(status)) {
412 d_printf("samr_EnumDomains failed: %s\n", nt_errstr(status));
416 if (enumdom.out.num_entries != 2) {
417 d_printf("samr_EnumDomains returned %d entries, expected 2\n",
418 enumdom.out.num_entries);
419 status = NT_STATUS_UNSUCCESSFUL;
423 dom_idx = strequal(enumdom.out.sam->entries[0].name.string,
426 l.in.connect_handle = &conn_handle;
427 domain_name.string = enumdom.out.sam->entries[0].name.string;
428 *domain = talloc_strdup(mem_ctx, domain_name.string);
429 l.in.domain_name = &domain_name;
431 status = dcerpc_samr_LookupDomain(samr_pipe, mem_ctx, &l);
432 if (!NT_STATUS_IS_OK(status)) {
433 d_printf("samr_LookupDomain failed: %s\n", nt_errstr(status));
437 o.in.connect_handle = &conn_handle;
438 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
439 o.in.sid = l.out.sid;
440 o.out.domain_handle = &domain_handle;
442 status = dcerpc_samr_OpenDomain(samr_pipe, mem_ctx, &o);
443 if (!NT_STATUS_IS_OK(status)) {
444 d_printf("samr_OpenDomain failed: %s\n", nt_errstr(status));
448 c.in.domain_handle = &domain_handle;
449 user_name.string = username;
450 c.in.account_name = &user_name;
451 c.in.acct_flags = ACB_NORMAL;
452 c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
453 user_handle = talloc(mem_ctx, struct policy_handle);
454 c.out.user_handle = user_handle;
455 c.out.access_granted = &access_granted;
456 c.out.rid = &user_rid;
458 status = dcerpc_samr_CreateUser2(samr_pipe, mem_ctx, &c);
460 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
461 struct samr_LookupNames ln;
462 struct samr_OpenUser ou;
464 ln.in.domain_handle = &domain_handle;
466 ln.in.names = &user_name;
468 status = dcerpc_samr_LookupNames(samr_pipe, mem_ctx, &ln);
469 if (!NT_STATUS_IS_OK(status)) {
470 d_printf("samr_LookupNames failed: %s\n",
475 ou.in.domain_handle = &domain_handle;
476 ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
477 user_rid = ou.in.rid = ln.out.rids.ids[0];
478 ou.out.user_handle = user_handle;
480 status = dcerpc_samr_OpenUser(samr_pipe, mem_ctx, &ou);
481 if (!NT_STATUS_IS_OK(status)) {
482 d_printf("samr_OpenUser failed: %s\n",
488 if (!NT_STATUS_IS_OK(status)) {
489 d_printf("samr_CreateUser failed: %s\n", nt_errstr(status));
493 *result_pipe = samr_pipe;
494 *result_handle = user_handle;
496 *sid = dom_sid_add_rid(mem_ctx, l.out.sid, user_rid);
508 static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
509 struct loadparm_context *lp_ctx,
510 struct cli_credentials *admin_creds,
511 const char *username, const char *password,
513 struct dom_sid **user_sid)
517 struct dcerpc_pipe *samr_pipe;
518 struct policy_handle *wks_handle;
521 if (!(tmp_ctx = talloc_new(mem_ctx))) {
522 d_printf("talloc_init failed\n");
526 status = get_usr_handle(cli, tmp_ctx, lp_ctx, admin_creds,
527 DCERPC_AUTH_TYPE_NTLMSSP,
528 DCERPC_AUTH_LEVEL_INTEGRITY,
529 username, domain_name, &samr_pipe, &wks_handle,
531 if (!NT_STATUS_IS_OK(status)) {
532 d_printf("get_usr_handle failed: %s\n", nt_errstr(status));
537 struct samr_SetUserInfo2 sui2;
538 struct samr_SetUserInfo sui;
539 struct samr_QueryUserInfo qui;
540 union samr_UserInfo u_info;
541 DATA_BLOB session_key;
545 encode_pw_buffer(u_info.info23.password.data, password,
548 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
549 if (!NT_STATUS_IS_OK(status)) {
550 d_printf("dcerpc_fetch_session_key failed\n");
553 arcfour_crypt_blob(u_info.info23.password.data, 516,
555 u_info.info23.info.password_expired = 0;
556 u_info.info23.info.fields_present = SAMR_FIELD_PASSWORD |
557 SAMR_FIELD_PASSWORD2 |
558 SAMR_FIELD_EXPIRED_FLAG;
559 sui2.in.user_handle = wks_handle;
560 sui2.in.info = &u_info;
563 status = dcerpc_samr_SetUserInfo2(samr_pipe, tmp_ctx, &sui2);
564 if (!NT_STATUS_IS_OK(status)) {
565 d_printf("samr_SetUserInfo(23) failed: %s\n",
570 u_info.info16.acct_flags = ACB_NORMAL;
571 sui.in.user_handle = wks_handle;
572 sui.in.info = &u_info;
575 status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
576 if (!NT_STATUS_IS_OK(status)) {
577 d_printf("samr_SetUserInfo(16) failed\n");
581 qui.in.user_handle = wks_handle;
584 status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
585 if (!NT_STATUS_IS_OK(status)) {
586 d_printf("samr_QueryUserInfo(21) failed\n");
590 qui.out.info->info21.allow_password_change = 0;
591 qui.out.info->info21.force_password_change = 0;
592 qui.out.info->info21.account_name.string = NULL;
593 qui.out.info->info21.rid = 0;
594 qui.out.info->info21.acct_expiry = 0;
595 qui.out.info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
597 u_info.info21 = qui.out.info->info21;
598 sui.in.user_handle = wks_handle;
599 sui.in.info = &u_info;
602 status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
603 if (!NT_STATUS_IS_OK(status)) {
604 d_printf("samr_SetUserInfo(21) failed\n");
609 *domain_name= talloc_steal(mem_ctx, *domain_name);
610 *user_sid = talloc_steal(mem_ctx, *user_sid);
613 talloc_free(tmp_ctx);
621 static bool delete_user(struct smbcli_state *cli,
622 struct loadparm_context *lp_ctx,
623 struct cli_credentials *admin_creds,
624 const char *username)
629 struct dcerpc_pipe *samr_pipe;
630 struct policy_handle *user_handle;
633 if ((mem_ctx = talloc_init("leave")) == NULL) {
634 d_printf("talloc_init failed\n");
638 status = get_usr_handle(cli, mem_ctx, lp_ctx, admin_creds,
639 DCERPC_AUTH_TYPE_NTLMSSP,
640 DCERPC_AUTH_LEVEL_INTEGRITY,
641 username, &dom_name, &samr_pipe,
644 if (!NT_STATUS_IS_OK(status)) {
645 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
650 struct samr_DeleteUser d;
652 d.in.user_handle = user_handle;
653 d.out.user_handle = user_handle;
655 status = dcerpc_samr_DeleteUser(samr_pipe, mem_ctx, &d);
656 if (!NT_STATUS_IS_OK(status)) {
657 d_printf("samr_DeleteUser failed %s\n", nt_errstr(status));
665 talloc_free(mem_ctx);
670 * Do a Samba3-style join
673 static bool join3(struct smbcli_state *cli,
674 struct loadparm_context *lp_ctx,
676 struct cli_credentials *admin_creds,
677 struct cli_credentials *wks_creds)
682 struct dcerpc_pipe *samr_pipe;
683 struct policy_handle *wks_handle;
686 if ((mem_ctx = talloc_init("join3")) == NULL) {
687 d_printf("talloc_init failed\n");
691 status = get_usr_handle(
692 cli, mem_ctx, lp_ctx, admin_creds,
693 DCERPC_AUTH_TYPE_NTLMSSP,
694 DCERPC_AUTH_LEVEL_PRIVACY,
695 talloc_asprintf(mem_ctx, "%s$",
696 cli_credentials_get_workstation(wks_creds)),
697 &dom_name, &samr_pipe, &wks_handle, NULL);
699 if (!NT_STATUS_IS_OK(status)) {
700 d_printf("get_wks_handle failed: %s\n", nt_errstr(status));
704 cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);
707 struct samr_SetUserInfo2 sui2;
708 union samr_UserInfo u_info;
709 struct samr_UserInfo21 *i21 = &u_info.info25.info;
710 DATA_BLOB session_key;
711 DATA_BLOB confounded_session_key = data_blob_talloc(
713 struct MD5Context ctx;
714 uint8_t confounder[16];
718 i21->full_name.string = talloc_asprintf(
720 cli_credentials_get_workstation(wks_creds));
721 i21->acct_flags = ACB_WSTRUST;
722 i21->fields_present = SAMR_FIELD_FULL_NAME |
723 SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_PASSWORD;
725 encode_pw_buffer(u_info.info25.password.data,
726 cli_credentials_get_password(wks_creds),
728 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
729 if (!NT_STATUS_IS_OK(status)) {
730 d_printf("dcerpc_fetch_session_key failed: %s\n",
734 generate_random_buffer((uint8_t *)confounder, 16);
737 MD5Update(&ctx, confounder, 16);
738 MD5Update(&ctx, session_key.data, session_key.length);
739 MD5Final(confounded_session_key.data, &ctx);
741 arcfour_crypt_blob(u_info.info25.password.data, 516,
742 &confounded_session_key);
743 memcpy(&u_info.info25.password.data[516], confounder, 16);
745 sui2.in.user_handle = wks_handle;
747 sui2.in.info = &u_info;
749 status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2);
750 if (!NT_STATUS_IS_OK(status)) {
751 d_printf("samr_SetUserInfo2(25) failed: %s\n",
756 struct samr_SetUserInfo2 sui2;
757 struct samr_SetUserInfo sui;
758 union samr_UserInfo u_info;
759 DATA_BLOB session_key;
761 encode_pw_buffer(u_info.info24.password.data,
762 cli_credentials_get_password(wks_creds),
764 u_info.info24.pw_len =
765 strlen_m(cli_credentials_get_password(wks_creds))*2;
767 status = dcerpc_fetch_session_key(samr_pipe, &session_key);
768 if (!NT_STATUS_IS_OK(status)) {
769 d_printf("dcerpc_fetch_session_key failed\n");
772 arcfour_crypt_blob(u_info.info24.password.data, 516,
774 sui2.in.user_handle = wks_handle;
775 sui2.in.info = &u_info;
778 status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2);
779 if (!NT_STATUS_IS_OK(status)) {
780 d_printf("samr_SetUserInfo(24) failed: %s\n",
785 u_info.info16.acct_flags = ACB_WSTRUST;
786 sui.in.user_handle = wks_handle;
787 sui.in.info = &u_info;
790 status = dcerpc_samr_SetUserInfo(samr_pipe, mem_ctx, &sui);
791 if (!NT_STATUS_IS_OK(status)) {
792 d_printf("samr_SetUserInfo(16) failed\n");
800 talloc_free(mem_ctx);
805 * Do a ReqChallenge/Auth2 and get the wks creds
808 static bool auth2(struct smbcli_state *cli,
809 struct loadparm_context *lp_ctx,
810 struct cli_credentials *wks_cred)
813 struct dcerpc_pipe *net_pipe;
816 struct netr_ServerReqChallenge r;
817 struct netr_Credential netr_cli_creds;
818 struct netr_Credential netr_srv_creds;
819 uint32_t negotiate_flags;
820 struct netr_ServerAuthenticate2 a;
821 struct creds_CredentialState *creds_state;
822 struct netr_Credential netr_cred;
823 struct samr_Password mach_pw;
825 mem_ctx = talloc_new(NULL);
826 if (mem_ctx == NULL) {
827 d_printf("talloc_new failed\n");
831 net_pipe = dcerpc_pipe_init(mem_ctx,
832 cli->transport->socket->event.ctx,
833 lp_iconv_convenience(lp_ctx));
834 if (net_pipe == NULL) {
835 d_printf("dcerpc_pipe_init failed\n");
839 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
840 if (!NT_STATUS_IS_OK(status)) {
841 d_printf("dcerpc_pipe_open_smb failed: %s\n",
846 status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon);
847 if (!NT_STATUS_IS_OK(status)) {
848 d_printf("dcerpc_bind_auth_none failed: %s\n",
853 r.in.computer_name = cli_credentials_get_workstation(wks_cred);
854 r.in.server_name = talloc_asprintf(
855 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
856 if (r.in.server_name == NULL) {
857 d_printf("talloc_asprintf failed\n");
860 generate_random_buffer(netr_cli_creds.data,
861 sizeof(netr_cli_creds.data));
862 r.in.credentials = &netr_cli_creds;
863 r.out.credentials = &netr_srv_creds;
865 status = dcerpc_netr_ServerReqChallenge(net_pipe, mem_ctx, &r);
866 if (!NT_STATUS_IS_OK(status)) {
867 d_printf("netr_ServerReqChallenge failed: %s\n",
872 negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
873 E_md4hash(cli_credentials_get_password(wks_cred), mach_pw.hash);
875 creds_state = talloc(mem_ctx, struct creds_CredentialState);
876 creds_client_init(creds_state, r.in.credentials,
877 r.out.credentials, &mach_pw,
878 &netr_cred, negotiate_flags);
880 a.in.server_name = talloc_asprintf(
881 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
882 a.in.account_name = talloc_asprintf(
883 mem_ctx, "%s$", cli_credentials_get_workstation(wks_cred));
884 a.in.computer_name = cli_credentials_get_workstation(wks_cred);
885 a.in.secure_channel_type = SEC_CHAN_WKSTA;
886 a.in.negotiate_flags = &negotiate_flags;
887 a.out.negotiate_flags = &negotiate_flags;
888 a.in.credentials = &netr_cred;
889 a.out.credentials = &netr_cred;
891 status = dcerpc_netr_ServerAuthenticate2(net_pipe, mem_ctx, &a);
892 if (!NT_STATUS_IS_OK(status)) {
893 d_printf("netr_ServerServerAuthenticate2 failed: %s\n",
898 if (!creds_client_check(creds_state, a.out.credentials)) {
899 d_printf("creds_client_check failed\n");
903 cli_credentials_set_netlogon_creds(wks_cred, creds_state);
908 talloc_free(mem_ctx);
913 * Do a couple of schannel protected Netlogon ops: Interactive and Network
914 * login, and change the wks password
917 static bool schan(struct smbcli_state *cli,
918 struct loadparm_context *lp_ctx,
919 struct cli_credentials *wks_creds,
920 struct cli_credentials *user_creds)
925 struct dcerpc_pipe *net_pipe;
928 mem_ctx = talloc_new(NULL);
929 if (mem_ctx == NULL) {
930 d_printf("talloc_new failed\n");
934 net_pipe = dcerpc_pipe_init(mem_ctx,
935 cli->transport->socket->event.ctx,
936 lp_iconv_convenience(lp_ctx));
937 if (net_pipe == NULL) {
938 d_printf("dcerpc_pipe_init failed\n");
942 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
943 if (!NT_STATUS_IS_OK(status)) {
944 d_printf("dcerpc_pipe_open_smb failed: %s\n",
950 net_pipe->conn->flags |= DCERPC_DEBUG_PRINT_IN |
951 DCERPC_DEBUG_PRINT_OUT;
954 net_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL);
955 status = dcerpc_bind_auth(net_pipe, &ndr_table_netlogon,
956 wks_creds, lp_ctx, DCERPC_AUTH_TYPE_SCHANNEL,
957 DCERPC_AUTH_LEVEL_PRIVACY,
960 status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon);
962 if (!NT_STATUS_IS_OK(status)) {
963 d_printf("schannel bind failed: %s\n", nt_errstr(status));
968 for (i=2; i<4; i++) {
970 DATA_BLOB chal, nt_resp, lm_resp, names_blob, session_key;
971 struct creds_CredentialState *creds_state;
972 struct netr_Authenticator netr_auth, netr_auth2;
973 struct netr_NetworkInfo ninfo;
974 struct netr_PasswordInfo pinfo;
975 struct netr_LogonSamLogon r;
977 flags = CLI_CRED_LANMAN_AUTH | CLI_CRED_NTLM_AUTH |
978 CLI_CRED_NTLMv2_AUTH;
980 chal = data_blob_talloc(mem_ctx, NULL, 8);
981 if (chal.data == NULL) {
982 d_printf("data_blob_talloc failed\n");
986 generate_random_buffer(chal.data, chal.length);
987 names_blob = NTLMv2_generate_names_blob(
988 mem_ctx, lp_iconv_convenience(lp_ctx),
989 cli_credentials_get_workstation(user_creds),
990 cli_credentials_get_domain(user_creds));
991 status = cli_credentials_get_ntlm_response(
992 user_creds, mem_ctx, &flags, chal, names_blob,
993 &lm_resp, &nt_resp, NULL, NULL);
994 if (!NT_STATUS_IS_OK(status)) {
995 d_printf("cli_credentials_get_ntlm_response failed:"
996 " %s\n", nt_errstr(status));
1000 creds_state = cli_credentials_get_netlogon_creds(wks_creds);
1001 creds_client_authenticator(creds_state, &netr_auth);
1003 ninfo.identity_info.account_name.string =
1004 cli_credentials_get_username(user_creds);
1005 ninfo.identity_info.domain_name.string =
1006 cli_credentials_get_domain(user_creds);
1007 ninfo.identity_info.parameter_control = 0;
1008 ninfo.identity_info.logon_id_low = 0;
1009 ninfo.identity_info.logon_id_high = 0;
1010 ninfo.identity_info.workstation.string =
1011 cli_credentials_get_workstation(user_creds);
1012 memcpy(ninfo.challenge, chal.data, sizeof(ninfo.challenge));
1013 ninfo.nt.length = nt_resp.length;
1014 ninfo.nt.data = nt_resp.data;
1015 ninfo.lm.length = lm_resp.length;
1016 ninfo.lm.data = lm_resp.data;
1018 r.in.server_name = talloc_asprintf(
1019 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1020 ZERO_STRUCT(netr_auth2);
1021 r.in.computer_name =
1022 cli_credentials_get_workstation(wks_creds);
1023 r.in.credential = &netr_auth;
1024 r.in.return_authenticator = &netr_auth2;
1025 r.in.logon_level = 2;
1026 r.in.validation_level = i;
1027 r.in.logon.network = &ninfo;
1028 r.out.return_authenticator = NULL;
1030 status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r);
1031 if (!NT_STATUS_IS_OK(status)) {
1032 d_printf("netr_LogonSamLogon failed: %s\n",
1037 if ((r.out.return_authenticator == NULL) ||
1038 (!creds_client_check(creds_state,
1039 &r.out.return_authenticator->cred))) {
1040 d_printf("Credentials check failed!\n");
1044 creds_client_authenticator(creds_state, &netr_auth);
1046 pinfo.identity_info = ninfo.identity_info;
1047 ZERO_STRUCT(pinfo.lmpassword.hash);
1048 E_md4hash(cli_credentials_get_password(user_creds),
1049 pinfo.ntpassword.hash);
1050 session_key = data_blob_talloc(mem_ctx,
1051 creds_state->session_key, 16);
1052 arcfour_crypt_blob(pinfo.ntpassword.hash,
1053 sizeof(pinfo.ntpassword.hash),
1056 r.in.logon_level = 1;
1057 r.in.logon.password = &pinfo;
1058 r.out.return_authenticator = NULL;
1060 status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r);
1061 if (!NT_STATUS_IS_OK(status)) {
1062 d_printf("netr_LogonSamLogon failed: %s\n",
1067 if ((r.out.return_authenticator == NULL) ||
1068 (!creds_client_check(creds_state,
1069 &r.out.return_authenticator->cred))) {
1070 d_printf("Credentials check failed!\n");
1076 struct netr_ServerPasswordSet s;
1077 char *password = generate_random_str(wks_creds, 8);
1078 struct creds_CredentialState *creds_state;
1080 s.in.server_name = talloc_asprintf(
1081 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1082 s.in.computer_name = cli_credentials_get_workstation(wks_creds);
1083 s.in.account_name = talloc_asprintf(
1084 mem_ctx, "%s$", s.in.computer_name);
1085 s.in.secure_channel_type = SEC_CHAN_WKSTA;
1086 E_md4hash(password, s.in.new_password.hash);
1088 creds_state = cli_credentials_get_netlogon_creds(wks_creds);
1089 creds_des_encrypt(creds_state, &s.in.new_password);
1090 creds_client_authenticator(creds_state, &s.in.credential);
1092 status = dcerpc_netr_ServerPasswordSet(net_pipe, mem_ctx, &s);
1093 if (!NT_STATUS_IS_OK(status)) {
1094 printf("ServerPasswordSet - %s\n", nt_errstr(status));
1098 if (!creds_client_check(creds_state,
1099 &s.out.return_authenticator.cred)) {
1100 printf("Credential chaining failed\n");
1103 cli_credentials_set_password(wks_creds, password,
1109 talloc_free(mem_ctx);
1114 * Delete the wks account again
1117 static bool leave(struct smbcli_state *cli,
1118 struct loadparm_context *lp_ctx,
1119 struct cli_credentials *admin_creds,
1120 struct cli_credentials *wks_creds)
1122 char *wks_name = talloc_asprintf(
1123 NULL, "%s$", cli_credentials_get_workstation(wks_creds));
1126 ret = delete_user(cli, lp_ctx, admin_creds, wks_name);
1127 talloc_free(wks_name);
1132 * Test the Samba3 DC code a bit. Join, do some schan netlogon ops, leave
1135 bool torture_netlogon_samba3(struct torture_context *torture)
1137 TALLOC_CTX *mem_ctx;
1140 struct smbcli_state *cli;
1141 struct cli_credentials *anon_creds;
1142 struct cli_credentials *wks_creds;
1143 const char *wks_name;
1145 struct smbcli_options options;
1147 wks_name = torture_setting_string(torture, "wksname", NULL);
1148 if (wks_name == NULL) {
1149 wks_name = get_myname();
1152 mem_ctx = talloc_init("torture_netlogon_samba3");
1154 if (mem_ctx == NULL) {
1155 d_printf("talloc_init failed\n");
1159 if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) {
1160 d_printf("create_anon_creds failed\n");
1164 lp_smbcli_options(torture->lp_ctx, &options);
1166 status = smbcli_full_connection(mem_ctx, &cli,
1167 torture_setting_string(torture, "host", NULL),
1168 lp_smb_ports(torture->lp_ctx),
1169 "IPC$", NULL, anon_creds,
1170 lp_resolve_context(torture->lp_ctx),
1172 if (!NT_STATUS_IS_OK(status)) {
1173 d_printf("smbcli_full_connection failed: %s\n",
1178 wks_creds = cli_credentials_init(mem_ctx);
1179 if (wks_creds == NULL) {
1180 d_printf("cli_credentials_init failed\n");
1184 cli_credentials_set_conf(wks_creds, torture->lp_ctx);
1185 cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1186 cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1187 cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1188 cli_credentials_set_password(wks_creds,
1189 generate_random_str(wks_creds, 8),
1192 if (!join3(cli, torture->lp_ctx, false, cmdline_credentials, wks_creds)) {
1193 d_printf("join failed\n");
1197 cli_credentials_set_domain(
1198 cmdline_credentials, cli_credentials_get_domain(wks_creds),
1201 for (i=0; i<2; i++) {
1203 /* Do this more than once, the routine "schan" changes
1204 * the workstation password using the netlogon
1205 * password change routine */
1209 if (!auth2(cli, torture->lp_ctx, wks_creds)) {
1210 d_printf("auth2 failed\n");
1214 for (j=0; j<2; j++) {
1215 if (!schan(cli, torture->lp_ctx, wks_creds, cmdline_credentials)) {
1216 d_printf("schan failed\n");
1222 if (!leave(cli, torture->lp_ctx, cmdline_credentials, wks_creds)) {
1223 d_printf("leave failed\n");
1230 talloc_free(mem_ctx);
1235 * Do a simple join, testjoin and leave using specified smb and samr
1239 static bool test_join3(struct torture_context *tctx,
1241 struct cli_credentials *smb_creds,
1242 struct cli_credentials *samr_creds,
1243 const char *wks_name)
1247 struct smbcli_state *cli;
1248 struct cli_credentials *wks_creds;
1249 struct smbcli_options options;
1251 lp_smbcli_options(tctx->lp_ctx, &options);
1253 status = smbcli_full_connection(tctx, &cli,
1254 torture_setting_string(tctx, "host", NULL),
1255 lp_smb_ports(tctx->lp_ctx),
1256 "IPC$", NULL, smb_creds,
1257 lp_resolve_context(tctx->lp_ctx),
1259 if (!NT_STATUS_IS_OK(status)) {
1260 d_printf("smbcli_full_connection failed: %s\n",
1265 wks_creds = cli_credentials_init(cli);
1266 if (wks_creds == NULL) {
1267 d_printf("cli_credentials_init failed\n");
1271 cli_credentials_set_conf(wks_creds, tctx->lp_ctx);
1272 cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);
1273 cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);
1274 cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);
1275 cli_credentials_set_password(wks_creds,
1276 generate_random_str(wks_creds, 8),
1279 if (!join3(cli, tctx->lp_ctx, use_level25, samr_creds, wks_creds)) {
1280 d_printf("join failed\n");
1284 cli_credentials_set_domain(
1285 cmdline_credentials, cli_credentials_get_domain(wks_creds),
1288 if (!auth2(cli, tctx->lp_ctx, wks_creds)) {
1289 d_printf("auth2 failed\n");
1293 if (!leave(cli, tctx->lp_ctx, samr_creds, wks_creds)) {
1294 d_printf("leave failed\n");
1307 * Test the different session key variants. Do it by joining, this uses the
1308 * session key in the setpassword routine. Test the join by doing the auth2.
1311 bool torture_samba3_sessionkey(struct torture_context *torture)
1314 struct cli_credentials *anon_creds;
1315 const char *wks_name;
1317 wks_name = torture_setting_string(torture, "wksname", get_myname());
1319 if (!(anon_creds = cli_credentials_init_anon(torture))) {
1320 d_printf("create_anon_creds failed\n");
1326 if (!torture_setting_bool(torture, "samba3", false)) {
1328 /* Samba3 in the build farm right now does this happily. Need
1331 if (test_join3(torture, false, anon_creds, NULL, wks_name)) {
1332 d_printf("join using anonymous bind on an anonymous smb "
1333 "connection succeeded -- HUH??\n");
1338 if (!test_join3(torture, false, anon_creds, cmdline_credentials,
1340 d_printf("join using ntlmssp bind on an anonymous smb "
1341 "connection failed\n");
1345 if (!test_join3(torture, false, cmdline_credentials, NULL, wks_name)) {
1346 d_printf("join using anonymous bind on an authenticated smb "
1347 "connection failed\n");
1351 if (!test_join3(torture, false, cmdline_credentials,
1352 cmdline_credentials,
1354 d_printf("join using ntlmssp bind on an authenticated smb "
1355 "connection failed\n");
1360 * The following two are tests for setuserinfolevel 25
1363 if (!test_join3(torture, true, anon_creds, cmdline_credentials,
1365 d_printf("join using ntlmssp bind on an anonymous smb "
1366 "connection failed\n");
1370 if (!test_join3(torture, true, cmdline_credentials, NULL, wks_name)) {
1371 d_printf("join using anonymous bind on an authenticated smb "
1372 "connection failed\n");
1382 * open pipe and bind, given an IPC$ context
1385 static NTSTATUS pipe_bind_smb(TALLOC_CTX *mem_ctx,
1386 struct loadparm_context *lp_ctx,
1387 struct smbcli_tree *tree,
1388 const char *pipe_name,
1389 const struct ndr_interface_table *iface,
1390 struct dcerpc_pipe **p)
1392 struct dcerpc_pipe *result;
1395 if (!(result = dcerpc_pipe_init(
1396 mem_ctx, tree->session->transport->socket->event.ctx,
1397 lp_iconv_convenience(lp_ctx)))) {
1398 return NT_STATUS_NO_MEMORY;
1401 status = dcerpc_pipe_open_smb(result, tree, pipe_name);
1402 if (!NT_STATUS_IS_OK(status)) {
1403 d_printf("dcerpc_pipe_open_smb failed: %s\n",
1405 talloc_free(result);
1409 status = dcerpc_bind_auth_none(result, iface);
1410 if (!NT_STATUS_IS_OK(status)) {
1411 d_printf("schannel bind failed: %s\n", nt_errstr(status));
1412 talloc_free(result);
1417 return NT_STATUS_OK;
1421 * Sane wrapper around lsa_LookupNames
1424 static struct dom_sid *name2sid(TALLOC_CTX *mem_ctx,
1425 struct dcerpc_pipe *p,
1429 struct lsa_ObjectAttribute attr;
1430 struct lsa_QosInfo qos;
1431 struct lsa_OpenPolicy2 r;
1434 struct policy_handle handle;
1435 struct lsa_LookupNames l;
1436 struct lsa_TransSidArray sids;
1437 struct lsa_String lsa_name;
1439 struct dom_sid *result;
1440 TALLOC_CTX *tmp_ctx;
1442 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1447 qos.impersonation_level = 2;
1448 qos.context_mode = 1;
1449 qos.effective_only = 0;
1452 attr.root_dir = NULL;
1453 attr.object_name = NULL;
1454 attr.attributes = 0;
1455 attr.sec_desc = NULL;
1456 attr.sec_qos = &qos;
1458 r.in.system_name = "\\";
1460 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1461 r.out.handle = &handle;
1463 status = dcerpc_lsa_OpenPolicy2(p, tmp_ctx, &r);
1464 if (!NT_STATUS_IS_OK(status)) {
1465 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
1466 talloc_free(tmp_ctx);
1473 lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, name);
1475 l.in.handle = &handle;
1477 l.in.names = &lsa_name;
1480 l.in.count = &count;
1481 l.out.count = &count;
1484 status = dcerpc_lsa_LookupNames(p, tmp_ctx, &l);
1485 if (!NT_STATUS_IS_OK(status)) {
1486 printf("LookupNames of %s failed - %s\n", lsa_name.string,
1488 talloc_free(tmp_ctx);
1492 result = dom_sid_add_rid(mem_ctx, l.out.domains->domains[0].sid,
1493 l.out.sids->sids[0].rid);
1495 c.in.handle = &handle;
1496 c.out.handle = &handle;
1498 status = dcerpc_lsa_Close(p, tmp_ctx, &c);
1499 if (!NT_STATUS_IS_OK(status)) {
1500 printf("dcerpc_lsa_Close failed - %s\n", nt_errstr(status));
1501 talloc_free(tmp_ctx);
1505 talloc_free(tmp_ctx);
1510 * Find out the user SID on this connection
1513 static struct dom_sid *whoami(TALLOC_CTX *mem_ctx,
1514 struct loadparm_context *lp_ctx,
1515 struct smbcli_tree *tree)
1517 struct dcerpc_pipe *lsa;
1518 struct lsa_GetUserName r;
1520 struct lsa_StringPointer authority_name_p;
1521 struct dom_sid *result;
1523 status = pipe_bind_smb(mem_ctx, lp_ctx, tree, "\\pipe\\lsarpc",
1524 &ndr_table_lsarpc, &lsa);
1525 if (!NT_STATUS_IS_OK(status)) {
1526 d_printf("(%s) Could not bind to LSA: %s\n",
1527 __location__, nt_errstr(status));
1531 r.in.system_name = "\\";
1532 r.in.account_name = NULL;
1533 authority_name_p.string = NULL;
1534 r.in.authority_name = &authority_name_p;
1536 status = dcerpc_lsa_GetUserName(lsa, mem_ctx, &r);
1538 if (!NT_STATUS_IS_OK(status)) {
1539 printf("(%s) GetUserName failed - %s\n",
1540 __location__, nt_errstr(status));
1545 result = name2sid(mem_ctx, lsa, r.out.account_name->string,
1546 r.out.authority_name->string->string);
1552 static int destroy_tree(struct smbcli_tree *tree)
1554 smb_tree_disconnect(tree);
1559 * Do a tcon, given a session
1562 NTSTATUS secondary_tcon(TALLOC_CTX *mem_ctx,
1563 struct smbcli_session *session,
1564 const char *sharename,
1565 struct smbcli_tree **res)
1567 struct smbcli_tree *result;
1568 TALLOC_CTX *tmp_ctx;
1569 union smb_tcon tcon;
1572 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1573 return NT_STATUS_NO_MEMORY;
1576 if (!(result = smbcli_tree_init(session, mem_ctx, false))) {
1577 talloc_free(tmp_ctx);
1578 return NT_STATUS_NO_MEMORY;
1581 tcon.generic.level = RAW_TCON_TCONX;
1582 tcon.tconx.in.flags = 0;
1583 tcon.tconx.in.password = data_blob(NULL, 0);
1584 tcon.tconx.in.path = sharename;
1585 tcon.tconx.in.device = "?????";
1587 status = smb_raw_tcon(result, tmp_ctx, &tcon);
1588 if (!NT_STATUS_IS_OK(status)) {
1589 d_printf("(%s) smb_raw_tcon failed: %s\n", __location__,
1591 talloc_free(tmp_ctx);
1595 result->tid = tcon.tconx.out.tid;
1596 result = talloc_steal(mem_ctx, result);
1597 talloc_set_destructor(result, destroy_tree);
1598 talloc_free(tmp_ctx);
1600 return NT_STATUS_OK;
1604 * Test the getusername behaviour
1607 bool torture_samba3_rpc_getusername(struct torture_context *torture)
1610 struct smbcli_state *cli;
1611 TALLOC_CTX *mem_ctx;
1613 struct dom_sid *user_sid;
1614 struct dom_sid *created_sid;
1615 struct cli_credentials *anon_creds;
1616 struct cli_credentials *user_creds;
1618 struct smbcli_options options;
1620 if (!(mem_ctx = talloc_new(torture))) {
1624 lp_smbcli_options(torture->lp_ctx, &options);
1626 status = smbcli_full_connection(
1627 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1628 lp_smb_ports(torture->lp_ctx),
1629 "IPC$", NULL, cmdline_credentials,
1630 lp_resolve_context(torture->lp_ctx),
1632 if (!NT_STATUS_IS_OK(status)) {
1633 d_printf("(%s) smbcli_full_connection failed: %s\n",
1634 __location__, nt_errstr(status));
1639 if (!(user_sid = whoami(mem_ctx, torture->lp_ctx, cli->tree))) {
1640 d_printf("(%s) whoami on auth'ed connection failed\n",
1647 if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) {
1648 d_printf("(%s) create_anon_creds failed\n", __location__);
1653 status = smbcli_full_connection(
1654 mem_ctx, &cli, torture_setting_string(torture, "host", NULL),
1655 lp_smb_ports(torture->lp_ctx),
1656 "IPC$", NULL, anon_creds,
1657 lp_resolve_context(torture->lp_ctx),
1659 if (!NT_STATUS_IS_OK(status)) {
1660 d_printf("(%s) anon smbcli_full_connection failed: %s\n",
1661 __location__, nt_errstr(status));
1666 if (!(user_sid = whoami(mem_ctx, torture->lp_ctx, cli->tree))) {
1667 d_printf("(%s) whoami on anon connection failed\n",
1673 if (!dom_sid_equal(user_sid,
1674 dom_sid_parse_talloc(mem_ctx, "s-1-5-7"))) {
1675 d_printf("(%s) Anon lsa_GetUserName returned %s, expected "
1676 "S-1-5-7", __location__,
1677 dom_sid_string(mem_ctx, user_sid));
1681 if (!(user_creds = cli_credentials_init(mem_ctx))) {
1682 d_printf("(%s) cli_credentials_init failed\n", __location__);
1687 cli_credentials_set_conf(user_creds, torture->lp_ctx);
1688 cli_credentials_set_username(user_creds, "torture_username",
1690 cli_credentials_set_password(user_creds,
1691 generate_random_str(user_creds, 8),
1694 if (!create_user(mem_ctx, cli, torture->lp_ctx, cmdline_credentials,
1695 cli_credentials_get_username(user_creds),
1696 cli_credentials_get_password(user_creds),
1697 &domain_name, &created_sid)) {
1698 d_printf("(%s) create_user failed\n", __location__);
1703 cli_credentials_set_domain(user_creds, domain_name,
1707 struct smbcli_session *session2;
1708 struct smb_composite_sesssetup setup;
1709 struct smbcli_tree *tree;
1711 session2 = smbcli_session_init(cli->transport, mem_ctx, false);
1712 if (session2 == NULL) {
1713 d_printf("(%s) smbcli_session_init failed\n",
1718 setup.in.sesskey = cli->transport->negotiate.sesskey;
1719 setup.in.capabilities = cli->transport->negotiate.capabilities;
1720 setup.in.workgroup = "";
1721 setup.in.credentials = user_creds;
1723 status = smb_composite_sesssetup(session2, &setup);
1724 if (!NT_STATUS_IS_OK(status)) {
1725 d_printf("(%s) session setup with new user failed: "
1726 "%s\n", __location__, nt_errstr(status));
1730 session2->vuid = setup.out.vuid;
1732 if (!NT_STATUS_IS_OK(secondary_tcon(mem_ctx, session2,
1734 d_printf("(%s) secondary_tcon failed\n",
1740 if (!(user_sid = whoami(mem_ctx, torture->lp_ctx, tree))) {
1741 d_printf("(%s) whoami on user connection failed\n",
1750 d_printf("Created %s, found %s\n",
1751 dom_sid_string(mem_ctx, created_sid),
1752 dom_sid_string(mem_ctx, user_sid));
1754 if (!dom_sid_equal(created_sid, user_sid)) {
1759 if (!delete_user(cli, torture->lp_ctx,
1760 cmdline_credentials,
1761 cli_credentials_get_username(user_creds))) {
1762 d_printf("(%s) delete_user failed\n", __location__);
1767 talloc_free(mem_ctx);
1771 static bool test_NetShareGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1772 const char *sharename)
1775 struct srvsvc_NetShareGetInfo r;
1776 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007, 1501 };
1780 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s",
1781 dcerpc_server_name(p));
1782 r.in.share_name = sharename;
1784 for (i=0;i<ARRAY_SIZE(levels);i++) {
1785 r.in.level = levels[i];
1789 printf("testing NetShareGetInfo level %u on share '%s'\n",
1790 r.in.level, r.in.share_name);
1792 status = dcerpc_srvsvc_NetShareGetInfo(p, mem_ctx, &r);
1793 if (!NT_STATUS_IS_OK(status)) {
1794 printf("NetShareGetInfo level %u on share '%s' failed"
1795 " - %s\n", r.in.level, r.in.share_name,
1800 if (!W_ERROR_IS_OK(r.out.result)) {
1801 printf("NetShareGetInfo level %u on share '%s' failed "
1802 "- %s\n", r.in.level, r.in.share_name,
1803 win_errstr(r.out.result));
1812 static bool test_NetShareEnum(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1813 const char **one_sharename)
1816 struct srvsvc_NetShareEnum r;
1817 struct srvsvc_NetShareCtr0 c0;
1818 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007 };
1822 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p));
1823 r.in.ctr.ctr0 = &c0;
1824 r.in.ctr.ctr0->count = 0;
1825 r.in.ctr.ctr0->array = NULL;
1826 r.in.max_buffer = (uint32_t)-1;
1827 r.in.resume_handle = NULL;
1829 for (i=0;i<ARRAY_SIZE(levels);i++) {
1830 r.in.level = levels[i];
1834 printf("testing NetShareEnum level %u\n", r.in.level);
1835 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r);
1836 if (!NT_STATUS_IS_OK(status)) {
1837 printf("NetShareEnum level %u failed - %s\n",
1838 r.in.level, nt_errstr(status));
1842 if (!W_ERROR_IS_OK(r.out.result)) {
1843 printf("NetShareEnum level %u failed - %s\n",
1844 r.in.level, win_errstr(r.out.result));
1847 if (r.in.level == 0) {
1848 struct srvsvc_NetShareCtr0 *ctr = r.out.ctr.ctr0;
1849 if (ctr->count > 0) {
1850 *one_sharename = ctr->array[0].name;
1858 bool torture_samba3_rpc_srvsvc(struct torture_context *torture)
1860 struct dcerpc_pipe *p;
1861 TALLOC_CTX *mem_ctx;
1863 const char *sharename = NULL;
1864 struct smbcli_state *cli;
1867 if (!(mem_ctx = talloc_new(torture))) {
1871 if (!(torture_open_connection_share(
1872 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
1874 talloc_free(mem_ctx);
1878 status = pipe_bind_smb(mem_ctx, torture->lp_ctx, cli->tree,
1879 "\\pipe\\srvsvc", &ndr_table_srvsvc, &p);
1880 if (!NT_STATUS_IS_OK(status)) {
1881 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1882 __location__, nt_errstr(status));
1887 ret &= test_NetShareEnum(p, mem_ctx, &sharename);
1888 if (sharename == NULL) {
1889 printf("did not get sharename\n");
1891 ret &= test_NetShareGetInfo(p, mem_ctx, sharename);
1895 talloc_free(mem_ctx);
1900 * Do a ReqChallenge/Auth2 with a random wks name, make sure it returns
1901 * NT_STATUS_NO_SAM_ACCOUNT
1904 bool torture_samba3_rpc_randomauth2(struct torture_context *torture)
1906 TALLOC_CTX *mem_ctx;
1907 struct dcerpc_pipe *net_pipe;
1909 bool result = false;
1911 struct netr_ServerReqChallenge r;
1912 struct netr_Credential netr_cli_creds;
1913 struct netr_Credential netr_srv_creds;
1914 uint32_t negotiate_flags;
1915 struct netr_ServerAuthenticate2 a;
1916 struct creds_CredentialState *creds_state;
1917 struct netr_Credential netr_cred;
1918 struct samr_Password mach_pw;
1919 struct smbcli_state *cli;
1921 if (!(mem_ctx = talloc_new(torture))) {
1922 d_printf("talloc_new failed\n");
1926 if (!(wksname = generate_random_str_list(
1927 mem_ctx, 14, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"))) {
1928 d_printf("generate_random_str_list failed\n");
1932 if (!(torture_open_connection_share(
1934 torture, torture_setting_string(torture, "host", NULL),
1936 d_printf("IPC$ connection failed\n");
1940 if (!(net_pipe = dcerpc_pipe_init(
1941 mem_ctx, cli->transport->socket->event.ctx,
1942 lp_iconv_convenience(torture->lp_ctx)))) {
1943 d_printf("dcerpc_pipe_init failed\n");
1947 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");
1948 if (!NT_STATUS_IS_OK(status)) {
1949 d_printf("dcerpc_pipe_open_smb failed: %s\n",
1954 status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon);
1955 if (!NT_STATUS_IS_OK(status)) {
1956 d_printf("dcerpc_bind_auth_none failed: %s\n",
1961 r.in.computer_name = wksname;
1962 r.in.server_name = talloc_asprintf(
1963 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1964 if (r.in.server_name == NULL) {
1965 d_printf("talloc_asprintf failed\n");
1968 generate_random_buffer(netr_cli_creds.data,
1969 sizeof(netr_cli_creds.data));
1970 r.in.credentials = &netr_cli_creds;
1971 r.out.credentials = &netr_srv_creds;
1973 status = dcerpc_netr_ServerReqChallenge(net_pipe, mem_ctx, &r);
1974 if (!NT_STATUS_IS_OK(status)) {
1975 d_printf("netr_ServerReqChallenge failed: %s\n",
1980 negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
1981 E_md4hash("foobar", mach_pw.hash);
1983 creds_state = talloc(mem_ctx, struct creds_CredentialState);
1984 creds_client_init(creds_state, r.in.credentials,
1985 r.out.credentials, &mach_pw,
1986 &netr_cred, negotiate_flags);
1988 a.in.server_name = talloc_asprintf(
1989 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));
1990 a.in.account_name = talloc_asprintf(
1991 mem_ctx, "%s$", wksname);
1992 a.in.computer_name = wksname;
1993 a.in.secure_channel_type = SEC_CHAN_WKSTA;
1994 a.in.negotiate_flags = &negotiate_flags;
1995 a.out.negotiate_flags = &negotiate_flags;
1996 a.in.credentials = &netr_cred;
1997 a.out.credentials = &netr_cred;
1999 status = dcerpc_netr_ServerAuthenticate2(net_pipe, mem_ctx, &a);
2001 if (!NT_STATUS_EQUAL(status, NT_STATUS_NO_TRUST_SAM_ACCOUNT)) {
2002 d_printf("dcerpc_netr_ServerAuthenticate2 returned %s, "
2003 "expected NT_STATUS_NO_TRUST_SAM_ACCOUNT\n",
2010 talloc_free(mem_ctx);
2014 static struct security_descriptor *get_sharesec(TALLOC_CTX *mem_ctx,
2015 struct loadparm_context *lp_ctx,
2016 struct smbcli_session *sess,
2017 const char *sharename)
2019 struct smbcli_tree *tree;
2020 TALLOC_CTX *tmp_ctx;
2021 struct dcerpc_pipe *p;
2023 struct srvsvc_NetShareGetInfo r;
2024 struct security_descriptor *result;
2026 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2027 d_printf("talloc_new failed\n");
2031 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) {
2032 d_printf("secondary_tcon failed\n");
2033 talloc_free(tmp_ctx);
2037 status = pipe_bind_smb(mem_ctx, lp_ctx, tree, "\\pipe\\srvsvc",
2038 &ndr_table_srvsvc, &p);
2039 if (!NT_STATUS_IS_OK(status)) {
2040 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
2041 __location__, nt_errstr(status));
2042 talloc_free(tmp_ctx);
2047 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2050 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
2051 dcerpc_server_name(p));
2052 r.in.share_name = sharename;
2055 status = dcerpc_srvsvc_NetShareGetInfo(p, tmp_ctx, &r);
2056 if (!NT_STATUS_IS_OK(status)) {
2057 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
2059 talloc_free(tmp_ctx);
2063 result = talloc_steal(mem_ctx, r.out.info.info502->sd);
2064 talloc_free(tmp_ctx);
2068 static NTSTATUS set_sharesec(TALLOC_CTX *mem_ctx,
2069 struct loadparm_context *lp_ctx,
2070 struct smbcli_session *sess,
2071 const char *sharename,
2072 struct security_descriptor *sd)
2074 struct smbcli_tree *tree;
2075 TALLOC_CTX *tmp_ctx;
2076 struct dcerpc_pipe *p;
2078 struct sec_desc_buf i;
2079 struct srvsvc_NetShareSetInfo r;
2082 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2083 d_printf("talloc_new failed\n");
2084 return NT_STATUS_NO_MEMORY;
2087 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) {
2088 d_printf("secondary_tcon failed\n");
2089 talloc_free(tmp_ctx);
2090 return NT_STATUS_UNSUCCESSFUL;
2093 status = pipe_bind_smb(mem_ctx, lp_ctx, tree, "\\pipe\\srvsvc",
2094 &ndr_table_srvsvc, &p);
2095 if (!NT_STATUS_IS_OK(status)) {
2096 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
2097 __location__, nt_errstr(status));
2098 talloc_free(tmp_ctx);
2099 return NT_STATUS_UNSUCCESSFUL;
2103 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2106 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s",
2107 dcerpc_server_name(p));
2108 r.in.share_name = sharename;
2111 r.in.info.info1501 = &i;
2112 r.in.parm_error = &error;
2114 status = dcerpc_srvsvc_NetShareSetInfo(p, tmp_ctx, &r);
2115 if (!NT_STATUS_IS_OK(status)) {
2116 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
2120 talloc_free(tmp_ctx);
2124 bool try_tcon(TALLOC_CTX *mem_ctx,
2125 struct loadparm_context *lp_ctx,
2126 struct security_descriptor *orig_sd,
2127 struct smbcli_session *session,
2128 const char *sharename, const struct dom_sid *user_sid,
2129 unsigned int access_mask, NTSTATUS expected_tcon,
2130 NTSTATUS expected_mkdir)
2132 TALLOC_CTX *tmp_ctx;
2133 struct smbcli_tree *rmdir_tree, *tree;
2134 struct dom_sid *domain_sid;
2136 struct security_descriptor *sd;
2140 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2141 d_printf("talloc_new failed\n");
2145 status = secondary_tcon(tmp_ctx, session, sharename, &rmdir_tree);
2146 if (!NT_STATUS_IS_OK(status)) {
2147 d_printf("first tcon to delete dir failed\n");
2148 talloc_free(tmp_ctx);
2152 smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2154 if (!NT_STATUS_IS_OK(dom_sid_split_rid(tmp_ctx, user_sid,
2155 &domain_sid, &rid))) {
2156 d_printf("dom_sid_split_rid failed\n");
2157 talloc_free(tmp_ctx);
2161 sd = security_descriptor_dacl_create(
2162 tmp_ctx, 0, "S-1-5-32-544",
2163 dom_sid_string(mem_ctx, dom_sid_add_rid(mem_ctx, domain_sid,
2165 dom_sid_string(mem_ctx, user_sid),
2166 SEC_ACE_TYPE_ACCESS_ALLOWED, access_mask, 0, NULL);
2168 d_printf("security_descriptor_dacl_create failed\n");
2169 talloc_free(tmp_ctx);
2173 status = set_sharesec(mem_ctx, lp_ctx, session, sharename, sd);
2174 if (!NT_STATUS_IS_OK(status)) {
2175 d_printf("custom set_sharesec failed: %s\n",
2177 talloc_free(tmp_ctx);
2181 status = secondary_tcon(tmp_ctx, session, sharename, &tree);
2182 if (!NT_STATUS_EQUAL(status, expected_tcon)) {
2183 d_printf("Expected %s, got %s\n", nt_errstr(expected_tcon),
2189 if (!NT_STATUS_IS_OK(status)) {
2190 /* An expected non-access, no point in trying to write */
2194 status = smbcli_mkdir(tree, "sharesec_testdir");
2195 if (!NT_STATUS_EQUAL(status, expected_mkdir)) {
2196 d_printf("(%s) Expected %s, got %s\n", __location__,
2197 nt_errstr(expected_mkdir), nt_errstr(status));
2202 smbcli_rmdir(rmdir_tree, "sharesec_testdir");
2204 status = set_sharesec(mem_ctx, lp_ctx, session, sharename, orig_sd);
2205 if (!NT_STATUS_IS_OK(status)) {
2206 d_printf("custom set_sharesec failed: %s\n",
2208 talloc_free(tmp_ctx);
2212 talloc_free(tmp_ctx);
2216 bool torture_samba3_rpc_sharesec(struct torture_context *torture)
2218 TALLOC_CTX *mem_ctx;
2220 struct smbcli_state *cli;
2221 struct security_descriptor *sd;
2222 struct dom_sid *user_sid;
2224 if (!(mem_ctx = talloc_new(torture))) {
2228 if (!(torture_open_connection_share(
2229 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
2231 d_printf("IPC$ connection failed\n");
2232 talloc_free(mem_ctx);
2236 if (!(user_sid = whoami(mem_ctx, torture->lp_ctx, cli->tree))) {
2237 d_printf("whoami failed\n");
2238 talloc_free(mem_ctx);
2242 sd = get_sharesec(mem_ctx, torture->lp_ctx, cli->session,
2243 torture_setting_string(torture, "share", NULL));
2245 ret &= try_tcon(mem_ctx, torture->lp_ctx, sd, cli->session,
2246 torture_setting_string(torture, "share", NULL),
2247 user_sid, 0, NT_STATUS_ACCESS_DENIED, NT_STATUS_OK);
2249 ret &= try_tcon(mem_ctx, torture->lp_ctx, sd, cli->session,
2250 torture_setting_string(torture, "share", NULL),
2251 user_sid, SEC_FILE_READ_DATA, NT_STATUS_OK,
2252 NT_STATUS_MEDIA_WRITE_PROTECTED);
2254 ret &= try_tcon(mem_ctx, torture->lp_ctx, sd, cli->session,
2255 torture_setting_string(torture, "share", NULL),
2256 user_sid, SEC_FILE_ALL, NT_STATUS_OK, NT_STATUS_OK);
2258 talloc_free(mem_ctx);
2262 bool torture_samba3_rpc_lsa(struct torture_context *torture)
2264 TALLOC_CTX *mem_ctx;
2266 struct smbcli_state *cli;
2267 struct dcerpc_pipe *p;
2268 struct policy_handle lsa_handle;
2270 struct dom_sid *domain_sid;
2272 if (!(mem_ctx = talloc_new(torture))) {
2276 if (!(torture_open_connection_share(
2277 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
2279 d_printf("IPC$ connection failed\n");
2280 talloc_free(mem_ctx);
2284 status = pipe_bind_smb(mem_ctx, torture->lp_ctx, cli->tree, "\\lsarpc",
2285 &ndr_table_lsarpc, &p);
2286 if (!NT_STATUS_IS_OK(status)) {
2287 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2289 talloc_free(mem_ctx);
2294 struct lsa_ObjectAttribute attr;
2295 struct lsa_OpenPolicy2 o;
2296 o.in.system_name = talloc_asprintf(
2297 mem_ctx, "\\\\%s", dcerpc_server_name(p));
2300 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2301 o.out.handle = &lsa_handle;
2302 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &o);
2303 if (!NT_STATUS_IS_OK(status)) {
2304 d_printf("(%s) dcerpc_lsa_OpenPolicy2 failed: %s\n",
2305 __location__, nt_errstr(status));
2306 talloc_free(mem_ctx);
2312 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;
2317 int levels[] = { 2,3,5,6 };
2319 for (i=0; i<ARRAY_SIZE(levels); i++) {
2320 struct lsa_QueryInfoPolicy r;
2321 r.in.handle = &lsa_handle;
2322 r.in.level = levels[i];
2323 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
2324 if (!NT_STATUS_IS_OK(status)) {
2325 d_printf("(%s) dcerpc_lsa_QueryInfoPolicy %d "
2326 "failed: %s\n", __location__,
2327 levels[i], nt_errstr(status));
2328 talloc_free(mem_ctx);
2331 if (levels[i] == 5) {
2332 domain_sid = r.out.info->account_domain.sid;
2340 static NTSTATUS get_servername(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree,
2341 struct smb_iconv_convenience *iconv_convenience,
2344 struct rap_WserverGetInfo r;
2346 char servername[17];
2349 r.in.bufsize = 0xffff;
2351 status = smbcli_rap_netservergetinfo(tree, iconv_convenience, mem_ctx, &r);
2352 if (!NT_STATUS_IS_OK(status)) {
2356 memcpy(servername, r.out.info.info0.name, 16);
2357 servername[16] = '\0';
2359 if (pull_ascii_talloc(mem_ctx, iconv_convenience,
2360 name, servername) < 0) {
2361 return NT_STATUS_NO_MEMORY;
2364 return NT_STATUS_OK;
2368 static NTSTATUS find_printers(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx,
2369 struct smbcli_tree *tree,
2370 const char ***printers, int *num_printers)
2372 TALLOC_CTX *mem_ctx;
2374 struct dcerpc_pipe *p;
2375 struct srvsvc_NetShareEnum r;
2376 struct srvsvc_NetShareCtr1 c1_in;
2377 struct srvsvc_NetShareCtr1 *c1;
2380 mem_ctx = talloc_new(ctx);
2381 if (mem_ctx == NULL) {
2382 return NT_STATUS_NO_MEMORY;
2385 status = pipe_bind_smb(mem_ctx, lp_ctx,
2386 tree, "\\srvsvc", &ndr_table_srvsvc,
2388 if (!NT_STATUS_IS_OK(status)) {
2389 d_printf("could not bind to srvsvc pipe\n");
2390 talloc_free(mem_ctx);
2394 r.in.server_unc = talloc_asprintf(
2395 mem_ctx, "\\\\%s", dcerpc_server_name(p));
2398 r.in.ctr.ctr1 = &c1_in;
2399 r.in.max_buffer = (uint32_t)-1;
2400 r.in.resume_handle = NULL;
2402 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r);
2403 if (!NT_STATUS_IS_OK(status)) {
2404 d_printf("NetShareEnum level %u failed - %s\n",
2405 r.in.level, nt_errstr(status));
2406 talloc_free(mem_ctx);
2412 c1 = r.out.ctr.ctr1;
2413 for (i=0; i<c1->count; i++) {
2414 if (c1->array[i].type != STYPE_PRINTQ) {
2417 if (!add_string_to_array(ctx, c1->array[i].name,
2418 printers, num_printers)) {
2420 return NT_STATUS_NO_MEMORY;
2424 talloc_free(mem_ctx);
2425 return NT_STATUS_OK;
2428 static bool enumprinters(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *pipe,
2429 const char *servername, int level, int *num_printers)
2431 struct spoolss_EnumPrinters r;
2435 r.in.flags = PRINTER_ENUM_LOCAL;
2436 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", servername);
2441 status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
2442 if (!NT_STATUS_IS_OK(status)) {
2443 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s\n",
2444 __location__, nt_errstr(status));
2448 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2449 d_printf("(%s) EnumPrinters unexpected return code %s, should "
2450 "be WERR_INSUFFICIENT_BUFFER\n", __location__,
2451 win_errstr(r.out.result));
2455 blob = data_blob_talloc_zero(mem_ctx, r.out.needed);
2456 if (blob.data == NULL) {
2457 d_printf("(%s) data_blob_talloc failed\n", __location__);
2461 r.in.buffer = &blob;
2462 r.in.offered = r.out.needed;
2464 status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r);
2465 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2466 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s, "
2467 "%s\n", __location__, nt_errstr(status),
2468 win_errstr(r.out.result));
2472 *num_printers = r.out.count;
2477 static NTSTATUS getprinterinfo(TALLOC_CTX *ctx, struct dcerpc_pipe *pipe,
2478 struct policy_handle *handle, int level,
2479 union spoolss_PrinterInfo **res)
2481 TALLOC_CTX *mem_ctx;
2482 struct spoolss_GetPrinter r;
2486 mem_ctx = talloc_new(ctx);
2487 if (mem_ctx == NULL) {
2488 return NT_STATUS_NO_MEMORY;
2491 r.in.handle = handle;
2496 status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r);
2497 if (!NT_STATUS_IS_OK(status)) {
2498 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s\n",
2499 __location__, nt_errstr(status));
2500 talloc_free(mem_ctx);
2504 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2505 printf("GetPrinter unexpected return code %s, should "
2506 "be WERR_INSUFFICIENT_BUFFER\n",
2507 win_errstr(r.out.result));
2508 talloc_free(mem_ctx);
2509 return NT_STATUS_UNSUCCESSFUL;
2512 r.in.handle = handle;
2514 blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
2515 if (blob.data == NULL) {
2516 talloc_free(mem_ctx);
2517 return NT_STATUS_NO_MEMORY;
2519 memset(blob.data, 0, blob.length);
2520 r.in.buffer = &blob;
2521 r.in.offered = r.out.needed;
2523 status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r);
2524 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2525 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s, "
2526 "%s\n", __location__, nt_errstr(status),
2527 win_errstr(r.out.result));
2528 talloc_free(mem_ctx);
2529 return NT_STATUS_IS_OK(status) ?
2530 NT_STATUS_UNSUCCESSFUL : status;
2534 *res = talloc_steal(ctx, r.out.info);
2537 talloc_free(mem_ctx);
2538 return NT_STATUS_OK;
2541 bool torture_samba3_rpc_spoolss(struct torture_context *torture)
2543 TALLOC_CTX *mem_ctx;
2545 struct smbcli_state *cli;
2546 struct dcerpc_pipe *p;
2548 struct policy_handle server_handle, printer_handle;
2549 const char **printers;
2551 struct spoolss_UserLevel1 userlevel1;
2554 if (!(mem_ctx = talloc_new(torture))) {
2558 if (!(torture_open_connection_share(
2559 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
2561 d_printf("IPC$ connection failed\n");
2562 talloc_free(mem_ctx);
2566 status = get_servername(mem_ctx, cli->tree, lp_iconv_convenience(torture->lp_ctx), &servername);
2567 if (!NT_STATUS_IS_OK(status)) {
2568 d_fprintf(stderr, "(%s) get_servername returned %s\n",
2569 __location__, nt_errstr(status));
2570 talloc_free(mem_ctx);
2574 if (!NT_STATUS_IS_OK(find_printers(mem_ctx, torture->lp_ctx, cli->tree,
2575 &printers, &num_printers))) {
2576 talloc_free(mem_ctx);
2580 if (num_printers == 0) {
2581 d_printf("Did not find printers\n");
2582 talloc_free(mem_ctx);
2586 status = pipe_bind_smb(mem_ctx, torture->lp_ctx, cli->tree, "\\spoolss",
2587 &ndr_table_spoolss, &p);
2588 if (!NT_STATUS_IS_OK(status)) {
2589 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2591 talloc_free(mem_ctx);
2595 ZERO_STRUCT(userlevel1);
2596 userlevel1.client = talloc_asprintf(
2597 mem_ctx, "\\\\%s", lp_netbios_name(torture->lp_ctx));
2598 userlevel1.user = cli_credentials_get_username(cmdline_credentials);
2599 userlevel1.build = 2600;
2600 userlevel1.major = 3;
2601 userlevel1.minor = 0;
2602 userlevel1.processor = 0;
2605 struct spoolss_OpenPrinterEx r;
2608 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
2610 r.in.datatype = NULL;
2611 r.in.access_mask = 0;
2613 r.in.userlevel.level1 = &userlevel1;
2614 r.out.handle = &server_handle;
2616 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
2617 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2618 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
2619 "%s, %s\n", __location__, nt_errstr(status),
2620 win_errstr(r.out.result));
2621 talloc_free(mem_ctx);
2627 struct spoolss_ClosePrinter r;
2629 r.in.handle = &server_handle;
2630 r.out.handle = &server_handle;
2632 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
2633 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2634 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
2635 "%s, %s\n", __location__, nt_errstr(status),
2636 win_errstr(r.out.result));
2637 talloc_free(mem_ctx);
2643 struct spoolss_OpenPrinterEx r;
2646 r.in.printername = talloc_asprintf(
2647 mem_ctx, "\\\\%s\\%s", servername, printers[0]);
2648 r.in.datatype = NULL;
2649 r.in.access_mask = 0;
2651 r.in.userlevel.level1 = &userlevel1;
2652 r.out.handle = &printer_handle;
2654 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
2655 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2656 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
2657 "%s, %s\n", __location__, nt_errstr(status),
2658 win_errstr(r.out.result));
2659 talloc_free(mem_ctx);
2667 for (i=0; i<8; i++) {
2668 status = getprinterinfo(mem_ctx, p, &printer_handle,
2670 if (!NT_STATUS_IS_OK(status)) {
2671 d_printf("(%s) getprinterinfo %d failed: %s\n",
2672 __location__, i, nt_errstr(status));
2679 struct spoolss_ClosePrinter r;
2681 r.in.handle = &printer_handle;
2682 r.out.handle = &printer_handle;
2684 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
2685 if (!NT_STATUS_IS_OK(status)) {
2686 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
2687 "%s\n", __location__, nt_errstr(status));
2688 talloc_free(mem_ctx);
2695 if (!enumprinters(mem_ctx, p, servername, 1,
2697 d_printf("(%s) enumprinters failed\n", __location__);
2698 talloc_free(mem_ctx);
2701 if (num_printers != num_enumerated) {
2702 d_printf("(%s) netshareenum gave %d printers, "
2703 "enumprinters lvl 1 gave %d\n", __location__,
2704 num_printers, num_enumerated);
2705 talloc_free(mem_ctx);
2712 if (!enumprinters(mem_ctx, p, servername, 2,
2714 d_printf("(%s) enumprinters failed\n", __location__);
2715 talloc_free(mem_ctx);
2718 if (num_printers != num_enumerated) {
2719 d_printf("(%s) netshareenum gave %d printers, "
2720 "enumprinters lvl 2 gave %d\n", __location__,
2721 num_printers, num_enumerated);
2722 talloc_free(mem_ctx);
2727 talloc_free(mem_ctx);
2732 bool torture_samba3_rpc_wkssvc(struct torture_context *torture)
2734 TALLOC_CTX *mem_ctx;
2735 struct smbcli_state *cli;
2736 struct dcerpc_pipe *p;
2740 if (!(mem_ctx = talloc_new(torture))) {
2744 if (!(torture_open_connection_share(
2745 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL),
2747 d_printf("IPC$ connection failed\n");
2748 talloc_free(mem_ctx);
2752 status = get_servername(mem_ctx, cli->tree, lp_iconv_convenience(torture->lp_ctx), &servername);
2753 if (!NT_STATUS_IS_OK(status)) {
2754 d_fprintf(stderr, "(%s) get_servername returned %s\n",
2755 __location__, nt_errstr(status));
2756 talloc_free(mem_ctx);
2760 status = pipe_bind_smb(mem_ctx, torture->lp_ctx, cli->tree, "\\wkssvc",
2761 &ndr_table_wkssvc, &p);
2762 if (!NT_STATUS_IS_OK(status)) {
2763 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__,
2765 talloc_free(mem_ctx);
2770 struct wkssvc_NetWkstaInfo100 wks100;
2771 union wkssvc_NetWkstaInfo info;
2772 struct wkssvc_NetWkstaGetInfo r;
2774 r.in.server_name = "\\foo";
2776 info.info100 = &wks100;
2779 status = dcerpc_wkssvc_NetWkstaGetInfo(p, mem_ctx, &r);
2780 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2781 d_printf("(%s) dcerpc_wkssvc_NetWksGetInfo failed: "
2782 "%s, %s\n", __location__, nt_errstr(status),
2783 win_errstr(r.out.result));
2784 talloc_free(mem_ctx);
2788 if (strcmp(servername,
2789 r.out.info->info100->server_name) != 0) {
2790 d_printf("(%s) servername inconsistency: RAP=%s, "
2791 "dcerpc_wkssvc_NetWksGetInfo=%s",
2792 __location__, servername,
2793 r.out.info->info100->server_name);
2794 talloc_free(mem_ctx);
2799 talloc_free(mem_ctx);
2803 static NTSTATUS winreg_close(struct dcerpc_pipe *p,
2804 struct policy_handle *handle)
2806 struct winreg_CloseKey c;
2808 TALLOC_CTX *mem_ctx;
2810 c.in.handle = c.out.handle = handle;
2812 if (!(mem_ctx = talloc_new(p))) {
2813 return NT_STATUS_NO_MEMORY;
2816 status = dcerpc_winreg_CloseKey(p, mem_ctx, &c);
2817 talloc_free(mem_ctx);
2819 if (!NT_STATUS_IS_OK(status)) {
2823 if (!W_ERROR_IS_OK(c.out.result)) {
2824 return werror_to_ntstatus(c.out.result);
2827 return NT_STATUS_OK;
2830 static NTSTATUS enumvalues(struct dcerpc_pipe *p, struct policy_handle *handle,
2831 TALLOC_CTX *mem_ctx)
2833 uint32_t enum_index = 0;
2836 struct winreg_EnumValue r;
2837 struct winreg_StringBuf name;
2838 enum winreg_Type type = 0;
2841 uint32_t size, length;
2843 r.in.handle = handle;
2844 r.in.enum_index = enum_index;
2847 r.in.name = r.out.name = &name;
2853 r.in.length = &length;
2855 status = dcerpc_winreg_EnumValue(p, mem_ctx, &r);
2856 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2857 return NT_STATUS_OK;
2863 static NTSTATUS enumkeys(struct dcerpc_pipe *p, struct policy_handle *handle,
2864 TALLOC_CTX *mem_ctx, int depth)
2866 struct winreg_EnumKey r;
2867 struct winreg_StringBuf class, name;
2872 return NT_STATUS_OK;
2878 r.in.handle = handle;
2879 r.in.enum_index = 0;
2881 r.in.keyclass = &class;
2883 r.in.last_changed_time = &t;
2886 TALLOC_CTX *tmp_ctx;
2887 struct winreg_OpenKey o;
2888 struct policy_handle key_handle;
2891 if (!(tmp_ctx = talloc_new(mem_ctx))) {
2892 return NT_STATUS_NO_MEMORY;
2898 status = dcerpc_winreg_EnumKey(p, tmp_ctx, &r);
2899 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2900 /* We're done enumerating */
2901 talloc_free(tmp_ctx);
2902 return NT_STATUS_OK;
2905 for (i=0; i<10-depth; i++)
2907 printf("%s\n", r.out.name->name);
2910 o.in.parent_handle = handle;
2911 o.in.keyname.name = r.out.name->name;
2913 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2914 o.out.handle = &key_handle;
2916 status = dcerpc_winreg_OpenKey(p, tmp_ctx, &o);
2917 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(o.out.result)) {
2918 enumkeys(p, &key_handle, tmp_ctx, depth-1);
2919 enumvalues(p, &key_handle, tmp_ctx);
2920 status = winreg_close(p, &key_handle);
2921 if (!NT_STATUS_IS_OK(status)) {
2926 talloc_free(tmp_ctx);
2928 r.in.enum_index += 1;
2931 return NT_STATUS_OK;
2934 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
2936 static bool test_Open3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2937 const char *name, winreg_open_fn open_fn)
2939 struct policy_handle handle;
2940 struct winreg_OpenHKLM r;
2943 r.in.system_name = 0;
2944 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2945 r.out.handle = &handle;
2947 status = open_fn(p, mem_ctx, &r);
2948 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
2949 d_printf("(%s) %s failed: %s, %s\n", __location__, name,
2950 nt_errstr(status), win_errstr(r.out.result));
2954 enumkeys(p, &handle, mem_ctx, 4);
2956 status = winreg_close(p, &handle);
2957 if (!NT_STATUS_IS_OK(status)) {
2958 d_printf("(%s) dcerpc_CloseKey failed: %s\n",
2959 __location__, nt_errstr(status));
2966 bool torture_samba3_rpc_winreg(struct torture_context *torture)
2969 struct dcerpc_pipe *p;
2970 TALLOC_CTX *mem_ctx;
2976 {"OpenHKLM", (winreg_open_fn)dcerpc_winreg_OpenHKLM },
2977 {"OpenHKU", (winreg_open_fn)dcerpc_winreg_OpenHKU },
2978 {"OpenHKPD", (winreg_open_fn)dcerpc_winreg_OpenHKPD },
2979 {"OpenHKPT", (winreg_open_fn)dcerpc_winreg_OpenHKPT },
2980 {"OpenHKCR", (winreg_open_fn)dcerpc_winreg_OpenHKCR }};
2985 mem_ctx = talloc_init("torture_rpc_winreg");
2987 status = torture_rpc_connection(torture, &p, &ndr_table_winreg);
2989 if (!NT_STATUS_IS_OK(status)) {
2990 talloc_free(mem_ctx);
2995 ret = test_Open3(p, mem_ctx, open_fns[0].name, open_fns[0].fn);
2997 for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
2998 if (!test_Open3(p, mem_ctx, open_fns[i].name, open_fns[i].fn))
3003 talloc_free(mem_ctx);
3008 static NTSTATUS get_shareinfo(TALLOC_CTX *mem_ctx,
3009 struct loadparm_context *lp_ctx,
3010 struct smbcli_state *cli,
3012 struct srvsvc_NetShareInfo502 **info)
3014 struct smbcli_tree *ipc;
3015 struct dcerpc_pipe *p;
3016 struct srvsvc_NetShareGetInfo r;
3019 if (!(p = dcerpc_pipe_init(cli,
3020 cli->transport->socket->event.ctx,
3021 lp_iconv_convenience(lp_ctx)))) {
3022 status = NT_STATUS_NO_MEMORY;
3026 status = secondary_tcon(p, cli->session, "IPC$", &ipc);
3027 if (!NT_STATUS_IS_OK(status)) {
3031 status = dcerpc_pipe_open_smb(p, ipc, "\\pipe\\srvsvc");
3032 if (!NT_STATUS_IS_OK(status)) {
3033 d_printf("dcerpc_pipe_open_smb failed: %s\n",
3038 status = dcerpc_bind_auth_none(p, &ndr_table_srvsvc);
3039 if (!NT_STATUS_IS_OK(status)) {
3040 d_printf("dcerpc_bind_auth_none failed: %s\n",
3045 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s",
3046 dcerpc_server_name(p));
3047 r.in.share_name = share;
3050 status = dcerpc_srvsvc_NetShareGetInfo(p, p, &r);
3051 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
3052 d_printf("(%s) OpenHKLM failed: %s, %s\n", __location__,
3053 nt_errstr(status), win_errstr(r.out.result));
3057 *info = talloc_move(mem_ctx, &r.out.info.info502);
3058 return NT_STATUS_OK;
3066 * Get us a handle on HKLM\
3069 static NTSTATUS get_hklm_handle(TALLOC_CTX *mem_ctx,
3070 struct smbcli_state *cli,
3071 struct smb_iconv_convenience *iconv_convenience,
3072 struct dcerpc_pipe **pipe_p,
3073 struct policy_handle **handle)
3075 struct smbcli_tree *ipc;
3076 struct dcerpc_pipe *p;
3077 struct winreg_OpenHKLM r;
3079 struct policy_handle *result;
3081 result = talloc(mem_ctx, struct policy_handle);
3083 if (result == NULL) {
3084 return NT_STATUS_NO_MEMORY;
3087 if (!(p = dcerpc_pipe_init(result,
3088 cli->transport->socket->event.ctx,
3089 iconv_convenience))) {
3090 status = NT_STATUS_NO_MEMORY;
3094 status = secondary_tcon(p, cli->session, "IPC$", &ipc);
3095 if (!NT_STATUS_IS_OK(status)) {
3099 status = dcerpc_pipe_open_smb(p, ipc, "\\winreg");
3100 if (!NT_STATUS_IS_OK(status)) {
3101 d_printf("dcerpc_pipe_open_smb failed: %s\n",
3106 status = dcerpc_bind_auth_none(p, &ndr_table_winreg);
3107 if (!NT_STATUS_IS_OK(status)) {
3108 d_printf("dcerpc_bind_auth_none failed: %s\n",
3113 r.in.system_name = 0;
3114 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3115 r.out.handle = result;
3117 status = dcerpc_winreg_OpenHKLM(p, p, &r);
3118 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
3119 d_printf("(%s) OpenHKLM failed: %s, %s\n", __location__,
3120 nt_errstr(status), win_errstr(r.out.result));
3126 return NT_STATUS_OK;
3129 talloc_free(result);
3133 static NTSTATUS torture_samba3_createshare(struct smbcli_state *cli,
3134 struct smb_iconv_convenience *iconv_convenience,
3135 const char *sharename)
3137 struct dcerpc_pipe *p;
3138 struct policy_handle *hklm = NULL;
3139 struct policy_handle new_handle;
3140 struct winreg_CreateKey c;
3141 struct winreg_CloseKey cl;
3142 enum winreg_CreateAction action_taken;
3144 TALLOC_CTX *mem_ctx;
3146 mem_ctx = talloc_new(cli);
3147 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
3149 status = get_hklm_handle(mem_ctx, cli, iconv_convenience, &p, &hklm);
3150 if (!NT_STATUS_IS_OK(status)) {
3151 d_printf("get_hklm_handle failed: %s\n", nt_errstr(status));
3156 c.in.name.name = talloc_asprintf(
3157 mem_ctx, "software\\samba\\smbconf\\%s", sharename);
3158 if (c.in.name.name == NULL) {
3159 d_printf("talloc_asprintf failed\n");
3160 status = NT_STATUS_NO_MEMORY;
3163 c.in.keyclass.name = "";
3165 c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3166 c.in.secdesc = NULL;
3167 c.in.action_taken = &action_taken;
3168 c.out.new_handle = &new_handle;
3169 c.out.action_taken = &action_taken;
3171 status = dcerpc_winreg_CreateKey(p, p, &c);
3172 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(c.out.result)) {
3173 d_printf("(%s) OpenKey failed: %s, %s\n", __location__,
3174 nt_errstr(status), win_errstr(c.out.result));
3178 cl.in.handle = &new_handle;
3179 cl.out.handle = &new_handle;
3180 status = dcerpc_winreg_CloseKey(p, p, &cl);
3181 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(cl.out.result)) {
3182 d_printf("(%s) OpenKey failed: %s, %s\n", __location__,
3183 nt_errstr(status), win_errstr(cl.out.result));
3189 talloc_free(mem_ctx);
3193 static NTSTATUS torture_samba3_deleteshare(struct torture_context *torture,
3194 struct smbcli_state *cli,
3195 const char *sharename)
3197 struct dcerpc_pipe *p;
3198 struct policy_handle *hklm = NULL;
3199 struct winreg_DeleteKey d;
3201 TALLOC_CTX *mem_ctx;
3203 mem_ctx = talloc_new(cli);
3204 NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
3206 status = get_hklm_handle(cli, cli, lp_iconv_convenience(torture->lp_ctx),
3208 if (!NT_STATUS_IS_OK(status)) {
3209 d_printf("get_hklm_handle failed: %s\n", nt_errstr(status));
3214 d.in.key.name = talloc_asprintf(
3215 mem_ctx, "software\\samba\\smbconf\\%s", sharename);
3216 if (d.in.key.name == NULL) {
3217 d_printf("talloc_asprintf failed\n");
3218 status = NT_STATUS_NO_MEMORY;
3221 status = dcerpc_winreg_DeleteKey(p, p, &d);
3222 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(d.out.result)) {
3223 d_printf("(%s) OpenKey failed: %s, %s\n", __location__,
3224 nt_errstr(status), win_errstr(d.out.result));
3229 talloc_free(mem_ctx);
3233 static NTSTATUS torture_samba3_setconfig(struct smbcli_state *cli,
3234 struct loadparm_context *lp_ctx,
3235 const char *sharename,
3236 const char *parameter,
3239 struct dcerpc_pipe *p = NULL;
3240 struct policy_handle *hklm = NULL, key_handle;
3241 struct winreg_OpenKey o;
3242 struct winreg_SetValue s;
3247 status = get_hklm_handle(cli, cli, lp_iconv_convenience(lp_ctx), &p, &hklm);
3248 if (!NT_STATUS_IS_OK(status)) {
3249 d_printf("get_hklm_handle failed: %s\n", nt_errstr(status));
3253 o.in.parent_handle = hklm;
3254 o.in.keyname.name = talloc_asprintf(
3255 hklm, "software\\samba\\smbconf\\%s", sharename);
3256 if (o.in.keyname.name == NULL) {
3257 d_printf("talloc_asprintf failed\n");
3258 status = NT_STATUS_NO_MEMORY;
3262 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3263 o.out.handle = &key_handle;
3265 status = dcerpc_winreg_OpenKey(p, p, &o);
3266 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(o.out.result)) {
3267 d_printf("(%s) OpenKey failed: %s, %s\n", __location__,
3268 nt_errstr(status), win_errstr(o.out.result));
3272 if (!reg_string_to_val(hklm, "REG_SZ", value, &type, &val)) {
3273 d_printf("(%s) reg_string_to_val failed\n", __location__);
3277 s.in.handle = &key_handle;
3278 s.in.name.name = parameter;
3280 s.in.data = val.data;
3281 s.in.size = val.length;
3283 status = dcerpc_winreg_SetValue(p, p, &s);
3284 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(s.out.result)) {
3285 d_printf("(%s) SetValue failed: %s, %s\n", __location__,
3286 nt_errstr(status), win_errstr(s.out.result));
3295 bool torture_samba3_regconfig(struct torture_context *torture)
3297 struct smbcli_state *cli;
3298 struct srvsvc_NetShareInfo502 *i = NULL;
3301 const char *comment = "Dummer Kommentar";
3303 if (!(torture_open_connection(&cli, torture, 0))) {
3307 status = torture_samba3_createshare(cli, lp_iconv_convenience(torture->lp_ctx), "blubber");
3308 if (!NT_STATUS_IS_OK(status)) {
3309 torture_warning(torture, "torture_samba3_createshare failed: "
3310 "%s\n", nt_errstr(status));
3314 status = torture_samba3_setconfig(cli, torture->lp_ctx, "blubber", "comment", comment);
3315 if (!NT_STATUS_IS_OK(status)) {
3316 torture_warning(torture, "torture_samba3_setconfig failed: "
3317 "%s\n", nt_errstr(status));
3321 status = get_shareinfo(torture, torture->lp_ctx, cli, "blubber", &i);
3322 if (!NT_STATUS_IS_OK(status)) {
3323 torture_warning(torture, "get_shareinfo failed: "
3324 "%s\n", nt_errstr(status));
3328 if (strcmp(comment, i->comment) != 0) {
3329 torture_warning(torture, "Expected comment [%s], got [%s]\n",
3330 comment, i->comment);
3334 status = torture_samba3_deleteshare(torture, cli, "blubber");
3335 if (!NT_STATUS_IS_OK(status)) {
3336 torture_warning(torture, "torture_samba3_deleteshare failed: "
3337 "%s\n", nt_errstr(status));