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