7d1ba5fdaeeddc7109f40bc9a36e4953c582a20c
[samba.git] / source4 / torture / rpc / lsa.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for lsa rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
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 2 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, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "librpc/gen_ndr/ndr_lsa.h"
24
25 static void init_lsa_String(struct lsa_String *name, const char *s)
26 {
27         name->string = s;
28 }
29
30 static BOOL test_OpenPolicy(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
31 {
32         struct lsa_ObjectAttribute attr;
33         struct policy_handle handle;
34         struct lsa_QosInfo qos;
35         struct lsa_OpenPolicy r;
36         NTSTATUS status;
37         uint16_t system_name = '\\';
38
39         printf("\ntesting OpenPolicy\n");
40
41         qos.len = 0;
42         qos.impersonation_level = 2;
43         qos.context_mode = 1;
44         qos.effective_only = 0;
45
46         attr.len = 0;
47         attr.root_dir = NULL;
48         attr.object_name = NULL;
49         attr.attributes = 0;
50         attr.sec_desc = NULL;
51         attr.sec_qos = &qos;
52
53         r.in.system_name = &system_name;
54         r.in.attr = &attr;
55         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
56         r.out.handle = &handle;
57
58         status = dcerpc_lsa_OpenPolicy(p, mem_ctx, &r);
59         if (!NT_STATUS_IS_OK(status)) {
60                 printf("OpenPolicy failed - %s\n", nt_errstr(status));
61                 return False;
62         }
63
64         return True;
65 }
66
67
68 static BOOL test_OpenPolicy2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
69                              struct policy_handle *handle)
70 {
71         struct lsa_ObjectAttribute attr;
72         struct lsa_QosInfo qos;
73         struct lsa_OpenPolicy2 r;
74         NTSTATUS status;
75
76         printf("\ntesting OpenPolicy2\n");
77
78         qos.len = 0;
79         qos.impersonation_level = 2;
80         qos.context_mode = 1;
81         qos.effective_only = 0;
82
83         attr.len = 0;
84         attr.root_dir = NULL;
85         attr.object_name = NULL;
86         attr.attributes = 0;
87         attr.sec_desc = NULL;
88         attr.sec_qos = &qos;
89
90         r.in.system_name = "\\";
91         r.in.attr = &attr;
92         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
93         r.out.handle = handle;
94
95         status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r);
96         if (!NT_STATUS_IS_OK(status)) {
97                 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
98                 return False;
99         }
100
101         return True;
102 }
103
104 static BOOL test_LookupNames(struct dcerpc_pipe *p, 
105                             TALLOC_CTX *mem_ctx, 
106                             struct policy_handle *handle,
107                             struct lsa_TransNameArray *tnames)
108 {
109         struct lsa_LookupNames r;
110         struct lsa_TransSidArray sids;
111         struct lsa_String *names;
112         uint32_t count = 0;
113         NTSTATUS status;
114         int i;
115
116         printf("\nTesting LookupNames with %d names\n", tnames->count);
117
118         sids.count = 0;
119         sids.sids = NULL;
120
121         names = talloc_array_p(mem_ctx, struct lsa_String, tnames->count);
122         for (i=0;i<tnames->count;i++) {
123                 init_lsa_String(&names[i], tnames->names[i].name.string);
124         }
125
126         r.in.handle = handle;
127         r.in.num_names = tnames->count;
128         r.in.names = names;
129         r.in.sids = &sids;
130         r.in.level = 1;
131         r.in.count = &count;
132         r.out.count = &count;
133         r.out.sids = &sids;
134
135         status = dcerpc_lsa_LookupNames(p, mem_ctx, &r);
136         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
137                 printf("LookupNames failed - %s\n", nt_errstr(status));
138                 return False;
139         }
140
141         printf("\n");
142
143         return True;
144 }
145
146 static BOOL test_LookupNames2(struct dcerpc_pipe *p, 
147                               TALLOC_CTX *mem_ctx, 
148                               struct policy_handle *handle,
149                               struct lsa_TransNameArray2 *tnames)
150 {
151         struct lsa_LookupNames2 r;
152         struct lsa_TransSidArray2 sids;
153         struct lsa_String *names;
154         uint32_t count = 0;
155         NTSTATUS status;
156         int i;
157
158         printf("\nTesting LookupNames2 with %d names\n", tnames->count);
159
160         sids.count = 0;
161         sids.sids = NULL;
162
163         names = talloc_array_p(mem_ctx, struct lsa_String, tnames->count);
164         for (i=0;i<tnames->count;i++) {
165                 init_lsa_String(&names[i], tnames->names[i].name.string);
166         }
167
168         r.in.handle = handle;
169         r.in.num_names = tnames->count;
170         r.in.names = names;
171         r.in.sids = &sids;
172         r.in.level = 1;
173         r.in.count = &count;
174         r.in.unknown1 = 0;
175         r.in.unknown2 = 0;
176         r.out.count = &count;
177         r.out.sids = &sids;
178
179         status = dcerpc_lsa_LookupNames2(p, mem_ctx, &r);
180         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
181                 printf("LookupNames2 failed - %s\n", nt_errstr(status));
182                 return False;
183         }
184
185         printf("\n");
186
187         return True;
188 }
189
190
191 static BOOL test_LookupSids(struct dcerpc_pipe *p, 
192                             TALLOC_CTX *mem_ctx, 
193                             struct policy_handle *handle,
194                             struct lsa_SidArray *sids)
195 {
196         struct lsa_LookupSids r;
197         struct lsa_TransNameArray names;
198         uint32_t count = sids->num_sids;
199         NTSTATUS status;
200
201         printf("\nTesting LookupSids\n");
202
203         names.count = 0;
204         names.names = NULL;
205
206         r.in.handle = handle;
207         r.in.sids = sids;
208         r.in.names = &names;
209         r.in.level = 1;
210         r.in.count = &count;
211         r.out.count = &count;
212         r.out.names = &names;
213
214         status = dcerpc_lsa_LookupSids(p, mem_ctx, &r);
215         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
216                 printf("LookupSids failed - %s\n", nt_errstr(status));
217                 return False;
218         }
219
220         printf("\n");
221
222         if (!test_LookupNames(p, mem_ctx, handle, &names)) {
223                 return False;
224         }
225
226         return True;
227 }
228
229
230 static BOOL test_LookupSids2(struct dcerpc_pipe *p, 
231                             TALLOC_CTX *mem_ctx, 
232                             struct policy_handle *handle,
233                             struct lsa_SidArray *sids)
234 {
235         struct lsa_LookupSids2 r;
236         struct lsa_TransNameArray2 names;
237         uint32_t count = sids->num_sids;
238         NTSTATUS status;
239
240         printf("\nTesting LookupSids2\n");
241
242         names.count = 0;
243         names.names = NULL;
244
245         r.in.handle = handle;
246         r.in.sids = sids;
247         r.in.names = &names;
248         r.in.level = 1;
249         r.in.count = &count;
250         r.in.unknown1 = 0;
251         r.in.unknown2 = 0;
252         r.out.count = &count;
253         r.out.names = &names;
254
255         status = dcerpc_lsa_LookupSids2(p, mem_ctx, &r);
256         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
257                 printf("LookupSids2 failed - %s\n", nt_errstr(status));
258                 return False;
259         }
260
261         printf("\n");
262
263         if (!test_LookupNames2(p, mem_ctx, handle, &names)) {
264                 return False;
265         }
266
267         return True;
268 }
269
270 static BOOL test_many_LookupSids(struct dcerpc_pipe *p, 
271                                  TALLOC_CTX *mem_ctx, 
272                                  struct policy_handle *handle)
273 {
274         struct lsa_LookupSids r;
275         struct lsa_TransNameArray names;
276         uint32_t count;
277         NTSTATUS status;
278         struct lsa_SidArray sids;
279         int i;
280
281         printf("\nTesting LookupSids with lots of SIDs\n");
282
283         names.count = 0;
284         names.names = NULL;
285
286         sids.num_sids = 100;
287
288         sids.sids = talloc_array_p(mem_ctx, struct lsa_SidPtr, sids.num_sids);
289
290         for (i=0; i<sids.num_sids; i++) {
291                 const char *sidstr = "S-1-5-32-545";
292                 sids.sids[i].sid = dom_sid_parse_talloc(mem_ctx, sidstr);
293         }
294
295         count = sids.num_sids;
296
297         r.in.handle = handle;
298         r.in.sids = &sids;
299         r.in.names = &names;
300         r.in.level = 1;
301         r.in.count = &names.count;
302         r.out.count = &count;
303         r.out.names = &names;
304
305         status = dcerpc_lsa_LookupSids(p, mem_ctx, &r);
306         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
307                 printf("LookupSids failed - %s\n", nt_errstr(status));
308                 return False;
309         }
310
311         printf("\n");
312
313         if (!test_LookupNames(p, mem_ctx, handle, &names)) {
314                 return False;
315         }
316
317         return True;
318 }
319
320 static BOOL test_LookupPrivValue(struct dcerpc_pipe *p, 
321                                  TALLOC_CTX *mem_ctx, 
322                                  struct policy_handle *handle,
323                                  struct lsa_String *name)
324 {
325         NTSTATUS status;
326         struct lsa_LookupPrivValue r;
327         struct lsa_LUID luid;
328
329         r.in.handle = handle;
330         r.in.name = name;
331         r.out.luid = &luid;
332
333         status = dcerpc_lsa_LookupPrivValue(p, mem_ctx, &r);
334         if (!NT_STATUS_IS_OK(status)) {
335                 printf("\nLookupPrivValue failed - %s\n", nt_errstr(status));
336                 return False;
337         }
338
339         return True;
340 }
341
342 static BOOL test_LookupPrivName(struct dcerpc_pipe *p, 
343                                 TALLOC_CTX *mem_ctx, 
344                                 struct policy_handle *handle,
345                                 struct lsa_LUID *luid)
346 {
347         NTSTATUS status;
348         struct lsa_LookupPrivName r;
349
350         r.in.handle = handle;
351         r.in.luid = luid;
352
353         status = dcerpc_lsa_LookupPrivName(p, mem_ctx, &r);
354         if (!NT_STATUS_IS_OK(status)) {
355                 printf("\nLookupPrivName failed - %s\n", nt_errstr(status));
356                 return False;
357         }
358
359         return True;
360 }
361
362 static BOOL test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, 
363                                              TALLOC_CTX *mem_ctx,                                 
364                                              struct policy_handle *acct_handle,
365                                              struct lsa_LUID *luid)
366 {
367         NTSTATUS status;
368         struct lsa_RemovePrivilegesFromAccount r;
369         struct lsa_PrivilegeSet privs;
370         BOOL ret = True;
371
372         printf("Testing RemovePrivilegesFromAccount\n");
373
374         r.in.handle = acct_handle;
375         r.in.remove_all = 0;
376         r.in.privs = &privs;
377
378         privs.count = 1;
379         privs.unknown = 0;
380         privs.set = talloc_array_p(mem_ctx, struct lsa_LUIDAttribute, 1);
381         privs.set[0].luid = *luid;
382         privs.set[0].attribute = 0;
383
384         status = dcerpc_lsa_RemovePrivilegesFromAccount(p, mem_ctx, &r);
385         if (!NT_STATUS_IS_OK(status)) {
386                 printf("RemovePrivilegesFromAccount failed - %s\n", nt_errstr(status));
387                 return False;
388         }
389
390         return ret;
391 }
392
393 static BOOL test_AddPrivilegesToAccount(struct dcerpc_pipe *p, 
394                                         TALLOC_CTX *mem_ctx,                              
395                                         struct policy_handle *acct_handle,
396                                         struct lsa_LUID *luid)
397 {
398         NTSTATUS status;
399         struct lsa_AddPrivilegesToAccount r;
400         struct lsa_PrivilegeSet privs;
401         BOOL ret = True;
402
403         printf("Testing AddPrivilegesToAccount\n");
404
405         r.in.handle = acct_handle;
406         r.in.privs = &privs;
407
408         privs.count = 1;
409         privs.unknown = 0;
410         privs.set = talloc_array_p(mem_ctx, struct lsa_LUIDAttribute, 1);
411         privs.set[0].luid = *luid;
412         privs.set[0].attribute = 0;
413
414         status = dcerpc_lsa_AddPrivilegesToAccount(p, mem_ctx, &r);
415         if (!NT_STATUS_IS_OK(status)) {
416                 printf("AddPrivilegesToAccount failed - %s\n", nt_errstr(status));
417                 return False;
418         }
419
420         return ret;
421 }
422
423 static BOOL test_EnumPrivsAccount(struct dcerpc_pipe *p, 
424                                   TALLOC_CTX *mem_ctx,                            
425                                   struct policy_handle *handle,
426                                   struct policy_handle *acct_handle)
427 {
428         NTSTATUS status;
429         struct lsa_EnumPrivsAccount r;
430         BOOL ret = True;
431
432         printf("Testing EnumPrivsAccount\n");
433
434         r.in.handle = acct_handle;
435
436         status = dcerpc_lsa_EnumPrivsAccount(p, mem_ctx, &r);
437         if (!NT_STATUS_IS_OK(status)) {
438                 printf("EnumPrivsAccount failed - %s\n", nt_errstr(status));
439                 return False;
440         }
441
442         if (r.out.privs && r.out.privs->count > 0) {
443                 int i;
444                 for (i=0;i<r.out.privs->count;i++) {
445                         test_LookupPrivName(p, mem_ctx, handle, 
446                                             &r.out.privs->set[i].luid);
447                 }
448
449                 ret &= test_RemovePrivilegesFromAccount(p, mem_ctx, acct_handle, 
450                                                         &r.out.privs->set[0].luid);
451                 ret &= test_AddPrivilegesToAccount(p, mem_ctx, acct_handle, 
452                                                    &r.out.privs->set[0].luid);
453         }
454
455         return ret;
456 }
457
458 static BOOL test_Delete(struct dcerpc_pipe *p, 
459                        TALLOC_CTX *mem_ctx, 
460                        struct policy_handle *handle)
461 {
462         NTSTATUS status;
463         struct lsa_Delete r;
464
465         printf("\ntesting Delete\n");
466
467         r.in.handle = handle;
468         status = dcerpc_lsa_Delete(p, mem_ctx, &r);
469         if (!NT_STATUS_IS_OK(status)) {
470                 printf("Delete failed - %s\n", nt_errstr(status));
471                 return False;
472         }
473
474         printf("\n");
475
476         return True;
477 }
478
479
480 static BOOL test_CreateAccount(struct dcerpc_pipe *p, 
481                                TALLOC_CTX *mem_ctx, 
482                                struct policy_handle *handle)
483 {
484         NTSTATUS status;
485         struct lsa_CreateAccount r;
486         struct dom_sid2 *newsid;
487         struct policy_handle acct_handle;
488
489         newsid = dom_sid_parse_talloc(mem_ctx, "S-1-5-12349876-4321-2854");
490
491         printf("Testing CreateAccount\n");
492
493         r.in.handle = handle;
494         r.in.sid = newsid;
495         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
496         r.out.acct_handle = &acct_handle;
497
498         status = dcerpc_lsa_CreateAccount(p, mem_ctx, &r);
499         if (!NT_STATUS_IS_OK(status)) {
500                 printf("CreateAccount failed - %s\n", nt_errstr(status));
501                 return False;
502         }
503
504         if (!test_Delete(p, mem_ctx, &acct_handle)) {
505                 return False;
506         }
507
508         return True;
509 }
510
511
512 static BOOL test_CreateTrustedDomain(struct dcerpc_pipe *p, 
513                                      TALLOC_CTX *mem_ctx, 
514                                      struct policy_handle *handle)
515 {
516         NTSTATUS status;
517         struct lsa_CreateTrustedDomain r;
518         struct lsa_TrustInformation trustinfo;
519         struct dom_sid *domsid;
520         struct policy_handle dom_handle;
521
522         printf("Testing CreateTrustedDomain\n");
523
524         domsid = dom_sid_parse_talloc(mem_ctx, "S-1-5-21-97398-379795-12345");
525
526         trustinfo.sid = domsid;
527         init_lsa_String(&trustinfo.name, "torturedomain");
528
529         r.in.handle = handle;
530         r.in.info = &trustinfo;
531         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
532         r.out.dom_handle = &dom_handle;
533
534         status = dcerpc_lsa_CreateTrustedDomain(p, mem_ctx, &r);
535         if (!NT_STATUS_IS_OK(status)) {
536                 printf("CreateTrustedDomain failed - %s\n", nt_errstr(status));
537                 return False;
538         }
539
540         if (!test_Delete(p, mem_ctx, &dom_handle)) {
541                 return False;
542         }
543
544         return True;
545 }
546
547 static BOOL test_CreateSecret(struct dcerpc_pipe *p, 
548                               TALLOC_CTX *mem_ctx, 
549                               struct policy_handle *handle)
550 {
551         NTSTATUS status;
552         struct lsa_CreateSecret r;
553         struct lsa_OpenSecret r2;
554         struct lsa_SetSecret r3;
555         struct lsa_QuerySecret r4;
556         struct policy_handle sec_handle, sec_handle2;
557         struct lsa_Delete d;
558         struct lsa_DATA_BUF buf1;
559         struct lsa_DATA_BUF_PTR bufp1;
560         DATA_BLOB enc_key;
561         BOOL ret = True;
562         DATA_BLOB session_key;
563         NTTIME old_mtime, new_mtime;
564         DATA_BLOB blob1, blob2;
565         const char *secret1 = "abcdef12345699qwerty";
566         char *secret2;
567         char *secname;
568
569         printf("Testing CreateSecret\n");
570
571         asprintf(&secname, "torturesecret-%u", (uint_t)random());
572
573         init_lsa_String(&r.in.name, secname);
574
575         r.in.handle = handle;
576         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
577         r.out.sec_handle = &sec_handle;
578
579         status = dcerpc_lsa_CreateSecret(p, mem_ctx, &r);
580         if (!NT_STATUS_IS_OK(status)) {
581                 printf("CreateSecret failed - %s\n", nt_errstr(status));
582                 return False;
583         }
584
585         r2.in.handle = handle;
586         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
587         r2.in.name = r.in.name;
588         r2.out.sec_handle = &sec_handle2;
589
590         printf("Testing OpenSecret\n");
591
592         status = dcerpc_lsa_OpenSecret(p, mem_ctx, &r2);
593         if (!NT_STATUS_IS_OK(status)) {
594                 printf("OpenSecret failed - %s\n", nt_errstr(status));
595                 ret = False;
596         }
597
598         status = dcerpc_fetch_session_key(p, &session_key);
599         if (!NT_STATUS_IS_OK(status)) {
600                 printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
601                 ret = False;
602         }
603
604         enc_key = sess_encrypt_string(secret1, &session_key);
605
606         r3.in.handle = &sec_handle;
607         r3.in.new_val = &buf1;
608         r3.in.old_val = NULL;
609         r3.in.new_val->data = enc_key.data;
610         r3.in.new_val->length = enc_key.length;
611         r3.in.new_val->size = enc_key.length;
612
613         printf("Testing SetSecret\n");
614
615         status = dcerpc_lsa_SetSecret(p, mem_ctx, &r3);
616         if (!NT_STATUS_IS_OK(status)) {
617                 printf("SetSecret failed - %s\n", nt_errstr(status));
618                 ret = False;
619         }
620
621         data_blob_free(&enc_key);
622
623         ZERO_STRUCT(new_mtime);
624         ZERO_STRUCT(old_mtime);
625
626         /* fetch the secret back again */
627         r4.in.handle = &sec_handle;
628         r4.in.new_val = &bufp1;
629         r4.in.new_mtime = &new_mtime;
630         r4.in.old_val = NULL;
631         r4.in.old_mtime = NULL;
632
633         bufp1.buf = NULL;
634
635         status = dcerpc_lsa_QuerySecret(p, mem_ctx, &r4);
636         if (!NT_STATUS_IS_OK(status)) {
637                 printf("QuerySecret failed - %s\n", nt_errstr(status));
638                 ret = False;
639         }
640
641         if (r4.out.new_val->buf == NULL) {
642                 printf("No secret buffer returned\n");
643                 ret = False;
644         } else {
645                 blob1.data = r4.out.new_val->buf->data;
646                 blob1.length = r4.out.new_val->buf->length;
647
648                 blob2 = data_blob(NULL, blob1.length);
649
650                 secret2 = sess_decrypt_string(&blob1, &session_key);
651
652                 printf("returned secret '%s'\n", secret2);
653
654                 if (strcmp(secret1, secret2) != 0) {
655                         printf("Returned secret doesn't match\n");
656                         ret = False;
657                 }
658         }
659
660         if (!test_Delete(p, mem_ctx, &sec_handle)) {
661                 ret = False;
662         }
663
664         d.in.handle = &sec_handle2;
665         status = dcerpc_lsa_Delete(p, mem_ctx, &d);
666         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
667                 printf("Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status));
668                 ret = False;
669         }
670
671         return ret;
672 }
673
674
675 static BOOL test_EnumAccountRights(struct dcerpc_pipe *p, 
676                                    TALLOC_CTX *mem_ctx, 
677                                    struct policy_handle *acct_handle,
678                                    struct dom_sid *sid)
679 {
680         NTSTATUS status;
681         struct lsa_EnumAccountRights r;
682         struct lsa_RightSet rights;
683
684         printf("Testing EnumAccountRights\n");
685
686         r.in.handle = acct_handle;
687         r.in.sid = sid;
688         r.out.rights = &rights;
689
690         status = dcerpc_lsa_EnumAccountRights(p, mem_ctx, &r);
691         if (!NT_STATUS_IS_OK(status)) {
692                 printf("EnumAccountRights failed - %s\n", nt_errstr(status));
693                 return False;
694         }
695
696         return True;
697 }
698
699
700 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, 
701                              TALLOC_CTX *mem_ctx, 
702                              struct policy_handle *handle,
703                              struct policy_handle *acct_handle)
704 {
705         NTSTATUS status;
706         struct lsa_QuerySecurity r;
707
708         printf("Testing QuerySecurity\n");
709
710         r.in.handle = acct_handle;
711         r.in.sec_info = 7;
712
713         status = dcerpc_lsa_QuerySecurity(p, mem_ctx, &r);
714         if (!NT_STATUS_IS_OK(status)) {
715                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
716                 return False;
717         }
718
719         return True;
720 }
721
722 static BOOL test_OpenAccount(struct dcerpc_pipe *p, 
723                              TALLOC_CTX *mem_ctx, 
724                              struct policy_handle *handle,
725                              struct dom_sid *sid)
726 {
727         NTSTATUS status;
728         struct lsa_OpenAccount r;
729         struct policy_handle acct_handle;
730
731         printf("Testing OpenAccount\n");
732
733         r.in.handle = handle;
734         r.in.sid = sid;
735         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
736         r.out.acct_handle = &acct_handle;
737
738         status = dcerpc_lsa_OpenAccount(p, mem_ctx, &r);
739         if (!NT_STATUS_IS_OK(status)) {
740                 printf("OpenAccount failed - %s\n", nt_errstr(status));
741                 return False;
742         }
743
744         if (!test_EnumPrivsAccount(p, mem_ctx, handle, &acct_handle)) {
745                 return False;
746         }
747
748         if (!test_QuerySecurity(p, mem_ctx, handle, &acct_handle)) {
749                 return False;
750         }
751
752         return True;
753 }
754
755 static BOOL test_EnumAccounts(struct dcerpc_pipe *p, 
756                           TALLOC_CTX *mem_ctx, 
757                           struct policy_handle *handle)
758 {
759         NTSTATUS status;
760         struct lsa_EnumAccounts r;
761         struct lsa_SidArray sids1, sids2;
762         uint32_t resume_handle = 0;
763         int i;
764
765         printf("\ntesting EnumAccounts\n");
766
767         r.in.handle = handle;
768         r.in.resume_handle = &resume_handle;
769         r.in.num_entries = 100;
770         r.out.resume_handle = &resume_handle;
771         r.out.sids = &sids1;
772
773         resume_handle = 0;
774         while (True) {
775                 status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
776                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
777                         break;
778                 }
779                 if (!NT_STATUS_IS_OK(status)) {
780                         printf("EnumAccounts failed - %s\n", nt_errstr(status));
781                         return False;
782                 }
783
784                 if (!test_LookupSids(p, mem_ctx, handle, &sids1)) {
785                         return False;
786                 }
787
788                 if (!test_LookupSids2(p, mem_ctx, handle, &sids1)) {
789                         return False;
790                 }
791
792                 printf("testing all accounts\n");
793                 for (i=0;i<sids1.num_sids;i++) {
794                         test_OpenAccount(p, mem_ctx, handle, sids1.sids[i].sid);
795                         test_EnumAccountRights(p, mem_ctx, handle, sids1.sids[i].sid);
796                 }
797                 printf("\n");
798         }
799
800         if (sids1.num_sids < 3) {
801                 return True;
802         }
803         
804         printf("trying EnumAccounts partial listing (asking for 1 at 2)\n");
805         resume_handle = 2;
806         r.in.num_entries = 1;
807         r.out.sids = &sids2;
808
809         status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
810         if (!NT_STATUS_IS_OK(status)) {
811                 printf("EnumAccounts failed - %s\n", nt_errstr(status));
812                 return False;
813         }
814
815         if (sids2.num_sids != 1) {
816                 printf("Returned wrong number of entries (%d)\n", sids2.num_sids);
817                 return False;
818         }
819
820         return True;
821 }
822
823 static BOOL test_LookupPrivDisplayName(struct dcerpc_pipe *p,
824                                 TALLOC_CTX *mem_ctx,
825                                 struct policy_handle *handle,
826                                 struct lsa_String *priv_name)
827 {
828         struct lsa_LookupPrivDisplayName r;
829         NTSTATUS status;
830         /* produce a reasonable range of language output without screwing up
831            terminals */
832         uint16 language_id = (random() % 4) + 0x409;
833
834         printf("testing LookupPrivDisplayName(%s)\n", priv_name->string);
835         
836         r.in.handle = handle;
837         r.in.name = priv_name;
838         r.in.language_id = &language_id;
839         r.out.language_id = &language_id;
840         r.in.unknown = 0;
841
842         status = dcerpc_lsa_LookupPrivDisplayName(p, mem_ctx, &r);
843         if (!NT_STATUS_IS_OK(status)) {
844                 printf("LookupPrivDisplayName failed - %s\n", nt_errstr(status));
845                 return False;
846         }
847         printf("%s -> \"%s\"  (language 0x%x/0x%x)\n", 
848                priv_name->string, r.out.disp_name->string, 
849                *r.in.language_id, *r.out.language_id);
850
851         return True;
852 }
853
854 static BOOL test_EnumAccountsWithUserRight(struct dcerpc_pipe *p, 
855                                 TALLOC_CTX *mem_ctx,
856                                 struct policy_handle *handle,
857                                 struct lsa_String *priv_name)
858 {
859         struct lsa_EnumAccountsWithUserRight r;
860         struct lsa_SidArray sids;
861         NTSTATUS status;
862
863         ZERO_STRUCT(sids);
864         
865         printf("testing EnumAccountsWithUserRight(%s)\n", priv_name->string);
866         
867         r.in.handle = handle;
868         r.in.name = priv_name;
869         r.out.sids = &sids;
870
871         status = dcerpc_lsa_EnumAccountsWithUserRight(p, mem_ctx, &r);
872
873         /* NT_STATUS_NO_MORE_ENTRIES means noone has this privilege */
874         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
875                 return True;
876         }
877
878         if (!NT_STATUS_IS_OK(status)) {
879                 printf("EnumAccountsWithUserRight failed - %s\n", nt_errstr(status));
880                 return False;
881         }
882         
883         return True;
884 }
885
886
887 static BOOL test_EnumPrivs(struct dcerpc_pipe *p, 
888                            TALLOC_CTX *mem_ctx, 
889                            struct policy_handle *handle)
890 {
891         NTSTATUS status;
892         struct lsa_EnumPrivs r;
893         struct lsa_PrivArray privs1;
894         uint32_t resume_handle = 0;
895         int i;
896         BOOL ret = True;
897
898         printf("\ntesting EnumPrivs\n");
899
900         r.in.handle = handle;
901         r.in.resume_handle = &resume_handle;
902         r.in.max_count = 100;
903         r.out.resume_handle = &resume_handle;
904         r.out.privs = &privs1;
905
906         resume_handle = 0;
907         status = dcerpc_lsa_EnumPrivs(p, mem_ctx, &r);
908         if (!NT_STATUS_IS_OK(status)) {
909                 printf("EnumPrivs failed - %s\n", nt_errstr(status));
910                 return False;
911         }
912
913         for (i = 0; i< privs1.count; i++) {
914                 test_LookupPrivDisplayName(p, mem_ctx, handle, &privs1.privs[i].name);
915                 test_LookupPrivValue(p, mem_ctx, handle, &privs1.privs[i].name);
916                 if (!test_EnumAccountsWithUserRight(p, mem_ctx, handle, &privs1.privs[i].name)) {
917                         ret = False;
918                 }
919         }
920
921         return ret;
922 }
923
924
925 static BOOL test_EnumTrustDom(struct dcerpc_pipe *p, 
926                               TALLOC_CTX *mem_ctx, 
927                               struct policy_handle *handle)
928 {
929         struct lsa_EnumTrustDom r;
930         NTSTATUS status;
931         uint32_t resume_handle = 0;
932         struct lsa_DomainList domains;
933         int i,j;
934         BOOL ret = True;
935
936         printf("\nTesting EnumTrustDom\n");
937
938         r.in.handle = handle;
939         r.in.resume_handle = &resume_handle;
940         r.in.num_entries = 100;
941         r.out.domains = &domains;
942         r.out.resume_handle = &resume_handle;
943
944         status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r);
945
946         /* NO_MORE_ENTRIES is allowed */
947         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
948                 return True;
949         }
950
951         if (!NT_STATUS_IS_OK(status)) {
952                 printf("EnumTrustDom failed - %s\n", nt_errstr(status));
953                 return False;
954         }
955
956         printf("\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
957
958         for (i=0; i< domains.count; i++) {
959                 struct lsa_OpenTrustedDomain trust;
960                 struct lsa_OpenTrustedDomainByName trust_by_name;
961                 struct policy_handle trustdom_handle;
962                 struct policy_handle handle2;
963                 struct lsa_Close c;
964                 int levels [] = {1, 3, 6, 8, 12};
965                 
966                 trust.in.handle = handle;
967                 trust.in.sid = domains.domains[i].sid;
968                 trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
969                 trust.out.trustdom_handle = &trustdom_handle;
970
971                 status = dcerpc_lsa_OpenTrustedDomain(p, mem_ctx, &trust);
972
973                 if (!NT_STATUS_IS_OK(status)) {
974                         printf("OpenTrustedDomain failed - %s\n", nt_errstr(status));
975                         return False;
976                 }
977
978                 c.in.handle = &trustdom_handle;
979                 c.out.handle = &handle2;
980                 
981                 for (j=0; j < ARRAY_SIZE(levels); j++) {
982                         struct lsa_QueryTrustedDomainInfo q;
983                         union lsa_TrustedDomainInfo info;
984                         q.in.trustdom_handle = &trustdom_handle;
985                         q.in.level = levels[j];
986                         q.out.info = &info;
987                         status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
988                         if (!NT_STATUS_IS_OK(status)) {
989                                 printf("QueryTrustedDomainInfo level %d failed - %s\n", 
990                                        levels[j], nt_errstr(status));
991                                 ret = False;
992                         }
993                 }
994                 
995                 status = dcerpc_lsa_Close(p, mem_ctx, &c);
996                 if (!NT_STATUS_IS_OK(status)) {
997                         printf("Close of trusted domain failed - %s\n", nt_errstr(status));
998                         return False;
999                 }
1000
1001                 trust_by_name.in.handle = handle;
1002                 trust_by_name.in.name = domains.domains[i].name;
1003                 trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1004                 trust_by_name.out.trustdom_handle = &trustdom_handle;
1005                 
1006                 status = dcerpc_lsa_OpenTrustedDomainByName(p, mem_ctx, &trust_by_name);
1007
1008                 if (!NT_STATUS_IS_OK(status)) {
1009                         printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
1010                         return False;
1011                 }
1012
1013                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1014                         struct lsa_QueryTrustedDomainInfo q;
1015                         union lsa_TrustedDomainInfo info;
1016                         q.in.trustdom_handle = &trustdom_handle;
1017                         q.in.level = levels[j];
1018                         q.out.info = &info;
1019                         status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
1020                         if (!NT_STATUS_IS_OK(status)) {
1021                                 printf("QueryTrustedDomainInfo level %d failed - %s\n", 
1022                                        levels[j], nt_errstr(status));
1023                                 ret = False;
1024                         }
1025                 }
1026                 
1027                 c.in.handle = &trustdom_handle;
1028                 c.out.handle = &handle2;
1029
1030                 status = dcerpc_lsa_Close(p, mem_ctx, &c);
1031                 if (!NT_STATUS_IS_OK(status)) {
1032                         printf("Close of trusted domain failed - %s\n", nt_errstr(status));
1033                         return False;
1034                 }
1035
1036                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1037                         struct lsa_QueryTrustedDomainInfoBySid q;
1038                         union lsa_TrustedDomainInfo info;
1039                         q.in.handle  = handle;
1040                         q.in.dom_sid = domains.domains[i].sid;
1041                         q.in.level   = levels[j];
1042                         q.out.info   = &info;
1043                         status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, mem_ctx, &q);
1044                         if (!NT_STATUS_IS_OK(status)) {
1045                                 printf("QueryTrustedDomainInfoBySid level %d failed - %s\n", 
1046                                        levels[j], nt_errstr(status));
1047                                 ret = False;
1048                         }
1049                 }
1050                 
1051                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1052                         struct lsa_QueryTrustedDomainInfoByName q;
1053                         union lsa_TrustedDomainInfo info;
1054                         q.in.handle         = handle;
1055                         q.in.trusted_domain = domains.domains[i].name;
1056                         q.in.level          = levels[j];
1057                         q.out.info          = &info;
1058                         status = dcerpc_lsa_QueryTrustedDomainInfoByName(p, mem_ctx, &q);
1059                         if (!NT_STATUS_IS_OK(status)) {
1060                                 printf("QueryTrustedDomainInfoByName level %d failed - %s\n", 
1061                                        levels[j], nt_errstr(status));
1062                                 ret = False;
1063                         }
1064                 }
1065                 
1066                 
1067
1068         }
1069
1070         return ret;
1071 }
1072
1073 static BOOL test_QueryInfoPolicy(struct dcerpc_pipe *p, 
1074                                  TALLOC_CTX *mem_ctx, 
1075                                  struct policy_handle *handle)
1076 {
1077         struct lsa_QueryInfoPolicy r;
1078         NTSTATUS status;
1079         int i;
1080         BOOL ret = True;
1081         printf("\nTesting QueryInfoPolicy\n");
1082
1083         for (i=1;i<13;i++) {
1084                 r.in.handle = handle;
1085                 r.in.level = i;
1086
1087                 printf("\ntrying QueryInfoPolicy level %d\n", i);
1088
1089                 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
1090
1091                 if ((i == 9 || i == 10 || i == 11) &&
1092                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1093                         printf("server failed level %u (OK)\n", i);
1094                         continue;
1095                 }
1096
1097                 if (!NT_STATUS_IS_OK(status)) {
1098                         printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
1099                         ret = False;
1100                         continue;
1101                 }
1102         }
1103
1104         return ret;
1105 }
1106
1107 static BOOL test_QueryInfoPolicy2(struct dcerpc_pipe *p, 
1108                                   TALLOC_CTX *mem_ctx, 
1109                                   struct policy_handle *handle)
1110 {
1111         struct lsa_QueryInfoPolicy2 r;
1112         NTSTATUS status;
1113         int i;
1114         BOOL ret = True;
1115         printf("\nTesting QueryInfoPolicy2\n");
1116
1117         for (i=1;i<13;i++) {
1118                 r.in.handle = handle;
1119                 r.in.level = i;
1120
1121                 printf("\ntrying QueryInfoPolicy2 level %d\n", i);
1122
1123                 status = dcerpc_lsa_QueryInfoPolicy2(p, mem_ctx, &r);
1124
1125                 if ((i == 9 || i == 10 || i == 11) &&
1126                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1127                         printf("server failed level %u (OK)\n", i);
1128                         continue;
1129                 }
1130
1131                 if (!NT_STATUS_IS_OK(status)) {
1132                         printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
1133                         ret = False;
1134                         continue;
1135                 }
1136         }
1137
1138         return ret;
1139 }
1140
1141 static BOOL test_GetUserName(struct dcerpc_pipe *p, 
1142                                   TALLOC_CTX *mem_ctx, 
1143                                   struct policy_handle *handle)
1144 {
1145         struct lsa_GetUserName r;
1146         NTSTATUS status;
1147         BOOL ret = True;
1148         struct lsa_StringPointer authority_name_p;
1149
1150         printf("\nTesting GetUserName\n");
1151
1152         r.in.system_name = "\\";        
1153         r.in.account_name = NULL;       
1154         r.in.authority_name = &authority_name_p;
1155         authority_name_p.string = NULL;
1156
1157         status = dcerpc_lsa_GetUserName(p, mem_ctx, &r);
1158
1159         if (!NT_STATUS_IS_OK(status)) {
1160                 printf("GetUserName failed - %s\n", nt_errstr(status));
1161                 ret = False;
1162         }
1163
1164         return ret;
1165 }
1166
1167 static BOOL test_Close(struct dcerpc_pipe *p, 
1168                        TALLOC_CTX *mem_ctx, 
1169                        struct policy_handle *handle)
1170 {
1171         NTSTATUS status;
1172         struct lsa_Close r;
1173         struct policy_handle handle2;
1174
1175         printf("\ntesting Close\n");
1176
1177         r.in.handle = handle;
1178         r.out.handle = &handle2;
1179
1180         status = dcerpc_lsa_Close(p, mem_ctx, &r);
1181         if (!NT_STATUS_IS_OK(status)) {
1182                 printf("Close failed - %s\n", nt_errstr(status));
1183                 return False;
1184         }
1185
1186         status = dcerpc_lsa_Close(p, mem_ctx, &r);
1187         /* its really a fault - we need a status code for rpc fault */
1188         if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1189                 printf("Close failed - %s\n", nt_errstr(status));
1190                 return False;
1191         }
1192
1193         printf("\n");
1194
1195         return True;
1196 }
1197
1198 BOOL torture_rpc_lsa(void)
1199 {
1200         NTSTATUS status;
1201         struct dcerpc_pipe *p;
1202         TALLOC_CTX *mem_ctx;
1203         BOOL ret = True;
1204         struct policy_handle handle;
1205
1206         mem_ctx = talloc_init("torture_rpc_lsa");
1207
1208         status = torture_rpc_connection(&p, 
1209                                         DCERPC_LSARPC_NAME, 
1210                                         DCERPC_LSARPC_UUID, 
1211                                         DCERPC_LSARPC_VERSION);
1212         if (!NT_STATUS_IS_OK(status)) {
1213                 return False;
1214         }
1215
1216         if (!test_OpenPolicy(p, mem_ctx)) {
1217                 ret = False;
1218         }
1219
1220         if (!test_OpenPolicy2(p, mem_ctx, &handle)) {
1221                 ret = False;
1222         }
1223
1224         if (!test_many_LookupSids(p, mem_ctx, &handle)) {
1225                 ret = False;
1226         }
1227
1228         if (!test_CreateAccount(p, mem_ctx, &handle)) {
1229                 ret = False;
1230         }
1231
1232         if (!test_CreateSecret(p, mem_ctx, &handle)) {
1233                 ret = False;
1234         }
1235
1236         if (!test_CreateTrustedDomain(p, mem_ctx, &handle)) {
1237                 ret = False;
1238         }
1239
1240         if (!test_EnumAccounts(p, mem_ctx, &handle)) {
1241                 ret = False;
1242         }
1243
1244         if (!test_EnumPrivs(p, mem_ctx, &handle)) {
1245                 ret = False;
1246         }
1247
1248         if (!test_EnumTrustDom(p, mem_ctx, &handle)) {
1249                 ret = False;
1250         }
1251
1252         if (!test_QueryInfoPolicy(p, mem_ctx, &handle)) {
1253                 ret = False;
1254         }
1255
1256         if (!test_QueryInfoPolicy2(p, mem_ctx, &handle)) {
1257                 ret = False;
1258         }
1259
1260         if (!test_GetUserName(p, mem_ctx, &handle)) {
1261                 ret = False;
1262         }
1263
1264 #if 0
1265         if (!test_Delete(p, mem_ctx, &handle)) {
1266                 ret = False;
1267         }
1268 #endif
1269         
1270         if (!test_Close(p, mem_ctx, &handle)) {
1271                 ret = False;
1272         }
1273
1274         talloc_destroy(mem_ctx);
1275
1276         torture_rpc_close(p);
1277
1278         return ret;
1279 }