2 Unix SMB/CIFS implementation.
3 Test suite for libnet calls.
5 Copyright (C) Rafal Szczesniak 2005
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 "system/time.h"
23 #include "lib/cmdline/popt_common.h"
24 #include "libnet/libnet.h"
25 #include "librpc/gen_ndr/ndr_samr_c.h"
26 #include "librpc/gen_ndr/ndr_lsa_c.h"
27 #include "torture/rpc/torture_rpc.h"
28 #include "torture/libnet/usertest.h"
29 #include "torture/libnet/proto.h"
30 #include "param/param.h"
34 bool torture_createuser(struct torture_context
*torture
)
38 struct libnet_context
*ctx
= NULL
;
39 struct libnet_CreateUser req
;
42 mem_ctx
= talloc_init("test_createuser");
44 if (!test_libnet_context_init(torture
, true, &ctx
)) {
48 req
.in
.user_name
= TEST_USERNAME
;
49 req
.in
.domain_name
= lp_workgroup(torture
->lp_ctx
);
50 req
.out
.error_string
= NULL
;
52 status
= libnet_CreateUser(ctx
, mem_ctx
, &req
);
53 if (!NT_STATUS_IS_OK(status
)) {
54 torture_comment(torture
, "libnet_CreateUser call failed: %s\n", nt_errstr(status
));
59 if (!test_user_cleanup(torture
, ctx
->samr
.pipe
->binding_handle
,
60 mem_ctx
, &ctx
->samr
.handle
, TEST_USERNAME
)) {
61 torture_comment(torture
, "cleanup failed\n");
66 if (!test_samr_close_handle(torture
,
67 ctx
->samr
.pipe
->binding_handle
, mem_ctx
, &ctx
->samr
.handle
)) {
68 torture_comment(torture
, "domain close failed\n");
79 bool torture_deleteuser(struct torture_context
*torture
)
82 struct dcerpc_pipe
*p
;
83 TALLOC_CTX
*prep_mem_ctx
, *mem_ctx
;
84 struct policy_handle h
;
85 struct lsa_String domain_name
;
86 const char *name
= TEST_USERNAME
;
87 struct libnet_context
*ctx
= NULL
;
88 struct libnet_DeleteUser req
;
91 prep_mem_ctx
= talloc_init("prepare test_deleteuser");
93 req
.in
.user_name
= TEST_USERNAME
;
94 req
.in
.domain_name
= lp_workgroup(torture
->lp_ctx
);
96 status
= torture_rpc_connection(torture
,
99 if (!NT_STATUS_IS_OK(status
)) {
104 domain_name
.string
= lp_workgroup(torture
->lp_ctx
);
105 if (!test_domain_open(torture
, p
->binding_handle
, &domain_name
, prep_mem_ctx
, &h
, NULL
)) {
110 if (!test_user_create(torture
, p
->binding_handle
, prep_mem_ctx
, &h
, name
, NULL
)) {
115 mem_ctx
= talloc_init("test_deleteuser");
117 if (!test_libnet_context_init(torture
, true, &ctx
)) {
121 status
= libnet_DeleteUser(ctx
, mem_ctx
, &req
);
122 if (!NT_STATUS_IS_OK(status
)) {
123 torture_comment(torture
, "libnet_DeleteUser call failed: %s\n", nt_errstr(status
));
127 talloc_free(mem_ctx
);
131 talloc_free(prep_mem_ctx
);
137 Generate testing set of random changes
140 static void set_test_changes(struct torture_context
*tctx
,
141 TALLOC_CTX
*mem_ctx
, struct libnet_ModifyUser
*r
,
142 int num_changes
, char **user_name
, enum test_fields req_change
)
144 const char* logon_scripts
[] = { "start_login.cmd", "login.bat", "start.cmd" };
145 const char* home_dirs
[] = { "\\\\srv\\home", "\\\\homesrv\\home\\user", "\\\\pdcsrv\\domain" };
146 const char* home_drives
[] = { "H:", "z:", "I:", "J:", "n:" };
147 const uint32_t flags
[] = { (ACB_DISABLED
| ACB_NORMAL
| ACB_PW_EXPIRED
),
148 (ACB_NORMAL
| ACB_PWNOEXP
),
149 (ACB_NORMAL
| ACB_PW_EXPIRED
) };
150 const char *homedir
, *homedrive
, *logonscript
;
154 torture_comment(tctx
, "Fields to change: [");
156 for (i
= 0; i
< num_changes
&& i
<= USER_FIELD_LAST
; i
++) {
159 testfld
= (req_change
== none
) ? (random() % USER_FIELD_LAST
) + 1 : req_change
;
161 /* get one in case we hit time field this time */
162 gettimeofday(&now
, NULL
);
166 continue_if_field_set(r
->in
.account_name
);
167 r
->in
.account_name
= talloc_asprintf(mem_ctx
, TEST_CHG_ACCOUNTNAME
,
168 (int)(random() % 100));
169 fldname
= "account_name";
171 /* update the test's user name in case it's about to change */
172 *user_name
= talloc_strdup(mem_ctx
, r
->in
.account_name
);
176 continue_if_field_set(r
->in
.full_name
);
177 r
->in
.full_name
= talloc_asprintf(mem_ctx
, TEST_CHG_FULLNAME
,
178 (unsigned int)random(), (unsigned int)random());
179 fldname
= "full_name";
182 case acct_description
:
183 continue_if_field_set(r
->in
.description
);
184 r
->in
.description
= talloc_asprintf(mem_ctx
, TEST_CHG_DESCRIPTION
,
186 fldname
= "description";
189 case acct_home_directory
:
190 continue_if_field_set(r
->in
.home_directory
);
191 homedir
= home_dirs
[random() % ARRAY_SIZE(home_dirs
)];
192 r
->in
.home_directory
= talloc_strdup(mem_ctx
, homedir
);
193 fldname
= "home_dir";
196 case acct_home_drive
:
197 continue_if_field_set(r
->in
.home_drive
);
198 homedrive
= home_drives
[random() % ARRAY_SIZE(home_drives
)];
199 r
->in
.home_drive
= talloc_strdup(mem_ctx
, homedrive
);
200 fldname
= "home_drive";
204 continue_if_field_set(r
->in
.comment
);
205 r
->in
.comment
= talloc_asprintf(mem_ctx
, TEST_CHG_COMMENT
,
206 (unsigned long)random(), (unsigned long)random());
210 case acct_logon_script
:
211 continue_if_field_set(r
->in
.logon_script
);
212 logonscript
= logon_scripts
[random() % ARRAY_SIZE(logon_scripts
)];
213 r
->in
.logon_script
= talloc_strdup(mem_ctx
, logonscript
);
214 fldname
= "logon_script";
217 case acct_profile_path
:
218 continue_if_field_set(r
->in
.profile_path
);
219 r
->in
.profile_path
= talloc_asprintf(mem_ctx
, TEST_CHG_PROFILEPATH
,
220 (unsigned long)random(), (unsigned int)random());
221 fldname
= "profile_path";
225 continue_if_field_set(r
->in
.acct_expiry
);
226 now
= timeval_add(&now
, (random() % (31*24*60*60)), 0);
227 r
->in
.acct_expiry
= (struct timeval
*)talloc_memdup(mem_ctx
, &now
, sizeof(now
));
228 fldname
= "acct_expiry";
232 continue_if_field_set(r
->in
.acct_flags
);
233 r
->in
.acct_flags
= flags
[random() % ARRAY_SIZE(flags
)];
234 fldname
= "acct_flags";
238 fldname
= "unknown_field";
241 torture_comment(tctx
, ((i
< num_changes
- 1) ? "%s," : "%s"), fldname
);
243 /* disable requested field (it's supposed to be the only one used) */
244 if (req_change
!= none
) req_change
= none
;
247 torture_comment(tctx
, "]\n");
251 #define TEST_STR_FLD(fld) \
252 if (!strequal(req.in.fld, user_req.out.fld)) { \
253 torture_comment(torture, "failed to change '%s'\n", #fld); \
258 #define TEST_TIME_FLD(fld) \
259 if (timeval_compare(req.in.fld, user_req.out.fld)) { \
260 torture_comment(torture, "failed to change '%s'\n", #fld); \
265 #define TEST_NUM_FLD(fld) \
266 if (req.in.fld != user_req.out.fld) { \
267 torture_comment(torture, "failed to change '%s'\n", #fld); \
273 bool torture_modifyuser(struct torture_context
*torture
)
276 struct dcerpc_pipe
*p
;
277 TALLOC_CTX
*prep_mem_ctx
;
278 struct policy_handle h
;
279 struct lsa_String domain_name
;
281 struct libnet_context
*ctx
= NULL
;
282 struct libnet_ModifyUser req
;
283 struct libnet_UserInfo user_req
;
286 struct dcerpc_binding_handle
*b
;
288 prep_mem_ctx
= talloc_init("prepare test_deleteuser");
290 status
= torture_rpc_connection(torture
,
293 if (!NT_STATUS_IS_OK(status
)) {
297 b
= p
->binding_handle
;
299 name
= talloc_strdup(prep_mem_ctx
, TEST_USERNAME
);
301 domain_name
.string
= lp_workgroup(torture
->lp_ctx
);
302 if (!test_domain_open(torture
, b
, &domain_name
, prep_mem_ctx
, &h
, NULL
)) {
307 if (!test_user_create(torture
, b
, prep_mem_ctx
, &h
, name
, NULL
)) {
312 torture_comment(torture
, "Testing change of all fields - each single one in turn\n");
314 if (!test_libnet_context_init(torture
, true, &ctx
)) {
318 for (fld
= USER_FIELD_FIRST
; fld
<= USER_FIELD_LAST
; fld
++) {
320 req
.in
.domain_name
= lp_workgroup(torture
->lp_ctx
);
321 req
.in
.user_name
= name
;
323 set_test_changes(torture
, torture
, &req
, 1, &name
, fld
);
325 status
= libnet_ModifyUser(ctx
, torture
, &req
);
326 if (!NT_STATUS_IS_OK(status
)) {
327 torture_comment(torture
, "libnet_ModifyUser call failed: %s\n", nt_errstr(status
));
332 ZERO_STRUCT(user_req
);
333 user_req
.in
.domain_name
= lp_workgroup(torture
->lp_ctx
);
334 user_req
.in
.data
.user_name
= name
;
335 user_req
.in
.level
= USER_INFO_BY_NAME
;
337 status
= libnet_UserInfo(ctx
, torture
, &user_req
);
338 if (!NT_STATUS_IS_OK(status
)) {
339 torture_comment(torture
, "libnet_UserInfo call failed: %s\n", nt_errstr(status
));
345 case acct_name
: TEST_STR_FLD(account_name
);
347 case acct_full_name
: TEST_STR_FLD(full_name
);
349 case acct_comment
: TEST_STR_FLD(comment
);
351 case acct_description
: TEST_STR_FLD(description
);
353 case acct_home_directory
: TEST_STR_FLD(home_directory
);
355 case acct_home_drive
: TEST_STR_FLD(home_drive
);
357 case acct_logon_script
: TEST_STR_FLD(logon_script
);
359 case acct_profile_path
: TEST_STR_FLD(profile_path
);
361 case acct_expiry
: TEST_TIME_FLD(acct_expiry
);
363 case acct_flags
: TEST_NUM_FLD(acct_flags
);
371 if (!test_user_cleanup(torture
, ctx
->samr
.pipe
->binding_handle
,
372 torture
, &ctx
->samr
.handle
, TEST_USERNAME
)) {
373 torture_comment(torture
, "cleanup failed\n");
378 if (!test_samr_close_handle(torture
,
379 ctx
->samr
.pipe
->binding_handle
, torture
, &ctx
->samr
.handle
)) {
380 torture_comment(torture
, "domain close failed\n");
386 talloc_free(prep_mem_ctx
);
391 bool torture_userinfo_api(struct torture_context
*torture
)
393 const char *name
= TEST_USERNAME
;
396 TALLOC_CTX
*mem_ctx
= NULL
, *prep_mem_ctx
;
397 struct libnet_context
*ctx
= NULL
;
398 struct dcerpc_pipe
*p
;
399 struct policy_handle h
;
400 struct lsa_String domain_name
;
401 struct libnet_UserInfo req
;
402 struct dcerpc_binding_handle
*b
;
404 prep_mem_ctx
= talloc_init("prepare torture user info");
406 status
= torture_rpc_connection(torture
,
409 if (!NT_STATUS_IS_OK(status
)) {
412 b
= p
->binding_handle
;
414 domain_name
.string
= lp_workgroup(torture
->lp_ctx
);
415 if (!test_domain_open(torture
, b
, &domain_name
, prep_mem_ctx
, &h
, NULL
)) {
420 if (!test_user_create(torture
, b
, prep_mem_ctx
, &h
, name
, NULL
)) {
425 mem_ctx
= talloc_init("torture user info");
427 if (!test_libnet_context_init(torture
, true, &ctx
)) {
433 req
.in
.domain_name
= domain_name
.string
;
434 req
.in
.data
.user_name
= name
;
435 req
.in
.level
= USER_INFO_BY_NAME
;
437 status
= libnet_UserInfo(ctx
, mem_ctx
, &req
);
438 if (!NT_STATUS_IS_OK(status
)) {
439 torture_comment(torture
, "libnet_UserInfo call failed: %s\n", nt_errstr(status
));
444 if (!test_user_cleanup(torture
, ctx
->samr
.pipe
->binding_handle
,
445 mem_ctx
, &ctx
->samr
.handle
, TEST_USERNAME
)) {
446 torture_comment(torture
, "cleanup failed\n");
451 if (!test_samr_close_handle(torture
,
452 ctx
->samr
.pipe
->binding_handle
, mem_ctx
, &ctx
->samr
.handle
)) {
453 torture_comment(torture
, "domain close failed\n");
459 talloc_free(mem_ctx
);
464 bool torture_userlist(struct torture_context
*torture
)
468 TALLOC_CTX
*mem_ctx
= NULL
;
469 struct libnet_context
*ctx
;
470 struct lsa_String domain_name
;
471 struct libnet_UserList req
;
474 ctx
= libnet_context_init(torture
->ev
, torture
->lp_ctx
);
475 ctx
->cred
= cmdline_credentials
;
477 domain_name
.string
= lp_workgroup(torture
->lp_ctx
);
478 mem_ctx
= talloc_init("torture user list");
482 torture_comment(torture
, "listing user accounts:\n");
486 req
.in
.domain_name
= domain_name
.string
;
487 req
.in
.page_size
= 128;
488 req
.in
.resume_index
= req
.out
.resume_index
;
490 status
= libnet_UserList(ctx
, mem_ctx
, &req
);
491 if (!NT_STATUS_IS_OK(status
) &&
492 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) break;
494 for (i
= 0; i
< req
.out
.count
; i
++) {
495 torture_comment(torture
, "\tuser: %s, sid=%s\n",
496 req
.out
.users
[i
].username
, req
.out
.users
[i
].sid
);
499 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
501 if (!(NT_STATUS_IS_OK(status
) ||
502 NT_STATUS_EQUAL(status
, NT_STATUS_NO_MORE_ENTRIES
))) {
503 torture_comment(torture
, "libnet_UserList call failed: %s\n", nt_errstr(status
));
508 if (!test_samr_close_handle(torture
,
509 ctx
->samr
.pipe
->binding_handle
, mem_ctx
, &ctx
->samr
.handle
)) {
510 torture_comment(torture
, "samr domain close failed\n");
515 if (!test_lsa_close_handle(torture
,
516 ctx
->lsa
.pipe
->binding_handle
, mem_ctx
, &ctx
->lsa
.handle
)) {
517 torture_comment(torture
, "lsa domain close failed\n");
524 talloc_free(mem_ctx
);