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 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "queryUserInfo failed");
72 static bool test_LookupName(struct dcerpc_binding_handle
*b
,
73 struct torture_context
*tctx
,
74 struct policy_handle
*domain_handle
,
79 struct samr_LookupNames n
;
80 struct lsa_String sname
[1];
81 struct samr_Ids rids
, types
;
83 init_lsa_String(&sname
[0], name
);
85 n
.in
.domain_handle
= domain_handle
;
91 status
= dcerpc_samr_LookupNames_r(b
, tctx
, &n
);
92 if (!NT_STATUS_IS_OK(status
)) {
95 if (!NT_STATUS_IS_OK(n
.out
.result
)) {
99 *rid
= n
.out
.rids
->ids
[0];
103 static bool test_samr_CreateUser(struct torture_context
*tctx
,
104 struct dcerpc_binding_handle
*b
,
105 struct policy_handle
*domain_handle
,
107 struct policy_handle
*user_handle
)
109 struct lsa_String username
;
110 struct samr_CreateUser r
;
114 init_lsa_String(&username
, name
);
116 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
117 r
.in
.domain_handle
= domain_handle
;
118 r
.in
.account_name
= &username
;
119 r
.out
.user_handle
= user_handle
;
122 status
= dcerpc_samr_CreateUser_r(b
, tctx
, &r
);
123 torture_assert_ntstatus_ok(tctx
, status
, "CreateUser failed");
125 return NT_STATUS_IS_OK(r
.out
.result
);
128 static bool test_samr_OpenUser(struct torture_context
*tctx
,
129 struct dcerpc_binding_handle
*b
,
130 struct policy_handle
*domain_handle
,
132 struct policy_handle
*user_handle
,
135 struct samr_OpenUser r
;
140 ok
= test_LookupName(b
, tctx
, domain_handle
, name
, &rid
);
141 if (!ok
&& expected
) {
142 torture_comment(tctx
, " - lookup name for %s failed\n", name
);
148 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
149 r
.in
.domain_handle
= domain_handle
;
151 r
.out
.user_handle
= user_handle
;
153 status
= dcerpc_samr_OpenUser_r(b
, tctx
, &r
);
154 torture_assert_ntstatus_ok(tctx
, status
, "OpenUser failed");
155 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "OpenUser failed");
160 static bool test_samr_openDomain(struct torture_context
*tctx
,
161 struct dcerpc_binding_handle
*b
,
162 struct policy_handle
*connect_handle
,
164 struct policy_handle
*domain_handle
)
166 struct samr_LookupDomain r
;
167 struct samr_OpenDomain r2
;
172 r
.in
.connect_handle
= connect_handle
;
173 init_lsa_String(&n
, domain
);
174 r
.in
.domain_name
= &n
;
177 status
= dcerpc_samr_LookupDomain_r(b
, tctx
, &r
);
178 torture_assert_ntstatus_ok(tctx
, status
, "LookupDomain failed");
179 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "LookupDomain failed");
181 r2
.in
.connect_handle
= connect_handle
;
182 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
184 r2
.out
.domain_handle
= domain_handle
;
186 status
= dcerpc_samr_OpenDomain_r(b
, tctx
, &r2
);
187 torture_assert_ntstatus_ok(tctx
, status
, "OpenDomain failed");
188 torture_assert_ntstatus_ok(tctx
, r2
.out
.result
, "OpenDomain failed");
193 static bool test_samr_Connect(struct torture_context
*tctx
,
194 struct dcerpc_binding_handle
*b
,
195 struct policy_handle
*connect_handle
)
197 struct samr_Connect r
;
200 r
.in
.system_name
= 0;
201 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
202 r
.out
.connect_handle
= connect_handle
;
204 status
= dcerpc_samr_Connect_r(b
, tctx
, &r
);
205 torture_assert_ntstatus_ok(tctx
, status
, "SAMR connect failed");
206 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "SAMR connect failed");
211 static bool test_samr_create_user(struct torture_context
*tctx
,
212 struct torture_access_context
*t
,
215 struct dcerpc_binding_handle
*b
= t
->pipe
->binding_handle
;
216 struct policy_handle connect_handle
;
217 struct policy_handle domain_handle
;
218 struct policy_handle user_handle
;
221 torture_comment(tctx
, "Connecting to SAMR\n");
222 ZERO_STRUCT(connect_handle
);
223 ok
= test_samr_Connect(tctx
, b
, &connect_handle
);
224 torture_assert(tctx
, ok
, "Unable to connect to domain");
226 torture_comment(tctx
, "Opening domain %s\n", t
->user
.domain
);
227 ZERO_STRUCT(domain_handle
);
228 ok
= test_samr_openDomain(tctx
,
233 torture_assert(tctx
, ok
, "Unable to open to domain");
235 torture_comment(tctx
, "Creating account %s\n", name
);
236 ZERO_STRUCT(user_handle
);
237 ok
= test_samr_CreateUser(tctx
,
243 /* We don't check ok with torture macros here because the
244 * caller might be looking for failure */
245 test_samr_handle_Close(b
, tctx
, &domain_handle
);
246 test_samr_handle_Close(b
, tctx
, &connect_handle
);
251 static bool test_samr_userinfo_getinfo(struct torture_context
*tctx
,
252 struct dcerpc_pipe
*p
,
256 struct dcerpc_pipe
*p2
= NULL
;
257 struct dcerpc_binding_handle
*b
;
258 struct policy_handle connect_handle
;
259 struct policy_handle domain_handle
;
260 struct policy_handle user_handle
;
265 status
= torture_rpc_connection(tctx
, &p2
, &ndr_table_samr
);
266 torture_assert_ntstatus_ok(tctx
, status
,
267 "Creating secondary connection failed");
268 b
= p2
->binding_handle
;
270 torture_comment(tctx
, " - 2nd connect\n");
272 ZERO_STRUCT(connect_handle
);
273 ok
= test_samr_Connect(tctx
, b
, &connect_handle
);
274 torture_assert(tctx
, ok
, "Unable to connect to domain");
276 torture_comment(tctx
, " - 2nd open domain\n");
278 ZERO_STRUCT(domain_handle
);
279 ok
= test_samr_openDomain(tctx
,
282 torture_setting_string(tctx
, "workgroup",
283 lpcfg_workgroup(tctx
->lp_ctx
)),
285 torture_assert(tctx
, ok
, "Unable to open to domain");
288 name
= talloc_asprintf(tctx
,
293 torture_comment(tctx
, " - 2nd open user\n");
294 ZERO_STRUCT(user_handle
);
295 ok
= test_samr_OpenUser(tctx
,
301 torture_assert(tctx
, ok
, "Unable to open user");
304 torture_comment(tctx
, " - 2nd query user\n");
305 ok
= test_samr_queryUserInfo(tctx
, b
, &user_handle
);
306 torture_assert(tctx
, ok
, "Unable to query user");
308 test_samr_handle_Close(b
, tctx
, &user_handle
);
311 test_samr_handle_Close(b
, tctx
, &domain_handle
);
312 test_samr_handle_Close(b
, tctx
, &connect_handle
);
320 static bool torture_rpc_samr_caching(struct torture_context
*tctx
,
321 struct dcerpc_pipe
*p
)
323 struct test_join
*join
;
324 const char *password
= NULL
;
330 torture_comment(tctx
, ">>> Testing User Info Caching\n");
333 name
= talloc_asprintf(tctx
,
338 torture_comment(tctx
, "- Creating user %s\n", name
);
340 join
= torture_create_testuser(tctx
,
342 torture_setting_string(tctx
, "workgroup",
343 lpcfg_workgroup(tctx
->lp_ctx
)),
346 torture_assert(tctx
, join
, "failed to join domain");
348 torture_comment(tctx
, "- Query user information\n");
349 for (i
= 0; i
< NUM_RUNS
; i
++) {
350 ok
= test_samr_userinfo_getinfo(tctx
, p
, false);
351 torture_assert(tctx
, ok
, "test_samr_userinfo_getinfo failed");
354 torture_comment(tctx
, "- Delete user\n");
355 status
= torture_delete_testuser(tctx
,
358 torture_assert_ntstatus_ok(tctx
, status
, "DeleteUser failed");
360 torture_comment(tctx
, "- Try to query user information again (should fail)\n");
361 for (i
= 0; i
< NUM_RUNS
; i
++) {
362 ok
= test_samr_userinfo_getinfo(tctx
,
365 torture_assert(tctx
, ok
, "test_samr_userinfo_getinfo failed");
372 static bool torture_rpc_samr_access_setup_membership(struct torture_context
*tctx
,
373 struct dcerpc_pipe
*p
,
374 uint32_t num_members
,
376 struct dom_sid
*user_sid
)
378 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
379 struct policy_handle connect_handle
, domain_handle
;
382 torture_comment(tctx
,
383 "Setting up BUILTIN membership for %s\n",
384 dom_sid_string(tctx
, user_sid
));
386 for (i
=0; i
< num_members
; i
++) {
387 torture_comment(tctx
, "adding user to S-1-5-32-%d\n", members
[i
]);
392 struct samr_Connect2 r
;
393 r
.in
.system_name
= "";
394 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
395 ZERO_STRUCT(connect_handle
);
396 r
.out
.connect_handle
= &connect_handle
;
398 torture_assert_ntstatus_ok(tctx
,
399 dcerpc_samr_Connect2_r(b
, tctx
, &r
),
400 "samr_Connect2 failed");
401 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
402 "samr_Connect2 failed");
407 struct samr_OpenDomain r
;
408 r
.in
.connect_handle
= &connect_handle
;
409 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
410 r
.in
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32");
411 ZERO_STRUCT(domain_handle
);
412 r
.out
.domain_handle
= &domain_handle
;
414 torture_assert_ntstatus_ok(tctx
,
415 dcerpc_samr_OpenDomain_r(b
, tctx
, &r
),
416 "samr_OpenDomain failed");
417 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
418 "samr_OpenDomain failed");
421 for (i
= 0; i
< num_members
; i
++) {
423 struct policy_handle alias_handle
;
427 struct samr_OpenAlias r
;
428 r
.in
.domain_handle
= &domain_handle
;
429 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
430 r
.in
.rid
= members
[i
];
431 ZERO_STRUCT(alias_handle
);
432 r
.out
.alias_handle
= &alias_handle
;
434 torture_assert_ntstatus_ok(tctx
,
435 dcerpc_samr_OpenAlias_r(b
, tctx
, &r
),
436 "samr_OpenAlias failed");
437 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
438 "samr_OpenAlias failed");
441 /* add alias member */
443 struct samr_AddAliasMember r
;
444 ZERO_STRUCT(alias_handle
);
445 r
.in
.alias_handle
= &alias_handle
;
448 torture_assert_ntstatus_ok(tctx
,
449 dcerpc_samr_AddAliasMember_r(b
, tctx
, &r
),
450 "samr_AddAliasMember failed");
451 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
452 "samr_AddAliasMember failed");
455 test_samr_handle_Close(b
, tctx
, &alias_handle
);
458 test_samr_handle_Close(b
, tctx
, &domain_handle
);
459 test_samr_handle_Close(b
, tctx
, &connect_handle
);
464 static bool torture_rpc_samr_access_setup(struct torture_context
*tctx
,
465 struct dcerpc_pipe
*p
,
466 struct torture_access_context
*t
)
468 const char *binding
= torture_setting_string(tctx
, "binding", NULL
);
469 struct cli_credentials
*test_credentials
;
470 struct test_join
*join
;
471 struct dom_sid
*test_sid
;
472 struct dcerpc_pipe
*samr_pipe
;
474 t
->user
.domain
= torture_setting_string(tctx
, "workgroup",
475 lpcfg_workgroup(tctx
->lp_ctx
)),
477 join
= torture_create_testuser(tctx
,
482 torture_assert(tctx
, join
, "failed to join domain");
485 test_credentials
= cli_credentials_init(tctx
);
487 cli_credentials_set_workstation(test_credentials
,
490 cli_credentials_set_domain(test_credentials
,
491 torture_setting_string(tctx
, "workgroup",
492 lpcfg_workgroup(tctx
->lp_ctx
)),
494 cli_credentials_set_username(test_credentials
,
497 cli_credentials_set_password(test_credentials
,
500 test_sid
= discard_const_p(struct dom_sid
,
501 torture_join_user_sid(t
->join
));
503 if (t
->user
.num_builtin_memberships
) {
505 torture_rpc_samr_access_setup_membership(tctx
,
507 t
->user
.num_builtin_memberships
,
508 t
->user
.builtin_memberships
,
510 "failed to setup membership");
513 torture_assert_ntstatus_ok(tctx
,
514 dcerpc_pipe_connect(tctx
,
521 "Error connecting to server");
528 static bool torture_rpc_samr_access(struct torture_context
*tctx
,
529 struct dcerpc_pipe
*p
)
531 struct torture_access_context
*t
;
532 const char *testuser
;
535 torture_comment(tctx
, "Testing non-privileged user access\n");
537 t
= talloc_zero(tctx
, struct torture_access_context
);
538 torture_assert(tctx
, t
, "talloc failed");
540 t
->user
.username
= talloc_asprintf(t
, "%s%04d", TEST_ACCOUNT_NAME
, 100);
542 torture_comment(tctx
, "*** Setting up non-privleged user\n"
545 ok
= torture_rpc_samr_access_setup(tctx
, p
, t
);
546 torture_assert(tctx
, ok
, "torture_rpc_samr_access_setup failed");
548 testuser
= talloc_asprintf(t
, "%s%04d", TEST_ACCOUNT_NAME
, 200);
550 torture_comment(tctx
, "*** Try to create user (%s) as non-privileged "
551 "user - should fail\n"
554 ok
= test_samr_create_user(tctx
, t
, testuser
);
556 torture_assert(tctx
, ok
== false, "*** Creating user was successful but it should fail");
561 struct torture_suite
*torture_rpc_samr_priv(TALLOC_CTX
*mem_ctx
)
563 struct torture_suite
*suite
=
564 torture_suite_create(mem_ctx
, "samr.priv");
565 struct torture_rpc_tcase
*tcase
;
567 tcase
= torture_suite_add_rpc_iface_tcase(suite
,
571 torture_rpc_tcase_add_test(tcase
,
573 torture_rpc_samr_caching
);
575 torture_rpc_tcase_add_test(tcase
,
577 torture_rpc_samr_access
);