s4/test: remove unused code
[kamenim/samba.git] / source4 / torture / libnet / libnet_user.c
1 /*
2    Unix SMB/CIFS implementation.
3    Test suite for libnet calls.
4
5    Copyright (C) Rafal Szczesniak 2005
6
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.
11
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.
16
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/>.
19 */
20
21 #include "includes.h"
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 "param/param.h"
30 #include "lib/ldb_wrap.h"
31
32
33 /**
34  * Find out user's samAccountName for given
35  * user RDN. We need samAccountName value
36  * when deleting users.
37  */
38 static bool _get_account_name_for_user_rdn(struct torture_context *tctx,
39                                            struct dcerpc_binding_handle *b,
40                                            const char *user_rdn,
41                                            TALLOC_CTX *mem_ctx,
42                                            const char **_account_name)
43 {
44         const char *url;
45         struct ldb_context *ldb;
46         TALLOC_CTX *tmp_ctx;
47         bool test_res = true;
48         struct dcerpc_pipe *p = talloc_get_type_abort(b->private_data, struct dcerpc_pipe);
49         int ldb_ret;
50         struct ldb_result *ldb_res;
51         const char *account_name = NULL;
52         static const char *attrs[] = {
53                 "samAccountName",
54                 NULL
55         };
56
57         tmp_ctx = talloc_new(tctx);
58         torture_assert(tctx, tmp_ctx != NULL, "Failed to create temporary mem context");
59
60         url = talloc_asprintf(tmp_ctx, "ldap://%s/", p->binding->target_hostname);
61         torture_assert_goto(tctx, url != NULL, test_res, done, "Failed to allocate URL for ldb");
62
63         ldb = ldb_wrap_connect(tmp_ctx,
64                                tctx->ev, tctx->lp_ctx,
65                                url, NULL, cmdline_credentials, 0);
66         torture_assert_goto(tctx, ldb != NULL, test_res, done, "Failed to make LDB connection");
67
68         ldb_ret = ldb_search(ldb, tmp_ctx, &ldb_res,
69                              ldb_get_default_basedn(ldb), LDB_SCOPE_SUBTREE,
70                              attrs,
71                              "(&(objectClass=user)(name=%s))", user_rdn);
72         if (LDB_SUCCESS == ldb_ret && 1 == ldb_res->count) {
73                 account_name = ldb_msg_find_attr_as_string(ldb_res->msgs[0], "samAccountName", NULL);
74         }
75
76         /* return user_rdn by default */
77         if (!account_name) {
78                 account_name = user_rdn;
79         }
80
81         /* duplicate memory in parent context */
82         *_account_name = talloc_strdup(mem_ctx, account_name);
83
84 done:
85         talloc_free(tmp_ctx);
86         return test_res;
87 }
88
89 /**
90  * Deletes a user account when given user RDN name
91  *
92  * @param username RDN for the user to be deleted
93  */
94 static bool test_cleanup(struct torture_context *tctx,
95                          struct dcerpc_binding_handle *b, TALLOC_CTX *mem_ctx,
96                          struct policy_handle *domain_handle, const char *username)
97 {
98         struct samr_LookupNames r1;
99         struct samr_OpenUser r2;
100         struct samr_DeleteUser r3;
101         struct lsa_String names[2];
102         uint32_t rid;
103         struct policy_handle user_handle;
104         struct samr_Ids rids, types;
105         const char *account_name;
106
107         if (!_get_account_name_for_user_rdn(tctx, b, username, mem_ctx, &account_name)) {
108                 torture_result(tctx, TORTURE_FAIL,
109                                __location__": Failed to find samAccountName for %s", username);
110                 return false;
111         }
112
113         names[0].string = account_name;
114
115         r1.in.domain_handle  = domain_handle;
116         r1.in.num_names      = 1;
117         r1.in.names          = names;
118         r1.out.rids          = &rids;
119         r1.out.types         = &types;
120
121         torture_comment(tctx, "user account lookup '%s'\n", account_name);
122
123         torture_assert_ntstatus_ok(tctx,
124                 dcerpc_samr_LookupNames_r(b, mem_ctx, &r1),
125                 "LookupNames failed");
126         torture_assert_ntstatus_ok(tctx, r1.out.result,
127                 "LookupNames failed");
128
129         rid = r1.out.rids->ids[0];
130
131         r2.in.domain_handle  = domain_handle;
132         r2.in.access_mask    = SEC_FLAG_MAXIMUM_ALLOWED;
133         r2.in.rid            = rid;
134         r2.out.user_handle   = &user_handle;
135
136         torture_comment(tctx, "opening user account\n");
137
138         torture_assert_ntstatus_ok(tctx,
139                 dcerpc_samr_OpenUser_r(b, mem_ctx, &r2),
140                 "OpenUser failed");
141         torture_assert_ntstatus_ok(tctx, r2.out.result,
142                 "OpenUser failed");
143
144         r3.in.user_handle  = &user_handle;
145         r3.out.user_handle = &user_handle;
146
147         torture_comment(tctx, "deleting user account\n");
148
149         torture_assert_ntstatus_ok(tctx,
150                 dcerpc_samr_DeleteUser_r(b, mem_ctx, &r3),
151                 "DeleteUser failed");
152         torture_assert_ntstatus_ok(tctx, r3.out.result,
153                 "DeleteUser failed");
154
155         return true;
156 }
157
158
159 static bool test_opendomain(struct torture_context *tctx,
160                             struct dcerpc_binding_handle *b, TALLOC_CTX *mem_ctx,
161                             struct policy_handle *handle, struct lsa_String *domname)
162 {
163         struct policy_handle h, domain_handle;
164         struct samr_Connect r1;
165         struct samr_LookupDomain r2;
166         struct dom_sid2 *sid = NULL;
167         struct samr_OpenDomain r3;
168
169         torture_comment(tctx, "connecting\n");
170
171         r1.in.system_name = 0;
172         r1.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
173         r1.out.connect_handle = &h;
174
175         torture_assert_ntstatus_ok(tctx,
176                 dcerpc_samr_Connect_r(b, mem_ctx, &r1),
177                 "Connect failed");
178         torture_assert_ntstatus_ok(tctx, r1.out.result,
179                 "Connect failed");
180
181         r2.in.connect_handle = &h;
182         r2.in.domain_name = domname;
183         r2.out.sid = &sid;
184
185         torture_comment(tctx, "domain lookup on %s\n", domname->string);
186
187         torture_assert_ntstatus_ok(tctx,
188                 dcerpc_samr_LookupDomain_r(b, mem_ctx, &r2),
189                 "LookupDomain failed");
190         torture_assert_ntstatus_ok(tctx, r2.out.result,
191                 "LookupDomain failed");
192
193         r3.in.connect_handle = &h;
194         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
195         r3.in.sid = *r2.out.sid;
196         r3.out.domain_handle = &domain_handle;
197
198         torture_comment(tctx, "opening domain\n");
199
200         torture_assert_ntstatus_ok(tctx,
201                 dcerpc_samr_OpenDomain_r(b, mem_ctx, &r3),
202                 "OpenDomain failed");
203         torture_assert_ntstatus_ok(tctx, r3.out.result,
204                 "OpenDomain failed");
205
206         *handle = domain_handle;
207
208         return true;
209 }
210
211
212 static bool test_samr_close(struct torture_context *tctx,
213                             struct dcerpc_binding_handle *b, TALLOC_CTX *mem_ctx,
214                             struct policy_handle *domain_handle)
215 {
216         struct samr_Close r;
217
218         r.in.handle = domain_handle;
219         r.out.handle = domain_handle;
220
221         torture_assert_ntstatus_ok(tctx,
222                 dcerpc_samr_Close_r(b, mem_ctx, &r),
223                 "Close samr domain failed");
224         torture_assert_ntstatus_ok(tctx, r.out.result,
225                 "Close samr domain failed");
226
227         return true;
228 }
229
230
231 static bool test_lsa_close(struct torture_context *tctx,
232                            struct dcerpc_binding_handle *b, TALLOC_CTX *mem_ctx,
233                            struct policy_handle *domain_handle)
234 {
235         struct lsa_Close r;
236
237         r.in.handle = domain_handle;
238         r.out.handle = domain_handle;
239
240         torture_assert_ntstatus_ok(tctx,
241                 dcerpc_lsa_Close_r(b, mem_ctx, &r),
242                 "Close lsa domain failed");
243         torture_assert_ntstatus_ok(tctx, r.out.result,
244                 "Close lsa domain failed");
245
246         return true;
247 }
248
249
250 static bool test_createuser(struct torture_context *tctx,
251                             struct dcerpc_binding_handle *b, TALLOC_CTX *mem_ctx,
252                             struct policy_handle *handle, const char* user)
253 {
254         struct policy_handle user_handle;
255         struct lsa_String username;
256         struct samr_CreateUser r1;
257         struct samr_Close r2;
258         uint32_t user_rid;
259
260         username.string = user;
261
262         r1.in.domain_handle = handle;
263         r1.in.account_name = &username;
264         r1.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
265         r1.out.user_handle = &user_handle;
266         r1.out.rid = &user_rid;
267
268         torture_comment(tctx, "creating user '%s'\n", username.string);
269
270         torture_assert_ntstatus_ok(tctx,
271                 dcerpc_samr_CreateUser_r(b, mem_ctx, &r1),
272                 "CreateUser failed");
273         if (!NT_STATUS_IS_OK(r1.out.result)) {
274                 torture_comment(tctx, "CreateUser failed - %s\n", nt_errstr(r1.out.result));
275
276                 if (NT_STATUS_EQUAL(r1.out.result, NT_STATUS_USER_EXISTS)) {
277                         torture_comment(tctx, "User (%s) already exists - attempting to delete and recreate account again\n", user);
278                         if (!test_cleanup(tctx, b, mem_ctx, handle, user)) {
279                                 return false;
280                         }
281
282                         torture_comment(tctx, "creating user account\n");
283
284                         torture_assert_ntstatus_ok(tctx,
285                                 dcerpc_samr_CreateUser_r(b, mem_ctx, &r1),
286                                 "CreateUser failed");
287                         torture_assert_ntstatus_ok(tctx, r1.out.result,
288                                 "CreateUser failed");
289
290                         return true;
291                 }
292                 return false;
293         }
294
295         r2.in.handle = &user_handle;
296         r2.out.handle = &user_handle;
297
298         torture_comment(tctx, "closing user '%s'\n", username.string);
299
300         torture_assert_ntstatus_ok(tctx,
301                 dcerpc_samr_Close_r(b, mem_ctx, &r2),
302                 "Close failed");
303         torture_assert_ntstatus_ok(tctx, r2.out.result,
304                 "Close failed");
305
306         return true;
307 }
308
309
310 bool torture_createuser(struct torture_context *torture)
311 {
312         NTSTATUS status;
313         TALLOC_CTX *mem_ctx;
314         struct libnet_context *ctx;
315         struct libnet_CreateUser req;
316         bool ret = true;
317
318         mem_ctx = talloc_init("test_createuser");
319
320         ctx = libnet_context_init(torture->ev, torture->lp_ctx);
321         ctx->cred = cmdline_credentials;
322
323         req.in.user_name = TEST_USERNAME;
324         req.in.domain_name = lp_workgroup(torture->lp_ctx);
325         req.out.error_string = NULL;
326
327         status = libnet_CreateUser(ctx, mem_ctx, &req);
328         if (!NT_STATUS_IS_OK(status)) {
329                 torture_comment(torture, "libnet_CreateUser call failed: %s\n", nt_errstr(status));
330                 ret = false;
331                 goto done;
332         }
333
334         if (!test_cleanup(torture, ctx->samr.pipe->binding_handle, mem_ctx, &ctx->samr.handle, TEST_USERNAME)) {
335                 torture_comment(torture, "cleanup failed\n");
336                 ret = false;
337                 goto done;
338         }
339
340         if (!test_samr_close(torture, ctx->samr.pipe->binding_handle, mem_ctx, &ctx->samr.handle)) {
341                 torture_comment(torture, "domain close failed\n");
342                 ret = false;
343         }
344
345 done:
346         talloc_free(ctx);
347         talloc_free(mem_ctx);
348         return ret;
349 }
350
351
352 bool torture_deleteuser(struct torture_context *torture)
353 {
354         NTSTATUS status;
355         struct dcerpc_pipe *p;
356         TALLOC_CTX *prep_mem_ctx, *mem_ctx;
357         struct policy_handle h;
358         struct lsa_String domain_name;
359         const char *name = TEST_USERNAME;
360         struct libnet_context *ctx;
361         struct libnet_DeleteUser req;
362         bool ret = true;
363
364         prep_mem_ctx = talloc_init("prepare test_deleteuser");
365
366         ctx = libnet_context_init(torture->ev, torture->lp_ctx);
367         ctx->cred = cmdline_credentials;
368
369         req.in.user_name = TEST_USERNAME;
370         req.in.domain_name = lp_workgroup(torture->lp_ctx);
371
372         status = torture_rpc_connection(torture,
373                                         &p,
374                                         &ndr_table_samr);
375         if (!NT_STATUS_IS_OK(status)) {
376                 ret = false;
377                 goto done;
378         }
379
380         domain_name.string = lp_workgroup(torture->lp_ctx);
381         if (!test_opendomain(torture, p->binding_handle, prep_mem_ctx, &h, &domain_name)) {
382                 ret = false;
383                 goto done;
384         }
385
386         if (!test_createuser(torture, p->binding_handle, prep_mem_ctx, &h, name)) {
387                 ret = false;
388                 goto done;
389         }
390
391         mem_ctx = talloc_init("test_deleteuser");
392
393         status = libnet_DeleteUser(ctx, mem_ctx, &req);
394         if (!NT_STATUS_IS_OK(status)) {
395                 torture_comment(torture, "libnet_DeleteUser call failed: %s\n", nt_errstr(status));
396                 ret = false;
397         }
398
399         talloc_free(mem_ctx);
400
401 done:
402         talloc_free(ctx);
403         talloc_free(prep_mem_ctx);
404         return ret;
405 }
406
407
408 /*
409   Generate testing set of random changes
410 */
411
412 static void set_test_changes(struct torture_context *tctx,
413                              TALLOC_CTX *mem_ctx, struct libnet_ModifyUser *r,
414                              int num_changes, char **user_name, enum test_fields req_change)
415 {
416         const char* logon_scripts[] = { "start_login.cmd", "login.bat", "start.cmd" };
417         const char* home_dirs[] = { "\\\\srv\\home", "\\\\homesrv\\home\\user", "\\\\pdcsrv\\domain" };
418         const char* home_drives[] = { "H:", "z:", "I:", "J:", "n:" };
419         const uint32_t flags[] = { (ACB_DISABLED | ACB_NORMAL | ACB_PW_EXPIRED),
420                                    (ACB_NORMAL | ACB_PWNOEXP),
421                                    (ACB_NORMAL | ACB_PW_EXPIRED) };
422         const char *homedir, *homedrive, *logonscript;
423         struct timeval now;
424         int i, testfld;
425
426         torture_comment(tctx, "Fields to change: [");
427
428         for (i = 0; i < num_changes && i <= USER_FIELD_LAST; i++) {
429                 const char *fldname;
430
431                 testfld = (req_change == none) ? (random() % USER_FIELD_LAST) + 1 : req_change;
432
433                 /* get one in case we hit time field this time */
434                 gettimeofday(&now, NULL);
435
436                 switch (testfld) {
437                 case acct_name:
438                         continue_if_field_set(r->in.account_name);
439                         r->in.account_name = talloc_asprintf(mem_ctx, TEST_CHG_ACCOUNTNAME,
440                                                              (int)(random() % 100));
441                         fldname = "account_name";
442
443                         /* update the test's user name in case it's about to change */
444                         *user_name = talloc_strdup(mem_ctx, r->in.account_name);
445                         break;
446
447                 case acct_full_name:
448                         continue_if_field_set(r->in.full_name);
449                         r->in.full_name = talloc_asprintf(mem_ctx, TEST_CHG_FULLNAME,
450                                                           (unsigned int)random(), (unsigned int)random());
451                         fldname = "full_name";
452                         break;
453
454                 case acct_description:
455                         continue_if_field_set(r->in.description);
456                         r->in.description = talloc_asprintf(mem_ctx, TEST_CHG_DESCRIPTION,
457                                                             (long)random());
458                         fldname = "description";
459                         break;
460
461                 case acct_home_directory:
462                         continue_if_field_set(r->in.home_directory);
463                         homedir = home_dirs[random() % ARRAY_SIZE(home_dirs)];
464                         r->in.home_directory = talloc_strdup(mem_ctx, homedir);
465                         fldname = "home_dir";
466                         break;
467
468                 case acct_home_drive:
469                         continue_if_field_set(r->in.home_drive);
470                         homedrive = home_drives[random() % ARRAY_SIZE(home_drives)];
471                         r->in.home_drive = talloc_strdup(mem_ctx, homedrive);
472                         fldname = "home_drive";
473                         break;
474
475                 case acct_comment:
476                         continue_if_field_set(r->in.comment);
477                         r->in.comment = talloc_asprintf(mem_ctx, TEST_CHG_COMMENT,
478                                                         (unsigned long)random(), (unsigned long)random());
479                         fldname = "comment";
480                         break;
481
482                 case acct_logon_script:
483                         continue_if_field_set(r->in.logon_script);
484                         logonscript = logon_scripts[random() % ARRAY_SIZE(logon_scripts)];
485                         r->in.logon_script = talloc_strdup(mem_ctx, logonscript);
486                         fldname = "logon_script";
487                         break;
488
489                 case acct_profile_path:
490                         continue_if_field_set(r->in.profile_path);
491                         r->in.profile_path = talloc_asprintf(mem_ctx, TEST_CHG_PROFILEPATH,
492                                                              (unsigned long)random(), (unsigned int)random());
493                         fldname = "profile_path";
494                         break;
495
496                 case acct_expiry:
497                         continue_if_field_set(r->in.acct_expiry);
498                         now = timeval_add(&now, (random() % (31*24*60*60)), 0);
499                         r->in.acct_expiry = (struct timeval *)talloc_memdup(mem_ctx, &now, sizeof(now));
500                         fldname = "acct_expiry";
501                         break;
502
503                 case acct_flags:
504                         continue_if_field_set(r->in.acct_flags);
505                         r->in.acct_flags = flags[random() % ARRAY_SIZE(flags)];
506                         fldname = "acct_flags";
507                         break;
508
509                 default:
510                         fldname = "unknown_field";
511                 }
512
513                 torture_comment(tctx, ((i < num_changes - 1) ? "%s," : "%s"), fldname);
514
515                 /* disable requested field (it's supposed to be the only one used) */
516                 if (req_change != none) req_change = none;
517         }
518
519         torture_comment(tctx, "]\n");
520 }
521
522
523 #define TEST_STR_FLD(fld) \
524         if (!strequal(req.in.fld, user_req.out.fld)) { \
525                 torture_comment(torture, "failed to change '%s'\n", #fld); \
526                 ret = false; \
527                 goto cleanup; \
528         }
529
530 #define TEST_TIME_FLD(fld) \
531         if (timeval_compare(req.in.fld, user_req.out.fld)) { \
532                 torture_comment(torture, "failed to change '%s'\n", #fld); \
533                 ret = false; \
534                 goto cleanup; \
535         }
536
537 #define TEST_NUM_FLD(fld) \
538         if (req.in.fld != user_req.out.fld) { \
539                 torture_comment(torture, "failed to change '%s'\n", #fld); \
540                 ret = false; \
541                 goto cleanup; \
542         }
543
544
545 bool torture_modifyuser(struct torture_context *torture)
546 {
547         NTSTATUS status;
548         struct dcerpc_binding *binding;
549         struct dcerpc_pipe *p;
550         TALLOC_CTX *prep_mem_ctx;
551         struct policy_handle h;
552         struct lsa_String domain_name;
553         char *name;
554         struct libnet_context *ctx;
555         struct libnet_ModifyUser req;
556         struct libnet_UserInfo user_req;
557         int fld;
558         bool ret = true;
559         struct dcerpc_binding_handle *b;
560
561         prep_mem_ctx = talloc_init("prepare test_deleteuser");
562
563         ctx = libnet_context_init(torture->ev, torture->lp_ctx);
564         ctx->cred = cmdline_credentials;
565
566         status = torture_rpc_connection(torture,
567                                         &p,
568                                         &ndr_table_samr);
569         if (!NT_STATUS_IS_OK(status)) {
570                 ret = false;
571                 goto done;
572         }
573         b = p->binding_handle;
574
575         name = talloc_strdup(prep_mem_ctx, TEST_USERNAME);
576
577         domain_name.string = lp_workgroup(torture->lp_ctx);
578         if (!test_opendomain(torture, b, prep_mem_ctx, &h, &domain_name)) {
579                 ret = false;
580                 goto done;
581         }
582
583         if (!test_createuser(torture, b, prep_mem_ctx, &h, name)) {
584                 ret = false;
585                 goto done;
586         }
587
588         status = torture_rpc_binding(torture, &binding);
589         if (!NT_STATUS_IS_OK(status)) {
590                 ret = false;
591                 goto done;
592         }
593
594         torture_comment(torture, "Testing change of all fields - each single one in turn\n");
595
596         for (fld = USER_FIELD_FIRST; fld <= USER_FIELD_LAST; fld++) {
597                 ZERO_STRUCT(req);
598                 req.in.domain_name = lp_workgroup(torture->lp_ctx);
599                 req.in.user_name = name;
600
601                 set_test_changes(torture, torture, &req, 1, &name, fld);
602
603                 status = libnet_ModifyUser(ctx, torture, &req);
604                 if (!NT_STATUS_IS_OK(status)) {
605                         torture_comment(torture, "libnet_ModifyUser call failed: %s\n", nt_errstr(status));
606                         ret = false;
607                         continue;
608                 }
609
610                 ZERO_STRUCT(user_req);
611                 user_req.in.domain_name = lp_workgroup(torture->lp_ctx);
612                 user_req.in.data.user_name = name;
613                 user_req.in.level = USER_INFO_BY_NAME;
614
615                 status = libnet_UserInfo(ctx, torture, &user_req);
616                 if (!NT_STATUS_IS_OK(status)) {
617                         torture_comment(torture, "libnet_UserInfo call failed: %s\n", nt_errstr(status));
618                         ret = false;
619                         continue;
620                 }
621
622                 switch (fld) {
623                 case acct_name: TEST_STR_FLD(account_name);
624                         break;
625                 case acct_full_name: TEST_STR_FLD(full_name);
626                         break;
627                 case acct_comment: TEST_STR_FLD(comment);
628                         break;
629                 case acct_description: TEST_STR_FLD(description);
630                         break;
631                 case acct_home_directory: TEST_STR_FLD(home_directory);
632                         break;
633                 case acct_home_drive: TEST_STR_FLD(home_drive);
634                         break;
635                 case acct_logon_script: TEST_STR_FLD(logon_script);
636                         break;
637                 case acct_profile_path: TEST_STR_FLD(profile_path);
638                         break;
639                 case acct_expiry: TEST_TIME_FLD(acct_expiry);
640                         break;
641                 case acct_flags: TEST_NUM_FLD(acct_flags);
642                         break;
643                 default:
644                         break;
645                 }
646         }
647
648 cleanup:
649         if (!test_cleanup(torture, ctx->samr.pipe->binding_handle,
650                           torture, &ctx->samr.handle, TEST_USERNAME)) {
651                 torture_comment(torture, "cleanup failed\n");
652                 ret = false;
653                 goto done;
654         }
655
656         if (!test_samr_close(torture, ctx->samr.pipe->binding_handle, torture, &ctx->samr.handle)) {
657                 torture_comment(torture, "domain close failed\n");
658                 ret = false;
659         }
660
661 done:
662         talloc_free(ctx);
663         talloc_free(prep_mem_ctx);
664         return ret;
665 }
666
667
668 bool torture_userinfo_api(struct torture_context *torture)
669 {
670         const char *name = TEST_USERNAME;
671         bool ret = true;
672         NTSTATUS status;
673         TALLOC_CTX *mem_ctx = NULL, *prep_mem_ctx;
674         struct libnet_context *ctx;
675         struct dcerpc_pipe *p;
676         struct policy_handle h;
677         struct lsa_String domain_name;
678         struct libnet_UserInfo req;
679         struct dcerpc_binding_handle *b;
680
681         prep_mem_ctx = talloc_init("prepare torture user info");
682
683         ctx = libnet_context_init(torture->ev, torture->lp_ctx);
684         ctx->cred = cmdline_credentials;
685
686         status = torture_rpc_connection(torture,
687                                         &p,
688                                         &ndr_table_samr);
689         if (!NT_STATUS_IS_OK(status)) {
690                 return false;
691         }
692         b = p->binding_handle;
693
694         domain_name.string = lp_workgroup(torture->lp_ctx);
695         if (!test_opendomain(torture, b, prep_mem_ctx, &h, &domain_name)) {
696                 ret = false;
697                 goto done;
698         }
699
700         if (!test_createuser(torture, b, prep_mem_ctx, &h, name)) {
701                 ret = false;
702                 goto done;
703         }
704
705         mem_ctx = talloc_init("torture user info");
706
707         ZERO_STRUCT(req);
708
709         req.in.domain_name = domain_name.string;
710         req.in.data.user_name   = name;
711         req.in.level = USER_INFO_BY_NAME;
712
713         status = libnet_UserInfo(ctx, mem_ctx, &req);
714         if (!NT_STATUS_IS_OK(status)) {
715                 torture_comment(torture, "libnet_UserInfo call failed: %s\n", nt_errstr(status));
716                 ret = false;
717                 goto done;
718         }
719
720         if (!test_cleanup(torture, ctx->samr.pipe->binding_handle, mem_ctx, &ctx->samr.handle, TEST_USERNAME)) {
721                 torture_comment(torture, "cleanup failed\n");
722                 ret = false;
723                 goto done;
724         }
725
726         if (!test_samr_close(torture, ctx->samr.pipe->binding_handle, mem_ctx, &ctx->samr.handle)) {
727                 torture_comment(torture, "domain close failed\n");
728                 ret = false;
729         }
730
731         talloc_free(ctx);
732
733 done:
734         talloc_free(mem_ctx);
735         return ret;
736 }
737
738
739 bool torture_userlist(struct torture_context *torture)
740 {
741         bool ret = true;
742         NTSTATUS status;
743         TALLOC_CTX *mem_ctx = NULL;
744         struct libnet_context *ctx;
745         struct lsa_String domain_name;
746         struct libnet_UserList req;
747         int i;
748
749         ctx = libnet_context_init(torture->ev, torture->lp_ctx);
750         ctx->cred = cmdline_credentials;
751
752         domain_name.string = lp_workgroup(torture->lp_ctx);
753         mem_ctx = talloc_init("torture user list");
754
755         ZERO_STRUCT(req);
756
757         torture_comment(torture, "listing user accounts:\n");
758
759         do {
760
761                 req.in.domain_name = domain_name.string;
762                 req.in.page_size   = 128;
763                 req.in.resume_index = req.out.resume_index;
764
765                 status = libnet_UserList(ctx, mem_ctx, &req);
766                 if (!NT_STATUS_IS_OK(status) &&
767                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) break;
768
769                 for (i = 0; i < req.out.count; i++) {
770                         torture_comment(torture, "\tuser: %s, sid=%s\n",
771                                req.out.users[i].username, req.out.users[i].sid);
772                 }
773
774         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
775
776         if (!(NT_STATUS_IS_OK(status) ||
777               NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))) {
778                 torture_comment(torture, "libnet_UserList call failed: %s\n", nt_errstr(status));
779                 ret = false;
780                 goto done;
781         }
782
783         if (!test_samr_close(torture, ctx->samr.pipe->binding_handle, mem_ctx, &ctx->samr.handle)) {
784                 torture_comment(torture, "samr domain close failed\n");
785                 ret = false;
786                 goto done;
787         }
788
789         if (!test_lsa_close(torture, ctx->lsa.pipe->binding_handle, mem_ctx, &ctx->lsa.handle)) {
790                 torture_comment(torture, "lsa domain close failed\n");
791                 ret = false;
792         }
793
794         talloc_free(ctx);
795
796 done:
797         talloc_free(mem_ctx);
798         return ret;
799 }