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