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