2 Unix SMB/CIFS implementation.
4 dcerpc torture tests, designed to walk Samba3 code paths
6 Copyright (C) Volker Lendecke 2006
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "libcli/raw/libcliraw.h"
25 #include "libcli/rap/rap.h"
26 #include "torture/torture.h"
27 #include "torture/util.h"
28 #include "torture/rap/proto.h"
29 #include "librpc/gen_ndr/ndr_lsa.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "librpc/gen_ndr/ndr_samr.h"
32 #include "librpc/gen_ndr/ndr_samr_c.h"
33 #include "librpc/gen_ndr/ndr_netlogon.h"
34 #include "librpc/gen_ndr/ndr_netlogon_c.h"
35 #include "librpc/gen_ndr/ndr_srvsvc.h"
36 #include "librpc/gen_ndr/ndr_srvsvc_c.h"
37 #include "librpc/gen_ndr/ndr_spoolss.h"
38 #include "librpc/gen_ndr/ndr_spoolss_c.h"
39 #include "librpc/gen_ndr/ndr_wkssvc.h"
40 #include "librpc/gen_ndr/ndr_wkssvc_c.h"
41 #include "lib/cmdline/popt_common.h"
42 #include "librpc/rpc/dcerpc.h"
43 #include "torture/rpc/rpc.h"
44 #include "libcli/libcli.h"
45 #include "libcli/composite/composite.h"
46 #include "libcli/smb_composite/smb_composite.h"
47 #include "libcli/auth/libcli_auth.h"
48 #include "libcli/auth/credentials.h"
49 #include "lib/crypto/crypto.h"
50 #include "libcli/security/proto.h"
52 static struct cli_credentials
*create_anon_creds(TALLOC_CTX
*mem_ctx
)
54 struct cli_credentials
*result
;
56 if (!(result
= cli_credentials_init(mem_ctx
))) {
60 cli_credentials_set_conf(result
);
61 cli_credentials_set_anonymous(result
);
67 * This tests a RPC call using an invalid vuid
70 BOOL
torture_bind_authcontext(struct torture_context
*torture
)
75 struct lsa_ObjectAttribute objectattr
;
76 struct lsa_OpenPolicy2 openpolicy
;
77 struct policy_handle handle
;
78 struct lsa_Close close_handle
;
79 struct smbcli_session
*tmp
;
80 struct smbcli_session
*session2
;
81 struct smbcli_state
*cli
;
82 struct dcerpc_pipe
*lsa_pipe
;
83 struct cli_credentials
*anon_creds
;
84 struct smb_composite_sesssetup setup
;
86 mem_ctx
= talloc_init("torture_bind_authcontext");
88 if (mem_ctx
== NULL
) {
89 d_printf("talloc_init failed\n");
93 status
= smbcli_full_connection(mem_ctx
, &cli
,
94 lp_parm_string(-1, "torture", "host"),
95 "IPC$", NULL
, cmdline_credentials
,
97 if (!NT_STATUS_IS_OK(status
)) {
98 d_printf("smbcli_full_connection failed: %s\n",
103 lsa_pipe
= dcerpc_pipe_init(mem_ctx
, cli
->transport
->socket
->event
.ctx
);
104 if (lsa_pipe
== NULL
) {
105 d_printf("dcerpc_pipe_init failed\n");
109 status
= dcerpc_pipe_open_smb(lsa_pipe
->conn
, cli
->tree
, "\\lsarpc");
110 if (!NT_STATUS_IS_OK(status
)) {
111 d_printf("dcerpc_pipe_open_smb failed: %s\n",
116 status
= dcerpc_bind_auth_none(lsa_pipe
, &dcerpc_table_lsarpc
);
117 if (!NT_STATUS_IS_OK(status
)) {
118 d_printf("dcerpc_bind_auth_none failed: %s\n",
123 openpolicy
.in
.system_name
=talloc_asprintf(
124 mem_ctx
, "\\\\%s", dcerpc_server_name(lsa_pipe
));
125 ZERO_STRUCT(objectattr
);
126 openpolicy
.in
.attr
= &objectattr
;
127 openpolicy
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
128 openpolicy
.out
.handle
= &handle
;
130 status
= dcerpc_lsa_OpenPolicy2(lsa_pipe
, mem_ctx
, &openpolicy
);
132 if (!NT_STATUS_IS_OK(status
)) {
133 d_printf("dcerpc_lsa_OpenPolicy2 failed: %s\n",
138 close_handle
.in
.handle
= &handle
;
139 close_handle
.out
.handle
= &handle
;
141 status
= dcerpc_lsa_Close(lsa_pipe
, mem_ctx
, &close_handle
);
142 if (!NT_STATUS_IS_OK(status
)) {
143 d_printf("dcerpc_lsa_Close failed: %s\n",
148 session2
= smbcli_session_init(cli
->transport
, mem_ctx
, False
);
149 if (session2
== NULL
) {
150 d_printf("smbcli_session_init failed\n");
154 if (!(anon_creds
= create_anon_creds(mem_ctx
))) {
155 d_printf("create_anon_creds failed\n");
159 setup
.in
.sesskey
= cli
->transport
->negotiate
.sesskey
;
160 setup
.in
.capabilities
= cli
->transport
->negotiate
.capabilities
;
161 setup
.in
.workgroup
= "";
162 setup
.in
.credentials
= anon_creds
;
164 status
= smb_composite_sesssetup(session2
, &setup
);
165 if (!NT_STATUS_IS_OK(status
)) {
166 d_printf("anon session setup failed: %s\n",
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 uint8_t auth_type
, uint8_t auth_level
)
205 struct dcerpc_pipe
*lsa_pipe
;
206 struct lsa_ObjectAttribute objectattr
;
207 struct lsa_OpenPolicy2 openpolicy
;
208 struct lsa_QueryInfoPolicy query
;
209 struct policy_handle handle
;
210 struct lsa_Close close_handle
;
212 if ((mem_ctx
= talloc_init("bindtest")) == NULL
) {
213 d_printf("talloc_init failed\n");
217 lsa_pipe
= dcerpc_pipe_init(mem_ctx
,
218 cli
->transport
->socket
->event
.ctx
);
219 if (lsa_pipe
== NULL
) {
220 d_printf("dcerpc_pipe_init failed\n");
224 status
= dcerpc_pipe_open_smb(lsa_pipe
->conn
, cli
->tree
, "\\lsarpc");
225 if (!NT_STATUS_IS_OK(status
)) {
226 d_printf("dcerpc_pipe_open_smb failed: %s\n",
231 status
= dcerpc_bind_auth(lsa_pipe
, &dcerpc_table_lsarpc
,
232 credentials
, auth_type
, auth_level
,
234 if (!NT_STATUS_IS_OK(status
)) {
235 d_printf("dcerpc_bind_auth failed: %s\n", nt_errstr(status
));
239 openpolicy
.in
.system_name
=talloc_asprintf(
240 mem_ctx
, "\\\\%s", dcerpc_server_name(lsa_pipe
));
241 ZERO_STRUCT(objectattr
);
242 openpolicy
.in
.attr
= &objectattr
;
243 openpolicy
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
244 openpolicy
.out
.handle
= &handle
;
246 status
= dcerpc_lsa_OpenPolicy2(lsa_pipe
, mem_ctx
, &openpolicy
);
248 if (!NT_STATUS_IS_OK(status
)) {
249 d_printf("dcerpc_lsa_OpenPolicy2 failed: %s\n",
254 query
.in
.handle
= &handle
;
255 query
.in
.level
= LSA_POLICY_INFO_DOMAIN
;
257 status
= dcerpc_lsa_QueryInfoPolicy(lsa_pipe
, mem_ctx
, &query
);
258 if (!NT_STATUS_IS_OK(status
)) {
259 d_printf("dcerpc_lsa_QueryInfoPolicy failed: %s\n",
264 close_handle
.in
.handle
= &handle
;
265 close_handle
.out
.handle
= &handle
;
267 status
= dcerpc_lsa_Close(lsa_pipe
, mem_ctx
, &close_handle
);
268 if (!NT_STATUS_IS_OK(status
)) {
269 d_printf("dcerpc_lsa_Close failed: %s\n",
276 talloc_free(mem_ctx
);
281 * test authenticated RPC binds with the variants Samba3 does support
284 BOOL
torture_bind_samba3(struct torture_context
*torture
)
289 struct smbcli_state
*cli
;
291 mem_ctx
= talloc_init("torture_bind_authcontext");
293 if (mem_ctx
== NULL
) {
294 d_printf("talloc_init failed\n");
298 status
= smbcli_full_connection(mem_ctx
, &cli
,
299 lp_parm_string(-1, "torture", "host"),
300 "IPC$", NULL
, cmdline_credentials
,
302 if (!NT_STATUS_IS_OK(status
)) {
303 d_printf("smbcli_full_connection failed: %s\n",
310 ret
&= bindtest(cli
, cmdline_credentials
, DCERPC_AUTH_TYPE_NTLMSSP
,
311 DCERPC_AUTH_LEVEL_INTEGRITY
);
312 ret
&= bindtest(cli
, cmdline_credentials
, DCERPC_AUTH_TYPE_NTLMSSP
,
313 DCERPC_AUTH_LEVEL_PRIVACY
);
314 ret
&= bindtest(cli
, cmdline_credentials
, DCERPC_AUTH_TYPE_SPNEGO
,
315 DCERPC_AUTH_LEVEL_INTEGRITY
);
316 ret
&= bindtest(cli
, cmdline_credentials
, DCERPC_AUTH_TYPE_SPNEGO
,
317 DCERPC_AUTH_LEVEL_PRIVACY
);
320 talloc_free(mem_ctx
);
325 * Lookup or create a user and return all necessary info
328 static NTSTATUS
get_usr_handle(struct smbcli_state
*cli
,
330 struct cli_credentials
*admin_creds
,
333 const char *username
,
335 struct dcerpc_pipe
**result_pipe
,
336 struct policy_handle
**result_handle
,
337 struct dom_sid
**sid
)
339 struct dcerpc_pipe
*samr_pipe
;
341 struct policy_handle conn_handle
;
342 struct policy_handle domain_handle
;
343 struct policy_handle
*user_handle
;
344 struct samr_Connect2 conn
;
345 struct samr_EnumDomains enumdom
;
346 uint32_t resume_handle
= 0;
347 struct samr_LookupDomain l
;
349 struct lsa_String domain_name
;
350 struct lsa_String user_name
;
351 struct samr_OpenDomain o
;
352 struct samr_CreateUser2 c
;
353 uint32_t user_rid
,access_granted
;
355 samr_pipe
= dcerpc_pipe_init(mem_ctx
,
356 cli
->transport
->socket
->event
.ctx
);
357 if (samr_pipe
== NULL
) {
358 d_printf("dcerpc_pipe_init failed\n");
359 status
= NT_STATUS_NO_MEMORY
;
363 status
= dcerpc_pipe_open_smb(samr_pipe
->conn
, cli
->tree
, "\\samr");
364 if (!NT_STATUS_IS_OK(status
)) {
365 d_printf("dcerpc_pipe_open_smb failed: %s\n",
370 if (admin_creds
!= NULL
) {
371 status
= dcerpc_bind_auth(samr_pipe
, &dcerpc_table_samr
,
372 admin_creds
, auth_type
, auth_level
,
374 if (!NT_STATUS_IS_OK(status
)) {
375 d_printf("dcerpc_bind_auth failed: %s\n",
380 /* We must have an authenticated SMB connection */
381 status
= dcerpc_bind_auth_none(samr_pipe
, &dcerpc_table_samr
);
382 if (!NT_STATUS_IS_OK(status
)) {
383 d_printf("dcerpc_bind_auth_none failed: %s\n",
389 conn
.in
.system_name
= talloc_asprintf(
390 mem_ctx
, "\\\\%s", dcerpc_server_name(samr_pipe
));
391 conn
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
392 conn
.out
.connect_handle
= &conn_handle
;
394 status
= dcerpc_samr_Connect2(samr_pipe
, mem_ctx
, &conn
);
395 if (!NT_STATUS_IS_OK(status
)) {
396 d_printf("samr_Connect2 failed: %s\n", nt_errstr(status
));
400 enumdom
.in
.connect_handle
= &conn_handle
;
401 enumdom
.in
.resume_handle
= &resume_handle
;
402 enumdom
.in
.buf_size
= (uint32_t)-1;
403 enumdom
.out
.resume_handle
= &resume_handle
;
405 status
= dcerpc_samr_EnumDomains(samr_pipe
, mem_ctx
, &enumdom
);
406 if (!NT_STATUS_IS_OK(status
)) {
407 d_printf("samr_EnumDomains failed: %s\n", nt_errstr(status
));
411 if (enumdom
.out
.num_entries
!= 2) {
412 d_printf("samr_EnumDomains returned %d entries, expected 2\n",
413 enumdom
.out
.num_entries
);
414 status
= NT_STATUS_UNSUCCESSFUL
;
418 dom_idx
= strequal(enumdom
.out
.sam
->entries
[0].name
.string
,
421 l
.in
.connect_handle
= &conn_handle
;
422 domain_name
.string
= enumdom
.out
.sam
->entries
[0].name
.string
;
423 *domain
= talloc_strdup(mem_ctx
, domain_name
.string
);
424 l
.in
.domain_name
= &domain_name
;
426 status
= dcerpc_samr_LookupDomain(samr_pipe
, mem_ctx
, &l
);
427 if (!NT_STATUS_IS_OK(status
)) {
428 d_printf("samr_LookupDomain failed: %s\n", nt_errstr(status
));
432 o
.in
.connect_handle
= &conn_handle
;
433 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
434 o
.in
.sid
= l
.out
.sid
;
435 o
.out
.domain_handle
= &domain_handle
;
437 status
= dcerpc_samr_OpenDomain(samr_pipe
, mem_ctx
, &o
);
438 if (!NT_STATUS_IS_OK(status
)) {
439 d_printf("samr_OpenDomain failed: %s\n", nt_errstr(status
));
443 c
.in
.domain_handle
= &domain_handle
;
444 user_name
.string
= username
;
445 c
.in
.account_name
= &user_name
;
446 c
.in
.acct_flags
= ACB_NORMAL
;
447 c
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
448 user_handle
= talloc(mem_ctx
, struct policy_handle
);
449 c
.out
.user_handle
= user_handle
;
450 c
.out
.access_granted
= &access_granted
;
451 c
.out
.rid
= &user_rid
;
453 status
= dcerpc_samr_CreateUser2(samr_pipe
, mem_ctx
, &c
);
455 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
456 struct samr_LookupNames ln
;
457 struct samr_OpenUser ou
;
459 ln
.in
.domain_handle
= &domain_handle
;
461 ln
.in
.names
= &user_name
;
463 status
= dcerpc_samr_LookupNames(samr_pipe
, mem_ctx
, &ln
);
464 if (!NT_STATUS_IS_OK(status
)) {
465 d_printf("samr_LookupNames failed: %s\n",
470 ou
.in
.domain_handle
= &domain_handle
;
471 ou
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
472 user_rid
= ou
.in
.rid
= ln
.out
.rids
.ids
[0];
473 ou
.out
.user_handle
= user_handle
;
475 status
= dcerpc_samr_OpenUser(samr_pipe
, mem_ctx
, &ou
);
476 if (!NT_STATUS_IS_OK(status
)) {
477 d_printf("samr_OpenUser failed: %s\n",
483 if (!NT_STATUS_IS_OK(status
)) {
484 d_printf("samr_CreateUser failed: %s\n", nt_errstr(status
));
488 *result_pipe
= samr_pipe
;
489 *result_handle
= user_handle
;
491 *sid
= dom_sid_add_rid(mem_ctx
, l
.out
.sid
, user_rid
);
503 static BOOL
create_user(TALLOC_CTX
*mem_ctx
, struct smbcli_state
*cli
,
504 struct cli_credentials
*admin_creds
,
505 const char *username
, const char *password
,
507 struct dom_sid
**user_sid
)
511 struct dcerpc_pipe
*samr_pipe
;
512 struct policy_handle
*wks_handle
;
515 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
516 d_printf("talloc_init failed\n");
520 status
= get_usr_handle(cli
, tmp_ctx
, admin_creds
,
521 DCERPC_AUTH_TYPE_NTLMSSP
,
522 DCERPC_AUTH_LEVEL_INTEGRITY
,
523 username
, domain_name
, &samr_pipe
, &wks_handle
,
525 if (!NT_STATUS_IS_OK(status
)) {
526 d_printf("get_wks_handle failed: %s\n", nt_errstr(status
));
531 struct samr_SetUserInfo2 sui2
;
532 struct samr_SetUserInfo sui
;
533 struct samr_QueryUserInfo qui
;
534 union samr_UserInfo u_info
;
535 DATA_BLOB session_key
;
537 encode_pw_buffer(u_info
.info24
.password
.data
, password
,
539 u_info
.info24
.pw_len
= strlen_m(password
)*2;
541 status
= dcerpc_fetch_session_key(samr_pipe
, &session_key
);
542 if (!NT_STATUS_IS_OK(status
)) {
543 d_printf("dcerpc_fetch_session_key failed\n");
546 arcfour_crypt_blob(u_info
.info24
.password
.data
, 516,
548 sui2
.in
.user_handle
= wks_handle
;
549 sui2
.in
.info
= &u_info
;
552 status
= dcerpc_samr_SetUserInfo2(samr_pipe
, tmp_ctx
, &sui2
);
553 if (!NT_STATUS_IS_OK(status
)) {
554 d_printf("samr_SetUserInfo(24) failed: %s\n",
559 u_info
.info16
.acct_flags
= ACB_NORMAL
;
560 sui
.in
.user_handle
= wks_handle
;
561 sui
.in
.info
= &u_info
;
564 status
= dcerpc_samr_SetUserInfo(samr_pipe
, tmp_ctx
, &sui
);
565 if (!NT_STATUS_IS_OK(status
)) {
566 d_printf("samr_SetUserInfo(16) failed\n");
570 qui
.in
.user_handle
= wks_handle
;
573 status
= dcerpc_samr_QueryUserInfo(samr_pipe
, tmp_ctx
, &qui
);
574 if (!NT_STATUS_IS_OK(status
)) {
575 d_printf("samr_QueryUserInfo(21) failed\n");
579 qui
.out
.info
->info21
.allow_password_change
= 0;
580 qui
.out
.info
->info21
.force_password_change
= 0;
581 qui
.out
.info
->info21
.account_name
.string
= NULL
;
582 qui
.out
.info
->info21
.rid
= 0;
583 qui
.out
.info
->info21
.fields_present
= 0x81827fa; /* copy usrmgr.exe */
585 u_info
.info21
= qui
.out
.info
->info21
;
586 sui
.in
.user_handle
= wks_handle
;
587 sui
.in
.info
= &u_info
;
590 status
= dcerpc_samr_SetUserInfo(samr_pipe
, tmp_ctx
, &sui
);
591 if (!NT_STATUS_IS_OK(status
)) {
592 d_printf("samr_SetUserInfo(21) failed\n");
597 *domain_name
= talloc_steal(mem_ctx
, *domain_name
);
598 *user_sid
= talloc_steal(mem_ctx
, *user_sid
);
601 talloc_free(tmp_ctx
);
609 static BOOL
delete_user(struct smbcli_state
*cli
,
610 struct cli_credentials
*admin_creds
,
611 const char *username
)
616 struct dcerpc_pipe
*samr_pipe
;
617 struct policy_handle
*user_handle
;
620 if ((mem_ctx
= talloc_init("leave")) == NULL
) {
621 d_printf("talloc_init failed\n");
625 status
= get_usr_handle(cli
, mem_ctx
, admin_creds
,
626 DCERPC_AUTH_TYPE_NTLMSSP
,
627 DCERPC_AUTH_LEVEL_INTEGRITY
,
628 username
, &dom_name
, &samr_pipe
,
631 if (!NT_STATUS_IS_OK(status
)) {
632 d_printf("get_wks_handle failed: %s\n", nt_errstr(status
));
637 struct samr_DeleteUser d
;
639 d
.in
.user_handle
= user_handle
;
640 d
.out
.user_handle
= user_handle
;
642 status
= dcerpc_samr_DeleteUser(samr_pipe
, mem_ctx
, &d
);
643 if (!NT_STATUS_IS_OK(status
)) {
644 d_printf("samr_DeleteUser failed\n");
652 talloc_free(mem_ctx
);
657 * Do a Samba3-style join
660 static BOOL
join3(struct smbcli_state
*cli
,
662 struct cli_credentials
*admin_creds
,
663 struct cli_credentials
*wks_creds
)
668 struct dcerpc_pipe
*samr_pipe
;
669 struct policy_handle
*wks_handle
;
672 if ((mem_ctx
= talloc_init("join3")) == NULL
) {
673 d_printf("talloc_init failed\n");
677 status
= get_usr_handle(
678 cli
, mem_ctx
, admin_creds
,
679 DCERPC_AUTH_TYPE_NTLMSSP
,
680 DCERPC_AUTH_LEVEL_PRIVACY
,
681 talloc_asprintf(mem_ctx
, "%s$",
682 cli_credentials_get_workstation(wks_creds
)),
683 &dom_name
, &samr_pipe
, &wks_handle
, NULL
);
685 if (!NT_STATUS_IS_OK(status
)) {
686 d_printf("get_wks_handle failed: %s\n", nt_errstr(status
));
690 cli_credentials_set_domain(wks_creds
, dom_name
, CRED_SPECIFIED
);
693 struct samr_SetUserInfo2 sui2
;
694 union samr_UserInfo u_info
;
695 struct samr_UserInfo21
*i21
= &u_info
.info25
.info
;
696 DATA_BLOB session_key
;
697 DATA_BLOB confounded_session_key
= data_blob_talloc(
699 struct MD5Context ctx
;
700 uint8_t confounder
[16];
704 i21
->full_name
.string
= talloc_asprintf(
706 cli_credentials_get_workstation(wks_creds
));
707 i21
->acct_flags
= ACB_WSTRUST
;
708 i21
->fields_present
= SAMR_FIELD_FULL_NAME
|
709 SAMR_FIELD_ACCT_FLAGS
| SAMR_FIELD_PASSWORD
;
711 encode_pw_buffer(u_info
.info25
.password
.data
,
712 cli_credentials_get_password(wks_creds
),
714 status
= dcerpc_fetch_session_key(samr_pipe
, &session_key
);
715 if (!NT_STATUS_IS_OK(status
)) {
716 d_printf("dcerpc_fetch_session_key failed: %s\n",
720 generate_random_buffer((uint8_t *)confounder
, 16);
723 MD5Update(&ctx
, confounder
, 16);
724 MD5Update(&ctx
, session_key
.data
, session_key
.length
);
725 MD5Final(confounded_session_key
.data
, &ctx
);
727 arcfour_crypt_blob(u_info
.info25
.password
.data
, 516,
728 &confounded_session_key
);
729 memcpy(&u_info
.info25
.password
.data
[516], confounder
, 16);
731 sui2
.in
.user_handle
= wks_handle
;
733 sui2
.in
.info
= &u_info
;
735 status
= dcerpc_samr_SetUserInfo2(samr_pipe
, mem_ctx
, &sui2
);
736 if (!NT_STATUS_IS_OK(status
)) {
737 d_printf("samr_SetUserInfo2(25) failed: %s\n",
742 struct samr_SetUserInfo2 sui2
;
743 struct samr_SetUserInfo sui
;
744 union samr_UserInfo u_info
;
745 DATA_BLOB session_key
;
747 encode_pw_buffer(u_info
.info24
.password
.data
,
748 cli_credentials_get_password(wks_creds
),
750 u_info
.info24
.pw_len
=
751 strlen_m(cli_credentials_get_password(wks_creds
))*2;
753 status
= dcerpc_fetch_session_key(samr_pipe
, &session_key
);
754 if (!NT_STATUS_IS_OK(status
)) {
755 d_printf("dcerpc_fetch_session_key failed\n");
758 arcfour_crypt_blob(u_info
.info24
.password
.data
, 516,
760 sui2
.in
.user_handle
= wks_handle
;
761 sui2
.in
.info
= &u_info
;
764 status
= dcerpc_samr_SetUserInfo2(samr_pipe
, mem_ctx
, &sui2
);
765 if (!NT_STATUS_IS_OK(status
)) {
766 d_printf("samr_SetUserInfo(24) failed: %s\n",
771 u_info
.info16
.acct_flags
= ACB_WSTRUST
;
772 sui
.in
.user_handle
= wks_handle
;
773 sui
.in
.info
= &u_info
;
776 status
= dcerpc_samr_SetUserInfo(samr_pipe
, mem_ctx
, &sui
);
777 if (!NT_STATUS_IS_OK(status
)) {
778 d_printf("samr_SetUserInfo(16) failed\n");
786 talloc_free(mem_ctx
);
791 * Do a ReqChallenge/Auth2 and get the wks creds
794 static BOOL
auth2(struct smbcli_state
*cli
,
795 struct cli_credentials
*wks_cred
)
798 struct dcerpc_pipe
*net_pipe
;
801 struct netr_ServerReqChallenge r
;
802 struct netr_Credential netr_cli_creds
;
803 struct netr_Credential netr_srv_creds
;
804 uint32_t negotiate_flags
;
805 struct netr_ServerAuthenticate2 a
;
806 struct creds_CredentialState
*creds_state
;
807 struct netr_Credential netr_cred
;
808 struct samr_Password mach_pw
;
810 mem_ctx
= talloc_new(NULL
);
811 if (mem_ctx
== NULL
) {
812 d_printf("talloc_new failed\n");
816 net_pipe
= dcerpc_pipe_init(mem_ctx
,
817 cli
->transport
->socket
->event
.ctx
);
818 if (net_pipe
== NULL
) {
819 d_printf("dcerpc_pipe_init failed\n");
823 status
= dcerpc_pipe_open_smb(net_pipe
->conn
, cli
->tree
, "\\netlogon");
824 if (!NT_STATUS_IS_OK(status
)) {
825 d_printf("dcerpc_pipe_open_smb failed: %s\n",
830 status
= dcerpc_bind_auth_none(net_pipe
, &dcerpc_table_netlogon
);
831 if (!NT_STATUS_IS_OK(status
)) {
832 d_printf("dcerpc_bind_auth_none failed: %s\n",
837 r
.in
.computer_name
= cli_credentials_get_workstation(wks_cred
);
838 r
.in
.server_name
= talloc_asprintf(
839 mem_ctx
, "\\\\%s", dcerpc_server_name(net_pipe
));
840 if (r
.in
.server_name
== NULL
) {
841 d_printf("talloc_asprintf failed\n");
844 generate_random_buffer(netr_cli_creds
.data
,
845 sizeof(netr_cli_creds
.data
));
846 r
.in
.credentials
= &netr_cli_creds
;
847 r
.out
.credentials
= &netr_srv_creds
;
849 status
= dcerpc_netr_ServerReqChallenge(net_pipe
, mem_ctx
, &r
);
850 if (!NT_STATUS_IS_OK(status
)) {
851 d_printf("netr_ServerReqChallenge failed: %s\n",
856 negotiate_flags
= NETLOGON_NEG_AUTH2_FLAGS
;
857 E_md4hash(cli_credentials_get_password(wks_cred
), mach_pw
.hash
);
859 creds_state
= talloc(mem_ctx
, struct creds_CredentialState
);
860 creds_client_init(creds_state
, r
.in
.credentials
,
861 r
.out
.credentials
, &mach_pw
,
862 &netr_cred
, negotiate_flags
);
864 a
.in
.server_name
= talloc_asprintf(
865 mem_ctx
, "\\\\%s", dcerpc_server_name(net_pipe
));
866 a
.in
.account_name
= talloc_asprintf(
867 mem_ctx
, "%s$", cli_credentials_get_workstation(wks_cred
));
868 a
.in
.computer_name
= cli_credentials_get_workstation(wks_cred
);
869 a
.in
.secure_channel_type
= SEC_CHAN_WKSTA
;
870 a
.in
.negotiate_flags
= &negotiate_flags
;
871 a
.out
.negotiate_flags
= &negotiate_flags
;
872 a
.in
.credentials
= &netr_cred
;
873 a
.out
.credentials
= &netr_cred
;
875 status
= dcerpc_netr_ServerAuthenticate2(net_pipe
, mem_ctx
, &a
);
876 if (!NT_STATUS_IS_OK(status
)) {
877 d_printf("netr_ServerServerAuthenticate2 failed: %s\n",
882 if (!creds_client_check(creds_state
, a
.out
.credentials
)) {
883 d_printf("creds_client_check failed\n");
887 cli_credentials_set_netlogon_creds(wks_cred
, creds_state
);
892 talloc_free(mem_ctx
);
897 * Do a couple of schannel protected Netlogon ops: Interactive and Network
898 * login, and change the wks password
901 static BOOL
schan(struct smbcli_state
*cli
,
902 struct cli_credentials
*wks_creds
,
903 struct cli_credentials
*user_creds
)
908 struct dcerpc_pipe
*net_pipe
;
911 mem_ctx
= talloc_new(NULL
);
912 if (mem_ctx
== NULL
) {
913 d_printf("talloc_new failed\n");
917 net_pipe
= dcerpc_pipe_init(mem_ctx
,
918 cli
->transport
->socket
->event
.ctx
);
919 if (net_pipe
== NULL
) {
920 d_printf("dcerpc_pipe_init failed\n");
924 status
= dcerpc_pipe_open_smb(net_pipe
->conn
, cli
->tree
, "\\netlogon");
925 if (!NT_STATUS_IS_OK(status
)) {
926 d_printf("dcerpc_pipe_open_smb failed: %s\n",
932 net_pipe
->conn
->flags
|= DCERPC_DEBUG_PRINT_IN
|
933 DCERPC_DEBUG_PRINT_OUT
;
936 net_pipe
->conn
->flags
|= (DCERPC_SIGN
| DCERPC_SEAL
);
937 status
= dcerpc_bind_auth(net_pipe
, &dcerpc_table_netlogon
,
938 wks_creds
, DCERPC_AUTH_TYPE_SCHANNEL
,
939 DCERPC_AUTH_LEVEL_PRIVACY
,
942 status
= dcerpc_bind_auth_none(net_pipe
, &dcerpc_table_netlogon
);
944 if (!NT_STATUS_IS_OK(status
)) {
945 d_printf("schannel bind failed: %s\n", nt_errstr(status
));
950 for (i
=2; i
<4; i
++) {
952 DATA_BLOB chal
, nt_resp
, lm_resp
, names_blob
, session_key
;
953 struct creds_CredentialState
*creds_state
;
954 struct netr_Authenticator netr_auth
, netr_auth2
;
955 struct netr_NetworkInfo ninfo
;
956 struct netr_PasswordInfo pinfo
;
957 struct netr_LogonSamLogon r
;
959 flags
= CLI_CRED_LANMAN_AUTH
| CLI_CRED_NTLM_AUTH
|
960 CLI_CRED_NTLMv2_AUTH
;
962 chal
= data_blob_talloc(mem_ctx
, NULL
, 8);
963 if (chal
.data
== NULL
) {
964 d_printf("data_blob_talloc failed\n");
968 generate_random_buffer(chal
.data
, chal
.length
);
969 names_blob
= NTLMv2_generate_names_blob(
970 mem_ctx
, cli_credentials_get_workstation(user_creds
),
971 cli_credentials_get_domain(user_creds
));
972 status
= cli_credentials_get_ntlm_response(
973 user_creds
, mem_ctx
, &flags
, chal
, names_blob
,
974 &lm_resp
, &nt_resp
, NULL
, NULL
);
975 if (!NT_STATUS_IS_OK(status
)) {
976 d_printf("cli_credentials_get_ntlm_response failed:"
977 " %s\n", nt_errstr(status
));
981 creds_state
= cli_credentials_get_netlogon_creds(wks_creds
);
982 creds_client_authenticator(creds_state
, &netr_auth
);
984 ninfo
.identity_info
.account_name
.string
=
985 cli_credentials_get_username(user_creds
);
986 ninfo
.identity_info
.domain_name
.string
=
987 cli_credentials_get_domain(user_creds
);
988 ninfo
.identity_info
.parameter_control
= 0;
989 ninfo
.identity_info
.logon_id_low
= 0;
990 ninfo
.identity_info
.logon_id_high
= 0;
991 ninfo
.identity_info
.workstation
.string
=
992 cli_credentials_get_workstation(user_creds
);
993 memcpy(ninfo
.challenge
, chal
.data
, sizeof(ninfo
.challenge
));
994 ninfo
.nt
.length
= nt_resp
.length
;
995 ninfo
.nt
.data
= nt_resp
.data
;
996 ninfo
.lm
.length
= lm_resp
.length
;
997 ninfo
.lm
.data
= lm_resp
.data
;
999 r
.in
.server_name
= talloc_asprintf(
1000 mem_ctx
, "\\\\%s", dcerpc_server_name(net_pipe
));
1001 ZERO_STRUCT(netr_auth2
);
1002 r
.in
.computer_name
=
1003 cli_credentials_get_workstation(wks_creds
);
1004 r
.in
.credential
= &netr_auth
;
1005 r
.in
.return_authenticator
= &netr_auth2
;
1006 r
.in
.logon_level
= 2;
1007 r
.in
.validation_level
= i
;
1008 r
.in
.logon
.network
= &ninfo
;
1009 r
.out
.return_authenticator
= NULL
;
1011 status
= dcerpc_netr_LogonSamLogon(net_pipe
, mem_ctx
, &r
);
1012 if (!NT_STATUS_IS_OK(status
)) {
1013 d_printf("netr_LogonSamLogon failed: %s\n",
1018 if ((r
.out
.return_authenticator
== NULL
) ||
1019 (!creds_client_check(creds_state
,
1020 &r
.out
.return_authenticator
->cred
))) {
1021 d_printf("Credentials check failed!\n");
1025 creds_client_authenticator(creds_state
, &netr_auth
);
1027 pinfo
.identity_info
= ninfo
.identity_info
;
1028 ZERO_STRUCT(pinfo
.lmpassword
.hash
);
1029 E_md4hash(cli_credentials_get_password(user_creds
),
1030 pinfo
.ntpassword
.hash
);
1031 session_key
= data_blob_talloc(mem_ctx
,
1032 creds_state
->session_key
, 16);
1033 arcfour_crypt_blob(pinfo
.ntpassword
.hash
,
1034 sizeof(pinfo
.ntpassword
.hash
),
1037 r
.in
.logon_level
= 1;
1038 r
.in
.logon
.password
= &pinfo
;
1039 r
.out
.return_authenticator
= NULL
;
1041 status
= dcerpc_netr_LogonSamLogon(net_pipe
, mem_ctx
, &r
);
1042 if (!NT_STATUS_IS_OK(status
)) {
1043 d_printf("netr_LogonSamLogon failed: %s\n",
1048 if ((r
.out
.return_authenticator
== NULL
) ||
1049 (!creds_client_check(creds_state
,
1050 &r
.out
.return_authenticator
->cred
))) {
1051 d_printf("Credentials check failed!\n");
1057 struct netr_ServerPasswordSet s
;
1058 char *password
= generate_random_str(wks_creds
, 8);
1059 struct creds_CredentialState
*creds_state
;
1061 s
.in
.server_name
= talloc_asprintf(
1062 mem_ctx
, "\\\\%s", dcerpc_server_name(net_pipe
));
1063 s
.in
.computer_name
= cli_credentials_get_workstation(wks_creds
);
1064 s
.in
.account_name
= talloc_asprintf(
1065 mem_ctx
, "%s$", s
.in
.computer_name
);
1066 s
.in
.secure_channel_type
= SEC_CHAN_WKSTA
;
1067 E_md4hash(password
, s
.in
.new_password
.hash
);
1069 creds_state
= cli_credentials_get_netlogon_creds(wks_creds
);
1070 creds_des_encrypt(creds_state
, &s
.in
.new_password
);
1071 creds_client_authenticator(creds_state
, &s
.in
.credential
);
1073 status
= dcerpc_netr_ServerPasswordSet(net_pipe
, mem_ctx
, &s
);
1074 if (!NT_STATUS_IS_OK(status
)) {
1075 printf("ServerPasswordSet - %s\n", nt_errstr(status
));
1079 if (!creds_client_check(creds_state
,
1080 &s
.out
.return_authenticator
.cred
)) {
1081 printf("Credential chaining failed\n");
1084 cli_credentials_set_password(wks_creds
, password
,
1090 talloc_free(mem_ctx
);
1095 * Delete the wks account again
1098 static BOOL
leave(struct smbcli_state
*cli
,
1099 struct cli_credentials
*admin_creds
,
1100 struct cli_credentials
*wks_creds
)
1102 char *wks_name
= talloc_asprintf(
1103 NULL
, "%s$", cli_credentials_get_workstation(wks_creds
));
1106 ret
= delete_user(cli
, admin_creds
, wks_name
);
1107 talloc_free(wks_name
);
1112 * Test the Samba3 DC code a bit. Join, do some schan netlogon ops, leave
1115 BOOL
torture_netlogon_samba3(struct torture_context
*torture
)
1117 TALLOC_CTX
*mem_ctx
;
1120 struct smbcli_state
*cli
;
1121 struct cli_credentials
*anon_creds
;
1122 struct cli_credentials
*wks_creds
;
1123 const char *wks_name
;
1126 wks_name
= lp_parm_string(-1, "torture", "wksname");
1127 if (wks_name
== NULL
) {
1128 wks_name
= get_myname();
1131 mem_ctx
= talloc_init("torture_bind_authcontext");
1133 if (mem_ctx
== NULL
) {
1134 d_printf("talloc_init failed\n");
1138 if (!(anon_creds
= create_anon_creds(mem_ctx
))) {
1139 d_printf("create_anon_creds failed\n");
1143 status
= smbcli_full_connection(mem_ctx
, &cli
,
1144 lp_parm_string(-1, "torture", "host"),
1145 "IPC$", NULL
, anon_creds
, NULL
);
1146 if (!NT_STATUS_IS_OK(status
)) {
1147 d_printf("smbcli_full_connection failed: %s\n",
1152 wks_creds
= cli_credentials_init(mem_ctx
);
1153 if (wks_creds
== NULL
) {
1154 d_printf("cli_credentials_init failed\n");
1158 cli_credentials_set_conf(wks_creds
);
1159 cli_credentials_set_secure_channel_type(wks_creds
, SEC_CHAN_WKSTA
);
1160 cli_credentials_set_username(wks_creds
, wks_name
, CRED_SPECIFIED
);
1161 cli_credentials_set_workstation(wks_creds
, wks_name
, CRED_SPECIFIED
);
1162 cli_credentials_set_password(wks_creds
,
1163 generate_random_str(wks_creds
, 8),
1166 if (!join3(cli
, False
, cmdline_credentials
, wks_creds
)) {
1167 d_printf("join failed\n");
1171 cli_credentials_set_domain(
1172 cmdline_credentials
, cli_credentials_get_domain(wks_creds
),
1175 for (i
=0; i
<2; i
++) {
1177 /* Do this more than once, the routine "schan" changes
1178 * the workstation password using the netlogon
1179 * password change routine */
1183 if (!auth2(cli
, wks_creds
)) {
1184 d_printf("auth2 failed\n");
1188 for (j
=0; j
<2; j
++) {
1189 if (!schan(cli
, wks_creds
, cmdline_credentials
)) {
1190 d_printf("schan failed\n");
1196 if (!leave(cli
, cmdline_credentials
, wks_creds
)) {
1197 d_printf("leave failed\n");
1204 talloc_free(mem_ctx
);
1209 * Do a simple join, testjoin and leave using specified smb and samr
1213 static BOOL
test_join3(TALLOC_CTX
*mem_ctx
,
1215 struct cli_credentials
*smb_creds
,
1216 struct cli_credentials
*samr_creds
,
1217 const char *wks_name
)
1221 struct smbcli_state
*cli
;
1222 struct cli_credentials
*wks_creds
;
1224 status
= smbcli_full_connection(mem_ctx
, &cli
,
1225 lp_parm_string(-1, "torture", "host"),
1226 "IPC$", NULL
, smb_creds
, NULL
);
1227 if (!NT_STATUS_IS_OK(status
)) {
1228 d_printf("smbcli_full_connection failed: %s\n",
1233 wks_creds
= cli_credentials_init(cli
);
1234 if (wks_creds
== NULL
) {
1235 d_printf("cli_credentials_init failed\n");
1239 cli_credentials_set_conf(wks_creds
);
1240 cli_credentials_set_secure_channel_type(wks_creds
, SEC_CHAN_WKSTA
);
1241 cli_credentials_set_username(wks_creds
, wks_name
, CRED_SPECIFIED
);
1242 cli_credentials_set_workstation(wks_creds
, wks_name
, CRED_SPECIFIED
);
1243 cli_credentials_set_password(wks_creds
,
1244 generate_random_str(wks_creds
, 8),
1247 if (!join3(cli
, use_level25
, samr_creds
, wks_creds
)) {
1248 d_printf("join failed\n");
1252 cli_credentials_set_domain(
1253 cmdline_credentials
, cli_credentials_get_domain(wks_creds
),
1256 if (!auth2(cli
, wks_creds
)) {
1257 d_printf("auth2 failed\n");
1261 if (!leave(cli
, samr_creds
, wks_creds
)) {
1262 d_printf("leave failed\n");
1275 * Test the different session key variants. Do it by joining, this uses the
1276 * session key in the setpassword routine. Test the join by doing the auth2.
1279 BOOL
torture_samba3_sessionkey(struct torture_context
*torture
)
1281 TALLOC_CTX
*mem_ctx
;
1283 struct cli_credentials
*anon_creds
;
1284 const char *wks_name
;
1286 wks_name
= lp_parm_string(-1, "torture", "wksname");
1287 if (wks_name
== NULL
) {
1288 wks_name
= get_myname();
1291 mem_ctx
= talloc_init("torture_samba3_sessionkey");
1293 if (mem_ctx
== NULL
) {
1294 d_printf("talloc_init failed\n");
1298 if (!(anon_creds
= create_anon_creds(mem_ctx
))) {
1299 d_printf("create_anon_creds failed\n");
1305 if (!lp_parm_bool(-1, "target", "samba3", False
)) {
1307 /* Samba3 in the build farm right now does this happily. Need
1310 if (test_join3(mem_ctx
, False
, anon_creds
, NULL
, wks_name
)) {
1311 d_printf("join using anonymous bind on an anonymous smb "
1312 "connection succeeded -- HUH??\n");
1317 if (!test_join3(mem_ctx
, False
, anon_creds
, cmdline_credentials
,
1319 d_printf("join using ntlmssp bind on an anonymous smb "
1320 "connection failed\n");
1324 if (!test_join3(mem_ctx
, False
, cmdline_credentials
, NULL
, wks_name
)) {
1325 d_printf("join using anonymous bind on an authenticated smb "
1326 "connection failed\n");
1330 if (!test_join3(mem_ctx
, False
, cmdline_credentials
,
1331 cmdline_credentials
,
1333 d_printf("join using ntlmssp bind on an authenticated smb "
1334 "connection failed\n");
1339 * The following two are tests for setuserinfolevel 25
1342 if (!test_join3(mem_ctx
, True
, anon_creds
, cmdline_credentials
,
1344 d_printf("join using ntlmssp bind on an anonymous smb "
1345 "connection failed\n");
1349 if (!test_join3(mem_ctx
, True
, cmdline_credentials
, NULL
, wks_name
)) {
1350 d_printf("join using anonymous bind on an authenticated smb "
1351 "connection failed\n");
1361 * open pipe and bind, given an IPC$ context
1364 static NTSTATUS
pipe_bind_smb(TALLOC_CTX
*mem_ctx
,
1365 struct smbcli_tree
*tree
,
1366 const char *pipe_name
,
1367 const struct dcerpc_interface_table
*iface
,
1368 struct dcerpc_pipe
**p
)
1370 struct dcerpc_pipe
*result
;
1373 if (!(result
= dcerpc_pipe_init(
1374 mem_ctx
, tree
->session
->transport
->socket
->event
.ctx
))) {
1375 return NT_STATUS_NO_MEMORY
;
1378 status
= dcerpc_pipe_open_smb(result
->conn
, tree
, pipe_name
);
1379 if (!NT_STATUS_IS_OK(status
)) {
1380 d_printf("dcerpc_pipe_open_smb failed: %s\n",
1382 talloc_free(result
);
1386 status
= dcerpc_bind_auth_none(result
, iface
);
1387 if (!NT_STATUS_IS_OK(status
)) {
1388 d_printf("schannel bind failed: %s\n", nt_errstr(status
));
1389 talloc_free(result
);
1394 return NT_STATUS_OK
;
1398 * Sane wrapper around lsa_LookupNames
1401 static struct dom_sid
*name2sid(TALLOC_CTX
*mem_ctx
,
1402 struct dcerpc_pipe
*p
,
1406 struct lsa_ObjectAttribute attr
;
1407 struct lsa_QosInfo qos
;
1408 struct lsa_OpenPolicy2 r
;
1411 struct policy_handle handle
;
1412 struct lsa_LookupNames l
;
1413 struct lsa_TransSidArray sids
;
1414 struct lsa_String lsa_name
;
1416 struct dom_sid
*result
;
1417 TALLOC_CTX
*tmp_ctx
;
1419 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
1424 qos
.impersonation_level
= 2;
1425 qos
.context_mode
= 1;
1426 qos
.effective_only
= 0;
1429 attr
.root_dir
= NULL
;
1430 attr
.object_name
= NULL
;
1431 attr
.attributes
= 0;
1432 attr
.sec_desc
= NULL
;
1433 attr
.sec_qos
= &qos
;
1435 r
.in
.system_name
= "\\";
1437 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1438 r
.out
.handle
= &handle
;
1440 status
= dcerpc_lsa_OpenPolicy2(p
, tmp_ctx
, &r
);
1441 if (!NT_STATUS_IS_OK(status
)) {
1442 printf("OpenPolicy2 failed - %s\n", nt_errstr(status
));
1443 talloc_free(tmp_ctx
);
1450 lsa_name
.string
= talloc_asprintf(tmp_ctx
, "%s\\%s", domain
, name
);
1452 l
.in
.handle
= &handle
;
1454 l
.in
.names
= &lsa_name
;
1457 l
.in
.count
= &count
;
1458 l
.out
.count
= &count
;
1461 status
= dcerpc_lsa_LookupNames(p
, tmp_ctx
, &l
);
1462 if (!NT_STATUS_IS_OK(status
)) {
1463 printf("LookupNames failed - %s\n", nt_errstr(status
));
1464 talloc_free(tmp_ctx
);
1468 result
= dom_sid_add_rid(mem_ctx
, l
.out
.domains
->domains
[0].sid
,
1469 l
.out
.sids
->sids
[0].rid
);
1471 c
.in
.handle
= &handle
;
1472 c
.out
.handle
= &handle
;
1474 status
= dcerpc_lsa_Close(p
, tmp_ctx
, &c
);
1475 if (!NT_STATUS_IS_OK(status
)) {
1476 printf("dcerpc_lsa_Close failed - %s\n", nt_errstr(status
));
1477 talloc_free(tmp_ctx
);
1481 talloc_free(tmp_ctx
);
1486 * Find out the user SID on this connection
1489 static struct dom_sid
*whoami(TALLOC_CTX
*mem_ctx
, struct smbcli_tree
*tree
)
1491 struct dcerpc_pipe
*lsa
;
1492 struct lsa_GetUserName r
;
1494 struct lsa_StringPointer authority_name_p
;
1495 struct dom_sid
*result
;
1497 status
= pipe_bind_smb(mem_ctx
, tree
, "\\pipe\\lsarpc",
1498 &dcerpc_table_lsarpc
, &lsa
);
1499 if (!NT_STATUS_IS_OK(status
)) {
1500 d_printf("(%s) Could not bind to LSA: %s\n",
1501 __location__
, nt_errstr(status
));
1505 r
.in
.system_name
= "\\";
1506 r
.in
.account_name
= NULL
;
1507 authority_name_p
.string
= NULL
;
1508 r
.in
.authority_name
= &authority_name_p
;
1510 status
= dcerpc_lsa_GetUserName(lsa
, mem_ctx
, &r
);
1512 if (!NT_STATUS_IS_OK(status
)) {
1513 printf("(%s) GetUserName failed - %s\n",
1514 __location__
, nt_errstr(status
));
1519 result
= name2sid(mem_ctx
, lsa
, r
.out
.account_name
->string
,
1520 r
.out
.authority_name
->string
->string
);
1527 * Do a tcon, given a session
1530 NTSTATUS
secondary_tcon(TALLOC_CTX
*mem_ctx
,
1531 struct smbcli_session
*session
,
1532 const char *sharename
,
1533 struct smbcli_tree
**res
)
1535 struct smbcli_tree
*result
;
1536 TALLOC_CTX
*tmp_ctx
;
1537 union smb_tcon tcon
;
1540 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
1541 return NT_STATUS_NO_MEMORY
;
1544 if (!(result
= smbcli_tree_init(session
, mem_ctx
, False
))) {
1545 talloc_free(tmp_ctx
);
1546 return NT_STATUS_NO_MEMORY
;
1549 tcon
.generic
.level
= RAW_TCON_TCONX
;
1550 tcon
.tconx
.in
.flags
= 0;
1551 tcon
.tconx
.in
.password
= data_blob(NULL
, 0);
1552 tcon
.tconx
.in
.path
= sharename
;
1553 tcon
.tconx
.in
.device
= "?????";
1555 status
= smb_raw_tcon(result
, tmp_ctx
, &tcon
);
1556 if (!NT_STATUS_IS_OK(status
)) {
1557 d_printf("(%s) smb_raw_tcon failed: %s\n", __location__
,
1559 talloc_free(tmp_ctx
);
1563 result
->tid
= tcon
.tconx
.out
.tid
;
1564 result
= talloc_steal(mem_ctx
, result
);
1565 talloc_free(tmp_ctx
);
1567 return NT_STATUS_OK
;
1571 * Test the getusername behaviour
1574 BOOL
torture_samba3_rpc_getusername(struct torture_context
*torture
)
1577 struct smbcli_state
*cli
;
1578 TALLOC_CTX
*mem_ctx
;
1580 struct dom_sid
*user_sid
;
1581 struct dom_sid
*created_sid
;
1582 struct cli_credentials
*anon_creds
;
1583 struct cli_credentials
*user_creds
;
1586 if (!(mem_ctx
= talloc_new(torture
))) {
1590 status
= smbcli_full_connection(
1591 mem_ctx
, &cli
, lp_parm_string(-1, "torture", "host"),
1592 "IPC$", NULL
, cmdline_credentials
, NULL
);
1593 if (!NT_STATUS_IS_OK(status
)) {
1594 d_printf("(%s) smbcli_full_connection failed: %s\n",
1595 __location__
, nt_errstr(status
));
1600 if (!(user_sid
= whoami(mem_ctx
, cli
->tree
))) {
1601 d_printf("(%s) whoami on auth'ed connection failed\n",
1608 if (!(anon_creds
= create_anon_creds(mem_ctx
))) {
1609 d_printf("(%s) create_anon_creds failed\n", __location__
);
1614 status
= smbcli_full_connection(
1615 mem_ctx
, &cli
, lp_parm_string(-1, "torture", "host"),
1616 "IPC$", NULL
, anon_creds
, NULL
);
1617 if (!NT_STATUS_IS_OK(status
)) {
1618 d_printf("(%s) anon smbcli_full_connection failed: %s\n",
1619 __location__
, nt_errstr(status
));
1624 if (!(user_sid
= whoami(mem_ctx
, cli
->tree
))) {
1625 d_printf("(%s) whoami on anon connection failed\n",
1631 if (!dom_sid_equal(user_sid
,
1632 dom_sid_parse_talloc(mem_ctx
, "s-1-5-7"))) {
1633 d_printf("(%s) Anon lsa_GetUserName returned %s, expected "
1634 "S-1-5-7", __location__
,
1635 dom_sid_string(mem_ctx
, user_sid
));
1639 if (!(user_creds
= cli_credentials_init(mem_ctx
))) {
1640 d_printf("(%s) cli_credentials_init failed\n", __location__
);
1645 cli_credentials_set_conf(user_creds
);
1646 cli_credentials_set_username(user_creds
, "torture_username",
1648 cli_credentials_set_password(user_creds
,
1649 generate_random_str(user_creds
, 8),
1652 if (!create_user(mem_ctx
, cli
, cmdline_credentials
,
1653 cli_credentials_get_username(user_creds
),
1654 cli_credentials_get_password(user_creds
),
1655 &domain_name
, &created_sid
)) {
1656 d_printf("(%s) create_user failed\n", __location__
);
1661 cli_credentials_set_domain(user_creds
, domain_name
,
1665 struct smbcli_session
*session2
;
1666 struct smb_composite_sesssetup setup
;
1667 struct smbcli_tree
*tree
;
1669 session2
= smbcli_session_init(cli
->transport
, mem_ctx
, False
);
1670 if (session2
== NULL
) {
1671 d_printf("(%s) smbcli_session_init failed\n",
1676 setup
.in
.sesskey
= cli
->transport
->negotiate
.sesskey
;
1677 setup
.in
.capabilities
= cli
->transport
->negotiate
.capabilities
;
1678 setup
.in
.workgroup
= "";
1679 setup
.in
.credentials
= user_creds
;
1681 status
= smb_composite_sesssetup(session2
, &setup
);
1682 if (!NT_STATUS_IS_OK(status
)) {
1683 d_printf("(%s) session setup with new user failed: "
1684 "%s\n", __location__
, nt_errstr(status
));
1689 if (!NT_STATUS_IS_OK(secondary_tcon(mem_ctx
, session2
,
1691 d_printf("(%s) secondary_tcon failed\n",
1697 if (!(user_sid
= whoami(mem_ctx
, tree
))) {
1698 d_printf("(%s) whoami on user connection failed\n",
1707 d_printf("Created %s, found %s\n",
1708 dom_sid_string(mem_ctx
, created_sid
),
1709 dom_sid_string(mem_ctx
, user_sid
));
1711 if (!dom_sid_equal(created_sid
, user_sid
)) {
1716 if (!delete_user(cli
, cmdline_credentials
,
1717 cli_credentials_get_username(user_creds
))) {
1718 d_printf("(%s) delete_user failed\n", __location__
);
1723 talloc_free(mem_ctx
);
1727 static BOOL
test_NetShareGetInfo(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1728 const char *sharename
)
1731 struct srvsvc_NetShareGetInfo r
;
1732 uint32_t levels
[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007, 1501 };
1736 r
.in
.server_unc
= talloc_asprintf(mem_ctx
, "\\\\%s",
1737 dcerpc_server_name(p
));
1738 r
.in
.share_name
= sharename
;
1740 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1741 r
.in
.level
= levels
[i
];
1745 printf("testing NetShareGetInfo level %u on share '%s'\n",
1746 r
.in
.level
, r
.in
.share_name
);
1748 status
= dcerpc_srvsvc_NetShareGetInfo(p
, mem_ctx
, &r
);
1749 if (!NT_STATUS_IS_OK(status
)) {
1750 printf("NetShareGetInfo level %u on share '%s' failed"
1751 " - %s\n", r
.in
.level
, r
.in
.share_name
,
1756 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1757 printf("NetShareGetInfo level %u on share '%s' failed "
1758 "- %s\n", r
.in
.level
, r
.in
.share_name
,
1759 win_errstr(r
.out
.result
));
1768 static BOOL
test_NetShareEnum(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1769 const char **one_sharename
)
1772 struct srvsvc_NetShareEnum r
;
1773 struct srvsvc_NetShareCtr0 c0
;
1774 uint32_t levels
[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007 };
1778 r
.in
.server_unc
= talloc_asprintf(mem_ctx
,"\\\\%s",dcerpc_server_name(p
));
1779 r
.in
.ctr
.ctr0
= &c0
;
1780 r
.in
.ctr
.ctr0
->count
= 0;
1781 r
.in
.ctr
.ctr0
->array
= NULL
;
1782 r
.in
.max_buffer
= (uint32_t)-1;
1783 r
.in
.resume_handle
= NULL
;
1785 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1786 r
.in
.level
= levels
[i
];
1790 printf("testing NetShareEnum level %u\n", r
.in
.level
);
1791 status
= dcerpc_srvsvc_NetShareEnum(p
, mem_ctx
, &r
);
1792 if (!NT_STATUS_IS_OK(status
)) {
1793 printf("NetShareEnum level %u failed - %s\n",
1794 r
.in
.level
, nt_errstr(status
));
1798 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1799 printf("NetShareEnum level %u failed - %s\n",
1800 r
.in
.level
, win_errstr(r
.out
.result
));
1803 if (r
.in
.level
== 0) {
1804 struct srvsvc_NetShareCtr0
*ctr
= r
.out
.ctr
.ctr0
;
1805 if (ctr
->count
> 0) {
1806 *one_sharename
= ctr
->array
[0].name
;
1814 BOOL
torture_samba3_rpc_srvsvc(struct torture_context
*torture
)
1816 struct dcerpc_pipe
*p
;
1817 TALLOC_CTX
*mem_ctx
;
1819 const char *sharename
= NULL
;
1820 struct smbcli_state
*cli
;
1823 if (!(mem_ctx
= talloc_new(torture
))) {
1827 if (!(torture_open_connection_share(
1828 mem_ctx
, &cli
, lp_parm_string(-1, "torture", "host"),
1830 talloc_free(mem_ctx
);
1834 status
= pipe_bind_smb(mem_ctx
, cli
->tree
, "\\pipe\\srvsvc",
1835 &dcerpc_table_srvsvc
, &p
);
1836 if (!NT_STATUS_IS_OK(status
)) {
1837 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1838 __location__
, nt_errstr(status
));
1843 ret
&= test_NetShareEnum(p
, mem_ctx
, &sharename
);
1844 if (sharename
== NULL
) {
1845 printf("did not get sharename\n");
1847 ret
&= test_NetShareGetInfo(p
, mem_ctx
, sharename
);
1851 talloc_free(mem_ctx
);
1855 static struct security_descriptor
*get_sharesec(TALLOC_CTX
*mem_ctx
,
1856 struct smbcli_session
*sess
,
1857 const char *sharename
)
1859 struct smbcli_tree
*tree
;
1860 TALLOC_CTX
*tmp_ctx
;
1861 struct dcerpc_pipe
*p
;
1863 struct srvsvc_NetShareGetInfo r
;
1864 struct security_descriptor
*result
;
1866 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
1867 d_printf("talloc_new failed\n");
1871 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx
, sess
, "IPC$", &tree
))) {
1872 d_printf("secondary_tcon failed\n");
1873 talloc_free(tmp_ctx
);
1877 status
= pipe_bind_smb(mem_ctx
, tree
, "\\pipe\\srvsvc",
1878 &dcerpc_table_srvsvc
, &p
);
1879 if (!NT_STATUS_IS_OK(status
)) {
1880 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1881 __location__
, nt_errstr(status
));
1882 talloc_free(tmp_ctx
);
1887 p
->conn
->flags
|= DCERPC_DEBUG_PRINT_IN
| DCERPC_DEBUG_PRINT_OUT
;
1890 r
.in
.server_unc
= talloc_asprintf(tmp_ctx
, "\\\\%s",
1891 dcerpc_server_name(p
));
1892 r
.in
.share_name
= sharename
;
1895 status
= dcerpc_srvsvc_NetShareGetInfo(p
, tmp_ctx
, &r
);
1896 if (!NT_STATUS_IS_OK(status
)) {
1897 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
1899 talloc_free(tmp_ctx
);
1903 result
= talloc_steal(mem_ctx
, r
.out
.info
.info502
->sd
);
1904 talloc_free(tmp_ctx
);
1908 static NTSTATUS
set_sharesec(TALLOC_CTX
*mem_ctx
,
1909 struct smbcli_session
*sess
,
1910 const char *sharename
,
1911 struct security_descriptor
*sd
)
1913 struct smbcli_tree
*tree
;
1914 TALLOC_CTX
*tmp_ctx
;
1915 struct dcerpc_pipe
*p
;
1917 struct sec_desc_buf i
;
1918 struct srvsvc_NetShareSetInfo r
;
1921 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
1922 d_printf("talloc_new failed\n");
1923 return NT_STATUS_NO_MEMORY
;
1926 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx
, sess
, "IPC$", &tree
))) {
1927 d_printf("secondary_tcon failed\n");
1928 talloc_free(tmp_ctx
);
1929 return NT_STATUS_UNSUCCESSFUL
;
1932 status
= pipe_bind_smb(mem_ctx
, tree
, "\\pipe\\srvsvc",
1933 &dcerpc_table_srvsvc
, &p
);
1934 if (!NT_STATUS_IS_OK(status
)) {
1935 d_printf("(%s) could not bind to srvsvc pipe: %s\n",
1936 __location__
, nt_errstr(status
));
1937 talloc_free(tmp_ctx
);
1938 return NT_STATUS_UNSUCCESSFUL
;
1942 p
->conn
->flags
|= DCERPC_DEBUG_PRINT_IN
| DCERPC_DEBUG_PRINT_OUT
;
1945 r
.in
.server_unc
= talloc_asprintf(tmp_ctx
, "\\\\%s",
1946 dcerpc_server_name(p
));
1947 r
.in
.share_name
= sharename
;
1950 r
.in
.info
.info1501
= &i
;
1951 r
.in
.parm_error
= &error
;
1953 status
= dcerpc_srvsvc_NetShareSetInfo(p
, tmp_ctx
, &r
);
1954 if (!NT_STATUS_IS_OK(status
)) {
1955 d_printf("srvsvc_NetShareGetInfo failed: %s\n",
1959 talloc_free(tmp_ctx
);
1963 BOOL
try_tcon(TALLOC_CTX
*mem_ctx
,
1964 struct security_descriptor
*orig_sd
,
1965 struct smbcli_session
*session
,
1966 const char *sharename
, const struct dom_sid
*user_sid
,
1967 unsigned int access_mask
, NTSTATUS expected_tcon
,
1968 NTSTATUS expected_mkdir
)
1970 TALLOC_CTX
*tmp_ctx
;
1971 struct smbcli_tree
*rmdir_tree
, *tree
;
1972 struct dom_sid
*domain_sid
;
1974 struct security_descriptor
*sd
;
1978 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
1979 d_printf("talloc_new failed\n");
1983 status
= secondary_tcon(tmp_ctx
, session
, sharename
, &rmdir_tree
);
1984 if (!NT_STATUS_IS_OK(status
)) {
1985 d_printf("first tcon to delete dir failed\n");
1986 talloc_free(tmp_ctx
);
1990 smbcli_rmdir(rmdir_tree
, "sharesec_testdir");
1992 if (!NT_STATUS_IS_OK(dom_sid_split_rid(tmp_ctx
, user_sid
,
1993 &domain_sid
, &rid
))) {
1994 d_printf("dom_sid_split_rid failed\n");
1995 talloc_free(tmp_ctx
);
1999 sd
= security_descriptor_create(
2000 tmp_ctx
, "S-1-5-32-544",
2001 dom_sid_string(mem_ctx
, dom_sid_add_rid(mem_ctx
, domain_sid
,
2003 dom_sid_string(mem_ctx
, user_sid
),
2004 SEC_ACE_TYPE_ACCESS_ALLOWED
, access_mask
, 0, NULL
);
2006 d_printf("security_descriptor_create failed\n");
2007 talloc_free(tmp_ctx
);
2011 status
= set_sharesec(mem_ctx
, session
, sharename
, sd
);
2012 if (!NT_STATUS_IS_OK(status
)) {
2013 d_printf("custom set_sharesec failed: %s\n",
2015 talloc_free(tmp_ctx
);
2019 status
= secondary_tcon(tmp_ctx
, session
, sharename
, &tree
);
2020 if (!NT_STATUS_EQUAL(status
, expected_tcon
)) {
2021 d_printf("Expected %s, got %s\n", nt_errstr(expected_tcon
),
2027 if (!NT_STATUS_IS_OK(status
)) {
2028 /* An expected non-access, no point in trying to write */
2032 status
= smbcli_mkdir(tree
, "sharesec_testdir");
2033 if (!NT_STATUS_EQUAL(status
, expected_mkdir
)) {
2034 d_printf("Expected %s, got %s\n", nt_errstr(expected_mkdir
),
2040 smbcli_rmdir(rmdir_tree
, "sharesec_testdir");
2042 status
= set_sharesec(mem_ctx
, session
, sharename
, orig_sd
);
2043 if (!NT_STATUS_IS_OK(status
)) {
2044 d_printf("custom set_sharesec failed: %s\n",
2046 talloc_free(tmp_ctx
);
2050 talloc_free(tmp_ctx
);
2054 BOOL
torture_samba3_rpc_sharesec(struct torture_context
*torture
)
2056 TALLOC_CTX
*mem_ctx
;
2058 struct smbcli_state
*cli
;
2059 struct security_descriptor
*sd
;
2060 struct dom_sid
*user_sid
;
2062 if (!(mem_ctx
= talloc_new(torture
))) {
2066 if (!(torture_open_connection_share(
2067 mem_ctx
, &cli
, lp_parm_string(-1, "torture", "host"),
2069 d_printf("IPC$ connection failed\n");
2070 talloc_free(mem_ctx
);
2074 if (!(user_sid
= whoami(mem_ctx
, cli
->tree
))) {
2075 d_printf("whoami failed\n");
2076 talloc_free(mem_ctx
);
2080 sd
= get_sharesec(mem_ctx
, cli
->session
, lp_parm_string(-1, "torture",
2083 ret
&= try_tcon(mem_ctx
, sd
, cli
->session
,
2084 lp_parm_string(-1, "torture", "share"),
2085 user_sid
, 0, NT_STATUS_ACCESS_DENIED
, NT_STATUS_OK
);
2087 ret
&= try_tcon(mem_ctx
, sd
, cli
->session
,
2088 lp_parm_string(-1, "torture", "share"),
2089 user_sid
, SEC_FILE_READ_DATA
, NT_STATUS_OK
,
2090 NT_STATUS_NETWORK_ACCESS_DENIED
);
2092 ret
&= try_tcon(mem_ctx
, sd
, cli
->session
,
2093 lp_parm_string(-1, "torture", "share"),
2094 user_sid
, SEC_FILE_ALL
, NT_STATUS_OK
, NT_STATUS_OK
);
2096 talloc_free(mem_ctx
);
2100 BOOL
torture_samba3_rpc_lsa(struct torture_context
*torture
)
2102 TALLOC_CTX
*mem_ctx
;
2104 struct smbcli_state
*cli
;
2105 struct dcerpc_pipe
*p
;
2106 struct policy_handle lsa_handle
;
2108 struct dom_sid
*domain_sid
;
2110 if (!(mem_ctx
= talloc_new(torture
))) {
2114 if (!(torture_open_connection_share(
2115 mem_ctx
, &cli
, lp_parm_string(-1, "torture", "host"),
2117 d_printf("IPC$ connection failed\n");
2118 talloc_free(mem_ctx
);
2122 status
= pipe_bind_smb(mem_ctx
, cli
->tree
, "\\lsarpc",
2123 &dcerpc_table_lsarpc
, &p
);
2124 if (!NT_STATUS_IS_OK(status
)) {
2125 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__
,
2127 talloc_free(mem_ctx
);
2132 struct lsa_ObjectAttribute attr
;
2133 struct lsa_OpenPolicy2 o
;
2134 o
.in
.system_name
= talloc_asprintf(
2135 mem_ctx
, "\\\\%s", dcerpc_server_name(p
));
2138 o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2139 o
.out
.handle
= &lsa_handle
;
2140 status
= dcerpc_lsa_OpenPolicy2(p
, mem_ctx
, &o
);
2141 if (!NT_STATUS_IS_OK(status
)) {
2142 d_printf("(%s) dcerpc_lsa_OpenPolicy2 failed: %s\n",
2143 __location__
, nt_errstr(status
));
2144 talloc_free(mem_ctx
);
2150 p
->conn
->flags
|= DCERPC_DEBUG_PRINT_IN
| DCERPC_DEBUG_PRINT_OUT
;
2155 int levels
[] = { 2,3,5,6 };
2157 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
2158 struct lsa_QueryInfoPolicy r
;
2159 r
.in
.handle
= &lsa_handle
;
2160 r
.in
.level
= levels
[i
];
2161 status
= dcerpc_lsa_QueryInfoPolicy(p
, mem_ctx
, &r
);
2162 if (!NT_STATUS_IS_OK(status
)) {
2163 d_printf("(%s) dcerpc_lsa_QueryInfoPolicy %d "
2164 "failed: %s\n", __location__
,
2165 levels
[i
], nt_errstr(status
));
2166 talloc_free(mem_ctx
);
2169 if (levels
[i
] == 5) {
2170 domain_sid
= r
.out
.info
->account_domain
.sid
;
2178 static NTSTATUS
get_servername(TALLOC_CTX
*mem_ctx
, struct smbcli_tree
*tree
,
2181 struct rap_WserverGetInfo r
;
2183 char servername
[17];
2186 r
.in
.bufsize
= 0xffff;
2188 status
= smbcli_rap_netservergetinfo(tree
, mem_ctx
, &r
);
2189 if (!NT_STATUS_IS_OK(status
)) {
2193 memcpy(servername
, r
.out
.info
.info0
.name
, 16);
2194 servername
[16] = '\0';
2196 if (pull_ascii_talloc(mem_ctx
, name
, servername
) < 0) {
2197 return NT_STATUS_NO_MEMORY
;
2200 return NT_STATUS_OK
;
2204 static NTSTATUS
find_printers(TALLOC_CTX
*ctx
, struct smbcli_tree
*tree
,
2205 const char ***printers
, int *num_printers
)
2207 TALLOC_CTX
*mem_ctx
;
2209 struct dcerpc_pipe
*p
;
2210 struct srvsvc_NetShareEnum r
;
2211 struct srvsvc_NetShareCtr1 c1_in
;
2212 struct srvsvc_NetShareCtr1
*c1
;
2215 mem_ctx
= talloc_new(ctx
);
2216 if (mem_ctx
== NULL
) {
2217 return NT_STATUS_NO_MEMORY
;
2220 status
= pipe_bind_smb(mem_ctx
, tree
, "\\srvsvc", &dcerpc_table_srvsvc
,
2222 if (!NT_STATUS_IS_OK(status
)) {
2223 d_printf("could not bind to srvsvc pipe\n");
2224 talloc_free(mem_ctx
);
2228 r
.in
.server_unc
= talloc_asprintf(
2229 mem_ctx
, "\\\\%s", dcerpc_server_name(p
));
2232 r
.in
.ctr
.ctr1
= &c1_in
;
2233 r
.in
.max_buffer
= (uint32_t)-1;
2234 r
.in
.resume_handle
= NULL
;
2236 status
= dcerpc_srvsvc_NetShareEnum(p
, mem_ctx
, &r
);
2237 if (!NT_STATUS_IS_OK(status
)) {
2238 d_printf("NetShareEnum level %u failed - %s\n",
2239 r
.in
.level
, nt_errstr(status
));
2240 talloc_free(mem_ctx
);
2246 c1
= r
.out
.ctr
.ctr1
;
2247 for (i
=0; i
<c1
->count
; i
++) {
2248 if (c1
->array
[i
].type
!= STYPE_PRINTQ
) {
2251 if (!add_string_to_array(ctx
, c1
->array
[i
].name
,
2252 printers
, num_printers
)) {
2254 return NT_STATUS_NO_MEMORY
;
2258 talloc_free(mem_ctx
);
2259 return NT_STATUS_OK
;
2262 static BOOL
enumprinters(TALLOC_CTX
*mem_ctx
, struct dcerpc_pipe
*pipe
,
2263 const char *servername
, int level
, int *num_printers
)
2265 struct spoolss_EnumPrinters r
;
2269 r
.in
.flags
= PRINTER_ENUM_LOCAL
;
2270 r
.in
.server
= talloc_asprintf(mem_ctx
, "\\\\%s", servername
);
2275 status
= dcerpc_spoolss_EnumPrinters(pipe
, mem_ctx
, &r
);
2276 if (!NT_STATUS_IS_OK(status
)) {
2277 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s\n",
2278 __location__
, nt_errstr(status
));
2282 if (!W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
2283 d_printf("(%s) EnumPrinters unexpected return code %s, should "
2284 "be WERR_INSUFFICIENT_BUFFER\n", __location__
,
2285 win_errstr(r
.out
.result
));
2289 blob
= data_blob_talloc(mem_ctx
, NULL
, r
.out
.needed
);
2290 if (blob
.data
== NULL
) {
2291 d_printf("(%s) data_blob_talloc failed\n", __location__
);
2295 r
.in
.buffer
= &blob
;
2296 r
.in
.offered
= r
.out
.needed
;
2298 status
= dcerpc_spoolss_EnumPrinters(pipe
, mem_ctx
, &r
);
2299 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(r
.out
.result
)) {
2300 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s, "
2301 "%s\n", __location__
, nt_errstr(status
),
2302 win_errstr(r
.out
.result
));
2306 *num_printers
= r
.out
.count
;
2311 static NTSTATUS
getprinterinfo(TALLOC_CTX
*ctx
, struct dcerpc_pipe
*pipe
,
2312 struct policy_handle
*handle
, int level
,
2313 union spoolss_PrinterInfo
**res
)
2315 TALLOC_CTX
*mem_ctx
;
2316 struct spoolss_GetPrinter r
;
2320 mem_ctx
= talloc_new(ctx
);
2321 if (mem_ctx
== NULL
) {
2322 return NT_STATUS_NO_MEMORY
;
2325 r
.in
.handle
= handle
;
2330 status
= dcerpc_spoolss_GetPrinter(pipe
, mem_ctx
, &r
);
2331 if (!NT_STATUS_IS_OK(status
)) {
2332 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s\n",
2333 __location__
, nt_errstr(status
));
2334 talloc_free(mem_ctx
);
2338 if (!W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
2339 printf("GetPrinter unexpected return code %s, should "
2340 "be WERR_INSUFFICIENT_BUFFER\n",
2341 win_errstr(r
.out
.result
));
2342 talloc_free(mem_ctx
);
2343 return NT_STATUS_UNSUCCESSFUL
;
2346 r
.in
.handle
= handle
;
2348 blob
= data_blob_talloc(mem_ctx
, NULL
, r
.out
.needed
);
2349 if (blob
.data
== NULL
) {
2350 talloc_free(mem_ctx
);
2351 return NT_STATUS_NO_MEMORY
;
2353 memset(blob
.data
, 0, blob
.length
);
2354 r
.in
.buffer
= &blob
;
2355 r
.in
.offered
= r
.out
.needed
;
2357 status
= dcerpc_spoolss_GetPrinter(pipe
, mem_ctx
, &r
);
2358 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(r
.out
.result
)) {
2359 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s, "
2360 "%s\n", __location__
, nt_errstr(status
),
2361 win_errstr(r
.out
.result
));
2362 talloc_free(mem_ctx
);
2363 return NT_STATUS_IS_OK(status
) ?
2364 NT_STATUS_UNSUCCESSFUL
: status
;
2368 *res
= talloc_steal(ctx
, r
.out
.info
);
2371 talloc_free(mem_ctx
);
2372 return NT_STATUS_OK
;
2375 BOOL
torture_samba3_rpc_spoolss(struct torture_context
*torture
)
2377 TALLOC_CTX
*mem_ctx
;
2379 struct smbcli_state
*cli
;
2380 struct dcerpc_pipe
*p
;
2382 struct policy_handle server_handle
, printer_handle
;
2383 const char **printers
;
2385 struct spoolss_UserLevel1 userlevel1
;
2388 if (!(mem_ctx
= talloc_new(torture
))) {
2392 if (!(torture_open_connection_share(
2393 mem_ctx
, &cli
, lp_parm_string(-1, "torture", "host"),
2395 d_printf("IPC$ connection failed\n");
2396 talloc_free(mem_ctx
);
2400 status
= get_servername(mem_ctx
, cli
->tree
, &servername
);
2401 if (!NT_STATUS_IS_OK(status
)) {
2402 d_fprintf(stderr
, "(%s) get_servername returned %s\n",
2403 __location__
, nt_errstr(status
));
2404 talloc_free(mem_ctx
);
2408 if (!NT_STATUS_IS_OK(find_printers(mem_ctx
, cli
->tree
,
2409 &printers
, &num_printers
))) {
2410 talloc_free(mem_ctx
);
2414 if (num_printers
== 0) {
2415 d_printf("Did not find printers\n");
2416 talloc_free(mem_ctx
);
2420 status
= pipe_bind_smb(mem_ctx
, cli
->tree
, "\\spoolss",
2421 &dcerpc_table_spoolss
, &p
);
2422 if (!NT_STATUS_IS_OK(status
)) {
2423 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__
,
2425 talloc_free(mem_ctx
);
2429 ZERO_STRUCT(userlevel1
);
2430 userlevel1
.client
= talloc_asprintf(
2431 mem_ctx
, "\\\\%s", lp_netbios_name());
2432 userlevel1
.user
= cli_credentials_get_username(cmdline_credentials
);
2433 userlevel1
.build
= 2600;
2434 userlevel1
.major
= 3;
2435 userlevel1
.minor
= 0;
2436 userlevel1
.processor
= 0;
2439 struct spoolss_OpenPrinterEx r
;
2442 r
.in
.printername
= talloc_asprintf(mem_ctx
, "\\\\%s",
2444 r
.in
.datatype
= NULL
;
2445 r
.in
.access_mask
= 0;
2447 r
.in
.userlevel
.level1
= &userlevel1
;
2448 r
.out
.handle
= &server_handle
;
2450 status
= dcerpc_spoolss_OpenPrinterEx(p
, mem_ctx
, &r
);
2451 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(r
.out
.result
)) {
2452 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
2453 "%s, %s\n", __location__
, nt_errstr(status
),
2454 win_errstr(r
.out
.result
));
2455 talloc_free(mem_ctx
);
2461 struct spoolss_ClosePrinter r
;
2463 r
.in
.handle
= &server_handle
;
2464 r
.out
.handle
= &server_handle
;
2466 status
= dcerpc_spoolss_ClosePrinter(p
, mem_ctx
, &r
);
2467 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(r
.out
.result
)) {
2468 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
2469 "%s, %s\n", __location__
, nt_errstr(status
),
2470 win_errstr(r
.out
.result
));
2471 talloc_free(mem_ctx
);
2477 struct spoolss_OpenPrinterEx r
;
2480 r
.in
.printername
= talloc_asprintf(
2481 mem_ctx
, "\\\\%s\\%s", servername
, printers
[0]);
2482 r
.in
.datatype
= NULL
;
2483 r
.in
.access_mask
= 0;
2485 r
.in
.userlevel
.level1
= &userlevel1
;
2486 r
.out
.handle
= &printer_handle
;
2488 status
= dcerpc_spoolss_OpenPrinterEx(p
, mem_ctx
, &r
);
2489 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(r
.out
.result
)) {
2490 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: "
2491 "%s, %s\n", __location__
, nt_errstr(status
),
2492 win_errstr(r
.out
.result
));
2493 talloc_free(mem_ctx
);
2501 for (i
=0; i
<8; i
++) {
2502 status
= getprinterinfo(mem_ctx
, p
, &printer_handle
,
2504 if (!NT_STATUS_IS_OK(status
)) {
2505 d_printf("(%s) getprinterinfo %d failed: %s\n",
2506 __location__
, i
, nt_errstr(status
));
2513 struct spoolss_ClosePrinter r
;
2515 r
.in
.handle
= &printer_handle
;
2516 r
.out
.handle
= &printer_handle
;
2518 status
= dcerpc_spoolss_ClosePrinter(p
, mem_ctx
, &r
);
2519 if (!NT_STATUS_IS_OK(status
)) {
2520 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: "
2521 "%s\n", __location__
, nt_errstr(status
));
2522 talloc_free(mem_ctx
);
2529 if (!enumprinters(mem_ctx
, p
, servername
, 1,
2531 d_printf("(%s) enumprinters failed\n", __location__
);
2532 talloc_free(mem_ctx
);
2535 if (num_printers
!= num_enumerated
) {
2536 d_printf("(%s) netshareenum gave %d printers, "
2537 "enumprinters lvl 1 gave %d\n", __location__
,
2538 num_printers
, num_enumerated
);
2539 talloc_free(mem_ctx
);
2546 if (!enumprinters(mem_ctx
, p
, servername
, 2,
2548 d_printf("(%s) enumprinters failed\n", __location__
);
2549 talloc_free(mem_ctx
);
2552 if (num_printers
!= num_enumerated
) {
2553 d_printf("(%s) netshareenum gave %d printers, "
2554 "enumprinters lvl 2 gave %d\n", __location__
,
2555 num_printers
, num_enumerated
);
2556 talloc_free(mem_ctx
);
2561 talloc_free(mem_ctx
);
2566 BOOL
torture_samba3_rpc_wkssvc(struct torture_context
*torture
)
2568 TALLOC_CTX
*mem_ctx
;
2569 struct smbcli_state
*cli
;
2570 struct dcerpc_pipe
*p
;
2574 if (!(mem_ctx
= talloc_new(torture
))) {
2578 if (!(torture_open_connection_share(
2579 mem_ctx
, &cli
, lp_parm_string(-1, "torture", "host"),
2581 d_printf("IPC$ connection failed\n");
2582 talloc_free(mem_ctx
);
2586 status
= get_servername(mem_ctx
, cli
->tree
, &servername
);
2587 if (!NT_STATUS_IS_OK(status
)) {
2588 d_fprintf(stderr
, "(%s) get_servername returned %s\n",
2589 __location__
, nt_errstr(status
));
2590 talloc_free(mem_ctx
);
2594 status
= pipe_bind_smb(mem_ctx
, cli
->tree
, "\\wkssvc",
2595 &dcerpc_table_wkssvc
, &p
);
2596 if (!NT_STATUS_IS_OK(status
)) {
2597 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__
,
2599 talloc_free(mem_ctx
);
2604 struct wkssvc_NetWkstaInfo100 wks100
;
2605 union wkssvc_NetWkstaInfo info
;
2606 struct wkssvc_NetWkstaGetInfo r
;
2608 r
.in
.server_name
= "\\foo";
2610 info
.info100
= &wks100
;
2613 status
= dcerpc_wkssvc_NetWkstaGetInfo(p
, mem_ctx
, &r
);
2614 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(r
.out
.result
)) {
2615 d_printf("(%s) dcerpc_wkssvc_NetWksGetInfo failed: "
2616 "%s, %s\n", __location__
, nt_errstr(status
),
2617 win_errstr(r
.out
.result
));
2618 talloc_free(mem_ctx
);
2622 if (strcmp(servername
,
2623 r
.out
.info
->info100
->server_name
) != 0) {
2624 d_printf("(%s) servername inconsistency: RAP=%s, "
2625 "dcerpc_wkssvc_NetWksGetInfo=%s",
2626 __location__
, servername
,
2627 r
.out
.info
->info100
->server_name
);
2628 talloc_free(mem_ctx
);
2633 talloc_free(mem_ctx
);