2 * Unix SMB/CIFS implementation.
3 * test suite for samr rpc operations
5 * Copyright (c) 2011 Andreas Schneider
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "param/param.h"
23 #include "torture/torture.h"
24 #include "librpc/gen_ndr/ndr_samr_c.h"
25 #include "librpc/rpc/dcerpc_proto.h"
26 #include "libcli/security/security.h"
27 #include "torture/rpc/torture_rpc.h"
29 #define TEST_ACCOUNT_NAME "guru"
35 uint32_t *builtin_memberships
;
36 uint32_t num_builtin_memberships
;
40 struct torture_access_context
{
41 struct dcerpc_pipe
*pipe
;
42 struct torture_user user
;
43 struct test_join
*join
;
46 static void init_lsa_String(struct lsa_String
*name
, const char *s
)
51 static bool test_samr_queryUserInfo(struct torture_context
*tctx
,
52 struct dcerpc_binding_handle
*b
,
53 struct policy_handle
*user_handle
)
55 struct samr_QueryUserInfo r
;
56 union samr_UserInfo
*info
;
59 r
.in
.level
= UserGeneralInformation
;
60 r
.in
.user_handle
= user_handle
;
63 status
= dcerpc_samr_QueryUserInfo_r(b
,
66 torture_assert_ntstatus_ok(tctx
, status
, "queryUserInfo failed");
67 if (!NT_STATUS_EQUAL(r
.out
.result
, NT_STATUS_OK
)) {
68 torture_comment(tctx
, "queryUserInfo failed");
75 static bool test_LookupName(struct dcerpc_binding_handle
*b
,
76 struct torture_context
*tctx
,
77 struct policy_handle
*domain_handle
,
82 struct samr_LookupNames n
;
83 struct lsa_String sname
[1];
84 struct samr_Ids rids
, types
;
86 init_lsa_String(&sname
[0], name
);
88 n
.in
.domain_handle
= domain_handle
;
94 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
95 if (!NT_STATUS_IS_OK(status
)) {
98 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
102 *rid
= n
.out
.rids
->ids
[0];
106 static bool test_samr_CreateUser(struct torture_context
*tctx
,
107 struct dcerpc_binding_handle
*b
,
108 struct policy_handle
*domain_handle
,
110 struct policy_handle
*user_handle
)
112 struct lsa_String username
;
113 struct samr_CreateUser r
;
117 init_lsa_String(&username
, name
);
119 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
120 r
.in
.domain_handle
= domain_handle
;
121 r
.in
.account_name
= &username
;
122 r
.out
.user_handle
= user_handle
;
125 status
= dcerpc_samr_CreateUser_r(b
, tctx
, &r
);
126 torture_assert_ntstatus_ok(tctx
, status
, "CreateUser failed");
127 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
128 torture_comment(tctx
, "CreateUser failed");
135 static bool test_samr_OpenUser(struct torture_context
*tctx
,
136 struct dcerpc_binding_handle
*b
,
137 struct policy_handle
*domain_handle
,
139 struct policy_handle
*user_handle
,
142 struct samr_OpenUser r
;
147 ok
= test_LookupName(b
, tctx
, domain_handle
, name
, &rid
);
148 if (!ok
&& expected
) {
149 torture_comment(tctx
, " - lookup name for %s failed\n", name
);
155 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
156 r
.in
.domain_handle
= domain_handle
;
158 r
.out
.user_handle
= user_handle
;
160 status
= dcerpc_samr_OpenUser_r(b
, tctx
, &r
);
161 torture_assert_ntstatus_ok(tctx
, status
, "CreateUser failed");
162 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
163 torture_comment(tctx
, "CreateUser failed");
170 static bool test_samr_openDomain(struct torture_context
*tctx
,
171 struct dcerpc_binding_handle
*b
,
172 struct policy_handle
*connect_handle
,
174 struct policy_handle
*domain_handle
)
176 struct samr_LookupDomain r
;
177 struct samr_OpenDomain r2
;
182 r
.in
.connect_handle
= connect_handle
;
183 init_lsa_String(&n
, domain
);
184 r
.in
.domain_name
= &n
;
187 status
= dcerpc_samr_LookupDomain_r(b
, tctx
, &r
);
188 torture_assert_ntstatus_ok(tctx
, status
, "LookupDomain failed");
189 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
190 torture_comment(tctx
, "LookupDomain failed - %s\n", nt_errstr(r
.out
.result
));
194 r2
.in
.connect_handle
= connect_handle
;
195 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
197 r2
.out
.domain_handle
= domain_handle
;
199 status
= dcerpc_samr_OpenDomain_r(b
, tctx
, &r2
);
200 torture_assert_ntstatus_ok(tctx
, status
, "OpenDomain failed");
201 if (!NT_STATUS_IS_OK(r2
.out
.result
)) {
202 torture_comment(tctx
, "OpenDomain failed - %s\n", nt_errstr(r
.out
.result
));
209 static bool test_samr_Connect(struct torture_context
*tctx
,
210 struct dcerpc_binding_handle
*b
,
211 struct policy_handle
*connect_handle
)
213 struct samr_Connect r
;
216 r
.in
.system_name
= 0;
217 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
218 r
.out
.connect_handle
= connect_handle
;
220 status
= dcerpc_samr_Connect_r(b
, tctx
, &r
);
221 torture_assert_ntstatus_ok(tctx
, status
, "SAMR connect failed");
222 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
223 torture_comment(tctx
, "Connect failed - %s\n", nt_errstr(r
.out
.result
));
230 static bool test_samr_create_user(struct torture_context
*tctx
,
231 struct torture_access_context
*t
,
234 struct dcerpc_binding_handle
*b
= t
->pipe
->binding_handle
;
235 struct policy_handle connect_handle
;
236 struct policy_handle domain_handle
;
237 struct policy_handle user_handle
;
240 torture_comment(tctx
, "Connecting to SAMR\n");
241 ZERO_STRUCT(connect_handle
);
242 ok
= test_samr_Connect(tctx
, b
, &connect_handle
);
243 torture_assert(tctx
, ok
, "Unable to connect to domain");
245 torture_comment(tctx
, "Opening domain %s\n", t
->user
.domain
);
246 ZERO_STRUCT(domain_handle
);
247 ok
= test_samr_openDomain(tctx
,
252 torture_assert(tctx
, ok
, "Unable to open to domain");
254 torture_comment(tctx
, "Creating account %s\n", name
);
255 ZERO_STRUCT(user_handle
);
256 ok
= test_samr_CreateUser(tctx
,
262 test_samr_handle_Close(b
, tctx
, &domain_handle
);
263 test_samr_handle_Close(b
, tctx
, &connect_handle
);
268 static bool test_samr_userinfo_getinfo(struct torture_context
*tctx
,
269 struct dcerpc_pipe
*p
,
273 struct dcerpc_pipe
*p2
= NULL
;
274 struct dcerpc_binding_handle
*b
;
275 struct policy_handle connect_handle
;
276 struct policy_handle domain_handle
;
277 struct policy_handle user_handle
;
282 status
= torture_rpc_connection(tctx
, &p2
, &ndr_table_samr
);
283 torture_assert_ntstatus_ok(tctx
, status
,
284 "Creating secondary connection failed");
285 b
= p2
->binding_handle
;
287 torture_comment(tctx
, " - 2nd connect\n");
289 ZERO_STRUCT(connect_handle
);
290 ok
= test_samr_Connect(tctx
, b
, &connect_handle
);
291 torture_assert(tctx
, ok
, "Unable to connect to domain");
293 torture_comment(tctx
, " - 2nd open domain\n");
295 ZERO_STRUCT(domain_handle
);
296 ok
= test_samr_openDomain(tctx
,
299 torture_setting_string(tctx
, "workgroup",
300 lpcfg_workgroup(tctx
->lp_ctx
)),
302 torture_assert(tctx
, ok
, "Unable to open to domain");
305 name
= talloc_asprintf(tctx
,
310 torture_comment(tctx
, " - 2nd open user\n");
311 ZERO_STRUCT(user_handle
);
312 ok
= test_samr_OpenUser(tctx
,
318 torture_assert(tctx
, ok
, "Unable to open user");
321 torture_comment(tctx
, " - 2nd query user\n");
322 ok
= test_samr_queryUserInfo(tctx
, b
, &user_handle
);
323 torture_assert(tctx
, ok
, "Unable to query user");
325 test_samr_handle_Close(b
, tctx
, &user_handle
);
328 test_samr_handle_Close(b
, tctx
, &domain_handle
);
329 test_samr_handle_Close(b
, tctx
, &connect_handle
);
337 static bool torture_rpc_samr_caching(struct torture_context
*tctx
,
338 struct dcerpc_pipe
*p
)
340 struct test_join
*join
;
341 const char *password
= NULL
;
347 torture_comment(tctx
, ">>> Testing User Info Caching\n");
350 name
= talloc_asprintf(tctx
,
355 torture_comment(tctx
, "- Creating user %s\n", name
);
357 join
= torture_create_testuser(tctx
,
359 torture_setting_string(tctx
, "workgroup",
360 lpcfg_workgroup(tctx
->lp_ctx
)),
367 torture_comment(tctx
, "- Query user information\n");
368 for (i
= 0; i
< NUM_RUNS
; i
++) {
369 ok
= test_samr_userinfo_getinfo(tctx
, p
, false);
370 torture_assert(tctx
, ok
, "test_samr_userinfo_getinfo failed");
373 torture_comment(tctx
, "- Delete user\n");
374 status
= torture_delete_testuser(tctx
,
377 if (!NT_STATUS_IS_OK(status
)) {
378 torture_comment(tctx
, "DeleteUser failed - %s\n",
383 torture_comment(tctx
, "- Try to query user information again (should fail)\n");
384 for (i
= 0; i
< NUM_RUNS
; i
++) {
385 ok
= test_samr_userinfo_getinfo(tctx
,
388 torture_assert(tctx
, ok
, "test_samr_userinfo_getinfo failed");
395 static bool torture_rpc_samr_access_setup_membership(struct torture_context
*tctx
,
396 struct dcerpc_pipe
*p
,
397 uint32_t num_members
,
399 struct dom_sid
*user_sid
)
401 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
402 struct policy_handle connect_handle
, domain_handle
;
405 torture_comment(tctx
,
406 "Setting up BUILTIN membership for %s\n",
407 dom_sid_string(tctx
, user_sid
));
409 for (i
=0; i
< num_members
; i
++) {
410 torture_comment(tctx
, "adding user to S-1-5-32-%d\n", members
[i
]);
415 struct samr_Connect2 r
;
416 r
.in
.system_name
= "";
417 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
418 ZERO_STRUCT(connect_handle
);
419 r
.out
.connect_handle
= &connect_handle
;
421 torture_assert_ntstatus_ok(tctx
,
422 dcerpc_samr_Connect2_r(b
, tctx
, &r
),
423 "samr_Connect2 failed");
424 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
425 "samr_Connect2 failed");
430 struct samr_OpenDomain r
;
431 r
.in
.connect_handle
= &connect_handle
;
432 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
433 r
.in
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32");
434 ZERO_STRUCT(domain_handle
);
435 r
.out
.domain_handle
= &domain_handle
;
437 torture_assert_ntstatus_ok(tctx
,
438 dcerpc_samr_OpenDomain_r(b
, tctx
, &r
),
439 "samr_OpenDomain failed");
440 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
441 "samr_OpenDomain failed");
444 for (i
= 0; i
< num_members
; i
++) {
446 struct policy_handle alias_handle
;
450 struct samr_OpenAlias r
;
451 r
.in
.domain_handle
= &domain_handle
;
452 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
453 r
.in
.rid
= members
[i
];
454 ZERO_STRUCT(alias_handle
);
455 r
.out
.alias_handle
= &alias_handle
;
457 torture_assert_ntstatus_ok(tctx
,
458 dcerpc_samr_OpenAlias_r(b
, tctx
, &r
),
459 "samr_OpenAlias failed");
460 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
461 "samr_OpenAlias failed");
464 /* add alias member */
466 struct samr_AddAliasMember r
;
467 ZERO_STRUCT(alias_handle
);
468 r
.in
.alias_handle
= &alias_handle
;
471 torture_assert_ntstatus_ok(tctx
,
472 dcerpc_samr_AddAliasMember_r(b
, tctx
, &r
),
473 "samr_AddAliasMember failed");
474 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
475 "samr_AddAliasMember failed");
478 test_samr_handle_Close(b
, tctx
, &alias_handle
);
481 test_samr_handle_Close(b
, tctx
, &domain_handle
);
482 test_samr_handle_Close(b
, tctx
, &connect_handle
);
487 static bool torture_rpc_samr_access_setup(struct torture_context
*tctx
,
488 struct dcerpc_pipe
*p
,
489 struct torture_access_context
*t
)
491 const char *binding
= torture_setting_string(tctx
, "binding", NULL
);
492 struct cli_credentials
*test_credentials
;
493 struct test_join
*join
;
494 struct dom_sid
*test_sid
;
495 struct dcerpc_pipe
*samr_pipe
;
497 t
->user
.domain
= torture_setting_string(tctx
, "workgroup",
498 lpcfg_workgroup(tctx
->lp_ctx
)),
500 join
= torture_create_testuser(tctx
,
510 test_credentials
= cli_credentials_init(tctx
);
512 cli_credentials_set_workstation(test_credentials
,
515 cli_credentials_set_domain(test_credentials
,
516 torture_setting_string(tctx
, "workgroup",
517 lpcfg_workgroup(tctx
->lp_ctx
)),
519 cli_credentials_set_username(test_credentials
,
522 cli_credentials_set_password(test_credentials
,
525 test_sid
= discard_const_p(struct dom_sid
,
526 torture_join_user_sid(t
->join
));
528 if (t
->user
.num_builtin_memberships
) {
530 torture_rpc_samr_access_setup_membership(tctx
,
532 t
->user
.num_builtin_memberships
,
533 t
->user
.builtin_memberships
,
535 "failed to setup membership");
538 torture_assert_ntstatus_ok(tctx
,
539 dcerpc_pipe_connect(tctx
,
546 "Error connecting to server");
553 static bool torture_rpc_samr_access(struct torture_context
*tctx
,
554 struct dcerpc_pipe
*p
)
556 struct torture_access_context
*t
;
557 const char *testuser
;
560 torture_comment(tctx
, "Testing non-privileged user access\n");
562 t
= talloc_zero(tctx
, struct torture_access_context
);
567 t
->user
.username
= talloc_asprintf(t
, "%s%04d", TEST_ACCOUNT_NAME
, 100);
569 torture_comment(tctx
, "*** Setting up non-privleged user\n"
572 ok
= torture_rpc_samr_access_setup(tctx
, p
, t
);
577 testuser
= talloc_asprintf(t
, "%s%04d", TEST_ACCOUNT_NAME
, 200);
579 torture_comment(tctx
, "*** Try to create user (%s) as non-privileged "
580 "user - should fail\n"
583 ok
= test_samr_create_user(tctx
, t
, testuser
);
585 torture_comment(tctx
, "*** Creating user (%s) failed, which is "
586 "correct!\n", testuser
);
590 torture_comment(tctx
, "*** Creating user (%s) was successful, but "
591 "should fail!\n", testuser
);
596 struct torture_suite
*torture_rpc_samr_priv(TALLOC_CTX
*mem_ctx
)
598 struct torture_suite
*suite
=
599 torture_suite_create(mem_ctx
, "samr.priv");
600 struct torture_rpc_tcase
*tcase
;
602 tcase
= torture_suite_add_rpc_iface_tcase(suite
,
606 torture_rpc_tcase_add_test(tcase
,
608 torture_rpc_samr_caching
);
610 torture_rpc_tcase_add_test(tcase
,
612 torture_rpc_samr_access
);