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