Sync parameter names with samba 3.
[amitay/samba.git] / source4 / torture / rpc / winreg.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for winreg rpc operations
4
5    Copyright (C) Tim Potter 2003
6    Copyright (C) Jelmer Vernooij 2004-2007
7    Copyright (C) Günther Deschner 2007
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "torture/torture.h"
25 #include "librpc/gen_ndr/ndr_winreg_c.h"
26 #include "librpc/gen_ndr/ndr_security.h"
27 #include "libcli/security/security.h"
28 #include "torture/rpc/rpc.h"
29
30 #define TEST_KEY_BASE "smbtorture test"
31 #define TEST_KEY1 TEST_KEY_BASE "\\spottyfoot"
32 #define TEST_KEY2 TEST_KEY_BASE "\\with a SD (#1)"
33 #define TEST_KEY3 TEST_KEY_BASE "\\with a subkey"
34 #define TEST_KEY4 TEST_KEY_BASE "\\sd_tests"
35 #define TEST_SUBKEY TEST_KEY3 "\\subkey"
36 #define TEST_SUBKEY_SD  TEST_KEY4 "\\subkey_sd"
37 #define TEST_SUBSUBKEY_SD TEST_KEY4 "\\subkey_sd\\subsubkey_sd"
38
39 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
40
41 static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
42 {
43         name->string = s;
44 }
45
46 static void init_winreg_String(struct winreg_String *name, const char *s)
47 {
48         name->name = s;
49         if (s) {
50                 name->name_len = 2 * (strlen_m(s) + 1);
51                 name->name_size = name->name_len;
52         } else {
53                 name->name_len = 0;
54                 name->name_size = 0;
55         }
56 }
57
58 static bool test_GetVersion(struct dcerpc_pipe *p,
59                             struct torture_context *tctx,
60                             struct policy_handle *handle)
61 {
62         struct winreg_GetVersion r;
63         uint32_t v;
64
65         ZERO_STRUCT(r);
66         r.in.handle = handle;
67         r.out.version = &v;
68
69         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion(p, tctx, &r),
70                                    "GetVersion failed");
71
72         torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
73
74         return true;
75 }
76
77 static bool test_NotifyChangeKeyValue(struct dcerpc_pipe *p,
78                                       struct torture_context *tctx,
79                                       struct policy_handle *handle)
80 {
81         struct winreg_NotifyChangeKeyValue r;
82
83         ZERO_STRUCT(r);
84         r.in.handle = handle;
85         r.in.watch_subtree = true;
86         r.in.notify_filter = 0;
87         r.in.unknown = r.in.unknown2 = 0;
88         init_winreg_String(&r.in.string1, NULL);
89         init_winreg_String(&r.in.string2, NULL);
90
91         torture_assert_ntstatus_ok(tctx,
92                                    dcerpc_winreg_NotifyChangeKeyValue(p, tctx, &r),
93                                    "NotifyChangeKeyValue failed");
94
95         if (!W_ERROR_IS_OK(r.out.result)) {
96                 torture_comment(tctx,
97                                 "NotifyChangeKeyValue failed - %s - not considering\n",
98                                 win_errstr(r.out.result));
99                 return true;
100         }
101
102         return true;
103 }
104
105 static bool test_CreateKey(struct dcerpc_pipe *p, struct torture_context *tctx,
106                            struct policy_handle *handle, const char *name,
107                            const char *class)
108 {
109         struct winreg_CreateKey r;
110         struct policy_handle newhandle;
111         enum winreg_CreateAction action_taken = 0;
112
113         ZERO_STRUCT(r);
114         r.in.handle = handle;
115         r.out.new_handle = &newhandle;
116         init_winreg_String(&r.in.name, name);
117         init_winreg_String(&r.in.keyclass, class);
118         r.in.options = 0x0;
119         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
120         r.in.action_taken = r.out.action_taken = &action_taken;
121         r.in.secdesc = NULL;
122
123         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
124                                    "CreateKey failed");
125
126         torture_assert_werr_ok(tctx,  r.out.result, "CreateKey failed");
127
128         return true;
129 }
130
131
132 /*
133   createkey testing with a SD
134 */
135 static bool test_CreateKey_sd(struct dcerpc_pipe *p,
136                               struct torture_context *tctx,
137                               struct policy_handle *handle, const char *name,
138                               const char *class,
139                               struct policy_handle *newhandle)
140 {
141         struct winreg_CreateKey r;
142         enum winreg_CreateAction action_taken = 0;
143         struct security_descriptor *sd;
144         DATA_BLOB sdblob;
145         struct winreg_SecBuf secbuf;
146
147         sd = security_descriptor_dacl_create(tctx,
148                                         0,
149                                         NULL, NULL,
150                                         SID_NT_AUTHENTICATED_USERS,
151                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
152                                         SEC_GENERIC_ALL,
153                                         SEC_ACE_FLAG_OBJECT_INHERIT |
154                                         SEC_ACE_FLAG_CONTAINER_INHERIT,
155                                         NULL);
156
157         torture_assert_ndr_success(tctx,
158                 ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
159                                      (ndr_push_flags_fn_t)ndr_push_security_descriptor),
160                                      "Failed to push security_descriptor ?!\n");
161
162         secbuf.sd.data = sdblob.data;
163         secbuf.sd.len = sdblob.length;
164         secbuf.sd.size = sdblob.length;
165         secbuf.length = sdblob.length-10;
166         secbuf.inherit = 0;
167
168         ZERO_STRUCT(r);
169         r.in.handle = handle;
170         r.out.new_handle = newhandle;
171         init_winreg_String(&r.in.name, name);
172         init_winreg_String(&r.in.keyclass, class);
173         r.in.options = 0x0;
174         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
175         r.in.action_taken = r.out.action_taken = &action_taken;
176         r.in.secdesc = &secbuf;
177
178         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
179                                    "CreateKey with sd failed");
180
181         torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
182
183         return true;
184 }
185
186 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
187                                  struct torture_context *tctx,
188                                  struct policy_handle *handle,
189                                  uint32_t *sec_info_ptr,
190                                  WERROR get_werr,
191                                  struct security_descriptor **sd_out)
192 {
193         struct winreg_GetKeySecurity r;
194         struct security_descriptor *sd = NULL;
195         uint32_t sec_info;
196         DATA_BLOB sdblob;
197
198         if (sec_info_ptr) {
199                 sec_info = *sec_info_ptr;
200         } else {
201                 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
202         }
203
204         ZERO_STRUCT(r);
205
206         r.in.handle = handle;
207         r.in.sec_info = sec_info;
208         r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
209         r.in.sd->size = 0x1000;
210
211         torture_assert_ntstatus_ok(tctx,
212                                    dcerpc_winreg_GetKeySecurity(p, tctx, &r),
213                                    "GetKeySecurity failed");
214
215         torture_assert_werr_equal(tctx, r.out.result, get_werr,
216                                   "GetKeySecurity failed");
217
218         sdblob.data = r.out.sd->data;
219         sdblob.length = r.out.sd->len;
220
221         sd = talloc_zero(tctx, struct security_descriptor);
222
223         torture_assert_ndr_success(tctx,
224                 ndr_pull_struct_blob(&sdblob, tctx, NULL, sd,
225                                      (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
226                                      "pull_security_descriptor failed");
227
228         if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
229                 NDR_PRINT_DEBUG(security_descriptor, sd);
230         }
231
232         if (sd_out) {
233                 *sd_out = sd;
234         } else {
235                 talloc_free(sd);
236         }
237
238         return true;
239 }
240
241 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
242                                 struct torture_context *tctx,
243                                 struct policy_handle *handle,
244                                 struct security_descriptor **sd_out)
245 {
246         return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
247 }
248
249 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
250                                  struct torture_context *tctx,
251                                  struct policy_handle *handle,
252                                  uint32_t *sec_info_ptr,
253                                  struct security_descriptor *sd,
254                                  WERROR werr)
255 {
256         struct winreg_SetKeySecurity r;
257         struct KeySecurityData *sdata = NULL;
258         DATA_BLOB sdblob;
259         uint32_t sec_info;
260
261         ZERO_STRUCT(r);
262
263         if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
264                 NDR_PRINT_DEBUG(security_descriptor, sd);
265         }
266
267         torture_assert_ndr_success(tctx,
268                 ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
269                                      (ndr_push_flags_fn_t)ndr_push_security_descriptor),
270                                      "push_security_descriptor failed");
271
272         sdata = talloc_zero(tctx, struct KeySecurityData);
273         sdata->data = sdblob.data;
274         sdata->size = sdblob.length;
275         sdata->len = sdblob.length;
276
277         if (sec_info_ptr) {
278                 sec_info = *sec_info_ptr;
279         } else {
280                 sec_info = SECINFO_UNPROTECTED_SACL |
281                            SECINFO_UNPROTECTED_DACL;
282                 if (sd->owner_sid) {
283                         sec_info |= SECINFO_OWNER;
284                 }
285                 if (sd->group_sid) {
286                         sec_info |= SECINFO_GROUP;
287                 }
288                 if (sd->sacl) {
289                         sec_info |= SECINFO_SACL;
290                 }
291                 if (sd->dacl) {
292                         sec_info |= SECINFO_DACL;
293                 }
294         }
295
296         r.in.handle = handle;
297         r.in.sec_info = sec_info;
298         r.in.sd = sdata;
299
300         torture_assert_ntstatus_ok(tctx,
301                                    dcerpc_winreg_SetKeySecurity(p, tctx, &r),
302                                    "SetKeySecurity failed");
303
304         torture_assert_werr_equal(tctx, r.out.result, werr,
305                                   "SetKeySecurity failed");
306
307         return true;
308 }
309
310 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
311                                 struct torture_context *tctx,
312                                 struct policy_handle *handle,
313                                 struct security_descriptor *sd)
314 {
315         return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
316 }
317
318 static bool test_CloseKey(struct dcerpc_pipe *p, struct torture_context *tctx,
319                           struct policy_handle *handle)
320 {
321         struct winreg_CloseKey r;
322
323         ZERO_STRUCT(r);
324         r.in.handle = r.out.handle = handle;
325
326         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey(p, tctx, &r),
327                                    "CloseKey failed");
328
329         torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
330
331         return true;
332 }
333
334 static bool test_FlushKey(struct dcerpc_pipe *p, struct torture_context *tctx,
335                           struct policy_handle *handle)
336 {
337         struct winreg_FlushKey r;
338
339         ZERO_STRUCT(r);
340         r.in.handle = handle;
341
342         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey(p, tctx, &r),
343                                    "FlushKey failed");
344
345         torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
346
347         return true;
348 }
349
350 static bool _test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
351                           struct policy_handle *hive_handle,
352                           const char *keyname, uint32_t access_mask,
353                           struct policy_handle *key_handle,
354                           WERROR open_werr,
355                           bool *success)
356 {
357         struct winreg_OpenKey r;
358
359         ZERO_STRUCT(r);
360         r.in.parent_handle = hive_handle;
361         init_winreg_String(&r.in.keyname, keyname);
362         r.in.unknown = 0x00000000;
363         r.in.access_mask = access_mask;
364         r.out.handle = key_handle;
365
366         torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey(p, tctx, &r),
367                                    "OpenKey failed");
368
369         torture_assert_werr_equal(tctx, r.out.result, open_werr,
370                                   "OpenKey failed");
371
372         if (success && W_ERROR_EQUAL(r.out.result, WERR_OK)) {
373                 *success = true;
374         }
375
376         return true;
377 }
378
379 static bool test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
380                          struct policy_handle *hive_handle,
381                          const char *keyname, struct policy_handle *key_handle)
382 {
383         return _test_OpenKey(p, tctx, hive_handle, keyname,
384                              SEC_FLAG_MAXIMUM_ALLOWED, key_handle,
385                              WERR_OK, NULL);
386 }
387
388 static bool test_Cleanup(struct dcerpc_pipe *p, struct torture_context *tctx,
389                          struct policy_handle *handle, const char *key)
390 {
391         struct winreg_DeleteKey r;
392
393         ZERO_STRUCT(r);
394         r.in.handle = handle;
395
396         init_winreg_String(&r.in.key, key);
397         dcerpc_winreg_DeleteKey(p, tctx, &r);
398
399         return true;
400 }
401
402 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
403                                            struct torture_context *tctx,
404                                            struct policy_handle *handle,
405                                            WERROR get_werr,
406                                            WERROR set_werr)
407 {
408         struct security_descriptor *sd = NULL;
409
410         if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
411                 return false;
412         }
413
414         if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
415                 return false;
416         }
417
418         return true;
419 }
420
421 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
422                                     struct torture_context *tctx,
423                                     struct policy_handle *handle,
424                                     const char *key)
425 {
426         struct policy_handle new_handle;
427         bool ret = true;
428
429         torture_comment(tctx, "SecurityDescriptor get & set\n");
430
431         if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
432                 return false;
433         }
434
435         if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
436                                             WERR_OK, WERR_OK)) {
437                 ret = false;
438         }
439
440         if (!test_CloseKey(p, tctx, &new_handle)) {
441                 return false;
442         }
443
444         return ret;
445 }
446
447 static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
448                                      struct torture_context *tctx,
449                                      struct policy_handle *handle,
450                                      uint32_t access_mask,
451                                      const char *key,
452                                      WERROR open_werr,
453                                      WERROR get_werr,
454                                      WERROR set_werr)
455 {
456         struct policy_handle new_handle;
457         bool ret = true;
458         bool got_key = false;
459
460         if (!_test_OpenKey(p, tctx, handle, key, access_mask, &new_handle,
461                            open_werr, &got_key)) {
462                 return false;
463         }
464
465         if (!got_key) {
466                 return true;
467         }
468
469         if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
470                                             get_werr, set_werr)) {
471                 ret = false;
472         }
473
474         if (!test_CloseKey(p, tctx, &new_handle)) {
475                 return false;
476         }
477
478         return ret;
479 }
480
481 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
482                                       struct torture_context *tctx,
483                                       struct policy_handle *handle,
484                                       const struct dom_sid *sid)
485 {
486         struct security_descriptor *sd = NULL;
487         int i;
488
489         if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
490                 return false;
491         }
492
493         if (!sd || !sd->dacl) {
494                 return false;
495         }
496
497         for (i = 0; i < sd->dacl->num_aces; i++) {
498                 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
499                         return true;
500                 }
501         }
502
503         return false;
504 }
505
506 static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
507                                        struct torture_context *tctx,
508                                        struct policy_handle *handle,
509                                        const char *key,
510                                        const struct dom_sid *sid)
511 {
512         struct policy_handle new_handle;
513         bool ret = true;
514
515         if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
516                 return false;
517         }
518
519         ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
520
521         test_CloseKey(p, tctx, &new_handle);
522
523         return ret;
524 }
525
526 static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
527                                       struct torture_context *tctx,
528                                       struct policy_handle *handle,
529                                       const struct dom_sid *sid)
530 {
531         struct security_descriptor *sd = NULL;
532         int i;
533         uint32_t sec_info = SECINFO_SACL;
534
535         if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
536                 return false;
537         }
538
539         if (!sd || !sd->sacl) {
540                 return false;
541         }
542
543         for (i = 0; i < sd->sacl->num_aces; i++) {
544                 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
545                         return true;
546                 }
547         }
548
549         return false;
550 }
551
552 static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
553                                        struct torture_context *tctx,
554                                        struct policy_handle *handle,
555                                        const char *key,
556                                        const struct dom_sid *sid)
557 {
558         struct policy_handle new_handle;
559         bool ret = true;
560
561         if (!_test_OpenKey(p, tctx, handle, key, SEC_FLAG_SYSTEM_SECURITY,
562                            &new_handle, WERR_OK, NULL)) {
563                 return false;
564         }
565
566         ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
567
568         test_CloseKey(p, tctx, &new_handle);
569
570         return ret;
571 }
572
573 static bool test_owner_present(struct dcerpc_pipe *p,
574                                struct torture_context *tctx,
575                                struct policy_handle *handle,
576                                const struct dom_sid *sid)
577 {
578         struct security_descriptor *sd = NULL;
579         uint32_t sec_info = SECINFO_OWNER;
580
581         if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
582                 return false;
583         }
584
585         if (!sd || !sd->owner_sid) {
586                 return false;
587         }
588
589         return dom_sid_equal(sd->owner_sid, sid);
590 }
591
592 static bool _test_owner_present(struct dcerpc_pipe *p,
593                                 struct torture_context *tctx,
594                                 struct policy_handle *handle,
595                                 const char *key,
596                                 const struct dom_sid *sid)
597 {
598         struct policy_handle new_handle;
599         bool ret = true;
600
601         if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
602                 return false;
603         }
604
605         ret = test_owner_present(p, tctx, &new_handle, sid);
606
607         test_CloseKey(p, tctx, &new_handle);
608
609         return ret;
610 }
611
612 static bool test_group_present(struct dcerpc_pipe *p,
613                                struct torture_context *tctx,
614                                struct policy_handle *handle,
615                                const struct dom_sid *sid)
616 {
617         struct security_descriptor *sd = NULL;
618         uint32_t sec_info = SECINFO_GROUP;
619
620         if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
621                 return false;
622         }
623
624         if (!sd || !sd->group_sid) {
625                 return false;
626         }
627
628         return dom_sid_equal(sd->group_sid, sid);
629 }
630
631 static bool _test_group_present(struct dcerpc_pipe *p,
632                                 struct torture_context *tctx,
633                                 struct policy_handle *handle,
634                                 const char *key,
635                                 const struct dom_sid *sid)
636 {
637         struct policy_handle new_handle;
638         bool ret = true;
639
640         if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
641                 return false;
642         }
643
644         ret = test_group_present(p, tctx, &new_handle, sid);
645
646         test_CloseKey(p, tctx, &new_handle);
647
648         return ret;
649 }
650
651 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
652                                             struct torture_context *tctx,
653                                             struct policy_handle *handle,
654                                             const struct dom_sid *sid,
655                                             uint8_t flags)
656 {
657         struct security_descriptor *sd = NULL;
658         int i;
659
660         if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
661                 return false;
662         }
663
664         if (!sd || !sd->dacl) {
665                 return false;
666         }
667
668         for (i = 0; i < sd->dacl->num_aces; i++) {
669                 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
670                     (sd->dacl->aces[i].flags == flags)) {
671                         return true;
672                 }
673         }
674
675         return false;
676 }
677
678 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
679                                   struct torture_context *tctx,
680                                   struct policy_handle *handle,
681                                   const struct security_ace *ace)
682 {
683         struct security_descriptor *sd = NULL;
684         int i;
685
686         if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
687                 return false;
688         }
689
690         if (!sd || !sd->dacl) {
691                 return false;
692         }
693
694         for (i = 0; i < sd->dacl->num_aces; i++) {
695                 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
696                         return true;
697                 }
698         }
699
700         return false;
701 }
702
703 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
704                                  struct torture_context *tctx,
705                                  struct policy_handle *handle,
706                                  const char *key,
707                                  struct security_descriptor *sd)
708 {
709         struct policy_handle new_handle;
710         bool ret = true;
711
712         if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
713                 return false;
714         }
715
716         if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
717                 ret = false;
718         }
719
720         if (!test_CloseKey(p, tctx, &new_handle)) {
721                 ret = false;
722         }
723
724         return ret;
725 }
726
727 static bool test_BackupSecurity(struct dcerpc_pipe *p,
728                                 struct torture_context *tctx,
729                                 struct policy_handle *handle,
730                                 const char *key,
731                                 struct security_descriptor **sd)
732 {
733         struct policy_handle new_handle;
734         bool ret = true;
735
736         if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
737                 return false;
738         }
739
740         if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
741                 ret = false;
742         }
743
744         if (!test_CloseKey(p, tctx, &new_handle)) {
745                 ret = false;
746         }
747
748         return ret;
749 }
750
751 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
752                                                struct torture_context *tctx,
753                                                struct policy_handle *handle,
754                                                const char *key)
755 {
756         /* get sd
757            add ace SEC_ACE_FLAG_CONTAINER_INHERIT
758            set sd
759            get sd
760            check ace
761            add subkey
762            get sd
763            check ace
764            add subsubkey
765            get sd
766            check ace
767            del subsubkey
768            del subkey
769            reset sd
770         */
771
772         struct security_descriptor *sd = NULL;
773         struct security_descriptor *sd_orig = NULL;
774         struct security_ace *ace = NULL;
775         struct policy_handle new_handle;
776         NTSTATUS status;
777         bool ret = true;
778
779         torture_comment(tctx, "SecurityDescriptor inheritance\n");
780
781         if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
782                 return false;
783         }
784
785         if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
786                 return false;
787         }
788
789         sd_orig = security_descriptor_copy(tctx, sd);
790         if (sd_orig == NULL) {
791                 return false;
792         }
793
794         ace = security_ace_create(tctx,
795                                   TEST_SID,
796                                   SEC_ACE_TYPE_ACCESS_ALLOWED,
797                                   SEC_STD_REQUIRED,
798                                   SEC_ACE_FLAG_CONTAINER_INHERIT);
799
800         status = security_descriptor_dacl_add(sd, ace);
801         if (!NT_STATUS_IS_OK(status)) {
802                 printf("failed to add ace: %s\n", nt_errstr(status));
803                 return false;
804         }
805
806         /* FIXME: add further tests for these flags */
807         sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
808                     SEC_DESC_SACL_AUTO_INHERITED;
809
810         if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
811                 return false;
812         }
813
814         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
815                 printf("new ACE not present!\n");
816                 return false;
817         }
818
819         if (!test_CloseKey(p, tctx, &new_handle)) {
820                 return false;
821         }
822
823         if (!test_CreateKey(p, tctx, handle, TEST_SUBKEY_SD, NULL)) {
824                 ret = false;
825                 goto out;
826         }
827
828         if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
829                 ret = false;
830                 goto out;
831         }
832
833         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
834                 printf("inherited ACE not present!\n");
835                 ret = false;
836                 goto out;
837         }
838
839         test_CloseKey(p, tctx, &new_handle);
840         if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
841                 ret = false;
842                 goto out;
843         }
844
845         if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
846                 ret = false;
847                 goto out;
848         }
849
850         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
851                 printf("inherited ACE not present!\n");
852                 ret = false;
853                 goto out;
854         }
855
856  out:
857         test_CloseKey(p, tctx, &new_handle);
858         test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
859         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
860
861         return true;
862 }
863
864 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
865                                                     struct torture_context *tctx,
866                                                     struct policy_handle *handle,
867                                                     const char *key)
868 {
869         /* get sd
870            add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
871            set sd
872            add subkey/subkey
873            get sd
874            check ace
875            get sd from subkey
876            check ace
877            del subkey/subkey
878            del subkey
879            reset sd
880         */
881
882         struct security_descriptor *sd = NULL;
883         struct security_descriptor *sd_orig = NULL;
884         struct security_ace *ace = NULL;
885         struct policy_handle new_handle;
886         struct dom_sid *sid = NULL;
887         NTSTATUS status;
888         bool ret = true;
889         uint8_t ace_flags = 0x0;
890
891         torture_comment(tctx, "SecurityDescriptor inheritance block\n");
892
893         if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
894                 return false;
895         }
896
897         if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
898                 return false;
899         }
900
901         sd_orig = security_descriptor_copy(tctx, sd);
902         if (sd_orig == NULL) {
903                 return false;
904         }
905
906         ace = security_ace_create(tctx,
907                                   TEST_SID,
908                                   SEC_ACE_TYPE_ACCESS_ALLOWED,
909                                   SEC_STD_REQUIRED,
910                                   SEC_ACE_FLAG_CONTAINER_INHERIT |
911                                   SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
912
913         status = security_descriptor_dacl_add(sd, ace);
914         if (!NT_STATUS_IS_OK(status)) {
915                 printf("failed to add ace: %s\n", nt_errstr(status));
916                 return false;
917         }
918
919         if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
920                 return false;
921         }
922
923         if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
924                 printf("new ACE not present!\n");
925                 return false;
926         }
927
928         if (!test_CloseKey(p, tctx, &new_handle)) {
929                 return false;
930         }
931
932         if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
933                 return false;
934         }
935
936         if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
937                 ret = false;
938                 goto out;
939         }
940
941         if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
942                 printf("inherited ACE present but should not!\n");
943                 ret = false;
944                 goto out;
945         }
946
947         sid = dom_sid_parse_talloc(tctx, TEST_SID);
948         if (sid == NULL) {
949                 return false;
950         }
951
952         if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
953                 printf("inherited trustee SID present but should not!\n");
954                 ret = false;
955                 goto out;
956         }
957
958         test_CloseKey(p, tctx, &new_handle);
959
960         if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
961                 ret = false;
962                 goto out;
963         }
964
965         if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
966                 printf("inherited ACE present but should not!\n");
967                 ret = false;
968                 goto out;
969         }
970
971         if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
972                 printf("inherited trustee SID with flags 0x%02x not present!\n",
973                         ace_flags);
974                 ret = false;
975                 goto out;
976         }
977
978  out:
979         test_CloseKey(p, tctx, &new_handle);
980         test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
981         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
982
983         return ret;
984 }
985
986 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
987                                           struct torture_context *tctx,
988                                           struct policy_handle *handle,
989                                           const char *key)
990 {
991         bool ret = true;
992         int i;
993
994         struct winreg_mask_result_table {
995                 uint32_t access_mask;
996                 WERROR open_werr;
997                 WERROR get_werr;
998                 WERROR set_werr;
999         } sd_mask_tests[] = {
1000                 { 0,
1001                         WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1002                 { SEC_FLAG_MAXIMUM_ALLOWED,
1003                         WERR_OK, WERR_OK, WERR_OK },
1004                 { SEC_STD_WRITE_DAC,
1005                         WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1006                 { SEC_FLAG_SYSTEM_SECURITY,
1007                         WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1008         };
1009
1010         /* FIXME: before this test can ever run successfully we need a way to
1011          * correctly read a NULL security_descritpor in ndr, get the required
1012          * length, requery, etc.
1013          */
1014
1015         return true;
1016
1017         for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1018
1019                 torture_comment(tctx,
1020                                 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1021                                 sd_mask_tests[i].access_mask);
1022                 torture_comment(tctx,
1023                                 "expecting: open %s, get: %s, set: %s\n",
1024                                 win_errstr(sd_mask_tests[i].open_werr),
1025                                 win_errstr(sd_mask_tests[i].get_werr),
1026                                 win_errstr(sd_mask_tests[i].set_werr));
1027
1028                 if (_test_SecurityDescriptor(p, tctx, handle,
1029                                              sd_mask_tests[i].access_mask, key,
1030                                              sd_mask_tests[i].open_werr,
1031                                              sd_mask_tests[i].get_werr,
1032                                              sd_mask_tests[i].set_werr)) {
1033                         ret = false;
1034                 }
1035         }
1036
1037         return ret;
1038 }
1039
1040 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1041                                   struct torture_context *,
1042                                   struct policy_handle *,
1043                                   const char *,
1044                                   const struct dom_sid *);
1045
1046 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1047                                                struct torture_context *tctx,
1048                                                struct policy_handle *handle,
1049                                                const char *key,
1050                                                const char *test,
1051                                                uint32_t access_mask,
1052                                                uint32_t sec_info,
1053                                                struct security_descriptor *sd,
1054                                                WERROR set_werr,
1055                                                bool expect_present,
1056                                                bool (*fn) (struct dcerpc_pipe *,
1057                                                            struct torture_context *,
1058                                                            struct policy_handle *,
1059                                                            const char *,
1060                                                            const struct dom_sid *),
1061                                                const struct dom_sid *sid)
1062 {
1063         struct policy_handle new_handle;
1064         bool open_success = false;
1065
1066         torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1067                         "0x%08x, access_mask: 0x%08x\n",
1068                         test, sec_info, access_mask);
1069
1070         if (!_test_OpenKey(p, tctx, handle, key,
1071                            access_mask,
1072                            &new_handle,
1073                            WERR_OK,
1074                            &open_success)) {
1075                 return false;
1076         }
1077
1078         if (!open_success) {
1079                 printf("key did not open\n");
1080                 test_CloseKey(p, tctx, &new_handle);
1081                 return false;
1082         }
1083
1084         if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1085                                   sd,
1086                                   set_werr)) {
1087                 torture_warning(tctx,
1088                                 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1089                                 sec_info);
1090                 smb_panic("");
1091                 test_CloseKey(p, tctx, &new_handle);
1092                 return false;
1093         }
1094
1095         test_CloseKey(p, tctx, &new_handle);
1096
1097         if (W_ERROR_IS_OK(set_werr)) {
1098                 bool present;
1099                 present = fn(p, tctx, handle, key, sid);
1100                 if ((expect_present) && (!present)) {
1101                         torture_warning(tctx,
1102                                         "%s sid is not present!\n",
1103                                         test);
1104                         return false;
1105                 }
1106                 if ((!expect_present) && (present)) {
1107                         torture_warning(tctx,
1108                                         "%s sid is present but not expected!\n",
1109                                         test);
1110                         return false;
1111                 }
1112         }
1113
1114         return true;
1115 }
1116
1117 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1118                                             struct torture_context *tctx,
1119                                             struct policy_handle *handle,
1120                                             const char *key)
1121 {
1122         struct security_descriptor *sd_orig = NULL;
1123         struct dom_sid *sid = NULL;
1124         bool ret = true;
1125         int i, a;
1126
1127         struct security_descriptor *sd_owner =
1128                 security_descriptor_dacl_create(tctx,
1129                                                 0,
1130                                                 TEST_SID, NULL, NULL);
1131
1132         struct security_descriptor *sd_group =
1133                 security_descriptor_dacl_create(tctx,
1134                                                 0,
1135                                                 NULL, TEST_SID, NULL);
1136
1137         struct security_descriptor *sd_dacl =
1138                 security_descriptor_dacl_create(tctx,
1139                                                 0,
1140                                                 NULL, NULL,
1141                                                 TEST_SID,
1142                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1143                                                 SEC_GENERIC_ALL,
1144                                                 0,
1145                                                 SID_NT_AUTHENTICATED_USERS,
1146                                                 SEC_ACE_TYPE_ACCESS_ALLOWED,
1147                                                 SEC_GENERIC_ALL,
1148                                                 0,
1149                                                 NULL);
1150
1151         struct security_descriptor *sd_sacl =
1152                 security_descriptor_sacl_create(tctx,
1153                                                 0,
1154                                                 NULL, NULL,
1155                                                 TEST_SID,
1156                                                 SEC_ACE_TYPE_SYSTEM_AUDIT,
1157                                                 SEC_GENERIC_ALL,
1158                                                 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1159                                                 NULL);
1160
1161         struct winreg_secinfo_table {
1162                 struct security_descriptor *sd;
1163                 uint32_t sec_info;
1164                 WERROR set_werr;
1165                 bool sid_present;
1166                 secinfo_verify_fn fn;
1167         };
1168
1169         struct winreg_secinfo_table sec_info_owner_tests[] = {
1170                 { sd_owner, 0, WERR_OK,
1171                         false, (secinfo_verify_fn)_test_owner_present },
1172                 { sd_owner, SECINFO_OWNER, WERR_OK,
1173                         true, (secinfo_verify_fn)_test_owner_present },
1174                 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1175                 { sd_owner, SECINFO_DACL, WERR_OK,
1176                         true, (secinfo_verify_fn)_test_owner_present },
1177                 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1178         };
1179
1180         uint32_t sd_owner_good_access_masks[] = {
1181                 SEC_FLAG_MAXIMUM_ALLOWED,
1182                 /* SEC_STD_WRITE_OWNER, */
1183         };
1184
1185         struct winreg_secinfo_table sec_info_group_tests[] = {
1186                 { sd_group, 0, WERR_OK,
1187                         false, (secinfo_verify_fn)_test_group_present },
1188                 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1189                 { sd_group, SECINFO_GROUP, WERR_OK,
1190                         true, (secinfo_verify_fn)_test_group_present },
1191                 { sd_group, SECINFO_DACL, WERR_OK,
1192                         true, (secinfo_verify_fn)_test_group_present },
1193                 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1194         };
1195
1196         uint32_t sd_group_good_access_masks[] = {
1197                 SEC_FLAG_MAXIMUM_ALLOWED,
1198         };
1199
1200         struct winreg_secinfo_table sec_info_dacl_tests[] = {
1201                 { sd_dacl, 0, WERR_OK,
1202                         false, (secinfo_verify_fn)_test_dacl_trustee_present },
1203                 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1204                 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1205                 { sd_dacl, SECINFO_DACL, WERR_OK,
1206                         true, (secinfo_verify_fn)_test_dacl_trustee_present },
1207                 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1208         };
1209
1210         uint32_t sd_dacl_good_access_masks[] = {
1211                 SEC_FLAG_MAXIMUM_ALLOWED,
1212                 SEC_STD_WRITE_DAC,
1213         };
1214
1215         struct winreg_secinfo_table sec_info_sacl_tests[] = {
1216                 { sd_sacl, 0, WERR_OK,
1217                         false, (secinfo_verify_fn)_test_sacl_trustee_present },
1218                 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1219                 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1220                 { sd_sacl, SECINFO_DACL, WERR_OK,
1221                         false, (secinfo_verify_fn)_test_sacl_trustee_present },
1222                 { sd_sacl, SECINFO_SACL, WERR_OK,
1223                         true, (secinfo_verify_fn)_test_sacl_trustee_present },
1224         };
1225
1226         uint32_t sd_sacl_good_access_masks[] = {
1227                 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1228                 /* SEC_FLAG_SYSTEM_SECURITY, */
1229         };
1230
1231         sid = dom_sid_parse_talloc(tctx, TEST_SID);
1232         if (sid == NULL) {
1233                 return false;
1234         }
1235
1236         if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1237                 return false;
1238         }
1239
1240         /* OWNER */
1241
1242         for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1243
1244                 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1245
1246                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1247                                         key,
1248                                         "OWNER",
1249                                         sd_owner_good_access_masks[a],
1250                                         sec_info_owner_tests[i].sec_info,
1251                                         sec_info_owner_tests[i].sd,
1252                                         sec_info_owner_tests[i].set_werr,
1253                                         sec_info_owner_tests[i].sid_present,
1254                                         sec_info_owner_tests[i].fn,
1255                                         sid))
1256                         {
1257                                 printf("test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1258                                 ret = false;
1259                                 goto out;
1260                         }
1261                 }
1262         }
1263
1264         /* GROUP */
1265
1266         for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1267
1268                 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1269
1270                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1271                                         key,
1272                                         "GROUP",
1273                                         sd_group_good_access_masks[a],
1274                                         sec_info_group_tests[i].sec_info,
1275                                         sec_info_group_tests[i].sd,
1276                                         sec_info_group_tests[i].set_werr,
1277                                         sec_info_group_tests[i].sid_present,
1278                                         sec_info_group_tests[i].fn,
1279                                         sid))
1280                         {
1281                                 printf("test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1282                                 ret = false;
1283                                 goto out;
1284                         }
1285                 }
1286         }
1287
1288         /* DACL */
1289
1290         for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1291
1292                 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1293
1294                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1295                                         key,
1296                                         "DACL",
1297                                         sd_dacl_good_access_masks[a],
1298                                         sec_info_dacl_tests[i].sec_info,
1299                                         sec_info_dacl_tests[i].sd,
1300                                         sec_info_dacl_tests[i].set_werr,
1301                                         sec_info_dacl_tests[i].sid_present,
1302                                         sec_info_dacl_tests[i].fn,
1303                                         sid))
1304                         {
1305                                 printf("test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1306                                 ret = false;
1307                                 goto out;
1308                         }
1309                 }
1310         }
1311
1312         /* SACL */
1313
1314         for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1315
1316                 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1317
1318                         if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1319                                         key,
1320                                         "SACL",
1321                                         sd_sacl_good_access_masks[a],
1322                                         sec_info_sacl_tests[i].sec_info,
1323                                         sec_info_sacl_tests[i].sd,
1324                                         sec_info_sacl_tests[i].set_werr,
1325                                         sec_info_sacl_tests[i].sid_present,
1326                                         sec_info_sacl_tests[i].fn,
1327                                         sid))
1328                         {
1329                                 printf("test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1330                                 ret = false;
1331                                 goto out;
1332                         }
1333                 }
1334         }
1335
1336  out:
1337         test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1338
1339         return ret;
1340 }
1341
1342 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1343                                      struct torture_context *tctx,
1344                                      struct policy_handle *handle,
1345                                      const char *key)
1346 {
1347         bool ret = true;
1348
1349         if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1350                 printf("test_SecurityDescriptor failed\n");
1351                 ret = false;
1352         }
1353
1354         if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1355                 printf("test_SecurityDescriptorInheritance failed\n");
1356                 ret = false;
1357         }
1358
1359         if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1360                 printf("test_SecurityDescriptorBlockInheritance failed\n");
1361                 ret = false;
1362         }
1363
1364         if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1365                 printf("test_SecurityDescriptorsSecInfo failed\n");
1366                 ret = false;
1367         }
1368
1369         if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1370                 printf("test_SecurityDescriptorsMasks failed\n");
1371                 ret = false;
1372         }
1373
1374         return ret;
1375 }
1376
1377 static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1378                            struct policy_handle *handle, const char *key)
1379 {
1380         NTSTATUS status;
1381         struct winreg_DeleteKey r;
1382
1383         r.in.handle = handle;
1384         init_winreg_String(&r.in.key, key);
1385
1386         status = dcerpc_winreg_DeleteKey(p, tctx, &r);
1387
1388         torture_assert_ntstatus_ok(tctx, status, "DeleteKey failed");
1389         torture_assert_werr_ok(tctx, r.out.result, "DeleteKey failed");
1390
1391         return true;
1392 }
1393
1394 static bool test_QueryInfoKey(struct dcerpc_pipe *p,
1395                               struct torture_context *tctx,
1396                               struct policy_handle *handle, char *class)
1397 {
1398         struct winreg_QueryInfoKey r;
1399         uint32_t num_subkeys, max_subkeylen, max_subkeysize,
1400                 num_values, max_valnamelen, max_valbufsize,
1401                 secdescsize;
1402         NTTIME last_changed_time;
1403
1404         ZERO_STRUCT(r);
1405         r.in.handle = handle;
1406         r.out.num_subkeys = &num_subkeys;
1407         r.out.max_subkeylen = &max_subkeylen;
1408         r.out.max_subkeysize = &max_subkeysize;
1409         r.out.num_values = &num_values;
1410         r.out.max_valnamelen = &max_valnamelen;
1411         r.out.max_valbufsize = &max_valbufsize;
1412         r.out.secdescsize = &secdescsize;
1413         r.out.last_changed_time = &last_changed_time;
1414
1415         r.out.classname = talloc(tctx, struct winreg_String);
1416
1417         r.in.classname = talloc(tctx, struct winreg_String);
1418         init_winreg_String(r.in.classname, class);
1419
1420         torture_assert_ntstatus_ok(tctx,
1421                                    dcerpc_winreg_QueryInfoKey(p, tctx, &r),
1422                                    "QueryInfoKey failed");
1423
1424         torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1425
1426         return true;
1427 }
1428
1429 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1430                      struct policy_handle *handle, int depth,
1431                      bool test_security);
1432
1433 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1434                          struct policy_handle *handle, int depth,
1435                          bool test_security)
1436 {
1437         struct winreg_EnumKey r;
1438         struct winreg_StringBuf class, name;
1439         NTSTATUS status;
1440         NTTIME t = 0;
1441
1442         class.name   = "";
1443         class.size   = 1024;
1444
1445         ZERO_STRUCT(r);
1446         r.in.handle = handle;
1447         r.in.enum_index = 0;
1448         r.in.name = &name;
1449         r.in.keyclass = &class;
1450         r.out.name = &name;
1451         r.in.last_changed_time = &t;
1452
1453         do {
1454                 name.name   = NULL;
1455                 name.size   = 1024;
1456
1457                 status = dcerpc_winreg_EnumKey(p, tctx, &r);
1458
1459                 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1460                         struct policy_handle key_handle;
1461
1462                         torture_comment(tctx, "EnumKey: %d: %s\n",
1463                                         r.in.enum_index,
1464                                         r.out.name->name);
1465
1466                         if (!test_OpenKey(p, tctx, handle, r.out.name->name,
1467                                           &key_handle)) {
1468                         } else {
1469                                 test_key(p, tctx, &key_handle,
1470                                          depth + 1, test_security);
1471                         }
1472                 }
1473
1474                 r.in.enum_index++;
1475
1476         } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1477
1478         torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1479
1480         if (!W_ERROR_IS_OK(r.out.result) &&
1481                 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1482                 torture_fail(tctx, "EnumKey failed");
1483         }
1484
1485         return true;
1486 }
1487
1488 static bool test_QueryMultipleValues(struct dcerpc_pipe *p,
1489                                      struct torture_context *tctx,
1490                                      struct policy_handle *handle,
1491                                      const char *valuename)
1492 {
1493         struct winreg_QueryMultipleValues r;
1494         NTSTATUS status;
1495         uint32_t bufsize=0;
1496
1497         ZERO_STRUCT(r);
1498         r.in.key_handle = handle;
1499         r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1500         r.in.values[0].name = talloc(tctx, struct winreg_String);
1501         r.in.values[0].name->name = valuename;
1502         r.in.values[0].offset = 0;
1503         r.in.values[0].length = 0;
1504         r.in.values[0].type = 0;
1505
1506         r.in.num_values = 1;
1507         r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1508         *r.in.buffer_size = bufsize;
1509         do {
1510                 *r.in.buffer_size = bufsize;
1511                 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1512                                                                *r.in.buffer_size);
1513
1514                 status = dcerpc_winreg_QueryMultipleValues(p, tctx, &r);
1515
1516                 if(NT_STATUS_IS_ERR(status))
1517                         torture_fail(tctx, "QueryMultipleValues failed");
1518
1519                 talloc_free(r.in.buffer);
1520                 bufsize += 0x20;
1521         } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1522
1523         torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1524
1525         return true;
1526 }
1527
1528 static bool test_QueryValue(struct dcerpc_pipe *p,
1529                             struct torture_context *tctx,
1530                             struct policy_handle *handle,
1531                             const char *valuename)
1532 {
1533         struct winreg_QueryValue r;
1534         NTSTATUS status;
1535         enum winreg_Type zero_type = 0;
1536         uint32_t offered = 0xfff;
1537         uint32_t zero = 0;
1538
1539         ZERO_STRUCT(r);
1540         r.in.handle = handle;
1541         r.in.data = NULL;
1542         r.in.value_name = talloc_zero(tctx, struct winreg_String);
1543         r.in.value_name->name = valuename;
1544         r.in.type = &zero_type;
1545         r.in.data_size = &offered;
1546         r.in.data_length = &zero;
1547
1548         status = dcerpc_winreg_QueryValue(p, tctx, &r);
1549         if (NT_STATUS_IS_ERR(status)) {
1550                 torture_fail(tctx, "QueryValue failed");
1551         }
1552
1553         torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1554
1555         return true;
1556 }
1557
1558 static bool test_EnumValue(struct dcerpc_pipe *p, struct torture_context *tctx,
1559                            struct policy_handle *handle, int max_valnamelen,
1560                            int max_valbufsize)
1561 {
1562         struct winreg_EnumValue r;
1563         enum winreg_Type type = 0;
1564         uint32_t size = max_valbufsize, zero = 0;
1565         bool ret = true;
1566         uint8_t buf8;
1567         struct winreg_StringBuf name;
1568
1569         name.name   = "";
1570         name.size   = 1024;
1571
1572         ZERO_STRUCT(r);
1573         r.in.handle = handle;
1574         r.in.enum_index = 0;
1575         r.in.name = &name;
1576         r.out.name = &name;
1577         r.in.type = &type;
1578         r.in.value = &buf8;
1579         r.in.length = &zero;
1580         r.in.size = &size;
1581
1582         do {
1583                 torture_assert_ntstatus_ok(tctx,
1584                                            dcerpc_winreg_EnumValue(p, tctx, &r),
1585                                            "EnumValue failed");
1586
1587                 if (W_ERROR_IS_OK(r.out.result)) {
1588                         ret &= test_QueryValue(p, tctx, handle,
1589                                                r.out.name->name);
1590                         ret &= test_QueryMultipleValues(p, tctx, handle,
1591                                                         r.out.name->name);
1592                 }
1593
1594                 r.in.enum_index++;
1595         } while (W_ERROR_IS_OK(r.out.result));
1596
1597         torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1598                                   "EnumValue failed");
1599
1600         return ret;
1601 }
1602
1603 static bool test_AbortSystemShutdown(struct dcerpc_pipe *p,
1604                                      struct torture_context *tctx)
1605 {
1606         struct winreg_AbortSystemShutdown r;
1607         uint16_t server = 0x0;
1608
1609         ZERO_STRUCT(r);
1610         r.in.server = &server;
1611
1612         torture_assert_ntstatus_ok(tctx,
1613                                    dcerpc_winreg_AbortSystemShutdown(p, tctx, &r),
1614                                    "AbortSystemShutdown failed");
1615
1616         torture_assert_werr_ok(tctx, r.out.result,
1617                                "AbortSystemShutdown failed");
1618
1619         return true;
1620 }
1621
1622 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1623                                         struct dcerpc_pipe *p)
1624 {
1625         struct winreg_InitiateSystemShutdown r;
1626         uint16_t hostname = 0x0;
1627
1628         ZERO_STRUCT(r);
1629         r.in.hostname = &hostname;
1630         r.in.message = talloc(tctx, struct lsa_StringLarge);
1631         init_lsa_StringLarge(r.in.message, "spottyfood");
1632         r.in.force_apps = 1;
1633         r.in.timeout = 30;
1634         r.in.do_reboot = 1;
1635
1636         torture_assert_ntstatus_ok(tctx,
1637                                    dcerpc_winreg_InitiateSystemShutdown(p, tctx, &r),
1638                                    "InitiateSystemShutdown failed");
1639
1640         torture_assert_werr_ok(tctx, r.out.result,
1641                                "InitiateSystemShutdown failed");
1642
1643         return test_AbortSystemShutdown(p, tctx);
1644 }
1645
1646
1647 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1648                                           struct dcerpc_pipe *p)
1649 {
1650         struct winreg_InitiateSystemShutdownEx r;
1651         uint16_t hostname = 0x0;
1652
1653         ZERO_STRUCT(r);
1654         r.in.hostname = &hostname;
1655         r.in.message = talloc(tctx, struct lsa_StringLarge);
1656         init_lsa_StringLarge(r.in.message, "spottyfood");
1657         r.in.force_apps = 1;
1658         r.in.timeout = 30;
1659         r.in.do_reboot = 1;
1660         r.in.reason = 0;
1661
1662         torture_assert_ntstatus_ok(tctx,
1663                 dcerpc_winreg_InitiateSystemShutdownEx(p, tctx, &r),
1664                 "InitiateSystemShutdownEx failed");
1665
1666         torture_assert_werr_ok(tctx, r.out.result,
1667                                "InitiateSystemShutdownEx failed");
1668
1669         return test_AbortSystemShutdown(p, tctx);
1670 }
1671 #define MAX_DEPTH 2             /* Only go this far down the tree */
1672
1673 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1674                      struct policy_handle *handle, int depth,
1675                      bool test_security)
1676 {
1677         if (depth == MAX_DEPTH)
1678                 return true;
1679
1680         if (!test_QueryInfoKey(p, tctx, handle, NULL)) {
1681         }
1682
1683         if (!test_NotifyChangeKeyValue(p, tctx, handle)) {
1684         }
1685
1686         if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1687         }
1688
1689         if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1690         }
1691
1692         if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) {
1693         }
1694
1695         test_CloseKey(p, tctx, handle);
1696
1697         return true;
1698 }
1699
1700 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
1701
1702 static bool test_Open_Security(struct torture_context *tctx,
1703                                struct dcerpc_pipe *p, void *userdata)
1704 {
1705         struct policy_handle handle, newhandle;
1706         bool ret = true, created2 = false;
1707         bool created4 = false;
1708         struct winreg_OpenHKLM r;
1709
1710         winreg_open_fn open_fn = userdata;
1711
1712         ZERO_STRUCT(r);
1713         r.in.system_name = 0;
1714         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1715         r.out.handle = &handle;
1716
1717         torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1718                                    "open");
1719
1720         test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1721
1722         if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1723                 torture_comment(tctx,
1724                                 "CreateKey (TEST_KEY_BASE) failed\n");
1725         }
1726
1727         if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
1728                               NULL, &newhandle)) {
1729                 created2 = true;
1730         }
1731
1732         if (created2 && !test_CloseKey(p, tctx, &newhandle)) {
1733                 printf("CloseKey failed\n");
1734                 ret = false;
1735         }
1736
1737         if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) {
1738                 created4 = true;
1739         }
1740
1741         if (created4 && !test_CloseKey(p, tctx, &newhandle)) {
1742                 printf("CloseKey failed\n");
1743                 ret = false;
1744         }
1745
1746         if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) {
1747                 ret = false;
1748         }
1749
1750         if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) {
1751                 printf("DeleteKey failed\n");
1752                 ret = false;
1753         }
1754
1755         if (created2 && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) {
1756                 printf("DeleteKey failed\n");
1757                 ret = false;
1758         }
1759
1760         /* The HKCR hive has a very large fanout */
1761         if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1762                 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, true)) {
1763                         ret = false;
1764                 }
1765         } else {
1766                 if (!test_key(p, tctx, &handle, 0, true)) {
1767                         ret = false;
1768                 }
1769         }
1770
1771         test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1772
1773         return ret;
1774 }
1775
1776 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
1777                       void *userdata)
1778 {
1779         struct policy_handle handle, newhandle;
1780         bool ret = true, created = false, deleted = false;
1781         bool created3 = false, created_subkey = false;
1782         struct winreg_OpenHKLM r;
1783
1784         winreg_open_fn open_fn = userdata;
1785
1786         ZERO_STRUCT(r);
1787         r.in.system_name = 0;
1788         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1789         r.out.handle = &handle;
1790
1791         torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1792                                    "open");
1793
1794         test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1795
1796         if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1797                 torture_comment(tctx,
1798                                 "CreateKey (TEST_KEY_BASE) failed\n");
1799         }
1800
1801         if (!test_CreateKey(p, tctx, &handle, TEST_KEY1, NULL)) {
1802                 torture_comment(tctx,
1803                                 "CreateKey failed - not considering a failure\n");
1804         } else {
1805                 created = true;
1806         }
1807
1808         if (created && !test_FlushKey(p, tctx, &handle)) {
1809                 torture_comment(tctx, "FlushKey failed\n");
1810                 ret = false;
1811         }
1812
1813         if (created && !test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle))
1814                 torture_fail(tctx,
1815                              "CreateKey failed (OpenKey after Create didn't work)\n");
1816
1817         if (created && !test_CloseKey(p, tctx, &newhandle))
1818                 torture_fail(tctx,
1819                              "CreateKey failed (CloseKey after Open didn't work)\n");
1820
1821         if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY1)) {
1822                 torture_comment(tctx, "DeleteKey failed\n");
1823                 ret = false;
1824         } else {
1825                 deleted = true;
1826         }
1827
1828         if (created && !test_FlushKey(p, tctx, &handle)) {
1829                 torture_comment(tctx, "FlushKey failed\n");
1830                 ret = false;
1831         }
1832
1833         if (created && deleted &&
1834             !_test_OpenKey(p, tctx, &handle, TEST_KEY1,
1835                            SEC_FLAG_MAXIMUM_ALLOWED, &newhandle,
1836                            WERR_BADFILE, NULL)) {
1837                 torture_comment(tctx,
1838                                 "DeleteKey failed (OpenKey after Delete "
1839                                 "did not return WERR_BADFILE)\n");
1840                 ret = false;
1841         }
1842
1843         if (!test_GetVersion(p, tctx, &handle)) {
1844                 torture_comment(tctx, "GetVersion failed\n");
1845                 ret = false;
1846         }
1847
1848         if (created && test_CreateKey(p, tctx, &handle, TEST_KEY3, NULL)) {
1849                 created3 = true;
1850         }
1851
1852         if (created3 &&
1853             test_CreateKey(p, tctx, &handle, TEST_SUBKEY, NULL)) {
1854                 created_subkey = true;
1855         }
1856
1857         if (created_subkey &&
1858             !test_DeleteKey(p, tctx, &handle, TEST_KEY3)) {
1859                 printf("DeleteKey failed\n");
1860                 ret = false;
1861         }
1862
1863         /* The HKCR hive has a very large fanout */
1864         if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1865                 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
1866                         ret = false;
1867                 }
1868         } else {
1869                 if (!test_key(p, tctx, &handle, 0, false)) {
1870                         ret = false;
1871                 }
1872         }
1873
1874         test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1875
1876         return ret;
1877 }
1878
1879 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
1880 {
1881         struct torture_rpc_tcase *tcase;
1882         struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
1883         struct torture_test *test;
1884
1885         tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
1886                                                   &ndr_table_winreg);
1887
1888         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
1889                                           test_InitiateSystemShutdown);
1890         test->dangerous = true;
1891
1892         test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
1893                                           test_InitiateSystemShutdownEx);
1894         test->dangerous = true;
1895
1896         /* Basic tests without security descriptors */
1897         torture_rpc_tcase_add_test_ex(tcase, "HKLM-basic",
1898                                       test_Open,
1899                                       (winreg_open_fn)dcerpc_winreg_OpenHKLM);
1900         torture_rpc_tcase_add_test_ex(tcase, "HKU-basic",
1901                                       test_Open,
1902                                       (winreg_open_fn)dcerpc_winreg_OpenHKU);
1903         torture_rpc_tcase_add_test_ex(tcase, "HKCR-basic",
1904                                       test_Open,
1905                                       (winreg_open_fn)dcerpc_winreg_OpenHKCR);
1906         torture_rpc_tcase_add_test_ex(tcase, "HKCU-basic",
1907                                       test_Open,
1908                                       (winreg_open_fn)dcerpc_winreg_OpenHKCU);
1909
1910         /* Security descriptor tests */
1911         torture_rpc_tcase_add_test_ex(tcase, "HKLM-security",
1912                                       test_Open_Security,
1913                                       (winreg_open_fn)dcerpc_winreg_OpenHKLM);
1914         torture_rpc_tcase_add_test_ex(tcase, "HKU-security",
1915                                       test_Open_Security,
1916                                       (winreg_open_fn)dcerpc_winreg_OpenHKU);
1917         torture_rpc_tcase_add_test_ex(tcase, "HKCR-security",
1918                                       test_Open_Security,
1919                                       (winreg_open_fn)dcerpc_winreg_OpenHKCR);
1920         torture_rpc_tcase_add_test_ex(tcase, "HKCU-security",
1921                                       test_Open_Security,
1922                                       (winreg_open_fn)dcerpc_winreg_OpenHKCU);
1923
1924         return suite;
1925 }