r7685: Simply the test for session key logic, so we pass against NT4.
[ira/wip.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    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "librpc/gen_ndr/ndr_lsa.h"
25
26 static void init_lsa_String(struct lsa_String *name, const char *s)
27 {
28         name->string = s;
29 }
30
31 static BOOL test_OpenPolicy(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
32 {
33         struct lsa_ObjectAttribute attr;
34         struct policy_handle handle;
35         struct lsa_QosInfo qos;
36         struct lsa_OpenPolicy r;
37         NTSTATUS status;
38         uint16_t system_name = '\\';
39
40         printf("\ntesting OpenPolicy\n");
41
42         qos.len = 0;
43         qos.impersonation_level = 2;
44         qos.context_mode = 1;
45         qos.effective_only = 0;
46
47         attr.len = 0;
48         attr.root_dir = NULL;
49         attr.object_name = NULL;
50         attr.attributes = 0;
51         attr.sec_desc = NULL;
52         attr.sec_qos = &qos;
53
54         r.in.system_name = &system_name;
55         r.in.attr = &attr;
56         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
57         r.out.handle = &handle;
58
59         status = dcerpc_lsa_OpenPolicy(p, mem_ctx, &r);
60         if (!NT_STATUS_IS_OK(status)) {
61                 printf("OpenPolicy failed - %s\n", nt_errstr(status));
62                 return False;
63         }
64
65         return True;
66 }
67
68
69 BOOL test_lsa_OpenPolicy2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
70                           struct policy_handle *handle)
71 {
72         struct lsa_ObjectAttribute attr;
73         struct lsa_QosInfo qos;
74         struct lsa_OpenPolicy2 r;
75         NTSTATUS status;
76
77         printf("\ntesting OpenPolicy2\n");
78
79         qos.len = 0;
80         qos.impersonation_level = 2;
81         qos.context_mode = 1;
82         qos.effective_only = 0;
83
84         attr.len = 0;
85         attr.root_dir = NULL;
86         attr.object_name = NULL;
87         attr.attributes = 0;
88         attr.sec_desc = NULL;
89         attr.sec_qos = &qos;
90
91         r.in.system_name = "\\";
92         r.in.attr = &attr;
93         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
94         r.out.handle = handle;
95
96         status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r);
97         if (!NT_STATUS_IS_OK(status)) {
98                 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
99                 return False;
100         }
101
102         return True;
103 }
104
105 static BOOL test_LookupNames(struct dcerpc_pipe *p, 
106                             TALLOC_CTX *mem_ctx, 
107                             struct policy_handle *handle,
108                             struct lsa_TransNameArray *tnames)
109 {
110         struct lsa_LookupNames r;
111         struct lsa_TransSidArray sids;
112         struct lsa_String *names;
113         uint32_t count = 0;
114         NTSTATUS status;
115         int i;
116
117         printf("\nTesting LookupNames with %d names\n", tnames->count);
118
119         sids.count = 0;
120         sids.sids = NULL;
121
122         names = talloc_array(mem_ctx, struct lsa_String, tnames->count);
123         for (i=0;i<tnames->count;i++) {
124                 init_lsa_String(&names[i], tnames->names[i].name.string);
125         }
126
127         r.in.handle = handle;
128         r.in.num_names = tnames->count;
129         r.in.names = names;
130         r.in.sids = &sids;
131         r.in.level = 1;
132         r.in.count = &count;
133         r.out.count = &count;
134         r.out.sids = &sids;
135
136         status = dcerpc_lsa_LookupNames(p, mem_ctx, &r);
137         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
138                 printf("LookupNames failed - %s\n", nt_errstr(status));
139                 return False;
140         }
141
142         printf("\n");
143
144         return True;
145 }
146
147 static BOOL test_LookupNames2(struct dcerpc_pipe *p, 
148                               TALLOC_CTX *mem_ctx, 
149                               struct policy_handle *handle,
150                               struct lsa_TransNameArray2 *tnames)
151 {
152         struct lsa_LookupNames2 r;
153         struct lsa_TransSidArray2 sids;
154         struct lsa_String *names;
155         uint32_t count = 0;
156         NTSTATUS status;
157         int i;
158
159         printf("\nTesting LookupNames2 with %d names\n", tnames->count);
160
161         sids.count = 0;
162         sids.sids = NULL;
163
164         names = talloc_array(mem_ctx, struct lsa_String, tnames->count);
165         for (i=0;i<tnames->count;i++) {
166                 init_lsa_String(&names[i], tnames->names[i].name.string);
167         }
168
169         r.in.handle = handle;
170         r.in.num_names = tnames->count;
171         r.in.names = names;
172         r.in.sids = &sids;
173         r.in.level = 1;
174         r.in.count = &count;
175         r.in.unknown1 = 0;
176         r.in.unknown2 = 0;
177         r.out.count = &count;
178         r.out.sids = &sids;
179
180         status = dcerpc_lsa_LookupNames2(p, mem_ctx, &r);
181         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
182                 printf("LookupNames2 failed - %s\n", nt_errstr(status));
183                 return False;
184         }
185
186         printf("\n");
187
188         return True;
189 }
190
191
192 static BOOL test_LookupNames3(struct dcerpc_pipe *p, 
193                               TALLOC_CTX *mem_ctx, 
194                               struct policy_handle *handle,
195                               struct lsa_TransNameArray2 *tnames)
196 {
197         struct lsa_LookupNames3 r;
198         struct lsa_TransSidArray3 sids;
199         struct lsa_String *names;
200         uint32_t count = 0;
201         NTSTATUS status;
202         int i;
203
204         printf("\nTesting LookupNames3 with %d names\n", tnames->count);
205
206         sids.count = 0;
207         sids.sids = NULL;
208
209         names = talloc_array(mem_ctx, struct lsa_String, tnames->count);
210         for (i=0;i<tnames->count;i++) {
211                 init_lsa_String(&names[i], tnames->names[i].name.string);
212         }
213
214         r.in.handle = handle;
215         r.in.num_names = tnames->count;
216         r.in.names = names;
217         r.in.sids = &sids;
218         r.in.level = 1;
219         r.in.count = &count;
220         r.in.unknown1 = 0;
221         r.in.unknown2 = 0;
222         r.out.count = &count;
223         r.out.sids = &sids;
224
225         status = dcerpc_lsa_LookupNames3(p, mem_ctx, &r);
226         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
227                 printf("LookupNames3 failed - %s\n", nt_errstr(status));
228                 return False;
229         }
230
231         printf("\n");
232
233         return True;
234 }
235
236
237 static BOOL test_LookupSids(struct dcerpc_pipe *p, 
238                             TALLOC_CTX *mem_ctx, 
239                             struct policy_handle *handle,
240                             struct lsa_SidArray *sids)
241 {
242         struct lsa_LookupSids r;
243         struct lsa_TransNameArray names;
244         uint32_t count = sids->num_sids;
245         NTSTATUS status;
246
247         printf("\nTesting LookupSids\n");
248
249         names.count = 0;
250         names.names = NULL;
251
252         r.in.handle = handle;
253         r.in.sids = sids;
254         r.in.names = &names;
255         r.in.level = 1;
256         r.in.count = &count;
257         r.out.count = &count;
258         r.out.names = &names;
259
260         status = dcerpc_lsa_LookupSids(p, mem_ctx, &r);
261         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
262                 printf("LookupSids failed - %s\n", nt_errstr(status));
263                 return False;
264         }
265
266         printf("\n");
267
268         if (!test_LookupNames(p, mem_ctx, handle, &names)) {
269                 return False;
270         }
271
272         return True;
273 }
274
275
276 static BOOL test_LookupSids2(struct dcerpc_pipe *p, 
277                             TALLOC_CTX *mem_ctx, 
278                             struct policy_handle *handle,
279                             struct lsa_SidArray *sids)
280 {
281         struct lsa_LookupSids2 r;
282         struct lsa_TransNameArray2 names;
283         uint32_t count = sids->num_sids;
284         NTSTATUS status;
285
286         printf("\nTesting LookupSids2\n");
287
288         names.count = 0;
289         names.names = NULL;
290
291         r.in.handle = handle;
292         r.in.sids = sids;
293         r.in.names = &names;
294         r.in.level = 1;
295         r.in.count = &count;
296         r.in.unknown1 = 0;
297         r.in.unknown2 = 0;
298         r.out.count = &count;
299         r.out.names = &names;
300
301         status = dcerpc_lsa_LookupSids2(p, mem_ctx, &r);
302         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
303                 printf("LookupSids2 failed - %s\n", nt_errstr(status));
304                 return False;
305         }
306
307         printf("\n");
308
309         if (!test_LookupNames2(p, mem_ctx, handle, &names)) {
310                 return False;
311         }
312
313         if (!test_LookupNames3(p, mem_ctx, handle, &names)) {
314                 return False;
315         }
316
317         return True;
318 }
319
320 static BOOL test_LookupSids3(struct dcerpc_pipe *p, 
321                             TALLOC_CTX *mem_ctx, 
322                             struct policy_handle *handle,
323                             struct lsa_SidArray *sids)
324 {
325         struct lsa_LookupSids3 r;
326         struct lsa_TransNameArray2 names;
327         uint32_t count = sids->num_sids;
328         NTSTATUS status;
329
330         printf("\nTesting LookupSids3\n");
331
332         names.count = 0;
333         names.names = NULL;
334
335         r.in.sids = sids;
336         r.in.names = &names;
337         r.in.level = 1;
338         r.in.count = &count;
339         r.in.unknown1 = 0;
340         r.in.unknown2 = 0;
341         r.out.count = &count;
342         r.out.names = &names;
343
344         status = dcerpc_lsa_LookupSids3(p, mem_ctx, &r);
345         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
346                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
347                     NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
348                         printf("not considering %s to be an error\n", nt_errstr(status));
349                         return True;
350                 }
351                 printf("LookupSids3 failed - %s - not considered an error\n", 
352                        nt_errstr(status));
353                 return False;
354         }
355
356         printf("\n");
357
358         if (!test_LookupNames3(p, mem_ctx, handle, &names)) {
359                 return False;
360         }
361
362         return True;
363 }
364
365 static BOOL test_many_LookupSids(struct dcerpc_pipe *p, 
366                                  TALLOC_CTX *mem_ctx, 
367                                  struct policy_handle *handle)
368 {
369         struct lsa_LookupSids r;
370         struct lsa_TransNameArray names;
371         uint32_t count;
372         NTSTATUS status;
373         struct lsa_SidArray sids;
374         int i;
375
376         printf("\nTesting LookupSids with lots of SIDs\n");
377
378         names.count = 0;
379         names.names = NULL;
380
381         sids.num_sids = 100;
382
383         sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, sids.num_sids);
384
385         for (i=0; i<sids.num_sids; i++) {
386                 const char *sidstr = "S-1-5-32-545";
387                 sids.sids[i].sid = dom_sid_parse_talloc(mem_ctx, sidstr);
388         }
389
390         count = sids.num_sids;
391
392         r.in.handle = handle;
393         r.in.sids = &sids;
394         r.in.names = &names;
395         r.in.level = 1;
396         r.in.count = &names.count;
397         r.out.count = &count;
398         r.out.names = &names;
399
400         status = dcerpc_lsa_LookupSids(p, mem_ctx, &r);
401         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
402                 printf("LookupSids failed - %s\n", nt_errstr(status));
403                 return False;
404         }
405
406         printf("\n");
407
408         if (!test_LookupNames(p, mem_ctx, handle, &names)) {
409                 return False;
410         }
411
412         return True;
413 }
414
415 static BOOL test_LookupPrivValue(struct dcerpc_pipe *p, 
416                                  TALLOC_CTX *mem_ctx, 
417                                  struct policy_handle *handle,
418                                  struct lsa_String *name)
419 {
420         NTSTATUS status;
421         struct lsa_LookupPrivValue r;
422         struct lsa_LUID luid;
423
424         r.in.handle = handle;
425         r.in.name = name;
426         r.out.luid = &luid;
427
428         status = dcerpc_lsa_LookupPrivValue(p, mem_ctx, &r);
429         if (!NT_STATUS_IS_OK(status)) {
430                 printf("\nLookupPrivValue failed - %s\n", nt_errstr(status));
431                 return False;
432         }
433
434         return True;
435 }
436
437 static BOOL test_LookupPrivName(struct dcerpc_pipe *p, 
438                                 TALLOC_CTX *mem_ctx, 
439                                 struct policy_handle *handle,
440                                 struct lsa_LUID *luid)
441 {
442         NTSTATUS status;
443         struct lsa_LookupPrivName r;
444
445         r.in.handle = handle;
446         r.in.luid = luid;
447
448         status = dcerpc_lsa_LookupPrivName(p, mem_ctx, &r);
449         if (!NT_STATUS_IS_OK(status)) {
450                 printf("\nLookupPrivName failed - %s\n", nt_errstr(status));
451                 return False;
452         }
453
454         return True;
455 }
456
457 static BOOL test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, 
458                                              TALLOC_CTX *mem_ctx,                                 
459                                              struct policy_handle *acct_handle,
460                                              struct lsa_LUID *luid)
461 {
462         NTSTATUS status;
463         struct lsa_RemovePrivilegesFromAccount r;
464         struct lsa_PrivilegeSet privs;
465         BOOL ret = True;
466
467         printf("Testing RemovePrivilegesFromAccount\n");
468
469         r.in.handle = acct_handle;
470         r.in.remove_all = 0;
471         r.in.privs = &privs;
472
473         privs.count = 1;
474         privs.unknown = 0;
475         privs.set = talloc_array(mem_ctx, struct lsa_LUIDAttribute, 1);
476         privs.set[0].luid = *luid;
477         privs.set[0].attribute = 0;
478
479         status = dcerpc_lsa_RemovePrivilegesFromAccount(p, mem_ctx, &r);
480         if (!NT_STATUS_IS_OK(status)) {
481                 printf("RemovePrivilegesFromAccount failed - %s\n", nt_errstr(status));
482                 return False;
483         }
484
485         return ret;
486 }
487
488 static BOOL test_AddPrivilegesToAccount(struct dcerpc_pipe *p, 
489                                         TALLOC_CTX *mem_ctx,                              
490                                         struct policy_handle *acct_handle,
491                                         struct lsa_LUID *luid)
492 {
493         NTSTATUS status;
494         struct lsa_AddPrivilegesToAccount r;
495         struct lsa_PrivilegeSet privs;
496         BOOL ret = True;
497
498         printf("Testing AddPrivilegesToAccount\n");
499
500         r.in.handle = acct_handle;
501         r.in.privs = &privs;
502
503         privs.count = 1;
504         privs.unknown = 0;
505         privs.set = talloc_array(mem_ctx, struct lsa_LUIDAttribute, 1);
506         privs.set[0].luid = *luid;
507         privs.set[0].attribute = 0;
508
509         status = dcerpc_lsa_AddPrivilegesToAccount(p, mem_ctx, &r);
510         if (!NT_STATUS_IS_OK(status)) {
511                 printf("AddPrivilegesToAccount failed - %s\n", nt_errstr(status));
512                 return False;
513         }
514
515         return ret;
516 }
517
518 static BOOL test_EnumPrivsAccount(struct dcerpc_pipe *p, 
519                                   TALLOC_CTX *mem_ctx,                            
520                                   struct policy_handle *handle,
521                                   struct policy_handle *acct_handle)
522 {
523         NTSTATUS status;
524         struct lsa_EnumPrivsAccount r;
525         BOOL ret = True;
526
527         printf("Testing EnumPrivsAccount\n");
528
529         r.in.handle = acct_handle;
530
531         status = dcerpc_lsa_EnumPrivsAccount(p, mem_ctx, &r);
532         if (!NT_STATUS_IS_OK(status)) {
533                 printf("EnumPrivsAccount failed - %s\n", nt_errstr(status));
534                 return False;
535         }
536
537         if (r.out.privs && r.out.privs->count > 0) {
538                 int i;
539                 for (i=0;i<r.out.privs->count;i++) {
540                         test_LookupPrivName(p, mem_ctx, handle, 
541                                             &r.out.privs->set[i].luid);
542                 }
543
544                 ret &= test_RemovePrivilegesFromAccount(p, mem_ctx, acct_handle, 
545                                                         &r.out.privs->set[0].luid);
546                 ret &= test_AddPrivilegesToAccount(p, mem_ctx, acct_handle, 
547                                                    &r.out.privs->set[0].luid);
548         }
549
550         return ret;
551 }
552
553 static BOOL test_Delete(struct dcerpc_pipe *p, 
554                        TALLOC_CTX *mem_ctx, 
555                        struct policy_handle *handle)
556 {
557         NTSTATUS status;
558         struct lsa_Delete r;
559
560         printf("testing Delete\n");
561
562         r.in.handle = handle;
563         status = dcerpc_lsa_Delete(p, mem_ctx, &r);
564         if (!NT_STATUS_IS_OK(status)) {
565                 printf("Delete failed - %s\n", nt_errstr(status));
566                 return False;
567         }
568
569         return True;
570 }
571
572
573 static BOOL test_CreateAccount(struct dcerpc_pipe *p, 
574                                TALLOC_CTX *mem_ctx, 
575                                struct policy_handle *handle)
576 {
577         NTSTATUS status;
578         struct lsa_CreateAccount r;
579         struct dom_sid2 *newsid;
580         struct policy_handle acct_handle;
581
582         newsid = dom_sid_parse_talloc(mem_ctx, "S-1-5-12349876-4321-2854");
583
584         printf("Testing CreateAccount\n");
585
586         r.in.handle = handle;
587         r.in.sid = newsid;
588         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
589         r.out.acct_handle = &acct_handle;
590
591         status = dcerpc_lsa_CreateAccount(p, mem_ctx, &r);
592         if (!NT_STATUS_IS_OK(status)) {
593                 printf("CreateAccount failed - %s\n", nt_errstr(status));
594                 return False;
595         }
596
597         if (!test_Delete(p, mem_ctx, &acct_handle)) {
598                 return False;
599         }
600
601         return True;
602 }
603
604 static BOOL test_DeleteTrustedDomain(struct dcerpc_pipe *p, 
605                                      TALLOC_CTX *mem_ctx, 
606                                      struct policy_handle *handle,
607                                      struct lsa_String name)
608 {
609         NTSTATUS status;
610         struct lsa_OpenTrustedDomainByName r;
611         struct policy_handle trustdom_handle;
612
613         r.in.handle = handle;
614         r.in.name = name;
615         r.in.access_mask = SEC_STD_DELETE;
616         r.out.trustdom_handle = &trustdom_handle;
617
618         status = dcerpc_lsa_OpenTrustedDomainByName(p, mem_ctx, &r);
619         if (!NT_STATUS_IS_OK(status)) {
620                 printf("lsa_OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
621                 return False;
622         }
623
624         if (!test_Delete(p, mem_ctx, &trustdom_handle)) {
625                 return False;
626         }
627
628         return True;
629 }
630
631
632 static BOOL test_CreateSecret(struct dcerpc_pipe *p, 
633                               TALLOC_CTX *mem_ctx, 
634                               struct policy_handle *handle)
635 {
636         NTSTATUS status;
637         struct lsa_CreateSecret r;
638         struct lsa_OpenSecret r2;
639         struct lsa_SetSecret r3;
640         struct lsa_QuerySecret r4;
641         struct lsa_SetSecret r5;
642         struct lsa_QuerySecret r6;
643         struct lsa_SetSecret r7;
644         struct lsa_QuerySecret r8;
645         struct policy_handle sec_handle, sec_handle2, sec_handle3;
646         struct lsa_Delete d;
647         struct lsa_DATA_BUF buf1;
648         struct lsa_DATA_BUF_PTR bufp1;
649         struct lsa_DATA_BUF_PTR bufp2;
650         DATA_BLOB enc_key;
651         BOOL ret = True;
652         DATA_BLOB session_key;
653         NTTIME old_mtime, new_mtime;
654         DATA_BLOB blob1, blob2;
655         const char *secret1 = "abcdef12345699qwerty";
656         char *secret2;
657         const char *secret3 = "ABCDEF12345699QWERTY";
658         char *secret4;
659         const char *secret5 = "NEW-SAMBA4-SECRET";
660         char *secret6;
661         char *secname[2];
662         int i;
663         const int LOCAL = 0;
664         const int GLOBAL = 1;
665
666         secname[LOCAL] = talloc_asprintf(mem_ctx, "torturesecret-%u", (uint_t)random());
667         secname[GLOBAL] = talloc_asprintf(mem_ctx, "G$torturesecret-%u", (uint_t)random());
668
669         for (i=0; i< 2; i++) {
670                 printf("Testing CreateSecret of %s\n", secname[i]);
671                 
672                 init_lsa_String(&r.in.name, secname[i]);
673                 
674                 r.in.handle = handle;
675                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
676                 r.out.sec_handle = &sec_handle;
677                 
678                 status = dcerpc_lsa_CreateSecret(p, mem_ctx, &r);
679                 if (!NT_STATUS_IS_OK(status)) {
680                         printf("CreateSecret failed - %s\n", nt_errstr(status));
681                         return False;
682                 }
683                 
684                 r.in.handle = handle;
685                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
686                 r.out.sec_handle = &sec_handle3;
687                 
688                 status = dcerpc_lsa_CreateSecret(p, mem_ctx, &r);
689                 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
690                         printf("CreateSecret should have failed OBJECT_NAME_COLLISION - %s\n", nt_errstr(status));
691                         return False;
692                 }
693                 
694                 r2.in.handle = handle;
695                 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
696                 r2.in.name = r.in.name;
697                 r2.out.sec_handle = &sec_handle2;
698                 
699                 printf("Testing OpenSecret\n");
700                 
701                 status = dcerpc_lsa_OpenSecret(p, mem_ctx, &r2);
702                 if (!NT_STATUS_IS_OK(status)) {
703                         printf("OpenSecret failed - %s\n", nt_errstr(status));
704                         ret = False;
705                 }
706                 
707                 status = dcerpc_fetch_session_key(p, &session_key);
708                 if (!NT_STATUS_IS_OK(status)) {
709                         printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
710                         ret = False;
711                 }
712                 
713                 enc_key = sess_encrypt_string(secret1, &session_key);
714                 
715                 r3.in.sec_handle = &sec_handle;
716                 r3.in.new_val = &buf1;
717                 r3.in.old_val = NULL;
718                 r3.in.new_val->data = enc_key.data;
719                 r3.in.new_val->length = enc_key.length;
720                 r3.in.new_val->size = enc_key.length;
721                 
722                 printf("Testing SetSecret\n");
723                 
724                 status = dcerpc_lsa_SetSecret(p, mem_ctx, &r3);
725                 if (!NT_STATUS_IS_OK(status)) {
726                         printf("SetSecret failed - %s\n", nt_errstr(status));
727                         ret = False;
728                 }
729                 
730                 r3.in.sec_handle = &sec_handle;
731                 r3.in.new_val = &buf1;
732                 r3.in.old_val = NULL;
733                 r3.in.new_val->data = enc_key.data;
734                 r3.in.new_val->length = enc_key.length;
735                 r3.in.new_val->size = enc_key.length;
736                 
737                 /* break the encrypted data */
738                 enc_key.data[0]++;
739
740                 printf("Testing SetSecret with broken key\n");
741                 
742                 status = dcerpc_lsa_SetSecret(p, mem_ctx, &r3);
743                 if (!NT_STATUS_EQUAL(status, NT_STATUS_UNKNOWN_REVISION)) {
744                         printf("SetSecret should have failed UNKNOWN_REVISION - %s\n", nt_errstr(status));
745                         ret = False;
746                 }
747                 
748                 data_blob_free(&enc_key);
749                 
750                 ZERO_STRUCT(new_mtime);
751                 ZERO_STRUCT(old_mtime);
752                 
753                 /* fetch the secret back again */
754                 r4.in.sec_handle = &sec_handle;
755                 r4.in.new_val = &bufp1;
756                 r4.in.new_mtime = &new_mtime;
757                 r4.in.old_val = NULL;
758                 r4.in.old_mtime = NULL;
759                 
760                 bufp1.buf = NULL;
761                 
762                 printf("Testing QuerySecret\n");
763                 status = dcerpc_lsa_QuerySecret(p, mem_ctx, &r4);
764                 if (!NT_STATUS_IS_OK(status)) {
765                         printf("QuerySecret failed - %s\n", nt_errstr(status));
766                         ret = False;
767                 } else {
768                         if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
769                                 printf("No secret buffer returned\n");
770                                 ret = False;
771                         } else {
772                                 blob1.data = r4.out.new_val->buf->data;
773                                 blob1.length = r4.out.new_val->buf->size;
774                                 
775                                 blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length);
776                                 
777                                 secret2 = sess_decrypt_string(&blob1, &session_key);
778                                 
779                                 if (strcmp(secret1, secret2) != 0) {
780                                         printf("Returned secret '%s' doesn't match '%s'\n", 
781                                                secret2, secret1);
782                                         ret = False;
783                                 }
784                         }
785                 }
786                 
787                 enc_key = sess_encrypt_string(secret3, &session_key);
788                 
789                 r5.in.sec_handle = &sec_handle;
790                 r5.in.new_val = &buf1;
791                 r5.in.old_val = NULL;
792                 r5.in.new_val->data = enc_key.data;
793                 r5.in.new_val->length = enc_key.length;
794                 r5.in.new_val->size = enc_key.length;
795                 
796                 printf("Testing SetSecret (existing value should move to old)\n");
797                 
798                 status = dcerpc_lsa_SetSecret(p, mem_ctx, &r5);
799                 if (!NT_STATUS_IS_OK(status)) {
800                         printf("SetSecret failed - %s\n", nt_errstr(status));
801                         ret = False;
802                 }
803                 
804                 data_blob_free(&enc_key);
805                 
806                 ZERO_STRUCT(new_mtime);
807                 ZERO_STRUCT(old_mtime);
808                 
809                 /* fetch the secret back again */
810                 r6.in.sec_handle = &sec_handle;
811                 r6.in.new_val = &bufp1;
812                 r6.in.new_mtime = &new_mtime;
813                 r6.in.old_val = &bufp2;
814                 r6.in.old_mtime = &old_mtime;
815                 
816                 bufp1.buf = NULL;
817                 bufp2.buf = NULL;
818                 
819                 status = dcerpc_lsa_QuerySecret(p, mem_ctx, &r6);
820                 if (!NT_STATUS_IS_OK(status)) {
821                         printf("QuerySecret failed - %s\n", nt_errstr(status));
822                         ret = False;
823                 } else {
824
825                         if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL 
826                                 || r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
827                                 printf("Both secret buffers and both times not returned\n");
828                                 ret = False;
829                         } else {
830                                 blob1.data = r6.out.new_val->buf->data;
831                                 blob1.length = r6.out.new_val->buf->size;
832                                 
833                                 blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length);
834                                 
835                                 secret4 = sess_decrypt_string(&blob1, &session_key);
836                                 
837                                 if (strcmp(secret3, secret4) != 0) {
838                                         printf("Returned NEW secret %s doesn't match %s\n", secret4, secret3);
839                                         ret = False;
840                                 }
841
842                                 blob1.data = r6.out.old_val->buf->data;
843                                 blob1.length = r6.out.old_val->buf->length;
844                                 
845                                 blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length);
846                                 
847                                 secret2 = sess_decrypt_string(&blob1, &session_key);
848                                 
849                                 if (strcmp(secret1, secret2) != 0) {
850                                         printf("Returned OLD secret %s doesn't match %s\n", secret2, secret1);
851                                         ret = False;
852                                 }
853                                 
854                                 if (*r6.out.new_mtime == *r6.out.old_mtime) {
855                                         printf("Returned secret %s had same mtime for both secrets: %s\n", 
856                                                secname[i],
857                                                nt_time_string(mem_ctx, *r6.out.new_mtime));
858                                         ret = False;
859                                 }
860                         }
861                 }
862
863                 enc_key = sess_encrypt_string(secret5, &session_key);
864                 
865                 r7.in.sec_handle = &sec_handle;
866                 r7.in.old_val = &buf1;
867                 r7.in.old_val->data = enc_key.data;
868                 r7.in.old_val->length = enc_key.length;
869                 r7.in.old_val->size = enc_key.length;
870                 r7.in.new_val = NULL;
871                 
872                 printf("Testing SetSecret of old Secret only\n");
873                 
874                 status = dcerpc_lsa_SetSecret(p, mem_ctx, &r7);
875                 if (!NT_STATUS_IS_OK(status)) {
876                         printf("SetSecret failed - %s\n", nt_errstr(status));
877                         ret = False;
878                 }
879                 
880                 data_blob_free(&enc_key);
881                 
882                 /* fetch the secret back again */
883                 r8.in.sec_handle = &sec_handle;
884                 r8.in.new_val = &bufp1;
885                 r8.in.new_mtime = &new_mtime;
886                 r8.in.old_val = &bufp2;
887                 r8.in.old_mtime = &old_mtime;
888                 
889                 bufp1.buf = NULL;
890                 bufp2.buf = NULL;
891                 
892                 status = dcerpc_lsa_QuerySecret(p, mem_ctx, &r8);
893                 if (!NT_STATUS_IS_OK(status)) {
894                         printf("QuerySecret failed - %s\n", nt_errstr(status));
895                         ret = False;
896                 } else {
897                         if (!r8.out.new_val || !r8.out.old_val) {
898                                 printf("in/out pointers not returned, despite being set on in for QuerySecret\n");
899                                 ret = False;
900                         } else if (r8.out.new_val->buf == NULL) {
901                                 if (i != LOCAL) { 
902                                         printf("NEW secret buffer not returned after GLOBAL OLD set\n");
903                                         ret = False;
904                                 }
905                         } else if (r8.out.old_val->buf == NULL) {
906                                 printf("OLD secret buffer not returned after OLD set\n");
907                                 ret = False;
908                         } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) {
909                                 printf("Both times not returned after OLD set\n");
910                                 ret = False;
911                         } else {
912                                 if (i == LOCAL) { 
913                                         printf("NEW secret buffer should not be returned after LOCAL OLD set\n");
914                                         ret = False;
915                                 }
916                                 blob1.data = r8.out.new_val->buf->data;
917                                 blob1.length = r8.out.new_val->buf->length;
918                                 
919                                 blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length);
920                                 
921                                 secret6 = sess_decrypt_string(&blob1, &session_key);
922                                 
923                                 if (strcmp(secret3, secret4) != 0) {
924                                         printf("Returned NEW secret '%s' doesn't match '%s'\n", secret4, secret3);
925                                         ret = False;
926                                 }
927
928                                 blob1.data = r8.out.old_val->buf->data;
929                                 blob1.length = r8.out.old_val->buf->size;
930                                 
931                                 blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length);
932                                 
933                                 secret6 = sess_decrypt_string(&blob1, &session_key);
934                                 
935                                 if (strcmp(secret5, secret6) != 0) {
936                                         printf("Returned OLD secret %s doesn't match %s\n", secret5, secret6);
937                                         ret = False;
938                                 }
939                                 
940                                 if (*r8.out.new_mtime == *r8.out.old_mtime) {
941                                         if (i != GLOBAL) { 
942                                                 printf("Returned secret %s had same mtime for both secrets: %s\n", 
943                                                        secname[i],
944                                                        nt_time_string(mem_ctx, *r8.out.new_mtime));
945                                                 ret = False;
946                                         }
947                                 } else {
948                                         printf("Returned secret %s should have had same mtime for both secrets: %s != %s\n", 
949                                                secname[i],
950                                                nt_time_string(mem_ctx, *r8.out.old_mtime),
951                                                nt_time_string(mem_ctx, *r8.out.new_mtime));
952                                         ret = False;
953                                 }
954                         }
955                 }
956
957                 if (!test_Delete(p, mem_ctx, &sec_handle)) {
958                         ret = False;
959                 }
960                 
961                 d.in.handle = &sec_handle2;
962                 status = dcerpc_lsa_Delete(p, mem_ctx, &d);
963                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
964                         printf("Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status));
965                         ret = False;
966                 } else {
967
968                         printf("Testing OpenSecret of just-deleted secret\n");
969                         
970                         status = dcerpc_lsa_OpenSecret(p, mem_ctx, &r2);
971                         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
972                                 printf("OpenSecret expected OBJECT_NAME_NOT_FOUND - %s\n", nt_errstr(status));
973                                 ret = False;
974                         }
975                 }
976                 
977         }
978
979         return ret;
980 }
981
982
983 static BOOL test_EnumAccountRights(struct dcerpc_pipe *p, 
984                                    TALLOC_CTX *mem_ctx, 
985                                    struct policy_handle *acct_handle,
986                                    struct dom_sid *sid)
987 {
988         NTSTATUS status;
989         struct lsa_EnumAccountRights r;
990         struct lsa_RightSet rights;
991
992         printf("Testing EnumAccountRights\n");
993
994         r.in.handle = acct_handle;
995         r.in.sid = sid;
996         r.out.rights = &rights;
997
998         status = dcerpc_lsa_EnumAccountRights(p, mem_ctx, &r);
999         if (!NT_STATUS_IS_OK(status)) {
1000                 printf("EnumAccountRights failed - %s\n", nt_errstr(status));
1001                 return False;
1002         }
1003
1004         return True;
1005 }
1006
1007
1008 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, 
1009                              TALLOC_CTX *mem_ctx, 
1010                              struct policy_handle *handle,
1011                              struct policy_handle *acct_handle)
1012 {
1013         NTSTATUS status;
1014         struct lsa_QuerySecurity r;
1015
1016         printf("Testing QuerySecurity\n");
1017
1018         r.in.handle = acct_handle;
1019         r.in.sec_info = 7;
1020
1021         status = dcerpc_lsa_QuerySecurity(p, mem_ctx, &r);
1022         if (!NT_STATUS_IS_OK(status)) {
1023                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
1024                 return False;
1025         }
1026
1027         return True;
1028 }
1029
1030 static BOOL test_OpenAccount(struct dcerpc_pipe *p, 
1031                              TALLOC_CTX *mem_ctx, 
1032                              struct policy_handle *handle,
1033                              struct dom_sid *sid)
1034 {
1035         NTSTATUS status;
1036         struct lsa_OpenAccount r;
1037         struct policy_handle acct_handle;
1038
1039         printf("Testing OpenAccount\n");
1040
1041         r.in.handle = handle;
1042         r.in.sid = sid;
1043         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1044         r.out.acct_handle = &acct_handle;
1045
1046         status = dcerpc_lsa_OpenAccount(p, mem_ctx, &r);
1047         if (!NT_STATUS_IS_OK(status)) {
1048                 printf("OpenAccount failed - %s\n", nt_errstr(status));
1049                 return False;
1050         }
1051
1052         if (!test_EnumPrivsAccount(p, mem_ctx, handle, &acct_handle)) {
1053                 return False;
1054         }
1055
1056         if (!test_QuerySecurity(p, mem_ctx, handle, &acct_handle)) {
1057                 return False;
1058         }
1059
1060         return True;
1061 }
1062
1063 static BOOL test_EnumAccounts(struct dcerpc_pipe *p, 
1064                           TALLOC_CTX *mem_ctx, 
1065                           struct policy_handle *handle)
1066 {
1067         NTSTATUS status;
1068         struct lsa_EnumAccounts r;
1069         struct lsa_SidArray sids1, sids2;
1070         uint32_t resume_handle = 0;
1071         int i;
1072
1073         printf("\ntesting EnumAccounts\n");
1074
1075         r.in.handle = handle;
1076         r.in.resume_handle = &resume_handle;
1077         r.in.num_entries = 100;
1078         r.out.resume_handle = &resume_handle;
1079         r.out.sids = &sids1;
1080
1081         resume_handle = 0;
1082         while (True) {
1083                 status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
1084                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
1085                         break;
1086                 }
1087                 if (!NT_STATUS_IS_OK(status)) {
1088                         printf("EnumAccounts failed - %s\n", nt_errstr(status));
1089                         return False;
1090                 }
1091
1092                 if (!test_LookupSids(p, mem_ctx, handle, &sids1)) {
1093                         return False;
1094                 }
1095
1096                 if (!test_LookupSids2(p, mem_ctx, handle, &sids1)) {
1097                         return False;
1098                 }
1099
1100                 if (!test_LookupSids3(p, mem_ctx, handle, &sids1)) {
1101                         return False;
1102                 }
1103
1104                 printf("testing all accounts\n");
1105                 for (i=0;i<sids1.num_sids;i++) {
1106                         test_OpenAccount(p, mem_ctx, handle, sids1.sids[i].sid);
1107                         test_EnumAccountRights(p, mem_ctx, handle, sids1.sids[i].sid);
1108                 }
1109                 printf("\n");
1110         }
1111
1112         if (sids1.num_sids < 3) {
1113                 return True;
1114         }
1115         
1116         printf("trying EnumAccounts partial listing (asking for 1 at 2)\n");
1117         resume_handle = 2;
1118         r.in.num_entries = 1;
1119         r.out.sids = &sids2;
1120
1121         status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
1122         if (!NT_STATUS_IS_OK(status)) {
1123                 printf("EnumAccounts failed - %s\n", nt_errstr(status));
1124                 return False;
1125         }
1126
1127         if (sids2.num_sids != 1) {
1128                 printf("Returned wrong number of entries (%d)\n", sids2.num_sids);
1129                 return False;
1130         }
1131
1132         return True;
1133 }
1134
1135 static BOOL test_LookupPrivDisplayName(struct dcerpc_pipe *p,
1136                                 TALLOC_CTX *mem_ctx,
1137                                 struct policy_handle *handle,
1138                                 struct lsa_String *priv_name)
1139 {
1140         struct lsa_LookupPrivDisplayName r;
1141         NTSTATUS status;
1142         /* produce a reasonable range of language output without screwing up
1143            terminals */
1144         uint16_t language_id = (random() % 4) + 0x409;
1145
1146         printf("testing LookupPrivDisplayName(%s)\n", priv_name->string);
1147         
1148         r.in.handle = handle;
1149         r.in.name = priv_name;
1150         r.in.language_id = &language_id;
1151         r.out.language_id = &language_id;
1152         r.in.unknown = 0;
1153
1154         status = dcerpc_lsa_LookupPrivDisplayName(p, mem_ctx, &r);
1155         if (!NT_STATUS_IS_OK(status)) {
1156                 printf("LookupPrivDisplayName failed - %s\n", nt_errstr(status));
1157                 return False;
1158         }
1159         printf("%s -> \"%s\"  (language 0x%x/0x%x)\n", 
1160                priv_name->string, r.out.disp_name->string, 
1161                *r.in.language_id, *r.out.language_id);
1162
1163         return True;
1164 }
1165
1166 static BOOL test_EnumAccountsWithUserRight(struct dcerpc_pipe *p, 
1167                                 TALLOC_CTX *mem_ctx,
1168                                 struct policy_handle *handle,
1169                                 struct lsa_String *priv_name)
1170 {
1171         struct lsa_EnumAccountsWithUserRight r;
1172         struct lsa_SidArray sids;
1173         NTSTATUS status;
1174
1175         ZERO_STRUCT(sids);
1176         
1177         printf("testing EnumAccountsWithUserRight(%s)\n", priv_name->string);
1178         
1179         r.in.handle = handle;
1180         r.in.name = priv_name;
1181         r.out.sids = &sids;
1182
1183         status = dcerpc_lsa_EnumAccountsWithUserRight(p, mem_ctx, &r);
1184
1185         /* NT_STATUS_NO_MORE_ENTRIES means noone has this privilege */
1186         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
1187                 return True;
1188         }
1189
1190         if (!NT_STATUS_IS_OK(status)) {
1191                 printf("EnumAccountsWithUserRight failed - %s\n", nt_errstr(status));
1192                 return False;
1193         }
1194         
1195         return True;
1196 }
1197
1198
1199 static BOOL test_EnumPrivs(struct dcerpc_pipe *p, 
1200                            TALLOC_CTX *mem_ctx, 
1201                            struct policy_handle *handle)
1202 {
1203         NTSTATUS status;
1204         struct lsa_EnumPrivs r;
1205         struct lsa_PrivArray privs1;
1206         uint32_t resume_handle = 0;
1207         int i;
1208         BOOL ret = True;
1209
1210         printf("\ntesting EnumPrivs\n");
1211
1212         r.in.handle = handle;
1213         r.in.resume_handle = &resume_handle;
1214         r.in.max_count = 100;
1215         r.out.resume_handle = &resume_handle;
1216         r.out.privs = &privs1;
1217
1218         resume_handle = 0;
1219         status = dcerpc_lsa_EnumPrivs(p, mem_ctx, &r);
1220         if (!NT_STATUS_IS_OK(status)) {
1221                 printf("EnumPrivs failed - %s\n", nt_errstr(status));
1222                 return False;
1223         }
1224
1225         for (i = 0; i< privs1.count; i++) {
1226                 test_LookupPrivDisplayName(p, mem_ctx, handle, &privs1.privs[i].name);
1227                 test_LookupPrivValue(p, mem_ctx, handle, &privs1.privs[i].name);
1228                 if (!test_EnumAccountsWithUserRight(p, mem_ctx, handle, &privs1.privs[i].name)) {
1229                         ret = False;
1230                 }
1231         }
1232
1233         return ret;
1234 }
1235
1236 static BOOL test_query_each_TrustDom(struct dcerpc_pipe *p, 
1237                                      TALLOC_CTX *mem_ctx, 
1238                                      struct policy_handle *handle, 
1239                                      struct lsa_DomainList *domains) 
1240 {
1241         NTSTATUS status;
1242         int i,j;
1243         BOOL ret = True;
1244                 
1245         printf("\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
1246         for (i=0; i< domains->count; i++) {
1247                 struct lsa_OpenTrustedDomain trust;
1248                 struct lsa_OpenTrustedDomainByName trust_by_name;
1249                 struct policy_handle trustdom_handle;
1250                 struct policy_handle handle2;
1251                 struct lsa_Close c;
1252                 int levels [] = {1, 3, 6, 8, 12};
1253                         
1254                 if (domains->domains[i].sid) {
1255                         trust.in.handle = handle;
1256                         trust.in.sid = domains->domains[i].sid;
1257                         trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1258                         trust.out.trustdom_handle = &trustdom_handle;
1259                         
1260                         status = dcerpc_lsa_OpenTrustedDomain(p, mem_ctx, &trust);
1261                         
1262                         if (!NT_STATUS_IS_OK(status)) {
1263                                 printf("OpenTrustedDomain failed - %s\n", nt_errstr(status));
1264                                 return False;
1265                         }
1266                         
1267                         c.in.handle = &trustdom_handle;
1268                         c.out.handle = &handle2;
1269                         
1270                         for (j=0; j < ARRAY_SIZE(levels); j++) {
1271                                 struct lsa_QueryTrustedDomainInfo q;
1272                                 union lsa_TrustedDomainInfo info;
1273                                 q.in.trustdom_handle = &trustdom_handle;
1274                                 q.in.level = levels[j];
1275                                 q.out.info = &info;
1276                                 status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
1277                                 if (!NT_STATUS_IS_OK(status)) {
1278                                         printf("QueryTrustedDomainInfo level %d failed - %s\n", 
1279                                                levels[j], nt_errstr(status));
1280                                         ret = False;
1281                                 }
1282                         }
1283                         
1284                         status = dcerpc_lsa_Close(p, mem_ctx, &c);
1285                         if (!NT_STATUS_IS_OK(status)) {
1286                                 printf("Close of trusted domain failed - %s\n", nt_errstr(status));
1287                                 return False;
1288                         }
1289                 }
1290
1291                 trust_by_name.in.handle = handle;
1292                 trust_by_name.in.name = domains->domains[i].name;
1293                 trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1294                 trust_by_name.out.trustdom_handle = &trustdom_handle;
1295                         
1296                 status = dcerpc_lsa_OpenTrustedDomainByName(p, mem_ctx, &trust_by_name);
1297                         
1298                 if (!NT_STATUS_IS_OK(status)) {
1299                         printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
1300                         return False;
1301                 }
1302
1303                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1304                         struct lsa_QueryTrustedDomainInfo q;
1305                         union lsa_TrustedDomainInfo info;
1306                         q.in.trustdom_handle = &trustdom_handle;
1307                         q.in.level = levels[j];
1308                         q.out.info = &info;
1309                         status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
1310                         if (!NT_STATUS_IS_OK(status)) {
1311                                 printf("QueryTrustedDomainInfo level %d failed - %s\n", 
1312                                        levels[j], nt_errstr(status));
1313                                 ret = False;
1314                         }
1315                 }
1316                 
1317                 c.in.handle = &trustdom_handle;
1318                 c.out.handle = &handle2;
1319
1320                 status = dcerpc_lsa_Close(p, mem_ctx, &c);
1321                 if (!NT_STATUS_IS_OK(status)) {
1322                         printf("Close of trusted domain failed - %s\n", nt_errstr(status));
1323                         return False;
1324                 }
1325
1326                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1327                         struct lsa_QueryTrustedDomainInfoBySid q;
1328                         union lsa_TrustedDomainInfo info;
1329
1330                         if (!domains->domains[i].sid) {
1331                                 continue;
1332                         }
1333
1334                         q.in.handle  = handle;
1335                         q.in.dom_sid = domains->domains[i].sid;
1336                         q.in.level   = levels[j];
1337                         q.out.info   = &info;
1338                         status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, mem_ctx, &q);
1339                         if (!NT_STATUS_IS_OK(status)) {
1340                                 printf("QueryTrustedDomainInfoBySid level %d failed - %s\n", 
1341                                        levels[j], nt_errstr(status));
1342                                 ret = False;
1343                         }
1344                 }
1345                 
1346                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1347                         struct lsa_QueryTrustedDomainInfoByName q;
1348                         union lsa_TrustedDomainInfo info;
1349                         q.in.handle         = handle;
1350                         q.in.trusted_domain = domains->domains[i].name;
1351                         q.in.level          = levels[j];
1352                         q.out.info          = &info;
1353                         status = dcerpc_lsa_QueryTrustedDomainInfoByName(p, mem_ctx, &q);
1354                         if (!NT_STATUS_IS_OK(status)) {
1355                                 printf("QueryTrustedDomainInfoByName level %d failed - %s\n", 
1356                                        levels[j], nt_errstr(status));
1357                                 ret = False;
1358                         }
1359                 }
1360         }
1361         return ret;
1362 }
1363
1364 static BOOL test_EnumTrustDom(struct dcerpc_pipe *p, 
1365                               TALLOC_CTX *mem_ctx, 
1366                               struct policy_handle *handle)
1367 {
1368         struct lsa_EnumTrustDom r;
1369         NTSTATUS enum_status;
1370         uint32_t resume_handle = 0;
1371         struct lsa_DomainList domains;
1372         BOOL ret = True;
1373
1374         printf("\nTesting EnumTrustDom\n");
1375
1376         do {
1377                 r.in.handle = handle;
1378                 r.in.resume_handle = &resume_handle;
1379                 r.in.max_size = LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3;
1380                 r.out.domains = &domains;
1381                 r.out.resume_handle = &resume_handle;
1382                 
1383                 enum_status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r);
1384                 
1385                 /* NO_MORE_ENTRIES is allowed */
1386                 if (NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES)) {
1387                         return True;
1388                 } else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) {
1389                         /* Windows 2003 gets this off by one on the first run */
1390                         if (r.out.domains->count < 3 || r.out.domains->count > 4) {
1391                                 printf("EnumTrustDom didn't fill the buffer we "
1392                                        "asked it to (got %d, expected %d / %d == %d entries)\n",
1393                                        r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3, 
1394                                        LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
1395                                 ret = False;
1396                         }
1397                 } else if (!NT_STATUS_IS_OK(enum_status)) {
1398                         printf("EnumTrustDom failed - %s\n", nt_errstr(enum_status));
1399                         return False;
1400                 }
1401                 
1402                 ret &= test_query_each_TrustDom(p, mem_ctx, handle, &domains);
1403
1404         } while ((NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)));
1405
1406         return ret;
1407 }
1408
1409 static BOOL test_CreateTrustedDomain(struct dcerpc_pipe *p, 
1410                                      TALLOC_CTX *mem_ctx, 
1411                                      struct policy_handle *handle)
1412 {
1413         NTSTATUS status;
1414         BOOL ret = True;
1415         struct lsa_CreateTrustedDomain r;
1416         struct lsa_TrustInformation trustinfo;
1417         struct dom_sid *domsid[12];
1418         struct policy_handle trustdom_handle[12];
1419         struct lsa_QueryTrustedDomainInfo q;
1420         int i;
1421
1422         printf("Testing CreateTrustedDomain for 12 domains\n");
1423
1424         for (i=0; i< 12; i++) {
1425                 char *trust_name = talloc_asprintf(mem_ctx, "torturedom%02d", i);
1426                 char *trust_sid = talloc_asprintf(mem_ctx, "S-1-5-21-97398-379795-100%02d", i);
1427                 
1428                 domsid[i] = dom_sid_parse_talloc(mem_ctx, trust_sid);
1429
1430                 trustinfo.sid = domsid[i];
1431                 init_lsa_String(&trustinfo.name, trust_name);
1432
1433                 r.in.handle = handle;
1434                 r.in.info = &trustinfo;
1435                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1436                 r.out.trustdom_handle = &trustdom_handle[i];
1437                 
1438                 status = dcerpc_lsa_CreateTrustedDomain(p, mem_ctx, &r);
1439                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1440                         test_DeleteTrustedDomain(p, mem_ctx, handle, trustinfo.name);
1441                         status = dcerpc_lsa_CreateTrustedDomain(p, mem_ctx, &r);
1442                 }
1443                 if (!NT_STATUS_IS_OK(status)) {
1444                         printf("CreateTrustedDomain failed - %s\n", nt_errstr(status));
1445                         ret = False;
1446                 } else {
1447                 
1448                         q.in.trustdom_handle = &trustdom_handle[i];
1449                         q.in.level = LSA_TRUSTED_DOMAIN_INFO_NAME;
1450                         status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
1451                         if (!NT_STATUS_IS_OK(status)) {
1452                                 printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
1453                                 ret = False;
1454                         } else if (!q.out.info) {
1455                                 ret = False;
1456                         } else {
1457                                 if (strcmp(q.out.info->name.netbios_name.string, trustinfo.name.string) != 0) {
1458                                         printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
1459                                                q.out.info->name.netbios_name.string, trustinfo.name.string);
1460                                         ret = False;
1461                                 }
1462                         }
1463                 }
1464         }
1465
1466         /* now that we have some domains to look over, we can test the enum calls */
1467         if (!test_EnumTrustDom(p, mem_ctx, handle)) {
1468                 ret = False;
1469         }
1470         
1471         for (i=0; i<12; i++) {
1472                 if (!test_Delete(p, mem_ctx, &trustdom_handle[i])) {
1473                         ret = False;
1474                 }
1475         }
1476
1477         return ret;
1478 }
1479
1480 static BOOL test_QueryInfoPolicy(struct dcerpc_pipe *p, 
1481                                  TALLOC_CTX *mem_ctx, 
1482                                  struct policy_handle *handle)
1483 {
1484         struct lsa_QueryInfoPolicy r;
1485         NTSTATUS status;
1486         int i;
1487         BOOL ret = True;
1488         printf("\nTesting QueryInfoPolicy\n");
1489
1490         for (i=1;i<13;i++) {
1491                 r.in.handle = handle;
1492                 r.in.level = i;
1493
1494                 printf("\ntrying QueryInfoPolicy level %d\n", i);
1495
1496                 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
1497
1498                 if ((i == 9 || i == 10 || i == 11) &&
1499                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1500                         printf("server failed level %u (OK)\n", i);
1501                         continue;
1502                 }
1503
1504                 if (!NT_STATUS_IS_OK(status)) {
1505                         printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
1506                         ret = False;
1507                         continue;
1508                 }
1509         }
1510
1511         return ret;
1512 }
1513
1514 static BOOL test_QueryInfoPolicy2(struct dcerpc_pipe *p, 
1515                                   TALLOC_CTX *mem_ctx, 
1516                                   struct policy_handle *handle)
1517 {
1518         struct lsa_QueryInfoPolicy2 r;
1519         NTSTATUS status;
1520         int i;
1521         BOOL ret = True;
1522         printf("\nTesting QueryInfoPolicy2\n");
1523
1524         for (i=1;i<13;i++) {
1525                 r.in.handle = handle;
1526                 r.in.level = i;
1527
1528                 printf("\ntrying QueryInfoPolicy2 level %d\n", i);
1529
1530                 status = dcerpc_lsa_QueryInfoPolicy2(p, mem_ctx, &r);
1531
1532                 if ((i == 9 || i == 10 || i == 11) &&
1533                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1534                         printf("server failed level %u (OK)\n", i);
1535                         continue;
1536                 }
1537
1538                 if (!NT_STATUS_IS_OK(status)) {
1539                         printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
1540                         ret = False;
1541                         continue;
1542                 }
1543         }
1544
1545         return ret;
1546 }
1547
1548 static BOOL test_GetUserName(struct dcerpc_pipe *p, 
1549                                   TALLOC_CTX *mem_ctx, 
1550                                   struct policy_handle *handle)
1551 {
1552         struct lsa_GetUserName r;
1553         NTSTATUS status;
1554         BOOL ret = True;
1555         struct lsa_StringPointer authority_name_p;
1556
1557         printf("\nTesting GetUserName\n");
1558
1559         r.in.system_name = "\\";        
1560         r.in.account_name = NULL;       
1561         r.in.authority_name = &authority_name_p;
1562         authority_name_p.string = NULL;
1563
1564         status = dcerpc_lsa_GetUserName(p, mem_ctx, &r);
1565
1566         if (!NT_STATUS_IS_OK(status)) {
1567                 printf("GetUserName failed - %s\n", nt_errstr(status));
1568                 ret = False;
1569         }
1570
1571         return ret;
1572 }
1573
1574 BOOL test_lsa_Close(struct dcerpc_pipe *p, 
1575                     TALLOC_CTX *mem_ctx, 
1576                     struct policy_handle *handle)
1577 {
1578         NTSTATUS status;
1579         struct lsa_Close r;
1580         struct policy_handle handle2;
1581
1582         printf("\ntesting Close\n");
1583
1584         r.in.handle = handle;
1585         r.out.handle = &handle2;
1586
1587         status = dcerpc_lsa_Close(p, mem_ctx, &r);
1588         if (!NT_STATUS_IS_OK(status)) {
1589                 printf("Close failed - %s\n", nt_errstr(status));
1590                 return False;
1591         }
1592
1593         status = dcerpc_lsa_Close(p, mem_ctx, &r);
1594         /* its really a fault - we need a status code for rpc fault */
1595         if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1596                 printf("Close failed - %s\n", nt_errstr(status));
1597                 return False;
1598         }
1599
1600         printf("\n");
1601
1602         return True;
1603 }
1604
1605 BOOL torture_rpc_lsa(void)
1606 {
1607         NTSTATUS status;
1608         struct dcerpc_pipe *p;
1609         TALLOC_CTX *mem_ctx;
1610         BOOL ret = True;
1611         struct policy_handle handle;
1612
1613         mem_ctx = talloc_init("torture_rpc_lsa");
1614
1615         status = torture_rpc_connection(mem_ctx, 
1616                                         &p, 
1617                                         DCERPC_LSARPC_NAME, 
1618                                         DCERPC_LSARPC_UUID, 
1619                                         DCERPC_LSARPC_VERSION);
1620         if (!NT_STATUS_IS_OK(status)) {
1621                 talloc_free(mem_ctx);
1622                 return False;
1623         }
1624
1625         if (!test_OpenPolicy(p, mem_ctx)) {
1626                 ret = False;
1627         }
1628
1629         if (!test_lsa_OpenPolicy2(p, mem_ctx, &handle)) {
1630                 ret = False;
1631         }
1632
1633         if (!test_many_LookupSids(p, mem_ctx, &handle)) {
1634                 ret = False;
1635         }
1636
1637         if (!test_CreateAccount(p, mem_ctx, &handle)) {
1638                 ret = False;
1639         }
1640
1641         if (!test_CreateSecret(p, mem_ctx, &handle)) {
1642                 ret = False;
1643         }
1644
1645         if (!test_CreateTrustedDomain(p, mem_ctx, &handle)) {
1646                 ret = False;
1647         }
1648
1649         if (!test_EnumAccounts(p, mem_ctx, &handle)) {
1650                 ret = False;
1651         }
1652
1653         if (!test_EnumPrivs(p, mem_ctx, &handle)) {
1654                 ret = False;
1655         }
1656
1657         if (!test_QueryInfoPolicy(p, mem_ctx, &handle)) {
1658                 ret = False;
1659         }
1660
1661         if (!test_QueryInfoPolicy2(p, mem_ctx, &handle)) {
1662                 ret = False;
1663         }
1664
1665         if (!test_GetUserName(p, mem_ctx, &handle)) {
1666                 ret = False;
1667         }
1668
1669 #if 0
1670         if (!test_Delete(p, mem_ctx, &handle)) {
1671                 ret = False;
1672         }
1673 #endif
1674         
1675         if (!test_lsa_Close(p, mem_ctx, &handle)) {
1676                 ret = False;
1677         }
1678
1679         talloc_free(mem_ctx);
1680
1681         return ret;
1682 }